| 1 | module math |
| 2 | |
| 3 | // BezierPoint represents point coordinates as floating point numbers. |
| 4 | // This type is used as the output of the cubic_bezier family of functions. |
| 5 | pub struct BezierPoint { |
| 6 | pub mut: |
| 7 | x f64 |
| 8 | y f64 |
| 9 | } |
| 10 | |
| 11 | // cubic_bezier returns a linear interpolation between the control points, |
| 12 | // specified by their X and Y coordinates in a single array of points `p`, and given the parameter t, |
| 13 | // varying between 0.0 and 1.0 . |
| 14 | // When `t` == 0.0, the output is P[0] . |
| 15 | // When `t` == 1.0, the output is P[3] . |
| 16 | // The points x[1],y[1] and x[2],y[2], serve as attractors. |
| 17 | @[direct_array_access; inline] |
| 18 | pub fn cubic_bezier(t f64, p []BezierPoint) BezierPoint { |
| 19 | if p.len != 4 { |
| 20 | panic('invalid p.len') |
| 21 | } |
| 22 | return cubic_bezier_coords(t, p[0].x, p[1].x, p[2].x, p[3].x, p[0].y, p[1].y, p[2].y, p[3].y) |
| 23 | } |
| 24 | |
| 25 | // cubic_bezier_a returns a linear interpolation between the control points, |
| 26 | // specified by their X and Y coordinates in 2 arrays, and given the parameter t, |
| 27 | // varying between 0.0 and 1.0 . |
| 28 | // When `t` == 0.0, the output is x[0],y[0] . |
| 29 | // When `t` == 1.0, the output is x[3],y[3] . |
| 30 | // The points x[1],y[1] and x[2],y[2], serve as attractors. |
| 31 | @[direct_array_access; inline] |
| 32 | pub fn cubic_bezier_a(t f64, x []f64, y []f64) BezierPoint { |
| 33 | if x.len != 4 { |
| 34 | panic('invalid x.len') |
| 35 | } |
| 36 | if y.len != 4 { |
| 37 | panic('invalid y.len') |
| 38 | } |
| 39 | return cubic_bezier_coords(t, x[0], x[1], x[2], x[3], y[0], y[1], y[2], y[3]) |
| 40 | } |
| 41 | |
| 42 | // cubic_bezier_fa returns a linear interpolation between the control points, |
| 43 | // specified by their X and Y coordinates in 2 fixed arrays, and given the parameter t, |
| 44 | // varying between 0.0 and 1.0 . |
| 45 | // When `t` == 0.0, the output is x[0],y[0] . |
| 46 | // When `t` == 1.0, the output is x[3],y[3] . |
| 47 | // The points x[1],y[1] and x[2],y[2], serve as attractors. |
| 48 | @[direct_array_access; inline] |
| 49 | pub fn cubic_bezier_fa(t f64, x [4]f64, y [4]f64) BezierPoint { |
| 50 | return cubic_bezier_coords(t, x[0], x[1], x[2], x[3], y[0], y[1], y[2], y[3]) |
| 51 | } |
| 52 | |
| 53 | // cubic_bezier_coords returns a linear interpolation between the control points, |
| 54 | // specified by their X and Y coordinates, and given the parameter t, |
| 55 | // varying between 0.0 and 1.0 . |
| 56 | // When `t` == 0.0, the output is x0,y0 . |
| 57 | // When `t` == 1.0, the output is x3,y3 . |
| 58 | // The points x1,y1 and x2,y2, serve as attractors. |
| 59 | @[inline] |
| 60 | pub fn cubic_bezier_coords(t f64, x0 f64, x1 f64, x2 f64, x3 f64, y0 f64, y1 f64, y2 f64, y3 f64) BezierPoint { |
| 61 | p0 := pow(1 - t, 3) |
| 62 | p1 := 3 * t * pow(1 - t, 2) |
| 63 | p2 := 3 * (1 - t) * pow(t, 2) |
| 64 | p3 := pow(t, 3) |
| 65 | xt := p0 * x0 + p1 * x1 + p2 * x2 + p3 * x3 |
| 66 | yt := p0 * y0 + p1 * y1 + p2 * y2 + p3 * y3 |
| 67 | return BezierPoint{xt, yt} |
| 68 | } |
| 69 | |