Skip to content

Instantly share code, notes, and snippets.

@quentint
Created November 21, 2016 15:06
Show Gist options
  • Save quentint/82da2059cf78a0c989dbc3bb98a17c7d to your computer and use it in GitHub Desktop.
Save quentint/82da2059cf78a0c989dbc3bb98a17c7d to your computer and use it in GitHub Desktop.
/*
* POINT3D CLASS Copyright (c) Brandon Williams - 3/3/2001 - ahab@houston.rr.com - use freely with accreditation.
*
*
* CONSTRUCTOR: point3d (px, py, pz, pcx, pcy, MC, psize, D)
*
* -- creates a new 3d point (can be used for 2d by making pz=0). The arguements "px", "py",
* and "pz" is the point's ordered triplet (x,y,z). Arguements "pcx" and "pcy" is where on
* the stage you want the origin to be. Since (0,0) on a computer screen is in the top left
* hand corner those variables are used to center the point's rotations/movements. This way
* you can move your point's around in a normal coordinate system but then when it comes time
* to rendering you can shift everything temporarily so it looks correct. The arguement "MC"
* is the name of the movie clip which will be rendered on the stage to represent your
* "point3d". See the notes at down below for the specifications of the name. "psize"
* is the size of the movie clip at the origin. And the last arguement is used
* for adding perspective to your points for rendering ("D"). You can play around with this
* value to see what you like best. It represents the distance from your eye to the screen
* so something like 400 or 500 is good enough.
*
*
* DEPENDENCIES -- the class uses my vector3d class too so I have an include statement in here for the vector script.
* Note that you need my vector class to use this and note that you do not need to include the vector
* class in your main file when using this.
*
*
* METHODS:
*
* p.reset (px, py, pz) -- allows you to reset the position of point "p"
*
* p.recenter (pcx, pcy) -- allows you to re-center the origin
*
* p.resize (psize) -- allows you to change the size of the movie clip that is representing point "p"
*
* p.translate (tx, ty, tz) -- translates point "p" on the x-, y-, and z-axis by increments of "tx", "ty",
* and "tz" respectively.
*
* p.scale (sx, sy, sz) -- scales point "p" on the x-, y-, and z-axis by the ratios "sx", "sy", and "sz"
*
* rotatex_matrix (a) -- constructs a rotation matrix around the x-axis by an angle of "a" (in radians).
* Note that this is not a member function but instead an entirely different
* object but is needed in rotations.
*
* rotatey_matrix (a) -- constructs a rotation matrix around the y-axis by an angle of "a" (in radians).
* Note that this is not a member function but instead an entirely different
* object but is needed in rotations.
*
* rotatez_matrix (a) -- constructs a rotation matrix around the z-axis by an angle of "a" (in radians).
* Note that this is not a member function but instead an entirely different
* object but is needed in rotations.
*
* axis_matrix (axis, a) -- creates a rotation matrix around an arbitrary axis "axis" (should to be
* a "vector3d" from my vector3d class) by an angle of "a" (in radians).
* Again this is not a member function but a separate object.
*
* p.rotate (mat) -- rotates point "p" with one of the above matrices.
*
* p.perspective () -- updates the perspective data members in the "point3d"
*
* p.render () -- positions the movie clip on the screen
*
* p.set_depth () -- sets the depth of the movie clip
*
*
* ADDITION FUNCTIONS
*
* distance (p1, p2) -- returns the distance between "p1" and "p2"
*
* point_line_d (p, v, s) -- returns the distance from a point to a line. The line is described with the vector
* "v" as the line's direction and the point "s" (can also be a vector) as any arbitrary
* point on the line.
*
* point_angle (p1, p2, p3) -- returns the cosine of the angle made up of "p1", "p2", and "p3" (in that order)
*
*
* NOTES:
*
* -- This class is fully functional with the vector class. Meaning you can take the dot product of a
* "vector3d" and a "point3d" and you will get the correct results. Therefore you can also add
* a "vector3d" and a "point3d" which is sometimes know as moving a point due to velocity (hint, hint).
*
* -- the most CPU demanding functions are the matrix constructors (they are not all that bad though). You
* should only call this once for every time you want to rotate a group of points.
*
* -- the rotation around any arbitrary angle is probably the most useful one. The axis must be described
* with a vector, in particular, a unit vector. The "axis_matrix" method will normalize the vector for
* you (without change the axis vector) so you do not need to worry about that.
*
* -- the "MC" parameter in the "point3d" constructor is kind of a draw back to this class. For some reason
* the only way I could get everything to work is if the movie clip is always assumed to be on the _root of
* the stage. Therefore you only have to pass the name of the movie clip and not the path to the movie clip,
* since the path is always assumed to be on the main stage. See the very bottom for examples.
*
* -- remember that you are not limited by how many different axes you can rotate around. You are limited by
* Flash of course, speed wise, but you could rotate a point around the x-, y-, and z-axes and then rotate
* around an addition three or four axes which you specify.
*/
/************************************************************************************************************************************************************************/
//Attention: certaines méthodes ne sont peut-être pas encore utilisable en as3. Fonctionnent pour l'instant: le constructeur, reset, recenter, resize, translate, scale,
//rotatex, rotatey, rotatez, rotate, perspective, render et setDepth. Le reste n'a pas été testé.
/************************************************************************************************************************************************************************/
package
{
import flash.display.MovieClip;
public class P3D {
var vecteur3D:Vector3d;
var x:Number, y:Number, z:Number, xctr:Number,yctr:Number,size:Number,D:Number, per_size:Number, xp:Number, yp:Number;
var _mc:MovieClip;
var MC:String;
function P3D(x1, y1, z1, pcx, pcy, MC1, psize, D1) {
x=x1;
y=y1;
z=z1;
vecteur3D = new Vector3d(x1,y1,z1);// position vector
xctr = pcx;// x-position on 2d screen
yctr = pcy;// y-position on 2d screen
MC = MC1.name;// path to movie clip which will represent "point3d"
_mc = MC1;
size = psize;// size of point at origin
per_size = psize;// size of point with perspective
D = D1;// used for perspective -- distance from your eye to the screen
}
function point3d_reset(px, py, pz)
{
this.x = px;
this.y = py;
this.z = pz;
}
function point3d_recenter(pcx, pcy)
{
this.xctr = pcx;
this.yctr = pcy;
}
function point3d_resize(psize)
{
this.size = psize;
}
function point3d_translate(tx, ty, tz)
{
this.x += tx;
this.y += ty;
this.z += tz;
}
function point3d_scale(sx, sy, sz)
{
this.x *= sx;
this.y *= sy;
this.z *= sz;
}
public static function rotatex_matrix(a):Array
{
var M:Array = new Array ();
M[0] = new Array(1,0,0);
M[1] = new Array(0,Math.cos(a), - Math.sin(a));
M[2] = new Array(0,Math.sin(a),Math.cos(a));
return M;
}
public static function rotatey_matrix(a):Array
{
var M:Array = new Array ();
M[0] = new Array(Math.cos(a),0, - Math.sin(a));
M[1] = new Array(0,1,0);
M[2] = new Array(Math.sin(a),0,Math.cos(a));
return M;
}
public static function rotatez_matrix(a):Array
{
var M:Array = new Array ();
M[0] = new Array(Math.cos(a), - Math.sin(a),0);
M[1] = new Array(Math.sin(a),Math.cos(a),0);
M[2] = new Array(0,0,1);
return M;
}
public static function axis_matrix(axis, a):Array
{
var s,c,t,a;
var ax = new Vector3d(axis.x,axis.y,axis.z);
ax.unit_vector();
a *= -1;// negate angle
s = Math.sin(a);
c = Math.cos(a);
t = 1 - c;
var M:Array = new Array (3);
M[0] = new Array(3);
M[1] = new Array(3);
M[2] = new Array(3);
M[0][0] = t * ax.x * ax.x + c;
M[0][1] = t * ax.x * ax.y + s * ax.z;
M[0][2] = t * ax.x * ax.z - ax.x * ax.y;
M[1][0] = t * ax.x * ax.y - s * ax.z;
M[1][1] = t * ax.y * ax.y + c;
M[1][2] = t * ax.y * ax.z + s * ax.z;
M[2][0] = t * ax.x * ax.z + s * ax.y;
M[2][1] = t * ax.y * ax.z - s * ax.x;
M[2][2] = t * ax.z * ax.z + c;
return M;
}
public function point3d_rotate(mat:Array)
{
var rx,ry,rz;
rx = this.x * mat[0][0] + this.y * mat[0][1] + this.z * mat[0][2];
ry = this.x * mat[1][0] + this.y * mat[1][1] + this.z * mat[1][2];
rz = this.x * mat[2][0] + this.y * mat[2][1] + this.z * mat[2][2];
this.x = rx;
this.y = ry;
this.z = rz;
}
public function point3d_perspective()
{
var per;
per = this.D / (this.z + this.D);
this.xp = this.x * per;
this.yp = this.y * per;
this.per_size = this.size * per;
}
public function point3d_render()
{
/*_root[this.name]._x = this.xctr + this.xp;
_root[this.name]._y = this.yctr - this.yp;
_root[this.name]._xscale = _root[this.name]._yscale = this.per_size;*/
//trace(this._mc.x);
this._mc.x = this.xctr + this.xp;
this._mc.y = this.yctr - this.yp;
this._mc.scaleX = this._mc.scaleY = this.per_size/100;
this.point3d_setDepth();
}
function point3d_setDepth()
{
//addChild remet au premier plan
if(this.z<0)
this._mc.parent.addChild(this._mc);
}
// used for debuggin -- prints properties of point
function point3d_printPoint()
{
//trace("Point: " + this.name);
trace("x = " + this.x);
trace("y = " + this.y);
trace("z = " + this.z);
}
// prototypes
/*point3d.prototype.vector_constr = vector3d.prototype.constructor;
point3d.prototype.__proto__ = vector3d.prototype;
point3d.prototype.reset = point3d_reset;
point3d.prototype.recenter = point3d_recenter;
point3d.prototype.resize = point3d_resize;
point3d.prototype.translate = point3d_translate;
point3d.prototype.scale = point3d_scale;
point3d.prototype.rotate = point3d_rotate;
point3d.prototype.perspective = point3d_perspective;
point3d.prototype.render = point3d_render;
point3d.prototype.set_depth = point3d_setDepth;
point3d.prototype.print_point = point3d_printPoint;
*/
// additional functions
function distance(a, b)
{
return (Math.sqrt ((a.x-b.x) * (a.x-b.x) + (a.y-b.y) * (a.y-b.y) + (a.z-b.z) * (a.z-b.z)));
}
function point_line_d1(p, v, s)
{
var temp:Vector3d,vect:Vector3d;
vect = new Vector3d(p.x - s.x,p.y - s.y,p.z - s.z);
temp.vector3d_crossProduct(vect, v);
return (temp.vector3d_norm () / v.vector3d_norm ());
}
/*function point_angle(a, b, c)
{
var v,w;
v = new Vector3d(a.x - b.x,a.y - b.y,a.z - b.z);
w = new Vector3d(c.x - b.x,c.y - b.y,c.z - b.z);
return (angle_vector3d(v, w));
}*/
}
}
/*
* EXAMPLE
*
* This is an example of what a script would look like to control a bunch of points. It assumes that you
* have a movie clip on the _root of the movie named "dot" which will be used to represent your "point3d's".
* This script would work best if put in a separate blank movie clip.
*
*
*
* onClipEvent (load)
* {
* // include point3d class
* #include "point3d_class.as"
*
* // x- and y-center of screen
* XCTR = 275;
* YCTR = 200;
*
* // size of movie clip at origin
* SIZE = 40;
*
* // used for perspective -- distance from the screen to your eye
* D = 400;
*
* // used for translating between degrees and radians
* TRANS = Math.PI / 180;
*
* // the number of points to put out
* NUM_POINTS = 20;
*
* // the array which will hold the points' information
* points = new Array (NUM_POINTS);
*
* // create points
* for (var j = 0; j < NUM_POINTS; j++)
* {
* // duplicate the "dot" movie clip
* _root.dot.duplicateMovieClip ("dot"+j, j);
*
* // get three random numbers for placing the dots out randomly
* var r1 = random (200) - 100; // x-position
* var r2 = random (200) - 100; // y-position
* var r3 = random (200) - 100; // z-position
*
* // name of movie clip
* var name = "dot" + j;
*
* // create a new "point3d" and set it's values
* points[j] = new point3d (r1, r2, r3, XCTR, YCTR, name, SIZE, D);
* }
* }
*
*
* // main loop
* onClipEvent (enterFrame)
* {
* // set up a rotation matrix for the x-, y-, and z-axes with their angles of rotation equal to two
* rot_x = new rotatex_matrix (2 * TRANS);
* rot_y = new rotatey_matrix (2 * TRANS);
* rot_z = new rotatez_matrix (2 * TRANS);
*
* // rotate, add perspective, and render all points
* for (var j = 0; j < NUM_POINTS; j++)
* {
* // rotate on x-axis
* points[j].rotate (rot_x);
* // rotate on y-axis
* points[j].rotate (rot_y);
* // rotate on z-axis
* points[j].rotate (rot_z);
*
* // update perspective
* points[j].perspective ();
*
* // render point
* points[j].render ();
* }
* }
*
*
*
*/
// end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment