/**
* Represents a point
*
* @alias Point
* @constructor
*/
function Point(x,y) {
this.x = x;
this.y = y;
}
/**
* Returns a clone of this point
* @return {Point} a clone of this point
*/
Point.prototype.clone = function(){
return new Point(this.x, this.y);
}
/**
* Reverses this point (x,y) -> (-x,-y)
* @return {Point} this for chaining
*/
Point.prototype.reverse = function(){
return Point.scale(this, -1);
}
/**
* Returns the Euclidian length auf this point
* @return {number} the length
*/
Point.prototype.len = function(){
return Math.sqrt(this.x*this.x + this.y*this.y);
}
/**
* Scales this Point
* @return {Point} this for chaining
*/
Point.prototype.scale = function(scale){
this.x = this.x * scale;
this.y = this.y * scale;
return this; //For chaining
}
/**
* Normalizes this point (when interpreted as 2D vector)
* @return {Point} this for chaining
*/
Point.prototype.normalize = function(){
var len = this.len();
if (len == 0) return;
this.scale(1.0/len);
return this;
}
/**
* Rotates this arrow by phi radians
* @param {number} phi angle in radians
* @return {Point} this for chaining
*/
Point.prototype.rotate = function(phi){
var x = this.x;
var y = this.y;
this.x = x * Math.cos(phi) - y * Math.sin(phi);
this.y = x * Math.sin(phi) + y * Math.cos(phi);
return this;
}
/**
* Returns this arrow as SATVector represenation
* @return {SAT.Vector} this as SAT Vector
*/
Point.prototype.toSATVector = function(){
return new SAT.Vector(this.x, this.y);
}
/**
* Adds two points
* @static
* @param {Point} p1 Point 1
* @param {Point} p2 Point 2
* @return {Point} p1 + p2
*/
Point.add = function(p1, p2){
return new Point(p1.x+p2.x, p1.y+p2.y);
}
/**
* Subtracts one point of another
* @static
* @param {Point} p1 Point 1
* @param {Point} p2 Point to be substracted
* @return {Point} p1 - p2
*/
Point.sub = function(p1, p2){
return new Point(p1.x-p2.x, p1.y-p2.y);
}
/**
* Scales a point by a scalar value
* @static
* @param {Point} point The point
* @param {number} scale The value for scaling
* @param {number} [scaley] The value for scaling in y
* @return {Point} point*scale
*/
Point.scale = function(point, scale, scaley){
scaley = scaley || scale;
return new Point(point.x*scale, point.y*scaley);
}
/**
* Interpolates two points
* @param {Point} p1 Point 1
* @param {Point} p2 Point 2
* @param {number} [amount] the influence of the secound point, default: 0.5
* @return {Point} p1*(1-amount) + p2*amount;
*/
Point.interpolate = function(p1, p2, amount){
var t = amount || 0.5;
return Point.add(Point.scale(p1,1-t),Point.scale(p2,t));
}
/**
* Returns the angle between two points (interpreted as Vector)
* @param {Point} p1 Point 1
* @param {Point} p2 Point 2
* @return {number} Angle between points in radians
*/
Point.angle = function(p1, p2){
p1c = p1.clone().normalize();
p2c = p2.clone().normalize();
p1p2dot = p1c.x * p2c.x + p1c.y * p2c.y;
return Math.acos(p1p2dot / (p1c.len() * p2c.len()));
}