-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgeometry.js
174 lines (140 loc) · 3.87 KB
/
geometry.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Constrained Delaunay Triangulation code in JavaScript
// Copyright 2018 Savithru Jayasinghe
// Licensed under the MIT License (LICENSE.txt)
class Point
{
constructor(x,y)
{
this.x = x;
this.y = y;
}
dot(p1)
{
return (this.x*p1.x + this.y*p1.y);
}
add(p1)
{
return new Point(this.x + p1.x, this.y + p1.y);
}
sub(p1)
{
return new Point(this.x - p1.x, this.y - p1.y);
}
scale(s)
{
return new Point(this.x*s, this.y*s);
}
sqDistanceTo(p1)
{
return (this.x - p1.x)*(this.x - p1.x) + (this.y - p1.y)*(this.y - p1.y);
}
toStr()
{
return "(" + this.x.toFixed(3) + ", " + this.y.toFixed(3) + ")";
}
copyFrom(p)
{
this.x = p.x;
this.y = p.y;
}
}
function cross(vec0, vec1)
{
return (vec0.x*vec1.y - vec0.y*vec1.x);
}
function barycentericCoordTriangle(p, pt0, pt1, pt2)
{
var vec0 = pt1.sub(pt0);
var vec1 = pt2.sub(pt0);
var vec2 = p.sub(pt0);
var d00 = vec0.dot(vec0);
var d01 = vec0.dot(vec1);
var d11 = vec1.dot(vec1);
var d20 = vec2.dot(vec0);
var d21 = vec2.dot(vec1);
var denom = d00*d11 - d01*d01;
var s = (d11 * d20 - d01 * d21) / denom;
var t = (d00 * d21 - d01 * d20) / denom;
var u = 1.0 - s - t;
return {s:s, t:t, u:u};
}
function isEdgeIntersecting(edgeA, edgeB)
{
var vecA0A1 = edgeA[1].sub(edgeA[0]);
var vecA0B0 = edgeB[0].sub(edgeA[0]);
var vecA0B1 = edgeB[1].sub(edgeA[0]);
var AxB0 = cross(vecA0A1, vecA0B0);
var AxB1 = cross(vecA0A1, vecA0B1);
//Check if the endpoints of edgeB are on the same side of edgeA
if ((AxB0 > 0 && AxB1 > 0) || (AxB0 < 0 && AxB1 < 0))
return false;
var vecB0B1 = edgeB[1].sub(edgeB[0]);
var vecB0A0 = edgeA[0].sub(edgeB[0]);
var vecB0A1 = edgeA[1].sub(edgeB[0]);
var BxA0 = cross(vecB0B1, vecB0A0);
var BxA1 = cross(vecB0B1, vecB0A1);
//Check if the endpoints of edgeA are on the same side of edgeB
if ((BxA0 > 0 && BxA1 > 0) || (BxA0 < 0 && BxA1 < 0))
return false;
//Special case of colinear edges
if (Math.abs(AxB0) < 1e-14 && Math.abs(AxB1) < 1e-14)
{
//Separated in x
if ( (Math.max(edgeB[0].x, edgeB[1].x) < Math.min(edgeA[0].x, edgeA[1].x)) ||
(Math.min(edgeB[0].x, edgeB[1].x) > Math.max(edgeA[0].x, edgeA[1].x)) )
return false;
//Separated in y
if ( (Math.max(edgeB[0].y, edgeB[1].y) < Math.min(edgeA[0].y, edgeA[1].y)) ||
(Math.min(edgeB[0].y, edgeB[1].y) > Math.max(edgeA[0].y, edgeA[1].y)) )
return false;
}
return true;
}
function isEdgeIntersectingAtEndpoint(edgeA, edgeB)
{
const rsq_tol = 1e-13;
if (edgeA[0].sqDistanceTo(edgeB[0]) < rsq_tol)
return true;
if (edgeA[0].sqDistanceTo(edgeB[1]) < rsq_tol)
return true;
if (edgeA[1].sqDistanceTo(edgeB[0]) < rsq_tol)
return true;
if (edgeA[1].sqDistanceTo(edgeB[1]) < rsq_tol)
return true;
return false;
}
function isQuadConvex(p0, p1, p2, p3)
{
var diag0 = [p0, p2];
var diag1 = [p1, p3];
return isEdgeIntersecting(diag0, diag1);
}
function isSameEdge(edge0, edge1)
{
return ((edge0[0] == edge1[0] && edge0[1] == edge1[1]) ||
(edge0[1] == edge1[0] && edge0[0] == edge1[1]))
}
function getCircumcenter(p0, p1, p2)
{
var d = 2*(p0.x*(p1.y - p2.y) + p1.x*(p2.y - p0.y) + p2.x*(p0.y - p1.y));
var p0_mag = p0.x*p0.x + p0.y*p0.y;
var p1_mag = p1.x*p1.x + p1.y*p1.y;
var p2_mag = p2.x*p2.x + p2.y*p2.y;
var xc = (p0_mag*(p1.y - p2.y) + p1_mag*(p2.y - p0.y) + p2_mag*(p0.y - p1.y)) / d;
var yc = (p0_mag*(p2.x - p1.x) + p1_mag*(p0.x - p2.x) + p2_mag*(p1.x - p0.x)) / d;
//var pc = new Point(xc, yc);
//var r = Math.sqrt(pc.sqDistanceTo(p0));
return new Point(xc, yc); //[pc, r];
}
function getPointOrientation(edge, p)
{
const vec_edge01 = edge[1].sub(edge[0]);
const vec_edge0_to_p = p.sub(edge[0]);
return cross(vec_edge01, vec_edge0_to_p);
// if (area > 0)
// return 1;
// else if (area < 0)
// return -1;
// else
// return 0;
}