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