带有轴和角度的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个可能的问题,你有其中之一:
因为3号很可能是这种情况,所以请尝试找到邮件列表或支持论坛或任何其他框架,并与当地人交谈。 他们应该能够向你解释你的框架有什么问题。 然后回来并在这里发布解决方案!
链接地址: http://www.djcxy.com/p/81801.html