xref: /aosp_15_r20/external/skia/src/base/SkQuads.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 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkQuads_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define SkQuads_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker /**
12*c8dee2aaSAndroid Build Coastguard Worker  * Utilities for dealing with quadratic formulas with one variable:
13*c8dee2aaSAndroid Build Coastguard Worker  *   f(t) = A*t^2 + B*t + C
14*c8dee2aaSAndroid Build Coastguard Worker  */
15*c8dee2aaSAndroid Build Coastguard Worker class SkQuads {
16*c8dee2aaSAndroid Build Coastguard Worker public:
17*c8dee2aaSAndroid Build Coastguard Worker     /**
18*c8dee2aaSAndroid Build Coastguard Worker      * Calculate a very accurate discriminant.
19*c8dee2aaSAndroid Build Coastguard Worker      * Given
20*c8dee2aaSAndroid Build Coastguard Worker      *    A*t^2 -2*B*t + C = 0,
21*c8dee2aaSAndroid Build Coastguard Worker      * calculate
22*c8dee2aaSAndroid Build Coastguard Worker      *    B^2 - AC
23*c8dee2aaSAndroid Build Coastguard Worker      * accurate to 2 bits.
24*c8dee2aaSAndroid Build Coastguard Worker      * Note the form of the quadratic is slightly different from the normal formulation.
25*c8dee2aaSAndroid Build Coastguard Worker      *
26*c8dee2aaSAndroid Build Coastguard Worker      * The method used to calculate the discriminant is from
27*c8dee2aaSAndroid Build Coastguard Worker      *    "On the Cost of Floating-Point Computation Without Extra-Precise Arithmetic"
28*c8dee2aaSAndroid Build Coastguard Worker      * by W. Kahan.
29*c8dee2aaSAndroid Build Coastguard Worker      */
30*c8dee2aaSAndroid Build Coastguard Worker     static double Discriminant(double A, double B, double C);
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker     struct RootResult {
33*c8dee2aaSAndroid Build Coastguard Worker         double discriminant;
34*c8dee2aaSAndroid Build Coastguard Worker         double root0;
35*c8dee2aaSAndroid Build Coastguard Worker         double root1;
36*c8dee2aaSAndroid Build Coastguard Worker     };
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker     /**
39*c8dee2aaSAndroid Build Coastguard Worker      * Calculate the roots of a quadratic.
40*c8dee2aaSAndroid Build Coastguard Worker      * Given
41*c8dee2aaSAndroid Build Coastguard Worker      *    A*t^2 -2*B*t + C = 0,
42*c8dee2aaSAndroid Build Coastguard Worker      * calculate the roots.
43*c8dee2aaSAndroid Build Coastguard Worker      *
44*c8dee2aaSAndroid Build Coastguard Worker      * This does not try to detect a linear configuration of the equation, or detect if the two
45*c8dee2aaSAndroid Build Coastguard Worker      * roots are the same. It returns the discriminant and the two roots.
46*c8dee2aaSAndroid Build Coastguard Worker      *
47*c8dee2aaSAndroid Build Coastguard Worker      * Not this uses a different form the quadratic equation to reduce rounding error. Give
48*c8dee2aaSAndroid Build Coastguard Worker      * standard A, B, C. You can call this root finder with:
49*c8dee2aaSAndroid Build Coastguard Worker      *    Roots(A, -0.5*B, C)
50*c8dee2aaSAndroid Build Coastguard Worker      * to find the roots of A*x^2 + B*x + C.
51*c8dee2aaSAndroid Build Coastguard Worker      *
52*c8dee2aaSAndroid Build Coastguard Worker      * The method used to calculate the roots is from
53*c8dee2aaSAndroid Build Coastguard Worker      *    "On the Cost of Floating-Point Computation Without Extra-Precise Arithmetic"
54*c8dee2aaSAndroid Build Coastguard Worker      * by W. Kahan.
55*c8dee2aaSAndroid Build Coastguard Worker      *
56*c8dee2aaSAndroid Build Coastguard Worker      * If the roots are imaginary then nan is returned.
57*c8dee2aaSAndroid Build Coastguard Worker      * If the roots can't be represented as double then inf is returned.
58*c8dee2aaSAndroid Build Coastguard Worker      */
59*c8dee2aaSAndroid Build Coastguard Worker     static RootResult Roots(double A, double B, double C);
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker     /**
62*c8dee2aaSAndroid Build Coastguard Worker      * Puts up to 2 real solutions to the equation
63*c8dee2aaSAndroid Build Coastguard Worker      *   A*t^2 + B*t + C = 0
64*c8dee2aaSAndroid Build Coastguard Worker      * in the provided array.
65*c8dee2aaSAndroid Build Coastguard Worker      */
66*c8dee2aaSAndroid Build Coastguard Worker     static int RootsReal(double A, double B, double C, double solution[2]);
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker     /**
69*c8dee2aaSAndroid Build Coastguard Worker      * Evaluates the quadratic function with the 3 provided coefficients and the
70*c8dee2aaSAndroid Build Coastguard Worker      * provided variable.
71*c8dee2aaSAndroid Build Coastguard Worker      */
72*c8dee2aaSAndroid Build Coastguard Worker     static double EvalAt(double A, double B, double C, double t);
73*c8dee2aaSAndroid Build Coastguard Worker };
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker #endif
76