带有轴和角度的3D旋转

我知道SO和许多其他网站都有很好的3D旋转记录,但尽管阅读了无数的解释,但我仍然没有弄清楚我错在哪里。 我的背景是艺术和设计,而不是数学和编程,而且我从来没有真正确定我的攻角(不是双关语)是否是正确的。 我并没有粘贴我糟糕的代码拼凑而成的东西,而是包含描述我的问题的图像。 我真正喜欢的是如何解决它的一步一步的分解。 伪代码很有用,但如果有人只会瞄准我的正确方向或指出常见的陷阱,我会了解更多信息。


替代文字

红色= X轴,绿色= Y轴,蓝色= Z轴

洋红色矢量=原点 - >一些X,Y,Z点

品红色立方体=两个洋红色矢量端点的平均值(这是否有更好的名称?)

白色矢量=两个洋红色矢量的叉积(扩展显示,实际矢量标准化)

青色立方体对象=旋转失败


我以前使用Away3D和Papervision; 在这些库中,将欧拉角应用到对象的rotationX,rotationY或rotationZ属性将使对象在本地旋转,就好像它位于原点一样,而不管其实际位置如何。 有了Three.js,情况并非如此。 修改对象的rotation.x和rotation.y属性会产生奇怪的效果,其中对象显然会在Z轴上倾斜一点。 更令人困惑的是,当物体停留在原点时会发生这种情况。 我认为也许使用四元数 - >矩阵或轴/角度 - >矩阵函数将解决我的问题,但没有骰子。 似乎有一个我没有得到的核心概念。

无论如何,我想要做的是将立方体定位到叉积矢量(白色),以使立方体的顶部朝向该矢量的方向。 然后我想沿同一个轴旋转立方体。 我附上的图片显示了比我想承认尝试实现这一结果更多小时的结果。 我的代码松散地看起来像这样:

axis = Vector3.cross(a, b)
axis.normalize()
angle = 45 * TO_RADIANS;
quat = AxisAngle2Quaternion(axis, angle)
rot = Quaternion2Matrix(quat)
cube.matrix = rot

提前致谢,

卡西


编辑:开始赏金

也许我误解了这应该如何工作。 这是另一张图片:

替代文字

我认为这个洋红色矢量是轴,而橙色箭头表示基于角度的这个轴的旋转吗? 无论如何,我想根据某个方向矢量来定位青色立方体并旋转它。 我究竟做错了什么!?


你的方法听起来是正确的,但你没有显示出a,b向量是什么,而且我猜测恒定角度仅仅用于测试。 我之前做过这个,所以我挖出了我的代码,这是我发现的数学...

给定:
originalVec =单位向量指向Y轴(立方体顶部/正常方向)
targetVec =白色矢量

现在,您需要旋转originalVec的轴和角度与targetVec对齐。 最直接的旋转轴垂直于两个输入矢量,因此需要它们的叉积。 该轴不是一个单位矢量,所以也对它进行了标准化。 旋转角度(以弧度表示)是点积的反余弦。

axis = Vector3.cross(originalVec, targetVec)
axis.normalise
angle = inversecos(Vector3.dot(originalVec, targetVec))

quat = AxisAngle2Quaternion(axis, angle)
rot = Quaternion2Matrix(quat)
cube.matrix = rot

而不是取代立方体的矩阵,我想你想用新的变换来编写它...

cube.matrix.multiplyBy(rot)

...但我不是100%确定的。 另外,我已经看到AxisAngle2Quaternion以度为角度的实现。 当输入矢量平行或相反时,轴是<0,0,0>,因此应该进行测试。 如果立方体以错误的方式旋转,那么交叉积矢量参数的顺序是错误的,我永远不会记住它们,只是尝试它们。 心连心。

编辑
我有机会和Three.js一起玩,并且攻击了一个例子来定位一个立方体。 评论显示我添加的东西和所有的定向数学发生在alignCube()中。
对齐和旋转的例子
向上/向下移动移动目标线。 鼠标左/右旋转在线上。

Three.js中的场景对象似乎都从默认情况下将autoUpdateMatrix属性设置为true的Object3D继承。 这需要设置为false,否则调用updateMatrix函数,从对象位置,缩放和旋转属性重新计算矩阵。 或者,您可以分配不同的updateMatrix功能。

如果Three.js有一些文档,它会很好:)


从Trochoid的例子中,我使用这个函数来实现第二个图像的对齐和旋转:

//object, normalized direction vector, rotation in radians
function align(target, dir, rot) {
    //Three.js uses a Y up coordinate system, so the cube inits with this vector
    var up = new THREE.Vector3(0, 1, 0);

    //euler angle between direction vector and up vector
    var angle = Math.acos(up.dot(dir));

    //cross product of the up vector and direction vector
    var axis = new THREE.Vector3();
    axis.cross(up, dir);
    axis.normalize();

    //rotation to aligns the target with the direction vector
    var rotate = THREE.Matrix4.rotationAxisAngleMatrix(axis, angle);

    //rotation around direction vector
    var revolve = THREE.Matrix4.rotationAxisAngleMatrix(dir, rot);

    //compose the rotations (order matters, can be done other ways)
    revolve.multiplySelf(rotate);

    //assign matrix (autoUpdateMatrix = false)
    target.matrix = revolve;
}

因为没有人有一个很好的解决方案,我至少可以告诉你如何靠近。

有3个可能的问题,你有其中之一:

  • 数学不对,或者你不明白。 (这里不应该是个问题)
  • 浮点算术一直是计算机的一个问题(也不应该是一个问题,因为它是一个非常基础的问题。如果你的框架无法提供解决方案,那么该框架对于3D编程毫无价值)
  • 你不使用框架的权利
  • 因为3号很可能是这种情况,所以请尝试找到邮件列表或支持论坛或任何其他框架,并与当地人交谈。 他们应该能够向你解释你的框架有什么问题。 然后回来并在这里发布解决方案!

    链接地址: http://www.djcxy.com/p/81801.html

    上一篇: 3D rotation with Axis & Angle

    下一篇: How to rotate any vector by quaternion in glm?