// Path: jopenvoronoi-main/src/main/java/org/rogach/jopenvoronoi/Numeric.java
// public static double chop(double val, double tol) {
//     double _epsilon = tol;
//     if (Math.abs(val) < _epsilon)
//         return 0;
//     else
//         return val;
// }
// 
// Path: jopenvoronoi-main/src/main/java/org/rogach/jopenvoronoi/Numeric.java
// public static List<Double> quadratic_roots(double a, double b, double c) {
//     List<Double> roots = new ArrayList<>();
//     if ((a == 0) && (b == 0)) {
//         return roots;
//     }
//     if (a == 0) {
//         roots.add( -c / b );
//         return roots;
//     }
//     if (b == 0) {
//         double sqr = -c / a;
//         if (sqr > 0) {
//             roots.add( Math.sqrt(sqr) );
//             roots.add( -roots.get(0) );
//             return roots;
//         } else if (sqr == 0) {
//             roots.add(0d);
//             return roots;
//         } else {
//             //std::cout << " quadratic_roots() b == 0. no roots.\n";
//             return roots;
//         }
//     }
//     double disc = chop(b*b - 4*a*c); // discriminant, chop!
//     if (disc > 0) {
//         double q;
//         if (b > 0)
//             q = (b + Math.sqrt(disc)) / -2;
//         else
//             q = (b - Math.sqrt(disc)) / -2;
//         roots.add( q / a );
//         roots.add( c / q );
//         return roots;
//     } else if (disc == 0) {
//         roots.add( -b / (2*a) );
//         return roots;
//     }
//     //std::cout << " quadratic_roots() disc < 0. no roots. disc= " << disc << "\n";
//     return roots;
// }


import java.util.List;
import java.util.ArrayList;
import static org.rogach.jopenvoronoi.Numeric.chop;
import static org.rogach.jopenvoronoi.Numeric.quadratic_roots;
                                quad.c, // xk*xk + yk*yk - rk*rk,
                                a0, b0,
                                a1, b1, isolns);
        double[][] tsolns = new double[2][3];
        for (int i=0; i<scount; i++) {
            tsolns[i][xi] = isolns[i][0];       // u       x
            tsolns[i][yi] = isolns[i][1];       // v       y
            tsolns[i][ti] = isolns[i][2];       // t       t  chop!
            solns.add(new Solution(new Point( tsolns[i][0], tsolns[i][1] ),
                                       tsolns[i][2], k3 ) );
        }
        //std::cout << " k3="<<kk3<<" qqq_solve found " << scount << " roots\n";
        return scount;
    }

    /// Solve a system of one quadratic equation, and two linear equations.
    ///
    /// (1) a0 u^2 + b0 u + c0 v^2 + d0 v + e0 w^2 + f0 w + g0 = 0
    /// (2) u = a1 w + b1
    /// (3) v = a2 w + b2
    /// solve (1) for w (can have 0, 1, or 2 roots)
    /// then substitute into (2) and (3) to find (u, v, t)
    private int qll_solve( double a0, double b0, double c0, double d0,
                           double e0, double f0, double g0,
                           double a1, double b1,
                           double a2, double b2,
                           double soln[][])
    {
        //std::cout << "qll_solver()\n";
        // TODO:  optimize using abs(a0) == abs(c0) == abs(d0) == 1
// Path: jopenvoronoi-main/src/main/java/org/rogach/jopenvoronoi/Numeric.java
// public static double chop(double val, double tol) {
//     double _epsilon = tol;
//     if (Math.abs(val) < _epsilon)
//         return 0;
//     else
//         return val;
// }
// 
// Path: jopenvoronoi-main/src/main/java/org/rogach/jopenvoronoi/Numeric.java
// public static List<Double> quadratic_roots(double a, double b, double c) {
//     List<Double> roots = new ArrayList<>();
//     if ((a == 0) && (b == 0)) {
//         return roots;
//     }
//     if (a == 0) {
//         roots.add( -c / b );
//         return roots;
//     }
//     if (b == 0) {
//         double sqr = -c / a;
//         if (sqr > 0) {
//             roots.add( Math.sqrt(sqr) );
//             roots.add( -roots.get(0) );
//             return roots;
//         } else if (sqr == 0) {
//             roots.add(0d);
//             return roots;
//         } else {
//             //std::cout << " quadratic_roots() b == 0. no roots.\n";
//             return roots;
//         }
//     }
//     double disc = chop(b*b - 4*a*c); // discriminant, chop!
//     if (disc > 0) {
//         double q;
//         if (b > 0)
//             q = (b + Math.sqrt(disc)) / -2;
//         else
//             q = (b - Math.sqrt(disc)) / -2;
//         roots.add( q / a );
//         roots.add( c / q );
//         return roots;
//     } else if (disc == 0) {
//         roots.add( -b / (2*a) );
//         return roots;
//     }
//     //std::cout << " quadratic_roots() disc < 0. no roots. disc= " << disc << "\n";
//     return roots;
// }


// Path: jopenvoronoi-main/src/main/java/org/rogach/jopenvoronoi/QLLSolver.java
import java.util.List;
import java.util.ArrayList;
import static org.rogach.jopenvoronoi.Numeric.chop;
import static org.rogach.jopenvoronoi.Numeric.quadratic_roots;

                                quad.c, // xk*xk + yk*yk - rk*rk,
                                a0, b0,
                                a1, b1, isolns);
        double[][] tsolns = new double[2][3];
        for (int i=0; i<scount; i++) {
            tsolns[i][xi] = isolns[i][0];       // u       x
            tsolns[i][yi] = isolns[i][1];       // v       y
            tsolns[i][ti] = isolns[i][2];       // t       t  chop!
            solns.add(new Solution(new Point( tsolns[i][0], tsolns[i][1] ),
                                       tsolns[i][2], k3 ) );
        }
        //std::cout << " k3="<<kk3<<" qqq_solve found " << scount << " roots\n";
        return scount;
    }

    /// Solve a system of one quadratic equation, and two linear equations.
    ///
    /// (1) a0 u^2 + b0 u + c0 v^2 + d0 v + e0 w^2 + f0 w + g0 = 0
    /// (2) u = a1 w + b1
    /// (3) v = a2 w + b2
    /// solve (1) for w (can have 0, 1, or 2 roots)
    /// then substitute into (2) and (3) to find (u, v, t)
    private int qll_solve( double a0, double b0, double c0, double d0,
                           double e0, double f0, double g0,
                           double a1, double b1,
                           double a2, double b2,
                           double soln[][])
    {
        //std::cout << "qll_solver()\n";
        // TODO:  optimize using abs(a0) == abs(c0) == abs(d0) == 1
        double a = chop( (a0*(a1*a1) + c0*(a2*a2) + e0) );