Blog

AS2 – Vector Class

Today I check my rss feeder and I’ve seen that michael has posted a Vector class here. Which reminds me that I have done one as well. So I’m posting it here.

Hope you’ll like it 🙂

[as]
/**
* @class net.webbymx.geom.Vector
* @author Xavier MARTIN
* @version 0.2
* @description Vector Class to hold most of all the operation you can do with
* @usage myVector:Vector = new Vector(x, y);
* x and y are optional (default 0)
**/

/*
* Class written by Xavier MARTIN (xxlm or zeflasher)
* http://dev.webbymx.net
* http://www.webbymx.net
* If you are using this class, I will be glad to receive a postcard of your place 🙂
* To do so please visit http://dev.webbymx.net and go in the about page to get my details…
*/

import flash.geom.Point
import flash.geom.Matrix;

class net.webbymx.geom.Vector {

/* ****************************************************************************
* STATIC FUNCTION
**************************************************************************** */
/**
* Returns a normalized vector of the one passed in the arguments
* @param v
* @return
*/
public static function Normalize( v : Vector ) : Vector {
var vr : Vector = new Vector();
var l : Number = v.length();
if ( l != 0 ) {
vr.vx = v.vx / l;
vr.vy = v.vy / l;
}
return vr;
}

/**
* Returns the distance between two vectors passed in arguments
* @param v1
* @param v2
* @return
*/
public static function Distance ( v1 : Vector, v2 : Vector ) : Number {
var ySeparation:Number = v2.vy – v1.vy;
var xSeparation:Number = v2.vx – v1._vx;
return ( Math.sqrt( ( ySeparation * ySeparation + xSeparation * xSeparation ), 2 ) );
}

/**
* Return the sqaured distance between two vector passed in arguments
* @param v1
* @param v2
* @return
*/
public static function DistanceSq ( v1 : Vector, v2 : Vector ) : Number {
var ySeparation:Number = v2.vy – v1.vy;
var xSeparation:Number = v2.vx – v1.vx;
return ( ySeparation * ySeparation + xSeparation * xSeparation );
}

/**
* Returns the length of a vector passed in argument
* @param v
* @return
*/
public static function Length ( v : Vector ) : Number {
return ( Math.sqrt( ( v.vx * v.vx + v.vy * v.vy ), 2 ) );
}

/**
* Convert a Point passed in argument to a Vector and returns the new vector
* @param p
* @return
*/
public static function PointToVector( p : Point ) : Vector {
var v:Vector = new Vector( p.x, p.y );
return v;
}

/**
* Convert a Vector passed in argument to a Point and returns the new Point
* @param v
* @return
*/
public static function VectorToPoint( v : Vector ) : Point {
var p:Point = new Point( v.vx, v.vy );
return p;
}

/**
* Rotate a Vector passed in argument around it’s origin and returns the new Vector
* @param v
* @param ang
* @return
*/
public static function RotateAroundOrigin( v : Vector, ang : Number ) : Vector {
// create a transformation matrix
var mtx:Matrix = new Matrix();

// rotate
mtx.rotate(ang);

// now transform the object’s vertices
var oldPt:Point = Vector.VectorToPoint(v);
var newPt:Point = mtx.transformPoint(oldPt);
v = Vector.PointToVector(newPt);

return v;
}

/**
* Returns the intersection point
* @param v1
* @param v2
* @param v3
* @param v4
* @return
*/
static public function GetIntersectionPoint(v1:Vector, v2:Vector, v3:Vector, v4:Vector ) : Point {
var factor:Number = ((v4.vy-v3.vy)*(v2.vx-v1.vx)) – ((v4.vx-v3.vx)*(v2.vy-v1.vy));
var ua:Number = ( ((v4.vx-v3.vx)*(v1.vy-v3.vy)) – ((v4.vy-v3.vy)*(v1.vx-v3.vx)) ) / factor;
var ub:Number = ( ((v2.vx-v1.vx)*(v1.vy-v3.vy)) – ((v2.vy-v1.vy)*(v1.vx-v3.vx)) ) / factor;
var ox:Number = v1.vx + (ua*(v2.vx-v1.vx));
var oy:Number = v1.vy + (ua*(v2.vy-v1.vy));
return new Point( ox, oy );
}

/* ****************************************************************************
* VARIABLES
**************************************************************************** */
/**
* @property (Number) vx vector ion X axis
* @property (Number) vy vector ion Y axis
**/
private var _vx:Number;
private var _vy:Number;

/* ****************************************************************************
* CONSTRUCTOR
**************************************************************************** */
public function Vector(x, y) {
// init the vector to 0
if (x==0 && y==0 || (x==undefined || y==undefined)) this.zero();
else {
_vx = x;
_vy = y;
}

}

/* ****************************************************************************
* PUBLIC FUNCTION
**************************************************************************** */
/**
* Returns the new vector after addition
* @param v
* @return
*/
public function add ( v : Vector ) : Vector {
var nv : Vector = new Vector( _vx + v.vx, _vy + v.vy );
return ( nv );
}

/**
* Returns the angl in degree or radian between the two vector
* @param v
* @return
*/
public function angl ( v : Vector ) : Number {
var cosA:Number;

//if ( this.isZero() && v.isZero() ) return NaN;
if ( this.isZero() && !v.isZero() ) cosA = v.vx;
else if ( !this.isZero() && v.isZero() ) cosA = this.vx;
else cosA = this.dot( v ) / ( this.length() * v.length() );

var A : Number = Math.acos( cosA );
// if we want it in degree
if ( arguments[1] == true ) {
var degrees = A / Math.PI * 180;
return degrees;
}

return A;
}

/**
* Returns the new vector after substraction
* @param v
* @return
*/
public function sub ( v : Vector ) : Vector {
var nv : Vector = new Vector( _vx – v.vx, _vy – v.vy );
return ( nv );
}

/**
* Returns the new vector after addition
* @param n
* @return
*/
public function mult ( n : Number ) : Vector {
var nv : Vector = new Vector( _vx * n, _vy * n );
return ( nv );
}

/**
* Returns the new vector after devision
* @param n
* @return
*/
public function div ( n : Number ) : Vector {
var nv : Vector = new Vector( _vx / n, _vy / n );
return ( nv );
}

/**
* Returns the length of the vector
* @param Void
* @return
*/
public function length ( Void ) : Number {
return ( Math.sqrt( ( _vx * _vx + _vy * _vy ), 2 ) );
}

/**
* Returns the length of the vector
* @param Void
* @return
*/
public function lengthSq ( Void ) : Number {
return ( _vx * _vx + _vy * _vy );
}

/**
* Calculate the dot product
* @param v
* @return
*/
public function dot ( v : Vector ) : Number {
return ( _vx * v.vx + _vy * v.vy );
}

/**
* Returns positive if v2 is clockwise of this vector,
* minus if anticlockwise (Y axis pointing down, X axis to right)
* @param v
* @return
*/
public function sign ( v : Vector ) : Number {
if( _vy * v.vx > _vx * v.vy ) return -1;
else return 1;
}

/**
* Returns a vector perpendicular to this vector
* @param Void
* @return
*/
public function perp ( Void ) : Vector {
var nv : Vector = new Vector( -_vy, _vx );
return nv;
}

/**
* Returns the distance between this vector and the one passed in params
* @param v
* @return
*/
public function distance ( v : Vector ) : Number {
var ySeparation:Number = v.vy – _vy;
var xSeparation:Number = v.vx – _vx;
return ( Math.sqrt( ( ySeparation * ySeparation + xSeparation * xSeparation ), 2 ) );
}

/**
* Returns the squared distance between this vector and the one passed in params
* @param v
* @return
*/
public function distanceSq ( v : Vector ) : Number {
var ySeparation:Number = v.vy – _vy;
var xSeparation:Number = v.vx – _vx;
return ( ySeparation * ySeparation + xSeparation * xSeparation );
}

/**
* Truncates a vector so that its length does not exceed max
* @param m
*/
public function truncate ( m : Number ) : Void {
if ( this.length() > m ) {
this.normalize();
_vx *= m;
_vy *= m;
}
}

/**
* given a normalized vector this method reflects the vector it is operating upon.
* (like the path of a ball bouncing off a wall)
* @param vn
* @return
*/
public function reflect ( v : Vector) : Vector {
var vn : Vector = new Vector();
vn.vy = _vy + 2.0 * dot( v ) * v.getReverse().vy;
vn.vx = _vx + 2.0 * dot( v ) * v.getReverse().vx;
return vn;
}

/**
* Return the opposite Vector;
* @param Void
* @return
*/
public function getReverse ( Void ) : Vector {
var vn : Vector = new Vector( -_vx, -_vy );
return vn;
}

/**
* Normalizes a 2D Vector
* @param Void
*/
public function normalize ( Void ) : Void {
var l : Number = this.length();
if ( l != 0 ) {
_vx /= l;
_vy /= l;
}
}

/**
* Init the vector to (0,0)
* @param Void
*/
public function zero ( Void ) : Void {
_vx = _vy = 0;
}

/**
* Check if the vector is null
* @param Void
* @return
*/
public function isZero ( Void ) : Boolean {
if ( _vx == 0 && _vy == 0 ) return true;
else return false;
}

/* ****************************************************************************
* GET && SET
**************************************************************************** */
public function get vx():Number {
return _vx;
}
public function get vy():Number {
return _vy;
}
public function set vy(n:Number) {
_vy = n;
}
public function set vx(n:Number) {
_vx = n;
}
}
[/as]

