Point class
const Point = function(x, y){
this.x = x;
this.y = y;
}
Line class
const Line = function(from, to){
this.from = from;
this.to = to;
}
Circle
const Circle = function(x, y, r){
this.cx = x;
this.cy = y;
this.r = r;
}
Geometry
const Geometry = function(){
return {
Line: {
intersect: function(l1, l2){
let ax = l1.from.x, ay = l1.from.y;
let bx = l1.to.x, by = l1.to.y;
let cx = l2.from.x, cy = l2.from.y;
let dx = l2.to.x, dy = l2.to.y;
var denominator = (by-ay) * (dx-cx) - (ax-bx) * (cy-dy);
if (denominator == 0) {
return false;
}
var x = +((bx-ax) * (dx-cx) * (cy-ay)
+ (by-ay) * (dx-cx) * ax
- (dy-cy) * (bx-ax) * cx ) / denominator;
var y = -((by-ay) * (dy-cy) * (cx-ax)
+ (bx-ax) * (dy-cy) * ay
- (dx-cx) * (by-ay) * cy ) / denominator;
if ((x-ax) * (x-bx) <= 0 && (y-ay) * (y-by) <= 0 && (x-cx) * (x-dx) <= 0 && (y-cy) * (y-dy) <= 0){
return new Point(x, y);
}
return false;
},
middle: function(line){
let p0 = line.from, p1 = line.to;
let x0 = p0.x, y0 = p0.y;
let x1 = p1.x, y1 = p1.y;
return new Point((x0+x1)/2, (y0+y1)/2);
}
},
Circle: {
tengent: function(c1, c2, D=50){
let x1 = c1.cx, y1 = c1.cy;
let x2 = c2.cx, y2 = c2.cy;
let r1 = c1.r, r2 = c2.r;
let dx = x1-x2, dy = y1-y2;
let d = Math.abs(Math.sqrt(dx*dx + dy*dy) - (r1+r2));
let x0, y0;
if( d < D) {
x0 = x1 + (x2-x1) * (r1/(r1+r2));
y0 = y1 + (y2-y1) * (r1/(r1+r2));
return new Point(x0, y0);
}
return false;
},
intersect: function(o1, o2){
let x1 = o1.cx, y1 = o1.cy;
let x2 = o2.cx, y2 = o2.cy;
let r1 = o1.r, r2 = o2.r;
let L = Geometry.distance(x1, y1, x2, y2);
//console.log('L: %d', L);
let k1 = (y2-y1)/(x2-x1), k2 = -1/k1;
//console.log(k1, k2);
let sum = r1 + r2, diff = Math.abs(r1 - r2);
if (L > sum) {
return 1;
}
else if(L < sum) {
if(L < diff){
return -1;
}
else{
//http://blog.csdn.net/zx3517288/article/details/53326420
let d = L;
let a = (r1*r1 - r2*r2 + d*d) / (2*d);
//console.log(d, a);
let x0 = x1+a*(x2-x1)/d;
let y0 = y1+a*(y2-y1)/d;
let h = Math.sqrt(Math.abs(r1*r1 - a*a));
//console.log(h);
let x3 = x0 - h*(y2-y1)/d, y3 = y0 + h*(x2-x1)/d;
let x4 = x0 + h*(y2-y1)/d, y4 = y0 - h*(x2-x1)/d;
return [new Point(x3, y3), new Point(x4, y4)];
}
}
else{
//console.log('d = (r1 + r2)');
return 0;
}
}
},
distance: function(x0, y0, x1, y1){
let dx = (x1-x0), dy = (y1-y0);
return Math.sqrt(dx*dx + dy*dy);
}
}
}();