d2/lib/geo/route.go
Alexander Wang 524c089a74 oss
Co-authored-by: Anmol Sethi <hi@nhooyr.io>
2022-11-03 06:54:49 -07:00

62 lines
1.1 KiB
Go

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
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 NewPoint(
curr.X*(1.0-t)+next.X*t,
curr.Y*(1.0-t)+next.Y*t,
), i
}
remaining -= length
}
return nil, -1
}
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)
}