[Download id not defined]

  • michaelxxoa

    Hey Man, yeah I like this…

    Mine is very unfinished. The only thing I’d say is that it seems a little convoluted. Would you mind if I took yours and adapted it to what I need, and then sent you the source?

    For no other reason then keeping it simple.

    The AI I’m working on is for a game (which I can’t speak of at the moment) the class resulted from some Flocking scripts I was writing for pre-production examples.

    Take care.
    Michael

  • michaelxxoa

    Hey Man, yeah I like this…

    Mine is very unfinished. The only thing I’d say is that it seems a little convoluted. Would you mind if I took yours and adapted it to what I need, and then sent you the source?

    For no other reason then keeping it simple.

    The AI I’m working on is for a game (which I can’t speak of at the moment) the class resulted from some Flocking scripts I was writing for pre-production examples.

    Take care.
    Michael

  • zeflasher

    Yes of course, you could dld it and share what you have done then…
    Otherwise I have done an engine (not yet fully finish but working for steering behavior AI) in AS2. Maybe you wold like to see some of the code …

  • zeflasher

    Yes of course, you could dld it and share what you have done then…
    Otherwise I have done an engine (not yet fully finish but working for steering behavior AI) in AS2. Maybe you wold like to see some of the code …

  • Hi Xavier

    Your vector class has proved very useful for me in some little widgets & games I have worked on. It has helped me to understand vector maths better. I discovered it last year when I was still working with AS2 and have I’ve now ported it to AS3 — no problem as it was nice, clean OO code to start with!

    I have one question though. At the moment I’m not using your native getIntersectionPoint() function because I don’t understand why it would take 4 vectors as parameters? Surely one would use just two vectors to calculate an intersection point?

    It would be very useful if you could offer some advice on this!

    Many Thanks!

    -Nick

  • Hi Xavier

    Your vector class has proved very useful for me in some little widgets & games I have worked on. It has helped me to understand vector maths better. I discovered it last year when I was still working with AS2 and have I’ve now ported it to AS3 — no problem as it was nice, clean OO code to start with!

    I have one question though. At the moment I’m not using your native getIntersectionPoint() function because I don’t understand why it would take 4 vectors as parameters? Surely one would use just two vectors to calculate an intersection point?

    It would be very useful if you could offer some advice on this!

    Many Thanks!

    -Nick