mirror of
https://github.com/vlang/v.git
synced 2025-08-03 09:47:15 -04:00
70 lines
2.5 KiB
V
70 lines
2.5 KiB
V
module math
|
|
|
|
// BezierPoint represents point coordinates as floating point numbers.
|
|
// This type is used as the output of the cubic_bezier family of functions.
|
|
pub struct BezierPoint {
|
|
pub mut:
|
|
x f64
|
|
y f64
|
|
}
|
|
|
|
// cubic_bezier returns a linear interpolation between the control points,
|
|
// specified by their X and Y coordinates in a single array of points `p`, and given the parameter t,
|
|
// varying between 0.0 and 1.0 .
|
|
// When `t` == 0.0, the output is P[0] .
|
|
// When `t` == 1.0, the output is P[3] .
|
|
// The points x[1],y[1] and x[2],y[2], serve as attractors.
|
|
@[direct_array_access; inline]
|
|
pub fn cubic_bezier(t f64, p []BezierPoint) BezierPoint {
|
|
if p.len != 4 {
|
|
panic('invalid p.len')
|
|
}
|
|
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)
|
|
}
|
|
|
|
// cubic_bezier_a returns a linear interpolation between the control points,
|
|
// specified by their X and Y coordinates in 2 arrays, and given the parameter t,
|
|
// varying between 0.0 and 1.0 .
|
|
// When `t` == 0.0, the output is x[0],y[0] .
|
|
// When `t` == 1.0, the output is x[3],y[3] .
|
|
// The points x[1],y[1] and x[2],y[2], serve as attractors.
|
|
@[direct_array_access; inline]
|
|
pub fn cubic_bezier_a(t f64, x []f64, y []f64) BezierPoint {
|
|
if x.len != 4 {
|
|
panic('invalid x.len')
|
|
}
|
|
if y.len != 4 {
|
|
panic('invalid y.len')
|
|
}
|
|
return cubic_bezier_coords(t, x[0], x[1], x[2], x[3], y[0], y[1], y[2], y[3])
|
|
}
|
|
|
|
// cubic_bezier_fa returns a linear interpolation between the control points,
|
|
// specified by their X and Y coordinates in 2 fixed arrays, and given the parameter t,
|
|
// varying between 0.0 and 1.0 .
|
|
// When `t` == 0.0, the output is x[0],y[0] .
|
|
// When `t` == 1.0, the output is x[3],y[3] .
|
|
// The points x[1],y[1] and x[2],y[2], serve as attractors.
|
|
@[direct_array_access; inline]
|
|
pub fn cubic_bezier_fa(t f64, x [4]f64, y [4]f64) BezierPoint {
|
|
return cubic_bezier_coords(t, x[0], x[1], x[2], x[3], y[0], y[1], y[2], y[3])
|
|
}
|
|
|
|
// cubic_bezier_coords returns a linear interpolation between the control points,
|
|
// specified by their X and Y coordinates, and given the parameter t,
|
|
// varying between 0.0 and 1.0 .
|
|
// When `t` == 0.0, the output is x0,y0 .
|
|
// When `t` == 1.0, the output is x3,y3 .
|
|
// The points x1,y1 and x2,y2, serve as attractors.
|
|
@[inline]
|
|
pub fn cubic_bezier_coords(t f64, x0 f64, x1 f64, x2 f64, x3 f64, y0 f64, y1 f64, y2 f64, y3 f64) BezierPoint {
|
|
p0 := pow(1 - t, 3)
|
|
p1 := 3 * t * pow(1 - t, 2)
|
|
p2 := 3 * (1 - t) * pow(t, 2)
|
|
p3 := pow(t, 3)
|
|
xt := p0 * x0 + p1 * x1 + p2 * x2 + p3 * x3
|
|
yt := p0 * y0 + p1 * y1 + p2 * y2 + p3 * y3
|
|
return BezierPoint{xt, yt}
|
|
}
|