/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "CurveIntersection.h"
#include "QuadraticParameterization.h"
#include "QuadraticUtilities.h"

/* from http://tom.cs.byu.edu/~tom/papers/cvgip84.pdf 4.1
 *
 * This paper proves that Syvester's method can compute the implicit form of
 * the quadratic from the parameterized form.
 *
 * Given x = a*t*t + b*t + c  (the parameterized form)
 *       y = d*t*t + e*t + f
 *
 * we want to find an equation of the implicit form:
 *
 * A*x*x + B*x*y + C*y*y + D*x + E*y + F = 0
 *
 * The implicit form can be expressed as a 4x4 determinant, as shown.
 *
 * The resultant obtained by Syvester's method is
 *
 * |   a   b   (c - x)     0     |
 * |   0   a      b     (c - x)  |
 * |   d   e   (f - y)     0     |
 * |   0   d      e     (f - y)  |
 *
 * which expands to
 *
 * d*d*x*x + -2*a*d*x*y + a*a*y*y
 *         + (-2*c*d*d + b*e*d - a*e*e + 2*a*f*d)*x
 *         + (-2*f*a*a + e*b*a - d*b*b + 2*d*c*a)*y
 *         +
 * |   a   b   c   0   |
 * |   0   a   b   c   | == 0.
 * |   d   e   f   0   |
 * |   0   d   e   f   |
 *
 * Expanding the constant determinant results in
 *
 *   | a b c |     | b c 0 |
 * a*| e f 0 | + d*| a b c | ==
 *   | d e f |     | d e f |
 *
 * a*(a*f*f + c*e*e - c*f*d - b*e*f) + d*(b*b*f + c*c*d - c*a*f - c*e*b)
 *
 */


static bool straight_forward = true;

QuadImplicitForm::QuadImplicitForm(const Quadratic& q) {
    double a, b, c;
    set_abc(&q[0].x, a, b, c);
    double d, e, f;
    set_abc(&q[0].y, d, e, f);
    // compute the implicit coefficients
    if (straight_forward) { // 42 muls, 13 adds
        p[xx_coeff] = d * d;
        p[xy_coeff] = -2 * a * d;
        p[yy_coeff] = a * a;
        p[x_coeff] = -2*c*d*d + b*e*d - a*e*e + 2*a*f*d;
        p[y_coeff] = -2*f*a*a + e*b*a - d*b*b + 2*d*c*a;
        p[c_coeff] = a*(a*f*f + c*e*e - c*f*d - b*e*f)
                   + d*(b*b*f + c*c*d - c*a*f - c*e*b);
    } else { // 26 muls, 11 adds
        double aa = a * a;
        double ad = a * d;
        double dd = d * d;
        p[xx_coeff] = dd;
        p[xy_coeff] = -2 * ad;
        p[yy_coeff] = aa;
        double be = b * e;
        double bde = be * d;
        double cdd = c * dd;
        double ee = e * e;
        p[x_coeff] =  -2*cdd + bde - a*ee + 2*ad*f;
        double aaf = aa * f;
        double abe = a * be;
        double ac = a * c;
        double bb_2ac = b*b - 2*ac;
        p[y_coeff] = -2*aaf + abe - d*bb_2ac;
        p[c_coeff] = aaf*f + ac*ee + d*f*bb_2ac - abe*f + c*cdd - c*bde;
    }
}

 /* Given a pair of quadratics, determine their parametric coefficients.
  * If the scaled coefficients are nearly equal, then the part of the quadratics
  * may be coincident.
  * FIXME: optimization -- since comparison short-circuits on no match,
  * lazily compute the coefficients, comparing the easiest to compute first.
  * xx and yy first; then xy; and so on.
  */
bool QuadImplicitForm::implicit_match(const QuadImplicitForm& p2) const {
    int first = 0;
    for (int index = 0; index < coeff_count; ++index) {
        if (approximately_zero(p[index]) && approximately_zero(p2.p[index])) {
            first += first == index;
            continue;
        }
        if (first == index) {
            continue;
        }
        if (!AlmostEqualUlps(p[index] * p2.p[first], p[first] * p2.p[index])) {
            return false;
        }
    }
    return true;
}

bool implicit_matches(const Quadratic& quad1, const Quadratic& quad2) {
    QuadImplicitForm i1(quad1);  // a'xx , b'xy , c'yy , d'x , e'y , f
    QuadImplicitForm i2(quad2);
    return i1.implicit_match(i2);
}

static double tangent(const double* quadratic, double t) {
    double a, b, c;
    set_abc(quadratic, a, b, c);
    return 2 * a * t + b;
}

void tangent(const Quadratic& quadratic, double t, _Point& result) {
    result.x = tangent(&quadratic[0].x, t);
    result.y = tangent(&quadratic[0].y, t);
}



// unit test to return and validate parametric coefficients
#include "QuadraticParameterization_TestUtility.cpp"
