gpt4 book ai didi

java - 从 PVector 获取 XYZ 旋转

转载 作者:行者123 更新时间:2023-12-02 02:20:48 26 4
gpt4 key购买 nike

我有一个标准化的PVector,它表示从原点开始的方向:

PVector dir = new PVector(-0.1, 0.8, 0.3);

我想获得该方向的 X、Y 和 Z 角度,这样我就可以使用 rotateX() 等矩阵变换。

在 2D 中,我会使用 atan2() 来获取角度,但我不知道如何对 3D 点执行此操作。

最佳答案

我找到与轴的角度的方法是使用点积。我的 vector 都称为 GravVector,主要是因为我在引力 n 体模拟中使用它。我的 vector 实现具有诸如 .magnitude() 之类的方法,可以轻松返回 vector 的大小,这是您需要的。

dot product基本上是乘以 vector X、Y 和 Z 值,然后对所有这些乘积求和。对于三个维度,可以明确地写成这样:

public double dotProduct(GravVector vector) {
return this.x * vector.x + this.y * vector.y + this.z * vector.z;
}

现在,点积具有一个很好的特性,其中乘积等于两个 vector 的大小乘以这两个 vector 之间的角度的余弦。当移动时,变成这样:

Latex is the best formatting.

这意味着要找到角度,您只需对右侧的值进行反余弦即可。

我的代码在下面执行此操作,生成带有 angleXangleYangleZdouble。请注意,结果以弧度为单位。如果您想要以度为单位,则需要将您的弧度值乘以 180/Math.PI

GravVector vector = new GravVector(1, 1, 0);

// magnitude * 1 because the magnitude of the temporary vector is 1.
double angleX = Math.acos(vector.dotProduct(new GravVector(1, 0, 0)) / (vector.magnitude() * 1));
double angleY = Math.acos(vector.dotProduct(new GravVector(0, 1, 0)) / (vector.magnitude() * 1));
double angleZ = Math.acos(vector.dotProduct(new GravVector(0, 0, 1)) / (vector.magnitude() * 1));

// in radians
System.out.println(String.format("x: %.2f, y: %.2f, z: %.2f",
angleX, angleY, angleZ));

// in degrees
System.out.println(String.format("x: %.2f, y: %.2f, z: %.2f",
angleX * 180 / Math.PI,
angleY * 180 / Math.PI,
angleZ * 180 / Math.PI));

打印到控制台的输出是,第一行以弧度为单位,第二行以度为单位:

x: 0.79, y: 0.79, z: 1.57
x: 45.00, y: 45.00, z: 90.00

您可以轻松地概括这一点以获取任意两个 vector 之间的角度(无论它们是否具有单位大小并不重要),如下所示:

public static double angleBetween(GravVector v1, GravVector v2) {
return Math.acos(v1.dotProduct(v2) / (v1.magnitude() * v2.magnitude()));
// in radians
}
<小时/>

编辑。考虑到对于任何一个轴,点积将始终等于相关组件。因此,对于 X 轴,它只是 X 分量。

这意味着您可以简化计算并使用如下方法:

public static double xAngle(GravVector vector) {
return Math.acos(vector.x / (vector.magnitude()));
}

public static double yAngle(GravVector vector) {
return Math.acos(vector.y / (vector.magnitude()));
}

public static double zAngle(GravVector vector) {
return Math.acos(vector.z / (vector.magnitude()));
}

对于分量为 [1, 1, 0] 的示例 vector ,如果您调用并打印每个方法的值,将得到以下结果,与上述值一致:

x, rad: 0.7853981633974484
y, rad: 0.7853981633974484
z, rad: 1.5707963267948966

关于java - 从 PVector 获取 XYZ 旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48532207/

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