-
Notifications
You must be signed in to change notification settings - Fork 404
/
route.go
63 lines (55 loc) · 1.29 KB
/
route.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
package geo
import (
"math"
)
type Route []*Point
func (route Route) Length() float64 {
l := 0.
for i := 0; i < len(route)-1; i++ {
l += EuclideanDistance(
route[i].X, route[i].Y,
route[i+1].X, route[i+1].Y,
)
}
return l
}
// return the point at _distance_ along the route, and the index of the segment it's on
func (route Route) GetPointAtDistance(distance float64) (*Point, int) {
remaining := distance
var curr, next *Point
var length float64
for i := 0; i < len(route)-1; i++ {
curr, next = route[i], route[i+1]
length = EuclideanDistance(curr.X, curr.Y, next.X, next.Y)
if remaining <= length {
t := remaining / length
// point t% of the way between curr and next
return curr.Interpolate(next, t), i
}
remaining -= length
}
// distance > length, so continue with last segment
// Note: distance < 0 handled above with first segment
return curr.Interpolate(next, 1+remaining/length), len(route) - 2
}
func (route Route) GetBoundingBox() (tl, br *Point) {
minX := math.Inf(1)
minY := math.Inf(1)
maxX := math.Inf(-1)
maxY := math.Inf(-1)
for _, p := range route {
if p.X < minX {
minX = p.X
}
if p.X > maxX {
maxX = p.X
}
if p.Y < minY {
minY = p.Y
}
if p.Y > maxY {
maxY = p.Y
}
}
return NewPoint(minX, minY), NewPoint(maxX, maxY)
}