function Vector2D(x,y){
this._x = x;
this._y = y;
}
Vector2D.angleBetween = function(v1,v2){
if(!v1.isNormalized()){
v1 = v1.clone().normalize();
}
if(!v2.isNormalized()){
v2 = v2.clone().normalize();
}
return Math.acos(v1.dotProd(v2));
};
Vector2D.prototype = {
setX : function(x){
this._x = x;
},
getX : function(){
return this._x;
},
setY : function(y){
this._y = y;
},
getY : function(){
return this._y;
},
clone : function(){
return new Vector2D(this._x,this._y);
},
zero : function(){
this._x = 0;
this._y = 0;
return this;
},
isZero : function(){
return this._x == 0 && this._y == 0;
},
setLength : function(length){
var angle = this.getAngle();
this._x = Math.cos(angle) * length;
this._y = Math.sin(angle) * length;
},
getLength : function(){
return Math.sqrt(this.getLengthSQ());
},
getLengthSQ : function(){
return this._x * this._x + this._y * this._y;
},
setAngle : function(angle){
var length = this.getLength();
this._x = Math.cos(angle) * length;
this._y = Math.sin(angle) * length;
},
getAngle : function(){
return Math.atan2(this._y,this._x);
},
normalize : function(){
var length = this.getLength();
if(length == 0){
this._x = 1;
return this;
}
this._x /= length;
this._y /= length;
return this;
},
isNormalized : function(){
return this.getLength() == 1.0;
},
reverse : function(){
this._x = -this._x;
this._y = -this._y;
return this;
},
dotProd : function(v2){
return this._x * v2.getX() + this._y * v2.getY();
},
crossProd : function(v2){
return this._x * v2.getY() - this._y * v2.getX();
},
getPerp : function(){
return new Vector2D(-this._y,this._x);
},
sign : function(v2){
return this.getPerp().dotProd(v2) < 0 ? -1 : 1;
},
dist : function(v2){
return Math.sqrt(this.distSQ(v2));
},
distSQ : function(v2){
var dx = v2.getX() - this._x;
dy = v2.getY() - this._y;
return dx * dx + dy * dy;
},
add : function(v2){
return new Vector2D(this._x + v2.getX(),this._y + this.getY());
},
subtract : function(v2){
return new Vector2D(this._x - v2.getX(),this._y - v2.getY());
},
multiply : function(n){
return new Vector2D(this._x * n,this._y * n);
},
divide : function(n){
return new Vector2D(this._x / n,this._y / n);
},
equals : function(v2){
return this._x == v2.getX() && this._y == v2.getY();
}
};