xref: /aosp_15_r20/external/skia/src/base/SkCubics.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2023 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkCubics_DEFINED
8*c8dee2aaSAndroid Build Coastguard Worker #define SkCubics_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include <cmath>
11*c8dee2aaSAndroid Build Coastguard Worker 
12*c8dee2aaSAndroid Build Coastguard Worker /**
13*c8dee2aaSAndroid Build Coastguard Worker  * Utilities for dealing with cubic formulas with one variable:
14*c8dee2aaSAndroid Build Coastguard Worker  *   f(t) = A*t^3 + B*t^2 + C*t + d
15*c8dee2aaSAndroid Build Coastguard Worker  */
16*c8dee2aaSAndroid Build Coastguard Worker class SkCubics {
17*c8dee2aaSAndroid Build Coastguard Worker public:
18*c8dee2aaSAndroid Build Coastguard Worker     /**
19*c8dee2aaSAndroid Build Coastguard Worker      * Puts up to 3 real solutions to the equation
20*c8dee2aaSAndroid Build Coastguard Worker      *   A*t^3 + B*t^2 + C*t + d = 0
21*c8dee2aaSAndroid Build Coastguard Worker      * in the provided array and returns how many roots that was.
22*c8dee2aaSAndroid Build Coastguard Worker      */
23*c8dee2aaSAndroid Build Coastguard Worker     static int RootsReal(double A, double B, double C, double D,
24*c8dee2aaSAndroid Build Coastguard Worker                          double solution[3]);
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker     /**
27*c8dee2aaSAndroid Build Coastguard Worker      * Puts up to 3 real solutions to the equation
28*c8dee2aaSAndroid Build Coastguard Worker      *   A*t^3 + B*t^2 + C*t + D = 0
29*c8dee2aaSAndroid Build Coastguard Worker      * in the provided array, with the constraint that t is in the range [0.0, 1.0],
30*c8dee2aaSAndroid Build Coastguard Worker      * and returns how many roots that was.
31*c8dee2aaSAndroid Build Coastguard Worker      */
32*c8dee2aaSAndroid Build Coastguard Worker     static int RootsValidT(double A, double B, double C, double D,
33*c8dee2aaSAndroid Build Coastguard Worker                            double solution[3]);
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker 
36*c8dee2aaSAndroid Build Coastguard Worker     /**
37*c8dee2aaSAndroid Build Coastguard Worker      * Puts up to 3 real solutions to the equation
38*c8dee2aaSAndroid Build Coastguard Worker      *   A*t^3 + B*t^2 + C*t + D = 0
39*c8dee2aaSAndroid Build Coastguard Worker      * in the provided array, with the constraint that t is in the range [0.0, 1.0],
40*c8dee2aaSAndroid Build Coastguard Worker      * and returns how many roots that was.
41*c8dee2aaSAndroid Build Coastguard Worker      * This is a slower method than RootsValidT, but more accurate in circumstances
42*c8dee2aaSAndroid Build Coastguard Worker      * where floating point error gets too big.
43*c8dee2aaSAndroid Build Coastguard Worker      */
44*c8dee2aaSAndroid Build Coastguard Worker     static int BinarySearchRootsValidT(double A, double B, double C, double D,
45*c8dee2aaSAndroid Build Coastguard Worker                                        double solution[3]);
46*c8dee2aaSAndroid Build Coastguard Worker 
47*c8dee2aaSAndroid Build Coastguard Worker     /**
48*c8dee2aaSAndroid Build Coastguard Worker      * Evaluates the cubic function with the 4 provided coefficients and the
49*c8dee2aaSAndroid Build Coastguard Worker      * provided variable.
50*c8dee2aaSAndroid Build Coastguard Worker      */
EvalAt(double A,double B,double C,double D,double t)51*c8dee2aaSAndroid Build Coastguard Worker     static double EvalAt(double A, double B, double C, double D, double t) {
52*c8dee2aaSAndroid Build Coastguard Worker         return std::fma(t, std::fma(t, std::fma(t, A, B), C), D);
53*c8dee2aaSAndroid Build Coastguard Worker     }
54*c8dee2aaSAndroid Build Coastguard Worker 
EvalAt(double coefficients[4],double t)55*c8dee2aaSAndroid Build Coastguard Worker     static double EvalAt(double coefficients[4], double t) {
56*c8dee2aaSAndroid Build Coastguard Worker         return EvalAt(coefficients[0], coefficients[1], coefficients[2], coefficients[3], t);
57*c8dee2aaSAndroid Build Coastguard Worker     }
58*c8dee2aaSAndroid Build Coastguard Worker };
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker #endif
61