package upath import "math" import "image" // P creates a path fom a list of integers that form X-Y pairs. func P (data ...int) []image.Point { result := make([]image.Point, len(data) / 2) for index := range result { result[index].X = data[index * 2] result[index].Y = data[index * 2 + 1] } return result } // Lerp linearally interpolates between two paths. If the paths differ in // 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 { if index >= len(end) { return result[:index] } endPt := end[index] result[index] = image.Pt ( lerp(fac, startPt.X, endPt.X), lerp(fac, startPt.Y, endPt.Y)) } 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) return math.Sqrt(float64(delta.X * delta.X) + float64(delta.Y * delta.Y)) } // DistanceToLine calculates the distance from a point to a line which passes // through points line1 and line2. func DistanceToLine (point, line1, line2 image.Point) float64 { x := float64(point.X) y := float64(point.Y) x1 := float64(line1.X) y1 := float64(line1.Y) x2 := float64(line2.X) y2 := float64(line2.Y) triangle := math.Abs((y2 - y1)*x - (x2 - x1)*y + x2*y1 - y2*x1) return triangle / Distance(line1, line2) } // Translate adds delta to all points in path. This modifies the slice contents. func Translate (delta image.Point, path []image.Point) { for index, point := range path { path[index] = point.Add(delta) } } func lerp (fac float64, x, y int) int { return int(float64(x) * fac + float64(y) * (1.0 - fac)) }