@@ -2,6 +2,7 @@ package sketchy
2
2
3
3
import (
4
4
"fmt"
5
+ "log"
5
6
"math"
6
7
)
7
8
@@ -158,9 +159,53 @@ func (c *Curve) Last() Point {
158
159
case 1 :
159
160
return c .Points [0 ]
160
161
}
162
+ if c .Closed {
163
+ return c .Points [0 ]
164
+ }
161
165
return c .Points [n - 1 ]
162
166
}
163
167
168
+ // Lerp calculates a point a given percentage along a curve
169
+ func (c * Curve ) Lerp (perc float64 ) Point {
170
+ var point Point
171
+ if perc < 0 || perc > 1 {
172
+ log .Fatalf ("percentage in Lerp not between 0 and 1: %v\n " , perc )
173
+ }
174
+ if NoTinyVals (perc ) == 0 {
175
+ return c .Points [0 ]
176
+ }
177
+ if math .Abs (perc - 1 ) < Smol {
178
+ return c .Last ()
179
+ }
180
+ totalDist := c .Length ()
181
+ targetDist := perc * totalDist
182
+ partialDist := 0.0
183
+ var foundPoint bool
184
+ n := len (c .Points )
185
+ for i := 0 ; i < n - 1 ; i ++ {
186
+ dist := Distance (c .Points [i ], c .Points [i + 1 ])
187
+ if partialDist + dist >= targetDist {
188
+ remainderDist := targetDist - partialDist
189
+ pct := remainderDist / dist
190
+ point = c .Points [i ].Lerp (c .Points [i + 1 ], pct )
191
+ foundPoint = true
192
+ break
193
+ }
194
+ partialDist += dist
195
+ }
196
+ if ! foundPoint {
197
+ if c .Closed {
198
+ dist := Distance (c .Points [n - 1 ], c .Points [0 ])
199
+ remainderDist := targetDist - partialDist
200
+ pct := remainderDist / dist
201
+ point = c .Points [n - 1 ].Lerp (c .Points [0 ], pct )
202
+ } else {
203
+ panic ("couldn't find curve lerp point" )
204
+ }
205
+ }
206
+ return point
207
+ }
208
+
164
209
// ContainsPoint determines if a point lies within a rectangle
165
210
func (r * Rect ) ContainsPoint (p Point ) bool {
166
211
return p .X >= r .X && p .X <= r .X + r .W && p .Y >= r .Y && p .Y <= r .Y + r .H
0 commit comments