fast quaternion

by lizhi
...
@author lizhi
♥0 | Line 67 | Modified 2015-01-26 14:50:20 | MIT License
play

ActionScript3 source code

/**
 * Copyright lizhi ( http://wonderfl.net/user/lizhi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/uU5l
 */

package  
{
	import flash.display.Sprite;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
        import com.actionscriptbible.Example	
/**
	 * ...
	 * @author lizhi
	 */
	public class TestQuaternion extends Example
	{
		
		public function TestQuaternion() 
		{
			var a:Vector3D = new Vector3D(Math.random(), Math.random(), Math.random());
			a.normalize();
			var matr:Matrix3D = new Matrix3D;
			matr.appendRotation(Math.random() * 100, a);
			var q:Quaternion = new Quaternion;
			q.fromMatrix(matr);
			var v1:Vector3D = new Vector3D(Math.random(),Math.random(),Math.random());
			var v2:Vector3D = q.rotatePoint(v1);
			var v3:Vector3D = q.rotatePoint2(v1);
			var v4:Vector3D = matr.transformVector(v1);
			
			trace(v1);
			trace(v2);
			trace(v3);
			trace(v4);
		}
	}
}

import flash.geom.*;
class Quaternion extends Vector3D
	{
		public function rotatePoint(vector:Vector3D, target:Vector3D = null):Vector3D
		{
			var x1:Number, y1:Number, z1:Number, w1:Number;
			var x2:Number = vector.x, y2:Number = vector.y, z2:Number = vector.z;
			
			target ||= new Vector3D();
			
			// p*q'
			w1 = -x*x2 - y*y2 - z*z2;
			x1 = w*x2 + y*z2 - z*y2;
			y1 = w*y2 - x*z2 + z*x2;
			z1 = w*z2 + x*y2 - y*x2;
			
			target.x = -w1*x + x1*w - y1*z + z1*y;
			target.y = -w1*y + x1*z + y1*w - z1*x;
			target.z = -w1*z - x1*y + y1*x + z1*w;
			
			return target;
		}
		
		//http://molecularmusings.wordpress.com/2013/05/24/a-faster-quaternion-vector-multiplication/
		//t = 2 * cross(q.xyz, v)
		//v' = v + q.w * t + cross(q.xyz, t)
		public function rotatePoint2(vector:Vector3D):Vector3D {
			var t:Vector3D = cross(this, vector);
			t.scaleBy(2);
			var t2:Vector3D = t.clone();
			t2.scaleBy(w);
			return vector.add(t2).add(cross(this,t));
		}
		
		private function cross(v1:Vector3D, v2:Vector3D):Vector3D {
			return new Vector3D(
			v1.y * v2.z - v1.z * v2.y,
			v1.z * v2.x - v1.x * v2.z,
			v1.x * v2.y - v1.y * v2.x
			);
		}
		
		public function fromMatrix(matrix:Matrix3D):void
		{
			var v:Vector3D = matrix.decompose(Orientation3D.QUATERNION)[1];
			x = v.x;
			y = v.y;
			z = v.z;
			w = v.w;
		}
		
	}