Math and (Quasi) Physics in Action Script 3

Cross Product

Cross product of two 3D vectors returns another vecter that is perpendicular to both the original vecters.

In this example vector A and B are indicated by blue line and green line, respectively, and their product is shown with red line.

Cross Product

A × B = [(a2 * b3 - a3 * b2) (a3 * b1 - a1 * b3) (a1 * b2 - a2 * b1)]
  • for any two vectors A = [a1 a2 a3] and B = [b1 b2 b3].

Main.as

package {
  import flash.display.*;
  import flash.events.*;
  import flash.geom.Point;
  import flash.ui.*;
  public class Main extends Sprite {
    private var points:Array,lines:Array;
    private var vp:Pp3dViewPoint;
    private var ang1:Number = 0, ang2:Number = 0;
    private var va1:Number = Math.PI / 180, va2:Number = Math.PI / 120;
    private var canvas:Sprite;
    private var colors:Array = [0x0000FF, 0xDDDDDD, 0x00FF00, 0xFF0000];
    
    public function Main() {
      addChild(canvas = new Sprite());
      canvas.x = stage.stageWidth / 2;
      canvas.y = stage.stageHeight / 2;
      addEventListener(Event.ENTER_FRAME, h_enterFrame);
    
      vp = new Pp3dViewPoint();
      defineShape();
    }
    
    protected function h_enterFrame(evt:Event):void {
      var g:Graphics = canvas.graphics;
      g.clear();
      
      ang1 += va1;
      ang2 += va2;
      points[1].x = Math.cos(ang1) * 100;
      points[1].y = Math.sin(ang1) * 100;
      points[2].x = Math.cos(ang2) * 100;
      points[2].z = Math.sin(ang2) * 100;
      
      // Cross Product
      points[3].x = (points[1].y * points[2].z - points[1].z * points[2].y);
      points[3].y = (points[1].z * points[2].x - points[1].x * points[2].z);
      points[3].z = (points[1].x * points[2].y - points[1].y * points[2].x);
      
      // Set length to 100
      var len = Pp3dObject.distance(new Pp3dPoint(0,0,0), points[3]);
      points[3].x = points[3].x / len * 100;
      points[3].y = points[3].y / len * 100;
      points[3].z = points[3].z / len * 100;
      
      
      var p:Point;
      var op:Point;
      
      var temp:Array = new Array();
      var p1:Pp2dPoint, p2:Pp2dPoint;
      for (var i:uint = 0; i < points.length; i ++) {
        temp.push(vp.projectTo2d(points[i]));
      }
      
      g.beginFill(0xDDDDDD,0.2);
      g.lineStyle(0,colors[0]);
      g.lineTo(temp[1].x, temp[1].y);
      g.lineStyle(0,colors[1]);
      g.lineTo(temp[2].x, temp[2].y);
      g.lineStyle(0,colors[2]);
      g.lineTo(0,0);
      g.endFill();
      g.lineStyle(0,colors[3]);
      g.lineTo(temp[3].x, temp[3].y);
    }
    
    private function defineShape():void {
      points = [  new Pp3dPoint(0,0,0), 
                new Pp3dPoint(0,0,0),
                new Pp3dPoint(0,0,0),
                new Pp3dPoint(0,0,0)];
      
      lines = [  [0,1],[0,2],[1,2],[0,3]];
    }
    
    
  }
}

Pp3dPoint.as

package {
  public class Pp3dPoint  extends Pp3dObject{
    private var _x:Number, _y:Number,_z:Number;
    public function Pp3dPoint(x:Number = 0, y:Number = 0, z:Number = 0) {
      super(x , y, z);
     }
  }
}

Pp3dObject.as

