-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpredicates.go
71 lines (56 loc) · 1.56 KB
/
predicates.go
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
package tin
func Orientation(a, b, c [2]float64) float32 {
d := a[0]*b[1] + b[0]*c[1] + c[0]*a[1] - b[1]*c[0] - c[1]*a[0] - a[1]*b[0]
return float32(d)
}
func IsCCW(a, b, c [2]float64) bool {
d := (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
return d > 0
}
func InTriangle(a, b, c [2]float64, p [2]float64) bool {
s := a[1]*c[0] - a[0]*c[1] + (c[1]-a[1])*p[0] + (a[0]-c[0])*p[1]
d := a[0]*b[1] - a[1]*b[0] + (a[1]-b[1])*p[0] + (b[0]-a[0])*p[1]
if (s < 0) != (d < 0) {
return false
}
r := -b[1]*c[0] + a[1]*(c[0]-b[0]) + a[0]*(b[1]-c[1]) + b[0]*c[1]
if r < 0 {
s = -s
d = -d
r = -r
}
return s > 0 && d > 0 && (s+d) <= r
}
func Minus(a, b [2]float64) [2]float64 {
return [2]float64{a[0] - b[0], a[1] - b[1]}
}
func InTriangleCCW(a, b, c [2]float64, p [2]float64) bool {
bb := Minus(b, a)
cc := Minus(c, a)
pp := Minus(p, a)
w := [2]float64{
cc[1]*pp[0] - cc[0]*pp[1],
-bb[1]*pp[0] + bb[0]*pp[1],
}
if w[0] <= 0 || w[1] <= 0 {
return false
}
d := bb[0]*cc[1] - cc[0]*bb[1]
return w[0]+w[1] < d
}
func InCircumcircle(a, b, c, d [2]float64) bool {
return (a[0]*a[0]+a[1]*a[1])*triArea(b, c, d)-(b[0]*b[0]+b[1]*b[1])*triArea(a, c, d)+(c[0]*c[0]+c[1]*c[1])*triArea(a, b, d)-(d[0]*d[0]+d[1]*d[1])*triArea(a, b, c) >
EPS
}
func Circumcenter(a, b, c [2]float64) [2]float64 {
ba := Minus(b, a)
ca := Minus(c, a)
lba := ba[0]*ba[0] + ba[1]*ba[1]
lca := ca[0]*ca[0] + ca[1]*ca[1]
d := 0.5 / (ba[0]*ca[1] - ba[1]*ca[0])
o := [2]float64{
(ca[1]*lba - ba[1]*lca) * d,
(ba[0]*lca - ca[0]*lba) * d,
}
return [2]float64{o[0] + a[0], o[1] + a[1]}
}