...

Source file src/oss.terrastruct.com/d2/lib/geo/route.go

Documentation: oss.terrastruct.com/d2/lib/geo

     1  package geo
     2  
     3  import (
     4  	"math"
     5  )
     6  
     7  type Route []*Point
     8  
     9  func (route Route) Length() float64 {
    10  	l := 0.
    11  	for i := 0; i < len(route)-1; i++ {
    12  		l += EuclideanDistance(
    13  			route[i].X, route[i].Y,
    14  			route[i+1].X, route[i+1].Y,
    15  		)
    16  	}
    17  	return l
    18  }
    19  
    20  // return the point at _distance_ along the route, and the index of the segment it's on
    21  func (route Route) GetPointAtDistance(distance float64) (*Point, int) {
    22  	remaining := distance
    23  	var curr, next *Point
    24  	var length float64
    25  	for i := 0; i < len(route)-1; i++ {
    26  		curr, next = route[i], route[i+1]
    27  		length = EuclideanDistance(curr.X, curr.Y, next.X, next.Y)
    28  
    29  		if remaining <= length {
    30  			t := remaining / length
    31  			// point t% of the way between curr and next
    32  			return curr.Interpolate(next, t), i
    33  		}
    34  		remaining -= length
    35  	}
    36  
    37  	// distance > length, so continue with last segment
    38  	// Note: distance < 0 handled above with first segment
    39  	return curr.Interpolate(next, 1+remaining/length), len(route) - 2
    40  }
    41  
    42  func (route Route) GetBoundingBox() (tl, br *Point) {
    43  	minX := math.Inf(1)
    44  	minY := math.Inf(1)
    45  	maxX := math.Inf(-1)
    46  	maxY := math.Inf(-1)
    47  
    48  	for _, p := range route {
    49  		if p.X < minX {
    50  			minX = p.X
    51  		}
    52  		if p.X > maxX {
    53  			maxX = p.X
    54  		}
    55  		if p.Y < minY {
    56  			minY = p.Y
    57  		}
    58  		if p.Y > maxY {
    59  			maxY = p.Y
    60  		}
    61  	}
    62  	return NewPoint(minX, minY), NewPoint(maxX, maxY)
    63  }
    64  

View as plain text