-
Vector Class
This is a simple Vector class I have written.
Please provide suggestions on what functions(methods?) to add to it or how to optimize it.
Thanks a bunch,
Jake
code:
//immutable Vector2D Class
class Vector2D
{
private var myComps : Object; //x and y components of the vector
function Vector2D(xComp : Number, yComp : Number)
{
myComps = new Object();
myComps.x = xComp;
myComps.y = yComp;
}
//return a new vector that is the vector sum of this and that
public function vectorSum(that : Vector2D) : Vector2D
{
return new Vector2D(myComps.x + that.myComps.x, myComps.y + that.myComps.y);
}
//return a new vector that is this subtracted with that
public function subtract(that : Vector2D) : Vector2D
{
return new Vector2D(myComps.x - that.myComps.x, myComps.y - that.myComps.y);
}
//return a new vector that is this multiplied by a factor
public function multiply(factor : Number) : Vector2D
{
return new Vector2D(myComps.x * factor, myComps.y * factor);
}
//The dot product is often used to calculate the cosine of the angle between two vectors.
public function dotProduct(that : Vector2D) : Number
{
return (myComps.x * that.myComps.x) + (myComps.y * that.myComps.y);
}
//The cross product of two vectors is a vector perpendicular to both of the two vectors
//returns the _length_ of the cross product of the two vectors
//useful for torque, magnetics, etc...
public function crossProductLength(that : Vector2D) : Number
{
return (myComps.x + that.myComps.y) - (that.myComps.x * myComps.y);
}
//return a new vector that is the reverse of this
public function reverse() : Vector2D
{
return new Vector2D(-myComps.x, -myComps.y);
}
//get the current angle of the vector travel (in radians)
public function angle() : Number
{
return Math.atan( myComps.y / myComps.x );
}
//return the angle between the two vectors (radians)
public function angleBetween(that : Vector2D) : Number
{
return Math.acos( dotProduct(that) / (magnitude() * that.magnitude()) );
}
//get the current magnitude of the vector
public function magnitude() : Number
{
return Math.sqrt( (myComps.x * myComps.x) + (myComps.y * myComps.y) );
}
//return the unit vector of this vector
public function unitVector() : Vector2D
{
return new Vector2D( myComps.x / magnitude(), myComps.y / magnitude() );
}
//access the x and y properties
public function getX() : Number
{
return myComps.x;
}
public function getY() : Number
{
return myComps.y;
}
//string representation
public function toString() : String
{
return myComps.x + " " + myComps.y;
}
}
-
Senior Member
Looks pretty good to me!
At first I was gonna nitpick about your use of
return Math.atan( myComps.y / myComps.x );
to compute angle. See in most of the languages I'm familiar with, when x is zero, you get a divide by zero error.
I was gonna suggest you use atan2 (y,x)
but it turns that Flash appears to handle divide by zero okay (making infinity) and atan() returns the correct value (and is slightly faster than atan2), so no worries!
My principle suggestion is that you do some speed testing on this and make sure you're happy with the performance.
My usual method is to use a loop of 10000 iterations, as follows:
Code:
kNbrTests = 10000;
st = getTimer();
for (var i = 0; i < kNbrTests; ++i)
{
// exercise the beastie here...
}
trace("Done, elapsed = " + (getTimer() - st) + " ms");
Things to test for speed:
* Does storing x,y inside myComps (as opposed to directly inside the Vector2D instance) incur a penalty?
The alternative would be:
code:
private var myX: Number;
private var myY: Number;
function Vector2D(xComp : Number, yComp : Number)
{
myX = xComp;
myY = yComp;
}
* What is the penalty of using this class, in a typical ball-physics collision test, as opposed to directly using x,y variables and performing calcs on them?
In general, I've found that Flash often surprises me, speedwise, so empirical speeds should always be preferred to guessing what is or isn't more efficient. In a post from some weeks back, someone very carefully optimized my code to remove some square-roots, and ended up making it quite a bit slower, as testing demonstrated.
- Jim
Last edited by jbum; 04-23-2004 at 04:42 AM.
-
I have found that using a vector class can produce a R-E-A-L-L-Y slow final result.
So if you are looking for speed I suggest you DO NOT use a vector class. But as jbum says ... use x y z component variables and do your calcs on them directly.
Shipstern
-
Looks good snake, I must have missed it the first time round - although it look like you posted it at a time when I had exams.
Aye, flash is a dog when it comes to big complex classes and such. Shame really ( not sure about flash 7 though, it's supposed to be a bit faster ).
It's an excellent idea to always get functionality ( i.e. with nice easy to remember function names via classes ) and when it's working start optomising by "inlining" the code.
Just in case no-one has seen this yet... http://members.shaw.ca/flashprogramm...wis/index.html
-
n00b
I have a bit a different version of a Vector2D class. I know the ifs are slowing down, but they also make ones live easyier when programming (and I think my x, y properties can be accessed faster).
code:
class Vector2D {
public var x:Number=0;
public var y:Number=0;
function Vector2D(px, py:Number) {
if (py == null) {
x = px.x;
y = px.y;
} else {
x = px;
y = py;
}
}
public function copy_Vector2D(v:Vector2D) {
x = v.x;
y = v.y;
}
public function equals(pv:Vector2D):Boolean {
return (pv.x == x && pv.y == y);
}
public function setTo(pv:Vector2D):Void {
x = pv.x;
y = pv.y;
}
public function Add(pv:Vector2D):Void {
x += pv.x;
y += pv.y;
}
public function Subtract(pv:Vector2D):Void {
Add(new Vector2D(-pv.x, -pv.y));
}
public function multiply(s:Number):Void {
x *= s;
y *= s;
}
public function divide(s:Number):Void {
x /= s;
y /= s;
}
public function Length():Number {
return Math.sqrt(x*x+y*y);
}
public function dotProduct(pv:Vector2D):Number {
return (x*pv.x)+(y*pv.y);
}
public function crossProduct(pv:Vector2D):Number {
return (x+pv.y)-(pv.x*y);
}
public function reverse():Vector2D {
return new Vector2D(-x, -y);
}
public function angle():Number {
return Math.atan(y/x);
}
public function angleBetween(pv:Vector2D):Number {
return Math.acos(dotProduct(pv)/(magnitude()*pv.magnitude()));
}
public function magnitude():Number {
return Math.sqrt((x*x)+(y*y));
}
public function unitVector():Vector2D {
return new Vector2D(x/magnitude(), y/magnitude());
}
public function toString():String {
return x+" "+y;
}
}
edit:
Accessing its properties directly (public x, y) without having to call a function is much faster!
Last edited by LeechmasterB; 11-20-2004 at 09:54 PM.
I do stuff that does stuff...
J-Force
-
Worked for me
I used a vector class in a physics based game that's pretty similar. I never figured out if the creation of new objects all the time (hundreds per second) has an impact on performance. As far as i can tell, the Flash garbage collector does the job and there is no obvious performance hit but i'm not sure. Any hints to info on this topic are appreciated.
Another thing: not sure if it belongs in a vector class but i have a distance function that's quite handy:
Code:
function DistanceTo(v) {
return((this.Subtract(v)).Length())
}
To see it in action : http://www.girlwithgun.com/hotseatgunner
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|