Math and (Quasi) Physics in Action Script 3

UV mapping

UV mapping is a method for texturing objects.

See ‘Adobe ActionScript 3.0 * UV mapping’ for details.

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;
    private var vp:Pp3dViewPoint;
    private var ang:Number = 0;
    private var va:Number = Math.PI / 180;
    private var canvas:Sprite;
    private var texture:BitmapData;
    
    public function Main() {
      addChild(canvas = new Sprite());
      canvas.x = stage.stageWidth / 2;
      canvas.y = stage.stageHeight / 2;
      addEventListener(Event.ENTER_FRAME, h_enterFrame);
      texture = new Woods(0,0);
      vp = new Pp3dViewPoint();
      defineShape();
    }
    
    protected function h_enterFrame(evt:Event):void {
      var g:Graphics = canvas.graphics;
      g.clear();
      
      ang += va;
      points[0].x = points[3].x = Math.cos(ang) * 100;
      points[1].x = points[2].x = Math.cos(ang) * -100;
      points[0].y = points[1].y = -100;
      points[2].y = points[3].y = 100;
      points[0].z = points[3].z = Math.sin(ang) * 100;
      points[1].z = points[2].z = Math.sin(ang) * -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.lineStyle(1,0xFF0000);
      g.beginBitmapFill(texture);
      g.drawTriangles( 
          Vector.<Number>([
              temp[0].x,temp[0].y,
              temp[1].x,temp[1].y,
              temp[2].x,temp[2].y,
              temp[3].x,temp[3].y
              ]), 
          Vector.<int>([0,1,3, 1,2,3]),
        Vector.<Number>([0,0,temp[0].scale, 1,0,temp[1].scale, 1,1,temp[2].scale, 0,1,temp[3].scale])
        );
      g.endFill();
    }
    
    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)];
    }
    
    
  }
}

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
    }
  }
}