Created
November 21, 2016 15:06
-
-
Save quentint/82da2059cf78a0c989dbc3bb98a17c7d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* POINT3D CLASS Copyright (c) Brandon Williams - 3/3/2001 - [email protected] - 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