// 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;
        // y and t in terms of x
        // t and x in terms of y
        qll_solver( lins, 0, 1, 2, quads.get(0), k3, slns);
        qll_solver( lins, 2, 0, 1, quads.get(0), k3, slns);
        qll_solver( lins, 1, 2, 0, quads.get(0), k3, slns);

        return slns.size();
    }


    /// \brief qll solver
    // l0 first linear eqn
    // l1 second linear eqn
    // xi,yi,ti  indexes to shuffle around
    // xk, yk, kk, rk = params of one ('last') quadratic site (point or arc)
    // solns = output solution triplets (x,y,t) or (u,v,t)
    // returns number of solutions found
    private int qll_solver(List<Eq> lins, int xi, int yi, int ti,
                           Eq quad, double k3, List<Solution> solns) {
        assert( lins.size() == 2 ) : " lins.size() == 2 ";
        double ai = lins.get(0).get(xi); // first linear
        double bi = lins.get(0).get(yi);
        double ki = lins.get(0).get(ti);
        double ci = lins.get(0).c;

        double aj = lins.get(1).get(xi); // second linear
        double bj = lins.get(1).get(yi);
        double kj = lins.get(1).get(ti);
        double cj = lins.get(1).c;

// 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;

        // y and t in terms of x
        // t and x in terms of y
        qll_solver( lins, 0, 1, 2, quads.get(0), k3, slns);
        qll_solver( lins, 2, 0, 1, quads.get(0), k3, slns);
        qll_solver( lins, 1, 2, 0, quads.get(0), k3, slns);

        return slns.size();
    }


    /// \brief qll solver
    // l0 first linear eqn
    // l1 second linear eqn
    // xi,yi,ti  indexes to shuffle around
    // xk, yk, kk, rk = params of one ('last') quadratic site (point or arc)
    // solns = output solution triplets (x,y,t) or (u,v,t)
    // returns number of solutions found
    private int qll_solver(List<Eq> lins, int xi, int yi, int ti,
                           Eq quad, double k3, List<Solution> solns) {
        assert( lins.size() == 2 ) : " lins.size() == 2 ";
        double ai = lins.get(0).get(xi); // first linear
        double bi = lins.get(0).get(yi);
        double ki = lins.get(0).get(ti);
        double ci = lins.get(0).c;

        double aj = lins.get(1).get(xi); // second linear
        double bj = lins.get(1).get(yi);
        double kj = lins.get(1).get(ti);
        double cj = lins.get(1).c;

        double d = chop( ai*bj - aj*bi ); // chop! (determinant for 2 linear eqns (?))