@Override
    public double[] intersect(Ray ray) {
        double a, b, c;		// Quadratic equation coefficients

        Vector3 AO = ray.getFrom().subtract(bottom);
        Vector3 AOxAB = AO.crossProduct(direction);
        Vector3 VxAB = ray.getDirection().crossProduct(direction);


        a = VxAB.dotProduct(VxAB);
        b = 2 * VxAB.dotProduct(AOxAB);
        c = AOxAB.dotProduct(AOxAB) - radius * radius;

        // Solve equation for at^2 + bt + c = 0
        double[] roots = MathUtils.solveQuadraticEquation(a, b, c);
        double distance = -1;
        
        if (roots.length == 1) {
            if (roots[0] >= 0) {
                return roots;
            }
        } else {
            if (roots[0] >= MathUtils.GEOMETRY_THRESHOLD && roots[1] >= MathUtils.GEOMETRY_THRESHOLD) {
                Vector3 point1 = ray.getFrom().add(ray.getDirection().multiply(roots[0]));
                Vector3 point2 = ray.getFrom().add(ray.getDirection().multiply(roots[1]));

                if (isPointOnCylinder(point1)) {
                    if (isPointOnCylinder(point2)) {
                        Arrays.sort(roots);
                        return roots;
                    } else {
                        return new double[] {roots[0]};
                    }
                } else if (isPointOnCylinder(point2)) {
                    return new double[] {roots[1]};
                }
            } else if (roots[0] >= 0 || roots[1] >= 0) {
                return new double[] {Math.max(roots[0], roots[1])};
            }
        }

        return EMPTY;
    }