package {
  public class Pp3dObject {
    private var _x:Number, _y:Number,_z:Number;
    private var _rx:Number, _ry:Number,_rz:Number;
    protected var _rxSin:Number, _rxCos:Number,_rySin:Number, _ryCos:Number,_rzSin:Number, _rzCos:Number;
    public function Pp3dObject(ix:Number = 0, iy:Number = 0, iz:Number = 0) {
      x = ix;
      y = iy;
      z = iz;
      rotationX = rotationY = rotationZ = 0;
    }
    
    public function get x():Number { return _x }
    public function get y():Number { return _y }
    public function get z():Number { return _z }
    public function set x(n:Number):void { _x = n }
    public function set y(n:Number):void { _y = n }
    public function set z(n:Number):void { _z = n }
    public function get rotationX():Number { return _rx }
    public function get rotationY():Number { return _ry }
    public function get rotationZ():Number { return _rz }
    
    public function set rotationX(n:Number):void { 
      _rx = n;
      _rxSin = Math.sin(degToRad(n));
      _rxCos = Math.cos(degToRad(n));
    }
    public function set rotationY(n:Number):void { 
      _ry = n;
      _rySin = Math.sin(degToRad(n));
      _ryCos = Math.cos(degToRad(n));
    }
    public function set rotationZ(n:Number):void { 
      _rz = n;
      _rzSin = Math.sin(degToRad(n));
      _rzCos = Math.cos(degToRad(n));
    }
    
    protected function rotateX(p:Pp3dPoint, dir:int = 1):Pp3dPoint {
      var p2:Pp3dPoint = new Pp3dPoint();
      p2.x = p.x;
      p2.y = _rxCos * p.y - _rxSin * p.z;
      p2.z = _rxCos * p.z+ _rxSin * p.y;
      return p2
    }
    protected function rotateY(p:Pp3dPoint, dir:int = 1):Pp3dPoint {
      var p2:Pp3dPoint = new Pp3dPoint();
      p2.x = _ryCos * p.x - _rySin * p.z;
      p2.y = p.y;
      p2.z = _ryCos * p.z+ _rySin * p.x;
      return p2
    }
    protected function rotateZ(p:Pp3dPoint, dir:int = 1):Pp3dPoint {
      var p2:Pp3dPoint = new Pp3dPoint();
      p2.x = _rzCos * p.x - _rzSin * p.y;
      p2.y = _rzCos * p.y + _rzSin * p.x;
      p2.z = p.z;
      return p2
    }
  
    protected function radToDeg(n:Number):Number {
      return n / Math.PI * 180;
    }
    
    protected function degToRad(n:Number):Number {
      return n * Math.PI / 180;
    }
    
     static public function distance(p1:Pp3dObject, p2:Pp3dObject ):Number {
       return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z));
     }
  }
}

Pp3dViewPoint.as

package {
  import flash.geom.*;
  public class Pp3dViewPoint extends Pp3dObject {
    private var _fl:Number;
    private var _zoom:Number;
    public function Pp3dViewPoint(x:Number = 0, y:Number = 0, z:Number = -600) {
       super(x,y,z);
       zoom = 5;
       focalLength = 200;
    }
    public function set focalLength(n:Number):void {
      _fl = n;
    }
    public function set zoom(n:Number):void {
      _zoom = n;
    }
    public function get focalLength():Number {
      return _fl;
    }
    public function get zoom():Number {
      return _zoom;
    }
    
    public function projectTo2d(p3d:Pp3dPoint):Pp2dPoint {
      var p2d:Pp2dPoint = new Pp2dPoint();
      var zero:Pp3dPoint = new Pp3dPoint();
      p3d = new Pp3dPoint(p3d.x - x, p3d.y - y, p3d.z - z);
      p3d = rotateX(p3d, -1);
      p3d = rotateY(p3d, -1);
      p3d = rotateZ(p3d, -1);
      p2d.scale = _fl / p3d.z / 2 * zoom;
      p2d.x = p3d.x  * p2d.scale;
      p2d.y = p3d.y * p2d.scale;
      return p2d
    }
  }
}