-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsteering.go
More file actions
86 lines (73 loc) · 2.41 KB
/
steering.go
File metadata and controls
86 lines (73 loc) · 2.41 KB
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
package steering
import (
"fmt"
"math/rand"
)
func Seek(s Steerer, target Vector) Vector {
desired_velocity := target.Minus(s.Position()).Normalize().Mult(s.MaxSpeed())
return desired_velocity.Minus(s.Velocity())
}
func Flee(s Steerer, target Vector) Vector {
desired_velocity := target.Minus(s.Position()).Normalize().Mult(s.MaxSpeed())
return s.Velocity().Minus(desired_velocity)
}
func Pursuit(s Steerer, q Quarry, futureUpdates float32) Vector {
pred := q.Position().Plus(q.Velocity().Mult(futureUpdates))
return Seek(s, pred)
}
func Wander(s Steerer, sphere float32, orientation Matrix) Vector {
x := rand.Float32()
y := rand.Float32()
z := rand.Float32()
v := Vector{x, y, z}
// fmt.Println("wander", v.Normalize(), sphere, orientation)
force := v.Normalize().Mult(sphere)
// fmt.Println("undirected force", force)
return orientation.Mult(force)
}
func Avoid(s Steerer, spheres []Entity, length float32) Vector {
closest := Entity(nil)
closestDistance := float32(100000000)
pos := s.Position()
for _, sphere := range spheres {
rel := sphere.Position().Minus(pos)
path := s.Forward().Mult(length)
if rel.Project(path) < s.Radius()+sphere.Radius() {
distance := rel.Len()
if distance >= length || distance == 0 { // Too far away, don't care
continue
}
// fmt.Println("collision potential", sphere.Position())
if distance < closestDistance {
// fmt.Println("closest!", sphere.Position())
closest = sphere
closestDistance = distance
}
}
}
if closest == nil {
return nil
}
// fmt.Println("fleeing", closest.Position(), "from", s.Position())
return Flee(s, closest.Position())
}
func Contain(s Steerer, leftTopBack Vector, rightBottomFront Vector, futureUpdates float32, dimensions int) Vector {
future := s.Position().Plus(s.Forward().Mult(futureUpdates))
for i := 0; i < dimensions; i++ {
gradient := Vector{0, 0, 0}
gradient[i] = 1
if leftTopBack[i] > future[i] {
normal := gradient.Normal(future, (future[i]-leftTopBack[i])*futureUpdates)
fmt.Println("too small", i, gradient, future, normal)
return Seek(s, normal)
// return Seek(s, s.Side().Mult(leftTopBack[i]-future[i]))
}
if rightBottomFront[i] < future[i] {
normal := gradient.Normal(future, (rightBottomFront[i]-future[i])*futureUpdates)
fmt.Println("too big", i, gradient, future, normal)
fmt.Println(s.Side().Hadamard(normal))
return Seek(s, normal)
}
}
return Vector(nil)
}