如何使用Joml将归一化向量向一个点旋转

时间:2019-02-11 14:47:13

标签: java math

这就是我对如何将向量向点旋转的理解:

向量A =(0,0,-1)
向量B =(15,164,16)

第1步:规范B
步骤2:计算A和归一化B之间的角度
步骤3:计算A与归一化B的叉积

然后,围绕步骤3中计算的轴旋转A到步骤2中计算的角度(以弧度为单位),应该给我B的归一化向量。

但是,尝试与joml一起使用时,我没有得到正确的结果。 这是我的代码:

function get_all_quiz($courseid) {
    global $DB;
    return $DB->get_records('quiz', array('course' => $courseid));
}

这将产生以下输出:

Vector3f vecA = new Vector3f(0.0f, 0.0f, -1.0f);
System.out.println("Vector A: " + vecA.toString(FORMAT));
Vector3f vecB = new Vector3f(0, 0.5f, 1.0f).normalize();
System.out.println("Vector B: " + vecB.toString(FORMAT));

float angle = (float) Math.acos(vecA.dot(vecB));
System.out.println("Angle between the two: " + angle + "(" + Math.toDegrees(angle) + "°)");

Vector3f rotationAxis = new Vector3f();
vecA.cross(vecB, rotationAxis);

Vector3f rotatedVector = new Vector3f();
vecA.rotateAxis(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z, rotatedVector).normalize();

System.out.println("Rotated Vector: " + rotatedVector.toString(FORMAT));

根据上述计算,旋转后的矢量不应该等于矢量B的输出吗?

2 个答案:

答案 0 :(得分:0)

您必须归一化rotationAxis-向量,因为轴由单位向量表示(例如,见https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation)。

因此,只需替换

vecA.cross(vecB, rotationAxis);

使用

vecA.cross(vecB, rotationAxis).normalize();

它有效:

Vector A: (0 0 -1)
Vector B: (0 0.44721 0.89443)
Angle between the two: 2.6779451(153.43495411905388°)
Rotated Vector: (0 0.44721 0.89443)

答案 1 :(得分:0)

如果您只关心最终结果(旋转的矢量),而无需以某种方式(例如3x3矩阵或四元数)保留实际旋转,则最简单的解决方案显然是:

Vector3f rotatedVector = new Vector3f(vecB).normalize();

因为最终向量将总是{em> 被vecB归一化,并且整个计算完全独立于源向量vecA

但是,如果您希望保留实际旋转-本质上是正交正交变换-以便也可以将其应用于其他向量,请使用Quaternionf.rotateTo(srcDir, destDir)。这将为您提供一个四元数,可用于通过Quaternionf.transform(v)进行相同的旋转来变换任何矢量。