update get point at distance

This commit is contained in:
Gavin Nishizawa 2023-05-01 13:18:50 -07:00
parent 6d2613effb
commit ae6618a195
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
2 changed files with 16 additions and 7 deletions

View file

@ -287,3 +287,11 @@ func (p *Point) Transpose() {
} }
p.X, p.Y = p.Y, p.X p.X, p.Y = p.Y, p.X
} }
// point t% of the way between a and b
func (a *Point) Interpolate(b *Point, t float64) *Point {
return NewPoint(
a.X*(1.0-t)+b.X*t,
a.Y*(1.0-t)+b.Y*t,
)
}

View file

@ -20,22 +20,23 @@ func (route Route) Length() float64 {
// return the point at _distance_ along the route, and the index of the segment it's on // 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) { func (route Route) GetPointAtDistance(distance float64) (*Point, int) {
remaining := distance remaining := distance
var curr, next *Point
var length float64
for i := 0; i < len(route)-1; i++ { for i := 0; i < len(route)-1; i++ {
curr, next := route[i], route[i+1] curr, next = route[i], route[i+1]
length := EuclideanDistance(curr.X, curr.Y, next.X, next.Y) length = EuclideanDistance(curr.X, curr.Y, next.X, next.Y)
if remaining <= length { if remaining <= length {
t := remaining / length t := remaining / length
// point t% of the way between curr and next // point t% of the way between curr and next
return NewPoint( return curr.Interpolate(next, t), i
curr.X*(1.0-t)+next.X*t,
curr.Y*(1.0-t)+next.Y*t,
), i
} }
remaining -= length remaining -= length
} }
return nil, -1 // 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) { func (route Route) GetBoundingBox() (tl, br *Point) {