• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #ifndef SkBezierCurves_DEFINED
8 #define SkBezierCurves_DEFINED
9 
10 #include <array>
11 
12 /**
13  * Utilities for dealing with cubic Bézier curves. These have a start XY
14  * point, an end XY point, and two control XY points in between. They take
15  * a parameter t which is between 0 and 1 (inclusive) which is used to
16  * interpolate between the start and end points, via a route dictated by
17  * the control points, and return a new XY point.
18  *
19  * We store a Bézier curve as an array of 8 floats or doubles, where
20  * the even indices are the X coordinates, and the odd indices are the Y
21  * coordinates.
22  */
23 class SkBezierCubic {
24 public:
25 
26     /**
27      * Evaluates the cubic Bézier curve for a given t. It returns an X and Y coordinate
28      * following the formula, which does the interpolation mentioned above.
29      *     X(t) = X_0*(1-t)^3 + 3*X_1*t(1-t)^2 + 3*X_2*t^2(1-t) + X_3*t^3
30      *     Y(t) = Y_0*(1-t)^3 + 3*Y_1*t(1-t)^2 + 3*Y_2*t^2(1-t) + Y_3*t^3
31      *
32      * t is typically in the range [0, 1], but this function will not assert that,
33      * as Bézier curves are well-defined for any real number input.
34      */
35     static std::array<double, 2> EvalAt(const double curve[8], double t);
36 
37     /**
38      * Splits the provided Bézier curve at the location t, resulting in two
39      * Bézier curves that share a point (the end point from curve 1
40      * and the start point from curve 2 are the same).
41      *
42      * t must be in the interval [0, 1].
43      *
44      * The provided twoCurves array will be filled such that indices
45      * 0-7 are the first curve (representing the interval [0, t]), and
46      * indices 6-13 are the second curve (representing [t, 1]).
47      */
48     static void Subdivide(const double curve[8], double t,
49                           double twoCurves[14]);
50 
51     /**
52      * Converts the provided Bézier curve into the the equivalent cubic
53      *    f(t) = A*t^3 + B*t^2 + C*t + D
54      * where f(t) will represent Y coordinates over time if yValues is
55      * true and the X coordinates if yValues is false.
56      *
57      * In effect, this turns the control points into an actual line, representing
58      * the x or y values.
59      */
60     static std::array<double, 4> ConvertToPolynomial(const double curve[8], bool yValues);
61 };
62 
63 #endif
64