-
Notifications
You must be signed in to change notification settings - Fork 33
/
aabb.go
133 lines (107 loc) · 3.22 KB
/
aabb.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
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
package chipmunk
import (
"github.com/vova616/chipmunk/vect"
)
//axis aligned bounding box.
type AABB struct {
Lower, //l b
Upper vect.Vect // r t
}
/*
l := aabb.Lower.X
b := aabb.Lower.Y
r := aabb.Upper.X
t := aabb.Upper.Y
*/
func (aabb *AABB) Valid() bool {
return aabb.Lower.X <= aabb.Upper.X && aabb.Lower.Y <= aabb.Upper.Y
}
func NewAABB(l, b, r, t vect.Float) AABB {
return AABB{vect.Vect{l, b}, vect.Vect{r, t}}
}
//returns the center of the aabb
func (aabb *AABB) Center() vect.Vect {
return vect.Mult(vect.Add(aabb.Lower, aabb.Upper), 0.5)
}
//returns if other is contained inside this aabb.
func (aabb *AABB) Contains(other AABB) bool {
return aabb.Lower.X <= other.Lower.X &&
aabb.Upper.X >= other.Upper.X &&
aabb.Lower.Y <= other.Lower.Y &&
aabb.Upper.Y >= other.Upper.Y
}
//returns if other is contained inside this aabb.
func (aabb *AABB) ContainsPtr(other *AABB) bool {
return aabb.Lower.X <= other.Lower.X &&
aabb.Upper.X >= other.Upper.X &&
aabb.Lower.Y <= other.Lower.Y &&
aabb.Upper.Y >= other.Upper.Y
}
//returns if v is contained inside this aabb.
func (aabb *AABB) ContainsVect(v vect.Vect) bool {
return aabb.Lower.X <= v.X &&
aabb.Upper.X >= v.X &&
aabb.Lower.Y <= v.Y &&
aabb.Upper.Y >= v.Y
}
func (aabb *AABB) Extents() vect.Vect {
return vect.Mult(vect.Sub(aabb.Upper, aabb.Lower), .5)
}
func (aabb *AABB) Perimeter() vect.Float {
w := vect.Sub(aabb.Upper, aabb.Lower)
return 2 * (w.X + w.Y)
}
//returns an AABB that holds both a and b.
func Combine(a, b AABB) AABB {
return AABB{
vect.Min(a.Lower, b.Lower),
vect.Max(a.Upper, b.Upper),
}
}
//returns an AABB that holds both a and b.
func CombinePtr(a, b *AABB) AABB {
return AABB{
vect.Min(a.Lower, b.Lower),
vect.Max(a.Upper, b.Upper),
}
}
//returns an AABB that holds both a and v.
func Expand(a AABB, v vect.Vect) AABB {
return AABB{
vect.Min(a.Lower, v),
vect.Max(a.Upper, v),
}
}
//returns the area of the bounding box.
func (aabb *AABB) Area() vect.Float {
return (aabb.Upper.X - aabb.Lower.X) * (aabb.Upper.Y - aabb.Lower.Y)
}
func MergedArea(a, b AABB) vect.Float {
return (vect.FMax(a.Upper.X, b.Upper.X) - vect.FMin(a.Lower.X, b.Lower.X)) * (vect.FMax(a.Upper.Y, b.Upper.Y) - vect.FMin(a.Lower.Y, b.Lower.Y))
}
func MergedAreaPtr(a, b *AABB) vect.Float {
return (vect.FMax(a.Upper.X, b.Upper.X) - vect.FMin(a.Lower.X, b.Lower.X)) * (vect.FMax(a.Upper.Y, b.Upper.Y) - vect.FMin(a.Lower.Y, b.Lower.Y))
}
func ProximityPtr(a, b *AABB) vect.Float {
return vect.FAbs(a.Lower.X+a.Upper.X-b.Lower.X-b.Upper.X) + vect.FAbs(a.Lower.Y+a.Upper.Y-b.Lower.Y-b.Upper.Y)
}
func Proximity(a, b AABB) vect.Float {
return vect.FAbs(a.Lower.X+a.Upper.X-b.Lower.X-b.Upper.X) + vect.FAbs(a.Lower.Y+a.Upper.Y-b.Lower.Y-b.Upper.Y)
}
func TestOverlap2(a, b AABB) bool {
d1 := vect.Sub(b.Lower, a.Upper)
d2 := vect.Sub(a.Lower, b.Upper)
if d1.X > 0.0 || d1.Y > 0.0 {
return false
}
if d2.X > 0.0 || d2.Y > 0.0 {
return false
}
return true
}
func TestOverlap(a, b AABB) bool {
return (a.Lower.X <= b.Upper.X && b.Lower.X <= a.Upper.X && a.Lower.Y <= b.Upper.Y && b.Lower.Y <= a.Upper.Y)
}
func TestOverlapPtr(a, b *AABB) bool {
return (a.Lower.X <= b.Upper.X && b.Lower.X <= a.Upper.X && a.Lower.Y <= b.Upper.Y && b.Lower.Y <= a.Upper.Y)
}