slerp test makc3d forked:0favorite:0lines:82license : MIT License modified : 2011-12-05 03:13:48 Embed Tweet package { import com.actionscriptbible.Example; /** * slerp test */ public class SlerpTest extends Example { public function SlerpTest () { var a:Vertex = new Vertex; a.x = 1; a.y = 0; a.z = 0; var b:Vertex = new Vertex; b.x = 3; b.y = 0; b.z = 0; var c:Vertex = a.interpolate (b, 0.5); trace (c.x, c.y, c.z); // 2,0,0 b.x = -3; c = a.interpolate (b, 0.5); trace (c.x, c.y, c.z); // 0,?,? (length = 2) b.x = 0; b.y = 1; c = a.interpolate (b, 0.5); trace (c.x, c.y, c.z); // .7071,.7071,0 c = a.interpolate (b, 1.0); trace (c.x, c.y, c.z); // 0,1,0 } } } class Vertex { public var x:Number; public var y:Number; public var z:Number; public function interpolate (other:Vertex, t:Number):Vertex { var v:Vertex = new Vertex; slerp (this.x, this.y, this.z, other.x, other.y, other.z, t); v.x = sx; v.y = sy; v.z = sz; return v; } private var cx:Number; private var cy:Number; private var cz:Number; private function cross (x1:Number, y1:Number, z1:Number, x2:Number, y2:Number, z2:Number):void { cx = y1 * z2 - z1 * y2; cy = z1 * x2 - x1 * z2; cz = x1 * y2 - y1 * x2; } private var sx:Number; private var sy:Number; private var sz:Number; private function slerp (x1:Number, y1:Number, z1:Number, x2:Number, y2:Number, z2:Number, t:Number):void { // projection plane var ax:Number, ay:Number, az:Number, bx:Number, by:Number, bz:Number; cross (x1, y1, z1, x2, y2, z2); var d:Number = cx * cx + cy * cy + cz * cz; if (d == 0) { ax = 1; ay = 0; az = 0; if ((x1 != 0) || (y1 != 0)) { bx = 0; by = 1; bz = 0; } else { bx = 0; by = 0; bz = 1; } } else { if ((cx != 0) || (cy != 0)) { ax = -cy; ay = +cx; az = 0; } else { ax = -cz; ay = 0; az = +cx; } cross (cx, cy, cz, ax, ay, az); bx = cx; by = cy; bz = cz; } // lengths var La:Number = Math.sqrt (ax * ax + ay * ay + az * az); var Lb:Number = Math.sqrt (bx * bx + by * by + bz * bz); // projection var a1:Number = (ax * x1 + ay * y1 + az * z1) / La; var b1:Number = (bx * x1 + by * y1 + bz * z1) / Lb; var a2:Number = (ax * x2 + ay * y2 + az * z2) / La; var b2:Number = (bx * x2 + by * y2 + bz * z2) / Lb; // lengths (should be mostly equal) var L1:Number = Math.sqrt (a1 * a1 + b1 * b1); var L2:Number = Math.sqrt (a2 * a2 + b2 * b2); // angles var p1:Number = Math.atan2 (a1, b1); if (p1 < 0) p1 += 2 * Math.PI; var p2:Number = Math.atan2 (a2, b2); if (p2 < 0) p2 += 2 * Math.PI; // interpolate var pt:Number = p1 * (1 - t) + p2 * t; d = p1 - p2; if ((d > Math.PI) || (d < -Math.PI)) pt += Math.PI; var Lt:Number = L1 * (1 - t) + L2 * t; // back to vector, 2D var at:Number = Lt * Math.sin (pt); var bt:Number = Lt * Math.cos (pt); // finally, 3D sx = ax * at + bx * bt; sy = ay * at + by * bt; sz = az * at + bz * bt; } } Code Fullscreen Preview Fullscreen Math.sqrt trace Math.atan2 Math.PI Math.cos Math.sin Number