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