package geometry._theory { import away3d.core.math.Quaternion; import away3d.primitives.Sphere; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix3D; import flash.geom.Orientation3D; import flash.geom.Utils3D; import flash.geom.Vector3D; import flash.utils.getTimer; import triga.maths.shapes.Line; import triga.maths.shapes.Sphere3D; import triga.maths.utils.SphereUtils; import triga.shapes.Axis; import triga.shapes.Tick; import triga.shapes.XYZ; /** * @author Nicolas Barradeau * http://en.nicoptere.net */ public class L_Quaternion2Vectors extends BaseScene { static public const DEGREES_TO_RADIANS:Number = Math.PI / 180; private var quaternionTick:Tick; private var vectorSphere:Sphere; private var pos:Vector3D; private var Q:Quaternion; private var Qstart:Quaternion; private var Qend:Quaternion; private var M:Matrix3D; private var Mstart:Matrix3D; private var Mend:Matrix3D; private var radius:Number = 150; public function L_Quaternion2Vectors() { setup(); pos = new Vector3D( radius, 0, 0 ); addMesh( new XYZ(100), new Sphere( WHITE, radius, 32, 24), quaternionTick = new Tick(null, 32, RED), vectorSphere = new Sphere( BLUE, 8 ) ); WHITE.alpha = .25; BLUE.alpha = .5; Q = new Quaternion(); Qstart = new Quaternion(); Qend = new Quaternion(); M = new Matrix3D(); Mstart = new Matrix3D(); Mend = new Matrix3D(); stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); addEventListener(Event.ENTER_FRAME, oef); } private function onMouseDown(e:MouseEvent = null ):void { //performs a ray casting //create eye - projection plane line var mouse:Vector3D = view.unproject(view.mouseX, view.mouseY); var line:Line = new Line( camera.position, mouse ); //find the intersection between the sphere and the camera - mouse ray var result:Line = SphereUtils.lineIntersectSphere( new Sphere3D( 0, 0, 0, radius ), line); //if there is an intersection if (result != null) { //this is the simplest way of doing the Quaternion computation //create a Matrix3D and make it look at a something Mstart.pointAt( result.v0, Vector3D.X_AXIS, Vector3D.Y_AXIS ); //then convert it to a Quaternion :) Qstart.fromMatrix( Mstart ); Mend.pointAt( result.v1, Vector3D.X_AXIS, Vector3D.Y_AXIS ); Qend.fromMatrix( Mend ); //debug addMesh( new Axis( result.v0, result.v1, 1, YELLOW ) );//adds a segment through the sphere addMesh( new Tick( Qstart.rotatePoint( pos ), 25, BLUE ) );//start vector addMesh( new Tick( Qend.rotatePoint( pos ), 25, GREEN ) );//end Vector } } private function oef(e:Event):void { var t:Number = .5 + Math.sin((getTimer() * .1) * DEGREES_TO_RADIANS) * .5; //spherical interpolation through the Quaternion Q.slerp( Qstart, Qend, t ); quaternionTick.position = Q.rotatePoint(pos); //the same with a Matrix3D M = Mstart.clone(); M.interpolateTo( Mend, t ); vectorSphere.position = M.transformVector(pos); } } }