-
Notifications
You must be signed in to change notification settings - Fork 17
/
hull_avoidance.go
97 lines (80 loc) · 2.51 KB
/
hull_avoidance.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
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
package unityai
import "sort"
type Vertex2Array []Vector2f
func (this Vertex2Array) Len() int {
return len(this)
}
func (this Vertex2Array) Less(i, j int) bool {
a := this[i]
b := this[j]
return a.x < b.x || (a.x == b.x && a.y < b.y)
}
func (this Vertex2Array) Swap(i, j int) {
this[i], this[j] = this[j], this[i]
}
func (this *Vertex2Array) resize_uninitialized(size int) {
if cap(*this) >= size {
*this = (*this)[:size]
} else {
*this = append(*this, make([]Vector2f, size-len(*this))...)
}
}
func (this *Vertex2Array) empty() bool {
return len(*this) == 0
}
func (this *Vertex2Array) pop_back() {
*this = (*this)[:this.Len()-1]
}
func (this *Vertex2Array) push_back(point Vector2f) {
*this = append(*this, point)
}
func (this *Vertex2Array) erase(index int) {
if index == len(*this)-1 {
*this = (*this)[:len(*this)-1]
} else if index == 0 {
*this = (*this)[1:]
} else {
tmp := make([]Vector2f, len(*this)-1)
copy(tmp[:index], (*this)[:index])
copy(tmp[index:], (*this)[index+1:])
*this = tmp
}
}
func CalculatePointSide(l0, l1, point Vector2f) float32 {
return (l1.y-l0.y)*(point.x-l0.x) - (l1.x-l0.x)*(point.y-l0.y)
}
func CalculateConvexHull(hull *Vertex2Array, points *Vertex2Array) {
// TODO : prune (near) duplicate points before calculating hull
hull.resize_uninitialized(0)
if points.empty() {
return
}
sort.Sort(points)
// Andrews monotone chain
for i := 0; i < points.Len(); i++ {
for hull.Len() >= 2 && CalculatePointSide((*hull)[hull.Len()-2], (*hull)[hull.Len()-1], (*points)[i]) <= 0 {
hull.pop_back()
}
hull.push_back((*points)[i])
}
for i, j := points.Len()-2, hull.Len()+1; i >= 0; i-- {
for hull.Len() >= j && CalculatePointSide((*hull)[hull.Len()-2], (*hull)[hull.Len()-1], (*points)[i]) <= 0 {
hull.pop_back()
}
hull.push_back((*points)[i])
}
hull.pop_back()
}
func FitCapsuleToExtents(radius, height *float32, capsuleExtents Vector3f) {
r := FloatMax(capsuleExtents.x, capsuleExtents.z)
*radius = r
*height = FloatMax(0.0, capsuleExtents.y-r)
}
func CalcCapsuleWorldExtents(worldExtents *Vector3f, localExtents, xAxis, yAxis, zAxis Vector3f) {
var radius, height float32
FitCapsuleToExtents(&radius, &height, localExtents)
*worldExtents = AbsVector3f(yAxis).Mulf(height).Add(NewVector3f(radius, radius, radius))
}
func CalcBoxWorldExtents(worldExtents *Vector3f, localExtents, xAxis, yAxis, zAxis Vector3f) {
*worldExtents = AbsVector3f(xAxis).Mulf(localExtents.x).Add(AbsVector3f(yAxis).Mulf(localExtents.y)).Add(AbsVector3f(zAxis).Mulf(localExtents.z))
}