-
Notifications
You must be signed in to change notification settings - Fork 0
/
point.js
63 lines (59 loc) · 1.36 KB
/
point.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
function Point(_x, _y)
{
this.x = _x;
this.y = _y;
}
Point.prototype.toString = function() { return "(" + this.x + "," + this.y + ")"; };
Point.prototype.lengthSq = function()
{
return this.x * this.x + this.y * this.y;
};
Point.prototype.dot = function(b)
{
return this.x * b.x + this.y * b.y;
};
Point.prototype.add = function(b)
{
return new Point(this.x+b.x, this.y+b.y);
};
Point.prototype.subtract = function(b)
{
return new Point(this.x-b.x, this.y-b.y);
};
Point.prototype.proj = function(b)
{
let dot = this.dot(b);
let blen2 = b.lengthSq();
let d = dot / Math.max(blen2, 0.000001);
return new Point(d * b.x, d * b.y);
};
Point.prototype.insideLineSegmentIfColinear = function(a, b)
{
let ap = point.subtract(a);
let ab = b.subtract(a);
let v = ap.dot(ab);
return v >= 0 && v <= ab.lengthSq();
};
Point.prototype.closestPointOnLineSegment = function(a, b)
{
let ab = b.subtract(a);
let ret = this.subtract(a).proj(ab).add(a);
let r = ret.subtract(a).dot(ab);
if(r < 0) return a;
if(r > ab.lengthSq()) return b;
return ret;
};
Point.prototype.closest = function(points)
{
let minDistanceSq = null;
let minPoint = null;
points.forEach(o => {
let distanceSq = this.subtract(o).lengthSq();
if (minDistanceSq === null || distanceSq < minDistanceSq)
{
minDistanceSq = distanceSq;
minPoint = o;
}
});
return minPoint;
};