diff --git a/image/path/path.go b/image/path/path.go index 4ed1abf..78a620e 100644 --- a/image/path/path.go +++ b/image/path/path.go @@ -14,7 +14,8 @@ func P (data ...int) []image.Point { } // Lerp linearally interpolates between two paths. If the paths differ in -// length, the returned path will only be as long as the smaller one. +// length, the returned path will only be as long as the smaller one. This +// function will always return a new slice. func Lerp (fac float64, start, end []image.Point) []image.Point { result := make([]image.Point, len(start)) for index, startPt := range start { @@ -27,6 +28,31 @@ func Lerp (fac float64, start, end []image.Point) []image.Point { return result } +// MultiLerp is like Lerp, but interpolates through several "stages". This +// function will always return a new slice. If no stages are provided, it will +// return nil. +func MultiLerp (fac float64, stages ...[]image.Point) []image.Point { + if len(stages) == 0 { return nil } + if len(stages) == 1 { + result := make([]image.Point, len(stages[0])) + copy(result, stages[0]) + return result + } + + expandedFac := fac * float64(len(stages)) + + startIndex := int(expandedFac) + if startIndex >= len(stages) { startIndex = len(stages) - 1 } + endIndex := startIndex + 1 + if endIndex >= len(stages) { endIndex = len(stages) - 1 } + + start := stages[startIndex] + end := stages[endIndex] + partialFac := expandedFac - float64(startIndex) + println(startIndex, endIndex, int(partialFac * 100)) + return Lerp(partialFac, start, end) +} + // Distance returns the distance between two points. func Distance (start, end image.Point) float64 { delta := start.Sub(end)