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