来自matrix3d的四元数slerp附加旋转俯仰,滚转,偏航AS3

时间:2015-04-10 16:47:10

标签: actionscript-3 quaternions away3d

我试图将一个物体的俯仰,滚动和偏航附加到一个matrix3d,然后得到四元数并旋转旋转......但结果它真的很不稳定,这是第一次我处理四元数并且我是3d编程的新手,到目前为止我猜测正确使用四元数(以避免万向节锁定)是否有一种方法可以不追加"追加"只是"分配"新的轮值?

pitch=(obj.pitch);
yaw=(obj.yaw);
roll=(obj.roll);

mtrx:Matrix3D=new Matrix3D();
mtrx=setV[a].transform.clone();

mtrx.appendRotation(pitch,Vector3D.Y_AXIS);
mtrx.appendRotation(roll,Vector3D.X_AXIS);
mtrx.appendRotation(yaw,Vector3D.Z_AXIS);

quat1:Quaternion=new Quaternion;
quat1.fromMatrix(mtrx);
quat2:Quaternion=new Quaternion;
quat2.fromMatrix(setV[a].transform);

quat2.slerp(quat2,quat1,0.1);

mtrx2:Matrix3D=new Matrix3D();              
quat1.toMatrix3D(mtrx2);

setV[a].transform=mtrx.clone();

1 个答案:

答案 0 :(得分:0)

检查这个课程,我是为IMU Brick制作的,所以如果你有类似的设备,它可能适合你。我是从javascript获取值,但在您的情况下可能会有所不同。您可能还需要调整relX,relY ...等(例如,观察我必须将quaternionArray [0]更改为否定等)。

package com.company.product.imu {

    import flash.external.ExternalInterface;
    import flash.geom.Matrix3D;

    public final class Brick {

        private static var _relX:Number;
        private static var _relY:Number;
        private static var _relZ:Number;
        private static var _relW:Number;

        public function Brick() {
            super();
            throw new Error("Brick is a static class.");
        }

        public static function saveOrientation():void {
            var quaternionString:String;
            if(ExternalInterface.available) {
                try {
                    quaternionString = ExternalInterface.call("getQuaternionString");
                }
                catch(e:SecurityError) {}
            }
            var quaternionArray:Array = quaternionString.split(",");
            _relX = -quaternionArray[0];
            _relY = -quaternionArray[1];
            _relZ = quaternionArray[2];
            _relW = quaternionArray[3];
        }

        public static function getTransformationMatrix():Matrix3D {
            var quaternionString:String;
            if(isNaN(_relX)) {
                saveOrientation();
            }
            if(ExternalInterface.available) {
                try {
                    quaternionString = ExternalInterface.call("getQuaternionString");
                }
                catch(e:SecurityError) {}
            }
            var quaternionArray:Array = quaternionString.split(",");
            var x:Number = -quaternionArray[0];
            var y:Number = -quaternionArray[1];
            var z:Number = quaternionArray[2];
            var w:Number = -quaternionArray[3];

            var wn:Number = w * _relW - x * _relX - y * _relY - z * _relZ;
            var xn:Number = w * _relX + x * _relW + y * _relZ - z * _relY;
            var yn:Number = w * _relY - x * _relZ + y * _relW + z * _relX;
            var zn:Number = w * _relZ + x * _relY - y * _relX + z * _relW;

            x = xn;
            y = yn;
            z = zn;
            w = wn;

            var xx:Number = x * x;
            var yy:Number = y * y;
            var zz:Number = z * z;
            var xy:Number = x * y;
            var xz:Number = x * z;
            var yz:Number = y * z;
            var wx:Number = w * x;
            var wy:Number = w * y;
            var wz:Number = w * z;

            var matrix:Matrix3D = new Matrix3D();
            var matrixData:Vector.<Number> = new <Number>[1 - 2 * (yy + zz), 2 * (xy - wz), 2 * (xz + wy), 0.0,
                                                          2 * (xy + wz), 1 - 2 * (xx + zz), 2 * (yz - wx), 0.0,
                                                          2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (xx + yy), 0.0,
                                                          0.0, 0.0, 0.0, 1];
            matrix.rawData = matrixData;
            return matrix;
        }
    }
}

然后,在其他一些课程(我的主要课程,在这种情况下),我只是打电话:

private function onEnterFrame(e:Event):void {
    if(_drill.isLoaded) {
        _drill.transform = Brick.getTransformationMatrix();
        //other things to perform
    }
    _view.render();
}

另请注意,在我的情况下,js错误捕获没有意义我确信它永远不会失败。当然,如果它可能适合你,你将不得不处理它(在这种情况下我的代码实际上会抛出一些错误)。