static void implicit_coefficients(const Quadratic& q, double p[coeff_count]) { 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; } }
static double tangent(const double* quadratic, double t) { double a, b, c; set_abc(quadratic, a, b, c); return 2 * a * t + b; }
static int findRoots(const QuadImplicitForm& i, const Quadratic& q2, double roots[4], bool useCubic, bool& disregardCount) { double a, b, c; set_abc(&q2[0].x, a, b, c); double d, e, f; set_abc(&q2[0].y, d, e, f); const double t4 = i.x2() * a * a + i.xy() * a * d + i.y2() * d * d; const double t3 = 2 * i.x2() * a * b + i.xy() * (a * e + b * d) + 2 * i.y2() * d * e; const double t2 = i.x2() * (b * b + 2 * a * c) + i.xy() * (c * d + b * e + a * f) + i.y2() * (e * e + 2 * d * f) + i.x() * a + i.y() * d; const double t1 = 2 * i.x2() * b * c + i.xy() * (c * e + b * f) + 2 * i.y2() * e * f + i.x() * b + i.y() * e; const double t0 = i.x2() * c * c + i.xy() * c * f + i.y2() * f * f + i.x() * c + i.y() * f + i.c(); #if QUARTIC_DEBUG // create a string mathematica understands char str[1024]; bzero(str, sizeof(str)); sprintf(str, "Solve[%1.19g x^4 + %1.19g x^3 + %1.19g x^2 + %1.19g x + %1.19g == 0, x]", t4, t3, t2, t1, t0); #endif if (approximately_zero(t4)) { disregardCount = true; if (approximately_zero(t3)) { return quadraticRootsX(t2, t1, t0, roots); } return cubicRootsX(t3, t2, t1, t0, roots); } if (approximately_zero(t0)) { // 0 is one root disregardCount = true; int num = cubicRootsX(t4, t3, t2, t1, roots); for (int i = 0; i < num; ++i) { if (approximately_zero(roots[i])) { return num; } } roots[num++] = 0; return num; } if (useCubic) { assert(approximately_zero(t4 + t3 + t2 + t1 + t0)); // 1 is one root int num = cubicRootsX(t4, t4 + t3, -(t1 + t0), -t0, roots); // note that -C==A+B+D+E for (int i = 0; i < num; ++i) { if (approximately_equal(roots[i], 1)) { return num; } } roots[num++] = 1; return num; } return quarticRoots(t4, t3, t2, t1, t0, roots); }