使用Axis& amp;角度

时间:2010-09-28 04:56:02

标签: javascript actionscript-3 3d matrix rotation

我知道在SO和许多其他网站上都有详细记录3D旋转,但尽管阅读了无数的解释,我仍然没有弄清楚我哪里出错了。我的背景是艺术和设计,而不是数学和编程,我不确定我的攻击角度(没有双关语)是否合适。而不是粘贴我的惨淡代码拼凑而成,我包括一个描述我的问题的图像。我真正喜欢的是如何解决它的逐步措辞。伪代码很有用,但如果有人将我瞄准正确的方向或指出常见的陷阱,我会学到更多。


alt text

红色= 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

提前致谢,

凯西


编辑:开始赏金

也许我误解了这应该是怎么回事。这是另一张图片:

alt text

我认为这个洋红色矢量是轴是不正确的,橙色箭头表示基于角度绕该轴旋转?无论如何,我想根据一些方向向量定向青色立方体并旋转它。我做错了什么!?

3 个答案:

答案 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个可能的问题,你有其中一个:

  1. 数学不对,或者你不理解。 (这不应该是一个问题)
  2. 浮点算术一直是计算机的一个问题(也不应该是一个问题,因为它是一个非常基本的问题。如果你的框架无法提供解决方案,那么框架根本不具备3D编程的价值)< / LI>
  3. 您没有使用正确的框架
  4. 因为很可能第3号就是这种情况,试着找一个邮件列表或支持论坛或其他任何框架,并与那里的人交谈。他们应该能够向你解释你的框架做错了什么。然后回来并在这里发布解决方案!