Skip to content

Instantly share code, notes, and snippets.

@MattRoelle
Created March 11, 2014 04:55
Show Gist options
  • Save MattRoelle/9479706 to your computer and use it in GitHub Desktop.
Save MattRoelle/9479706 to your computer and use it in GitHub Desktop.
/*
Geometry Library
All angles are in radian measurements
*/
// Point Object
function Point(x, y) {
if (x.length === undefined) {
this.x = x;
this.y = y;
} else {
this.x = x[0];
this.y = x[1];
}
};
Point.prototype.distanceBetween = function(p2) {
return Math.sqrt(Math.pow(this.x - p2.x, 2) + Math.pow(this.y - p2.y, 2));
};
Point.prototype.midpointBetween = function(p2) {
return new Point((this.x + p2.x)/2, (this.y + p2.y)/2);
};
Point.prototype.angleBetween = function(p2) {
return Math.atan((this.y - p2.y) / (this.x - p2.x));
};
Point.prototype.translate = function(dx, dy) {
this.x += (dx === undefined) ? 0 : dx;
this.y += (dy === undefined) ? 0 : dy;
return this;
};
point.prototype.warp = function(nx, ny) {
if (nx.length === undefined) {
this.x = nx;
this.y = ny;
} else {
this.x = nx[0];
this.y = nx[1];
}
return this;
};
Point.prototype.rotate = function(angle, origin) {
var x, y;
if (origin === undefined ) {
x = (this.x*Math.cos(angle)) - (this.y*Math.sin(angle));
y = (this.x*Math.sin(angle)) + (this.y*Math.cos(angle));
} else {
if (origin.length !== undefined) {
origin = new Point(origin);
};
x = (this.x-origin.x)*Math.cos(angle) - (this.y-origin.y)*Math.sin(angle) + origin.x;
y = (this.x-origin.x)*Math.sin(angle) + (this.y-origin.y)*Math.cos(angle) + origin.y;
}
this.x = x;
this.y = y;
return this;
};
// Line Object
function Line(p1, p2) {
if (p1.length !== undefined) {
this.p1 = new Point(p1[0], p1[1]);
this.p2 = new Point(p2[0], p2[1]);
} else {
this.p1 = p1;
this.p2 = p2;
}
};
Line.prototype.translate = function(dx, dy) {
this.p1.translate(dx, dy);
this.p2.translate(dx, dy);
};
Line.prototype.rotate = function(angle, origin) {
this.p1.rotate(angle, origin);
this.p2.rotate(angle, origin);
};
Line.prototype.intersectsLine = function(l2) {
// based off of http://bryceboe.com/2006/10/23/line-segment-intersection-algorithm/
function ccw(A, B, C) {
return (C.y-A.y)*(B.x-A.x) > (B.y-A.y)*(C.x-A.x);
};
return ccw(this.p1, l2.p1, l2.p2) !== ccw(this.p2, l2.p1, l2.p2) && ccw(this.p1, this.p2, l2.p1) !== ccw(this.p1, this.p2, l2.p2);
};
// Polygon Object
function Polygon(points) {
if (points[0].length !== undefined) {
// if points is an array of arrays [ [10, 20], [15, 5] ]
this.points = points.map(function(point) {
return new Point(point[0], point[1]);
});
} else {
// if points is an array of Point objects
this.points = points;
}
}
Polygon.prototype.translate = function(dx, dy) {
this.points.map(function(point) {
point.translate(dx, dy);
});
};
Polygon.prototype.rotate = function(angle, origin) {
this.points.map(function(point) {
point.rotate(angle, origin);
});
};
Polygon.prototype.containsPoint = function(point) {
// based off of http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var p;
if (point.length === undefined) {
p = point;
} else {
p = new Point(point[0], point[1]);
}
var x = p.x, y = p.y;
var inside = false;
var j = this.points.length - 1;
for(var i = 0; i < this.points.length; j = i++) {
var xi = this.points[i].x, yi = this.points[i].y;
var xj = this.points[j].x, yj = this.points[j].y;
var intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) {
inside = !inside;
}
}
return inside;
};
Polygon.prototype.estimateCenter = function() {
var approxX = approxY = 0;
this.points.forEach(function(point) {
approxX += point.x;
approxY += point.y;
});
approxX = approxX / this.points.length;
approxY = approxY / this.points.length;
return new Point(approxX, approxY);
};
Polygon.prototype.intersectsPolygon = function(polygon) {
var lineBuffer1 = [],
lineBuffer2 = [],
that = this,
intersects = false;
that.points.forEach(function(point, i) {
var point2 = (that.points[i + 1] === undefined) ? that.points[0] : that.points[i + 1];
lineBuffer1.push(new Line(point, point2));
});
polygon.points.forEach(function(point, i) {
var point2 = (polygon.points[i + 1] === undefined) ? polygon.points[0] : polygon.points[i + 1];
lineBuffer2.push(new Line(point, point2));
});
lineBuffer2.forEach(function(l1) {
lineBuffer1.forEach(function(l2) {
if (l1.intersectsLine(l2)) {
intersects = true;
}
});
});
return intersects;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment