gpt4 book ai didi

java - Java 中的 2D vector 旋转

转载 作者:行者123 更新时间:2023-12-01 14:03:22 25 4
gpt4 key购买 nike

我尝试制作一个简单的竞赛游戏。为此,我得到了一辆带有位置 vector 和面向方向 vector 的汽车。

我有一个更新和一个输入法:

public void update(double delta) {
float rotation = 0;
if(movement.normalized().getY() < 0) {
rotation = (float) (2*Math.PI - Math.acos(movement.normalized().getX()));
} else {
rotation = (float) Math.acos(movement.normalized().getX());
}

pos = pos.add(new Vector3f((float) (Math.cos(rotation) * (movement.length() - 2) * delta), (float) (Math.sin(rotation) * (movement.length() - 2) * delta), 0f));

v1 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((rotation + basicAngel)) * radius), (float) (pos.getY() + (Math.sin((rotation + basicAngel)) * radius)), 0), new Vector2f(0, 0));
v2 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((2*Math.PI - basicAngel) + rotation)) * radius), (float) (pos.getY() + Math.sin(((2*Math.PI - basicAngel) + rotation)) * radius), 0), new Vector2f(0, 0));
v3 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((Math.PI + rotation + basicAngel)) * radius), (float)(pos.getY() + Math.sin((Math.PI + rotation + basicAngel)) * radius), 0), new Vector2f(0, 0));
v4 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((Math.PI - basicAngel) + rotation)) * radius), (float)(pos.getY() + Math.sin(((Math.PI - basicAngel) + rotation)) * radius), 0), new Vector2f(0, 0));
v5 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((windowAngel + rotation)) * windowRadius), (float)(pos.getY() + Math.sin((windowAngel + rotation)) * windowRadius), 0), new Vector2f(0, 0));
v6 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((2*Math.PI - windowAngel) + rotation)) * windowRadius), (float)(pos.getY() + Math.sin(((2*Math.PI - windowAngel) + rotation)) * windowRadius), 0), new Vector2f(0, 0));
}

第一个 if 语句检查归一化 vector 的 y 分量是否小于 0。
这确保了汽车在水平轴下方旋转。
下一行将旋转和速度应用于该位置。
带有 v1...v4 的 block 计算汽车的角点来渲染它。
v5 和 v6 是车窗的角。

public void input() {

float tempX = movement.normalized().getX();
float tempY = movement.normalized().getY();
float tempLength = movement.length();

if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
movement = movement.rotate(3);
}

if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
movement = movement.rotate(-3);
}

if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
if (tempLength <= 7) {

movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength + 0.2)));
movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength + 0.2)));

}
} else {
if(tempLength > 2) {

movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength - 0.05)));
movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength - 0.05)));

}
}

if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
if (tempLength >= 0) {

movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength - 0.2)));
movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength - 0.2)));

}
} else {
if (tempLength < 2) {

movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength + 0.05)));
movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength + 0.05)));

}
}

if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
reset();
}
}

前两个 if 语句检查是否按下了左键或右键。如果发生这种情况,运动 vector 就会旋转。接下来的两个语句检查向上和向下键,并使用以下公式将速度应用于运动 vector :

x = cos a * (l + speed)
y = sin a * (l + speed)

其中a是运动 vector 的角度
l 是运动 vector 的长度

一切都应该工作正常,而且确实如此,只是有时会计算错误,导致汽车按照预期朝不同的方向行驶。

有人可以帮我找出错误吗?

最佳答案

您不能使用 acos 来获取角度。例如,Math.cos(Math.PI*3/4) 和 Math.cos(Math.PI*5/4) 都给出 -0.7071。查看余弦曲线即可了解原因。要获取 vector 的角度,请使用 Math.atan2(y,x)。另外,为什么要将 vector 转换为角度,然后再转换回 vector 。那是没有必要的。为什么不使用归一化 vector 作为方向,使用 float/double 作为速度,并在每次更新时将其相乘?

或者你可以做 moving = moving.add(movement.normalized().mul(0.2));

关于java - Java 中的 2D vector 旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19149781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com