在Actionscript 3中,我有一个3D对象,它绕着x,y和z轴随机旋转。我希望能够将其停在适当的位置,然后将其旋转到采用最短路径的指定旋转之间。似乎四元数是完成这项工作的正确工具,但我不确定如何正确地对其进行补间。我正在尝试补间轴角旋转,然后将其转换为四元数。到目前为止,这是我的测试代码。
var startV3DV:Vector.<Vector3D> = new <Vector3D>[positionV3D, new Vector3D(0,1,0,0), scaleV3D];
var endV3DV:Vector.<Vector3D> = new <Vector3D>[positionV3D, new Vector3D(0,1,0,Math.PI), scaleV3D];
var recomposeV3DV:Vector.<Vector3D> = new <Vector3D>[positionV3D, new Vector3D(0,0,0,0), scaleV3D];
TweenMax.to(startV3DV[1], 2, {x:endV3DV[1].x, y:endV3D[1].y, z:endV3D[1].z, w:endV3D[1].w, onUpdate:quat});
var quatV3D:Vector3D = new Vector3D();
function quat():void {
quatV3D.x = currentV3D[1].x * Math.sin(currentV3D[1].w * .5);
quatV3D.y = currentV3D[1].y * Math.sin(currentV3D[1].w * .5);
quatV3D.z = currentV3D[1].z * Math.sin(currentV3D[1].w * .5);
quatV3D.w = Math.cos(currentV3D[1].w * .5);
recomposeV3DV[1] = quatV3D;
myMatrix3D.recompose(recomposeV3DV,"quaternion");
}
它实际上使对象绕其y轴旋转了一段时间,但是当它达到PI / 2时,它出错了,我在重组行上收到“ ArgumentError:错误#2004:参数之一无效”,我认为这意味着quatV3D属性之一不适合四元数公式。有关如何正确执行此操作的任何想法?
我无法使用您提供的数据进行复制。但是似乎您正在使用currentV3D Vector来补间startV3DV,示例代码中未提及。它可能包含无效数据,例如0轴或0比例。
此外,这不是四元数应该用于补间的方式。您似乎要在此处进行的操作是在两个轴/角度表示之间进行补间,然后在每次更新时从中生成一个四元数。您也可以直接使用内置的“ axisAngle”旋转模式进行重构。这可能无法满足您的期望,因为1)不能保证采用最短的角度,并且2)当轴不同时-所有插值都将取决于插值的样子;)
您应该执行的操作是将开始旋转和结束旋转转换为四元数,方法与当前在quat()中进行的相同,然后在这些四元数之间进行插值。您仍然需要更正最短路径:如果两个四元数之间的4分量点积<0,则需要取反其中一个的所有分量。最后,您必须对quat重新进行规范化(再次在4分量方向上,旋转四元数必须为单位长度)。
如果您想坚持使用TweenMax,您仍然可以做这样的事情(可能包含一些粗心的错误,但是您应该明白要点):
t = 0;
TweenMax.to(this, 2, {t:1, onUpdate:lerp});
function lerp() : void
{
var x:Number, y:Number, z:Number, w:Number;
var w1:Number = start.w, x1:Number = start.x, y1:Number = start.y, z1:Number = start.z;
var w2:Number = end.w, end:Number = end.x, y2:Number = end.y, z2:Number = end.z;
var len:Number;
// shortest direction
if (x1*x2 + y1*y2 + z1*z2 + w1*w2 < 0) {
x2 = -x2;
y2 = -y2;
z2 = -z2;
w2 = -w2;
}
x = x1 + t*(x2 - x1);
y = y1 + t*(y2 - y1);
z = z1 + t*(z2 - z1);
w = w1 + t*(w2 - w1);
len = 1.0/Math.sqrt(x*x + y*y + z*z + w*w);
quatV3D.x = x*len;
quatV3D.y = y*len;
quatV3D.z = z*len;
quatV3D.w = w*len;
recomposeV3DV[1] = quatV3D;
myMatrix3D.recompose(recomposeV3DV,"quaternion");
}
您可能还想研究球形线性插值(“ slerp”),它们与线性插值不同,具有恒定的角速度。我会很懒惰,只是将您定向到我几年前写的Away3D四元数类:https : //github.com/away3d/away3d-core-fp11/blob/008b1d83d3330281034b90ca7072722a9f486958/src/away3d/core/math/Quaternion 。如
希望这可以帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句