We begin by downloading the file simple3d_sphere.fla from the last page of our tutorial "Simple 3D Drawing in Flash CS3". We will augment the code by adding more examples and make a few minor changes that will make the code more customizable. This is what we want to accomplish:
Download
- Download all Flash CS3 'fla' files and AS3 'as' class file: surfaces.zip
The zip file contains all the source files related to this tutorial. The fla files are thoroughly commented so they should be easy to follow. The source file for the applet above is surfaces_start.fla
Parametric Surfaces
A few words about parametric surfaces for those of our readers who are not mathematicians. A parametric
surface in the 3D xyz-space is given by the so-called parametric equations:
x=x(t,s), y=y(t,s) z=z(t,s).
As the parameters t and s go through given ranges [tmin,tmax] and [smin,smax], all the corresponding points in the
xyz-space:
[x(t,s),y(t,s),z(t,s)]
form a surface. To plot such a surface we create a mesh of points on the surface and connect them by polygons.
Namely, we choose equally spaced number of points from the interval [tmin,tmax] and equally spaced number of points from the interval [smin,smax].
The number of those points is stored in our script in the variable
'nMesh' and equals 20 or 30 or 15 (eventually we give the user control over nMesh). The t-points are indexed by j, the s-points by i.
We define the variable istep=(smax-smin)/nMesh, which, of course, gives the distance between the consecutive points in the interval
[smin,smax]. Similarly, we define the variable jstep=(tmax-tmin)/nMesh. As i runs from 0 to nMesh, and j runs from 0 to nMesh, the pairs
of values istep*i+smin, jstep*j+tmin, form a grid of points in the rectangle [smin,smax] by [tmin,tmax]. Using the parametric equations, we find the xyz-coordinates
of the corresponding point on the surface for each of the points in the grid. We obtain a bunch of points in xyz-space.
We store those points as tilesArray[i][j] in the array variable
'tilesArray'. Now we have a mesh of points in 3D. For each pair i, j, we imagine connecting points in the mesh by polygons
with vertices tilesArray[i][j], tilesArray[i+1][j], tilesArray[i][j+1]
tilesArray[i+1][j+1]. Then we project the 3D polygons onto the 2D plane and draw them. That part is explained
thoroughly in 'Simple 3D Drawing in Flash CS3' tutorial.
In simple3d_sphere.fla, we drew a sphere so we used the parametric equation of the sphere with radius 90:
x(t,s)=90sin(t)cos(s), y(t,s)=90sin(t)sin(s), z(t,s)=90cos(t).
Note that the equations are in pixel terms, 90 is the radius of the sphere in pixels. In the applet above, we draw the same sphere. It is now example 1 of 11; that is, it corresponds to exampleNum=1, where exampleNum is a new variable in the script. Here is the code from within the 'setTilesArray' function which calculates the xyz-coordinates of the mesh points on each surface:
function setTilesArray():void {
.......................
//We set the t and the s ranges for the sphere. More precisely, a partially open shpere.
//To close the sphere up, all you need to do is to change smax to 2*Math.PI.
if(exampleNum==1){
tmin=0;
tmax=Math.PI;
smin=0;
smax=7/4*Math.PI;
}
.......................
//In the portion of the code below, we define the mesh of xyz-points for the sphere:
for(i=0;i<=nMesh;i++){
curs=istep*i+smin;
tilesArray[i]=[];
for(j=0;j<=nMesh;j++){
curt=jstep*j+tmin;
if(exampleNum==1){
tilesArray[i][j]=[cubeSize*Math.cos(curs)*Math.sin(curt),
cubeSize*Math.sin(curs)*Math.sin(curt),cubeSize*Math.cos(curt)];
}
.......................
}
}
.......................
}
As you see, we stored the radius 90 of the sphere in a global variable cubeSize in order to make the code more customizable. cubeSize is, roughly, the size of the bounding box for each surface. How do we add more examples to create a gallery? By adding within the function 'setTilesArray' ranges and equations corresponding to consecutive values of exampleNum. Here is the code with the second example added:
function setTilesArray():void {
.......................
//We set the t and the s ranges for the sphere. More precisely, a partially open shpere.
//To close the sphere up, all you need to do is to change smax to 2*Math.PI.
if(exampleNum==1){
tmin=0;
tmax=Math.PI;
smin=0;
smax=7/4*Math.PI;
}
if(exampleNum==2){
tmin=0;
tmax=2*Math.PI;
smin=0;
smax=2*Math.PI;
}
.......................
//In the portion of the code below, we define the mesh of xyz-points for the sphere:
for(i=0;i<=nMesh;i++){
curs=istep*i+smin;
tilesArray[i]=[];
for(j=0;j<=nMesh;j++){
curt=jstep*j+tmin;
if(exampleNum==1){
tilesArray[i][j]=[cubeSize*Math.cos(curs)*Math.sin(curt),
cubeSize*Math.sin(curs)*Math.sin(curt),cubeSize*Math.cos(curt)];
}
if(exampleNum==2){
tilesArray[i][j]=[cubeSize/4.4*(curt)*Math.cos(curs+Math.PI)*Math.sin(Math.cos(curt)),
cubeSize/4.3*Math.sin(curs)*(2+Math.cos(curt)*2),cubeSize/2.6*(3-curt)-0.3*cubeSize];
}
.......................
}
}
.......................
}
And so you can keep adding new examples. All you need to do besides the changes shown above is to change the value of the global variable in the script named 'examplesTot' to reflect the total number of examples. Creating the two buttons that loop through the examples is very easy and it is self-explanatory if you look at surface_start.fla file. Note also that we changed event listeners a bit so surfaces would spin when the user merely mouses over them rather than have to press the button.
Why are the equations so complicated? For two reasons. First, parametric equations in xyz-coordinates for interesting surfaces are usually rather complicated. You often look for them in cylindrical or spherical coordinates and then you have to translate those coordinates to the xyz-coordinates. This translation adds lots of sines and cosines. Second, in the code above we are writing the equations in pixel terms rather than the functional terms. To make a nice sphere in our window, we draw a sphere of radius 90 (or cubeSize) rather than write equations for the unit sphere of radius 1 and then translate the xyz-values into pixel values appropriate for our cubeSize. It is not difficult to write such conversion functions but we decided to avoid doing it in this tutorial as we are presenting a set of examples rather than a general functionality 3D grapher.
How did we get parametric equations for the cool surfaces? By experimenting using our general 3D Graphers that you can find at
3D Graphers in ActionScript 3. In those graphers
you can enter arbitrary parametric equations and parameters' ranges in rectangular, cylindrical, and spherical coordinates
and see the resulting surfaces. We took those equations and translated all of them into xyz-coordinates in pixel terms.
How do we make our code easily customizable? Suppose we like our collection of surfaces but want to easily customize sizes, colors, and other visual features. If you look at the code in surfaces_start.fla, you will notice that many features can easily be changed by changing values of a few variables in the script. For example, if you change the value of the global variable 'boardSize' defined at the beginning of the script from 280 to any number, whole display board and surfaces' sizes will adjust accordingly producing very dramatic changes in appearance:
var boardSize:Number=280;
If you change, 0xFFFFFF to 0x000000 (or any other color) in the 'drawBack' function, you will change the color of the background of the board:
function drawBack():void {
shBack.graphics.lineStyle(1,0x000000);
shBack.graphics.beginFill(0xFFFFFF);
shBack.graphics.drawRect(-boardSize/2,-boardSize/2,boardSize,boardSize);
shBack.graphics.endFill();
}
It would be awfully difficult, however, to explain all the lines in the code that can be changed to customize the applet. The real answer is to put our timeline code into an ActionScript 3 class and to include in the class user-friendly customization methods. We talk about it on the next page of this tutorial.






