src/3D/Model.cpp
// solve a quadratic formula
//
// only real-valued results supported - no complex-plane results
solve a quadratic formula
only real-valued results supported - no complex-plane results
solve a quadratic formula only real - valued results supported - no complex - plane results
static QuadraticFormulaResult solveQuadratic(float a, float b, float c) {
    QuadraticFormulaResult res;
    float discriminant = b*b - 4.0f*a*c;
    if (discriminant < 0.0f) {
        res.computeable = false;
        return res;
    }
    float q = -0.5f * (b + copysign(sqrt(discriminant), b));
     the reason is because `-b +- sqrt(b2 - 4ac)` can result in catastrophic
     cancellation if `-b` is close to `sqrt(disc)`
     so, instead, we use two similar, complementing, quadratics:
     the textbook one:
         x = (-b +- sqrt(disc)) / 2a
     and the "Muller's method" one:
         x = 2c / (-b -+ sqrt(disc))
     the great thing about these two is that the "+-" part of their
     equations are complements, so you can have:
     q = -0.5 * (b + sign(b)*sqrt(disc))
     which, handily, will only *accumulate* the sum inside those
     parentheses. If `b` is positive, you end up with a positive
     number. If `b` is negative, you end up with a negative number. No
     catastropic cancellation. By multiplying it by "-0.5" you end up
     with:
         -b - sqrt(disc)
     or, if B was negative:
         -b + sqrt(disc)
     both of which are valid terms of both the quadratic equations above
     see:
         https:math.stackexchange.com/questions/1340267/alternative-quadratic-formula
         https:en.wikipedia.org/wiki/Quadratic_equation
    res.computeable = true;
    res.x0 = q/a;   textbook "complete the square" equation
    res.x1 = c/q;   Muller's method equation
    return res;
}
static QuadraticFormulaResult solveQuadratic ( float a , float b , float c ) { QuadraticFormulaResult res ; float discriminant = b * b - 4.0f * a * c ; if ( discriminant < 0.0f ) { res . computeable = false ; return res ; } float q = -0.5f * ( b + copysign ( sqrt ( discriminant ) , b ) ) ; res . computeable = true ; res . x0 = q / a ; res . x1 = c / q ; return res ; }
solve a quadratic formula
only real-valued results supported - no complex-plane results
solve a quadratic formula only real - valued results supported - no complex - plane results
// b2 - 4ac // q = -1/2 * (b +- sqrt(b2 - 4ac)) // you might be wondering why this doesn't just compute a textbook // version of the quadratic equation (-b +- sqrt(disc))/2a // // the reason is because `-b +- sqrt(b2 - 4ac)` can result in catastrophic // cancellation if `-b` is close to `sqrt(disc)` // // so, instead, we use two similar, complementing, quadratics: // // the textbook one: // //     x = (-b +- sqrt(disc)) / 2a // // and the "Muller's method" one: // //     x = 2c / (-b -+ sqrt(disc)) // // the great thing about these two is that the "+-" part of their // equations are complements, so you can have: // // q = -0.5 * (b + sign(b)*sqrt(disc)) // // which, handily, will only *accumulate* the sum inside those // parentheses. If `b` is positive, you end up with a positive // number. If `b` is negative, you end up with a negative number. No // catastropic cancellation. By multiplying it by "-0.5" you end up // with: // //     -b - sqrt(disc) // // or, if B was negative: // //     -b + sqrt(disc) // // both of which are valid terms of both the quadratic equations above // // see: // //     https://math.stackexchange.com/questions/1340267/alternative-quadratic-formula //     https://en.wikipedia.org/wiki/Quadratic_equation // textbook "complete the square" equation // Muller's method equation