| 303 | |
| 304 | function buildSmoothCurve(/** @type {{ x: number, y: number }[]} **/ samples) { |
| 305 | const get = (/** @type {number} **/ index) => { |
| 306 | if (index < 0) { |
| 307 | // Reflect first segment to derive a virtual point with matching tangent |
| 308 | const a = samples[0]; |
| 309 | const b = samples[1]; |
| 310 | return { x: 2 * a.x - b.x, y: 2 * a.y - b.y }; |
| 311 | } |
| 312 | if (index >= samples.length) { |
| 313 | const a = samples[samples.length - 1]; |
| 314 | const b = samples[samples.length - 2]; |
| 315 | return { x: 2 * a.x - b.x, y: 2 * a.y - b.y }; |
| 316 | } |
| 317 | return samples[index]; |
| 318 | }; |
| 319 | |
| 320 | // Catmull-Rom-to-cubic-Bezier across the sample chain for a smooth surface curve |
| 321 | return samples |