我知道在SO和许多其他网站上都有详细记录3D旋转,但尽管阅读了无数的解释,我仍然没有弄清楚我哪里出错了。我的背景是艺术和设计,而不是数学和编程,我不确定我的攻击角度(没有双关语)是否合适。而不是粘贴我的惨淡代码拼凑而成,我包括一个描述我的问题的图像。我真正喜欢的是如何解决它的逐步措辞。伪代码很有用,但如果有人将我瞄准正确的方向或指出常见的陷阱,我会学到更多。
红色= X轴,绿色= Y轴,蓝色= Z轴
洋红色载体=原点 - >一些X,Y,Z点
洋红色立方体=两个洋红色向量的端点的平均值(有更好的名称吗?)
白色矢量=两个洋红色矢量的交叉乘积(扩展显示,实际矢量归一化)
青色立方体对象=旋转失败
我之前使用过Away3D和Papervision;在这些库中,将Euler角应用于对象的rotationX,rotationY或rotationZ属性将在本地旋转对象,就好像它位于原点,而不管其实际位置如何。使用Three.js,情况并非如此。修改对象的rotation.x和rotation.y属性会产生奇怪的效果,其中对象显然在Z轴上稍微倾斜。更令人困惑的是,当对象停留在原点时会发生这种情况。我认为可能使用Quaternion - > Matrix或Axis / Angle - > Matrix函数可以解决我的问题,但没有骰子。似乎有一个我没有得到的核心概念。
无论如何,我想要做的是将立方体定向到十字产品矢量(白色),以便立方体的顶部面向该矢量的方向。然后我想沿同一轴旋转立方体。我附上的图片显示的结果比我想承认试图达到这个结果的时间要多。我的代码看起来很像:
axis = Vector3.cross(a, b)
axis.normalize()
angle = 45 * TO_RADIANS;
quat = AxisAngle2Quaternion(axis, angle)
rot = Quaternion2Matrix(quat)
cube.matrix = rot
提前致谢,
凯西
编辑:开始赏金
也许我误解了这应该是怎么回事。这是另一张图片:
我认为这个洋红色矢量是轴是不正确的,橙色箭头表示基于角度绕该轴旋转?无论如何,我想根据一些方向向量定向青色立方体并旋转它。我做错了什么!?
答案 0 :(得分:4)
你的方法听起来是正确的,但你没有显示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)
......但我不是百分百肯定的。此外,我已经看到AxisAngle2Quaternion采用度数角度的实现。当输入矢量平行或相反时,轴是< 0,0,0>。所以应该进行测试。如果多维数据集以错误的方式旋转,那么跨产品向量参数的顺序是错误的,我永远不会记住哪个并且只是尝试它们。第h。
修改强>
我有机会玩Three.js并且攻击其中一个例子来定位一个立方体。评论显示我在哪里添加了东西,所有定向数学都发生在alignCube()中
Align and Spin example
向上/向下鼠标移动目标线。将鼠标左/右旋转在线上。
Three.js中的场景对象似乎都是从Object3D继承的,默认情况下autoUpdateMatrix属性设置为true。这需要设置为false,否则将调用updateMatrix函数,从对象位置,缩放和旋转属性重新计算矩阵。或者,您可以分配不同的updateMatrix函数。
如果Three.js有一些文档,那就太好了。)
答案 1 :(得分:3)
从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;
}
答案 2 :(得分:0)
因为没有人有一个非常好的解决方案,我至少可以建议你如何靠近。
有3个可能的问题,你有其中一个:
因为很可能第3号就是这种情况,试着找一个邮件列表或支持论坛或其他任何框架,并与那里的人交谈。他们应该能够向你解释你的框架做错了什么。然后回来并在这里发布解决方案!