(AS3) Making 3D function from the scratch

| No Comments | No TrackBacks
This is a short study to grasp how a 3D object is projected onto a 2D plane.
I could have used Vector3D or other original classes to represent the points in 3D space or sets of points(the sets making up lines), but I didn't because the point is not to write a clean code but only to show the basic concepts.

The keys points are
1. the line that determines how the perspective affects the scale of the object scale = _fl / (_fl + p3d.z);
2. and the codes to rotate the object about the y-axis p.x = Math.cos(angle) * p3d.x - Math.sin(angle) * p3d.z;
p.y = p3d.y; p.z = Math.cos(angle) * p3d.z+ Math.sin(angle) * p3d.x;

for more about rotation, see Rotation (mathematics) on Wikipedia.


package {
    import flash.display .Sprite;
    import flash.events.Event;
    public class Test3D extends Sprite {
        private var points:Array = [
                            {x:50,y:50,z:50},
                            {x:50,y:50,z:-50},
                            {x:-50,y:50,z:-50},
                            {x:-50,y:50,z:50},
                           
                            {x:50,y:-50,z:50},
                            {x:50,y:-50,z:-50},
                            {x:-50,y:-50,z:-50},
                            {x:-50,y:-50,z:50},
                            ]
        private var lines:Array = [
                           [0,1],
                           [1,2],
                           [2,3],
                           [3,0],
                           [4,5],
                           [5,6],
                           [6,7],
                           [7,4],
                           [0,4],
                           [1,5],
                           [2,6],
                           [3,7]
                           ];
                          
        private var cx:Number,cy:Number;
        private var focalLength = 200;
       
        public function Test3D() {
            //center point
            cx = stage.stageWidth / 2;
            cy = stage.stageHeight / 2;
           
            addEventListener(Event.ENTER_FRAME, h_enterframe);
        }
       
        private function h_enterframe(evt:Event):void {
            graphics.clear();
           
            var i:uint;
           
            for (i = 0; i < points.length; i ++) {
                points[i] = rotateY(points[i], 5);
            }
            for (i = 0; i < lines.length; i ++) {
                drawLine(lines[i]);
            }
        }
       
        private function rotateY(p3d:Object, angle:Number):Object {
            var p:Object = new Object();
            angle = angle /180 * Math.PI;
            p.x = Math.cos(angle) * p3d.x - Math.sin(angle) * p3d.z;
            p.y = p3d.y;
            p.z = Math.cos(angle) * p3d.z+ Math.sin(angle) * p3d.x;
            return p
        }
       
       
        private function drawLine(line:Array):void {
            graphics.lineStyle(1, 0xFFFFFF);
            var p:Object;
            var p3d:Object;
           
            p3d = points[line[0]];
            p = p3Dto2D(p3d, focalLength);
            graphics.moveTo(cx + p.x, cy + p.y);
           
            p3d = points[line[1]];
            p = p3Dto2D(p3d, focalLength);
            graphics.lineTo(cx + p.x, cy + p.y);
        }
       
        private function p3Dto2D(p3d:Object, _fl:Number):Object {
            var scale:Number;
            var p:Object = new Object();
            scale = _fl / (_fl + p3d.z);
            p.x = p3d.x  * scale;
            p.y = p3d.y * scale;
            return p
        }
       
    }
}




Install flash player 10 or later if you don't see the sample movie.

No TrackBacks

TrackBack URL: http://www.kynd.info/cp-bin/mt/mt-tb.cgi/15

Leave a comment