Transform+Solid Geometry
Go directly to content
|
|||
|
Simple 3D Dynamic Drawing in Flash CS4
A 3D Cube
Flash CS4 supports many new ActionScript 3 classes and methods. In particular, it provides methods that make manipulating objects in 3D much easier. Flipping images, text fields, and other flat display objects has become very simple. See our Player 10 tutorial: 'Getting Started with 3D Methods in Flash Player 10'. (Use Beta 2 versions.) Dynamic drawing in 3D is much easier, too, altough it does require the use of Matrix3D and Vector3D classes. This tutorial covers basics of dynamic drawing in Flash CS4 done in the simplest possible way.
Download
The 'fla' file linked above is exhaustively commented. The simple 3D engine provided in the file can be used for a cube as well as other surfaces. All you need to change is the coordinates of the vertices and the definition of the faces that correspond to your surface. All the code is attached to the first frame on the Timeline for maximum simplicity. Note: This tutorial has some similarities with our very populr tutorial: 'Simple 3D Drawing in Flash CS3'. There are siginficant differences, however:
Overall, the rendering technique presented here is simpler and more flexible. It requires, however, Player 10. If you'd like to be backwards compatible, you may want to use the Flash CS3 version, which, of course, works just fine in Flash CS4 and FP10 as well as in FP9. On the next page, we use our mini 3D engine to render an icosahedron. |
We gratefully acknowledge the past support of the National Science Foundation, the Mathematical Association of America, and the Mathematical Sciences Digital Library. |
Back to Flash CS4 Tutorials Back to Flash and Math Home
It has been developed with partial funding from the National Science Foundation and the Mathematical Association of America.
Simple 3D Dynamic Drawing in Flash CS4
A 3D Icosahedron
By changing the coordinates of vertices and faces in the cube file from the previous page, we created a icosahedron - the regular polyhedron with twelve vertices and twenty faces.
Download
In this applet, we added the auto rotation functionality and removed the sliders. On the next page, we discuss the code behind the applets. |
We gratefully acknowledge the past support of the National Science Foundation, the Mathematical Association of America, and the Mathematical Sciences Digital Library. |
Back to Flash CS4 Tutorials Back to Flash and Math Home
It has been developed with partial funding from the National Science Foundation and the Mathematical Association of America.
Simple 3D Dynamic Drawing in Flash CS4
The Code Behind the Simple 3D Engine
Below we discuss the code behind our simple 3D dynamic drawing renderer. We use the cube file and focus only on the portions of the code related to 3D functionality. We skip the code that controls sliders. To keep the flow of the code intact, we put our comments in the form of code comments.
/* var numVertices:int=8; var numFaces:int=6; /* var objRad:Number=70; /* var vertsVec:Vector.<Vector3D>=new Vector.<Vector3D>(); var facesVec:Vector.<Array>=new Vector.<Array>(); /* var fLen:Number=500; /* var spBoard:Sprite=new Sprite(); this.addChild(spBoard); spBoard.x=180; spBoard.y=205; spBoard.filters=[ new DropShadowFilter() ]; /* var shBack:Shape=new Shape(); spBoard.addChild(shBack); drawBack(); /* var spObject:Sprite=new Sprite(); var spObjImage:Sprite=new Sprite(); spBoard.addChild(spObjImage); spObject.rotationX=0; spObject.rotationY=0; spObject.rotationZ=0; /* /* var doRotate:Boolean=false; var prevX:Number; var prevY:Number; /* var facesColors:Array=[0xFFFFCC,0x00FF66,0x0066FF,0x33FFFF,0x9A7DDF,0xFFCCFF]; /* function drawBack():void { shBack.graphics.beginFill(0x000000); shBack.graphics.drawRect(-160,-160,320,320); shBack.graphics.endFill(); } /* setVertices(); setFaces(); rotateObj(0,0,0); /* function setVertices():void { vertsVec[0]= new Vector3D(-objRad,-objRad,-objRad); vertsVec[1]=new Vector3D(objRad,-objRad,-objRad); vertsVec[2]= new Vector3D(objRad,-objRad,objRad); vertsVec[3]=new Vector3D(-objRad,-objRad,objRad); vertsVec[4]= new Vector3D(-objRad,objRad,-objRad); vertsVec[5]=new Vector3D(objRad,objRad,-objRad); vertsVec[6]=new Vector3D(objRad,objRad,objRad); vertsVec[7]=new Vector3D(-objRad,objRad,objRad); } /* function setFaces():void { facesVec[0]=[0,4,5,1]; facesVec[1]=[1,5,6,2]; facesVec[2]=[2,6,7,3]; facesVec[3]=[3,7,4,0]; facesVec[4]=[4,5,6,7]; facesVec[5]=[0,1,2,3]; } /* /* function rotateObj(rotx:Number,roty:Number,rotz:Number):void { var i:int; var j:int;
//distArray will be used for sorting faces.
var distArray:Array=[];
//dispVec will store vertices of the cube //(or other object) projected onto xy-plane.
var dispVec:Vector.<Point>=new Vector.<Point>();
//Vertices in 3D, after rotx, roty, rotz rotations are applied, //will be stored in the next variable.
var newVertsVec:Vector.<Vector3D>=new Vector.<Vector3D>();
//z coordinates of midpoints of faces, zAverage, will be used for sorting faces.
var zAverage:Number;
var dist:Number; var curFace:int; var curFaceLen:int; var curObjMat:Matrix3D;
//The beauty of the Matrix3D class is that you don't have to manipulate //matrix elements directly. There are many methods that will do that for you //and create a matrix that corresponds to the 3D transformation that you want. //Below we are adding three rotations about the three coordinate axes //to the current matrix3D property of spObject.
spObject.transform.matrix3D.appendRotation(rotx,Vector3D.X_AXIS); spObject.transform.matrix3D.appendRotation(roty,Vector3D.Y_AXIS); spObject.transform.matrix3D.appendRotation(rotz,Vector3D.Z_AXIS);
//For simplicity of the notation below we are creating a copy of spObject's //matrix3D. Note: if we didn't use 'clone()' but a simple assignment, //any possible future changes in curObjMat would automatically be applied //to spObject.transform.matrix3D as well.
curObjMat=spObject.transform.matrix3D.clone(); spObjImage.graphics.clear();
//We are transforming vertices of our object using the current matrix3D //of spObject, curObjMat. Note: We are using 'deltaTransformVector' //and not 'transformVector' below. The deltaTransformVector method //only applies the linear portion of a transformation defined by a matrix //and ignores translation coefficients. The transformVector method takes //translation coefficients into the account. Since spObject has not been //translated, there should be no difference in our case between the two methods. //However, the transformVector method behaves differently in Flash Player //10.0.2.54 that shipped with the initial release of Flash CS4 //and the current release version 10.0.12.36.
for(i=0;i<numVertices;i++){ newVertsVec[i]=curObjMat.deltaTransformVector(vertsVec[i]); }
//For each of the transformed vertices, we are adding the fourth //coordinate 'w' and applying the 'project' method. 'project' divides //x, y, and z coordinates of a Vector3D by its w coordinate. It is //the w coordinate defined below and 'project' that create //the perspective distortion.
for(i=0;i<numVertices;i++){ newVertsVec[i].w=(fLen+newVertsVec[i].z)/fLen; newVertsVec[i].project(); }
//For each face, we are calculating the z coordinate of the center //of the face. (More precisely, the average of z coordinates of its //vertices.) We will use zAverage for sorting which face should //appear in front and which behind. The face with larger zAverage, //is farther away than a face with smaller zAverage.
for(i=0;i<numFaces;i++){
//In our case of a cube, the length of each face is 4 //but for other objects it may be different.
curFaceLen=facesVec[i].length; zAverage=0; for(j=0;j<curFaceLen;j++){ zAverage+=newVertsVec[facesVec[i][j]].z; } zAverage/=curFaceLen; dist=zAverage; distArray[i]=[dist,i]; }
//We are sorting faces by their zAverage. (See the function 'byDist' //defined later in the script.) Each element of distArray is an array //of two elements: zAverage and the number of the corresponding face. //After sorting, the faces in distArray appear in order from //the back to the front.
distArray.sort(byDist);
//We are preparing 2D points for drawing by taking x and y coordinates //of transformed vertices. Those points are stored in a Vector, dispVec.
for(i=0;i<numVertices;i++){ dispVec[i]=new Point(); dispVec[i].x=newVertsVec[i].x; dispVec[i].y=newVertsVec[i].y; }
//Now we are leaving the abstract setting and proceed to draw in spObjImage //based on points in dispVec and the order of faces detemined by distArray.
for(i=0;i<numFaces;i++){ spObjImage.graphics.lineStyle(1,0xCC0000); curFace=distArray[i][1]; curFaceLen=facesVec[curFace].length;
spObjImage.graphics.beginFill(facesColors[curFace],0.7);
spObjImage.graphics.moveTo(dispVec[facesVec[curFace][0]].x, dispVec[facesVec[curFace][0]].y);
for(j=1;j<curFaceLen;j++){ spObjImage.graphics.lineTo(dispVec[facesVec[curFace][j]].x, dispVec[facesVec[curFace][j]].y); }
spObjImage.graphics.lineTo(dispVec[facesVec[curFace][0]].x, dispVec[facesVec[curFace][0]].y);
spObjImage.graphics.endFill(); } }
/* function byDist(v:Array,w:Array):Number { if (v[0]>w[0]){ return -1; } else if (v[0]<w[0]){ return 1; } else { return 0; } }
/* function resetObj():void { spObject.transform.matrix3D=new Matrix3D(); rotateObj(0,0,0); } /* ...........................
spBoard.addEventListener(MouseEvent.MOUSE_MOVE,boardMove);
spBoard.addEventListener(MouseEvent.MOUSE_DOWN,boardDown);
...........................
function boardDown(e:MouseEvent):void { prevX=spBoard.mouseX; prevY=spBoard.mouseY; doRotate=true; }
function boardMove(e:MouseEvent):void { var locX:Number=prevX; var locY:Number=prevY; if(doRotate){ prevX=spBoard.mouseX; prevY=spBoard.mouseY; rotateObj(prevY-locY,-(prevX-locX),0); e.updateAfterEvent(); } }
........................... Download
|
We gratefully acknowledge the past support of the National Science Foundation, the Mathematical Association of America, and the Mathematical Sciences Digital Library. |
Back to Flash CS4 Tutorials Back to Flash and Math Home
It has been developed with partial funding from the National Science Foundation and the Mathematical Association of America.