Java 从PVector获取XYZ旋转
我有一个标准化的Java 从PVector获取XYZ旋转,java,3d,angle,Java,3d,Angle,我有一个标准化的PVector,表示从原点开始的方向: PVector dir = new PVector(-0.1, 0.8, 0.3); 我想得到该方向上的X、Y和Z角,所以我可以使用rotateX()等矩阵变换 在2D中,我会使用atan2()获取角度,但我不知道如何对3D点进行此操作 我找到轴的角度的方法是使用点积。我的向量都叫做重力向量,主要是因为我在引力n体模拟中使用它。我的向量实现有一些方法,比如.magnity(),可以轻松返回向量的大小,这是您需要的 基本上是将向量X、Y和Z
PVector
,表示从原点开始的方向:
PVector dir = new PVector(-0.1, 0.8, 0.3);
我想得到该方向上的X、Y和Z角,所以我可以使用rotateX()
等矩阵变换
在2D中,我会使用
atan2()
获取角度,但我不知道如何对3D点进行此操作 我找到轴的角度的方法是使用点积。我的向量都叫做重力向量,主要是因为我在引力n体模拟中使用它。我的向量实现有一些方法,比如.magnity()
,可以轻松返回向量的大小,这是您需要的
基本上是将向量X、Y和Z值相乘,然后将所有这些乘积相加。对于三维,可以这样明确地写:
public double dotProduct(GravVector vector) {
return this.x * vector.x + this.y * vector.y + this.z * vector.z;
}
现在,点积有一个很好的特性,它等于两个向量的大小乘以这两个向量之间夹角的余弦。当改变方向时,会变成这样:
这意味着要找到角度,只需对右侧的值进行反余弦运算即可
我的代码在下面执行此操作,生成带有angleX
、angleY
和angleZ
的double
s。请注意,结果以弧度为单位。如果你想用度数来表示,你需要用弧度乘以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
您可以很容易地将其推广到任意两个向量之间的角度(不管它们是否为单位大小),如下所示:
< > >编辑> 。考虑到任何一个轴,点积总是等同于相关组件。因此,对于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]的示例向量,如果调用并打印这些方法中每种方法的值,将产生以下结果,这些结果与上述值一致:
x, rad: 0.7853981633974484
y, rad: 0.7853981633974484
z, rad: 1.5707963267948966
我找到轴的角度的方法是使用点积。我的向量都叫做重力向量,主要是因为我在引力n体模拟中使用它。我的向量实现有一些方法,比如
.magnity()
,可以轻松返回向量的大小,这是您需要的
基本上是将向量X、Y和Z值相乘,然后将所有这些乘积相加。对于三维,可以这样明确地写:
public double dotProduct(GravVector vector) {
return this.x * vector.x + this.y * vector.y + this.z * vector.z;
}
现在,点积有一个很好的特性,它等于两个向量的大小乘以这两个向量之间夹角的余弦。当改变方向时,会变成这样:
这意味着要找到角度,只需对右侧的值进行反余弦运算即可
我的代码在下面执行此操作,生成带有angleX
、angleY
和angleZ
的double
s。请注意,结果以弧度为单位。如果你想用度数来表示,你需要用弧度乘以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
您可以很容易地将其推广到任意两个向量之间的角度(不管它们是否为单位大小),如下所示:
< > >编辑> 。考虑到任何一个轴,点积总是等同于相关组件。因此,对于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]的示例向量,如果调用并打印这些方法中每种方法的值,将产生以下结果,这些结果与上述值一致:
x, rad: 0.7853981633974484
y, rad: 0.7853981633974484
z, rad: 1.5707963267948966
不是100%确定我是否理解你所说的x,y,z角的意思,但我认为你的意思是,在“z角”的情况下,用你的话来说,旋转一个向量所需要的角度,原点是(0,0,0),终点是z是0,它沿着x或y轴(这是你的选择),将其绕Z轴旋转,以使生成的向量是原始向量在X,Y平面上的投影,顺便说一句,该投影仅为(X,Y,0) 围绕Z的角度将是y/x或(x/y)的反正切
对X轴和Y轴执行相同的操作,就得到了这三个旋转角度。你只需要其中的两个和一个初始向量,但我不知道这是否与问题有关。我不100%确定我是否理解你所说的x,y,z角的意思,但我想你的意思是,在“z角”的情况下,用你的话来说,用原点(0,0,0)旋转向量所需要的角度最后,Z是0,它沿着X或Y轴(这是你的选择),绕Z轴旋转,得到的向量是原始向量在X,Y平面上的投影,顺便说一句,投影就是(X,Y,0) 围绕Z的角度将是y/x或(x/y)的反正切
对X轴和Y轴执行相同的操作,就得到了这三个旋转角度。你只需要其中的两个和一个初始向量,但我不知道这是否与问题有关。我要补充一点,关于欧拉角和相关的东西有很多问题,但不确定这是否适用于获得XYZ角度?在向量和坐标之间使用点积axes@ifly6–你能发布一些代码作为答案吗?我的向量数学是。。。太糟糕了,我现在正在写这篇文章,我要补充一点,关于欧拉角和一些相关的问题,b