find Intersection Of Two Lines - Java 2D Graphics

Java examples for 2D Graphics:Line

Description

find Intersection Of Two Lines

Demo Code



public class Main{
    public static double[] findIntersectionOfTwoLines(double l1x1,
            double l1y1, double l1x2, double l1y2, double l2x1,
            double l2y1, double l2x2, double l2y2) {
        // Cheating check to make sure the lines do not connect up end to end
        // This is required because such delicate intersections can be fucked by cumulative floating point error
        if (l1x1 == l2x1 && l1y1 == l2y1) {
            return new double[] { l1x1, l1y1 };
        }//from   w w  w  .  ja  v  a2s  .  c o  m
        if (l1x1 == l2x2 && l1y1 == l2y2) {
            return new double[] { l1x1, l1y1 };
        }
        if (l1x2 == l2x1 && l1y2 == l2y1) {
            return new double[] { l1x2, l1y2 };
        }
        if (l1x2 == l2x2 && l1y2 == l2y2) {
            return new double[] { l1x2, l1y2 };
        }
        if (l1x1 == l1x2 && l1y1 > l1y2) {// The first line is pointing up
            if (l2x1 == l2x2) { // The second line is vertical
                return new double[] { l1x1, Math.max(l2y1, l2y2) };
            } else {
                double intersectY = solveForY(l2x1, l2y1, l2x2, l2y2, l1x1);
                return new double[] { l1x1, intersectY };
            }
        }
        if (l1x1 == l1x2 && l1y1 < l1y2) { // The first line is pointing straight down
            if (l2x1 == l2x2) { // The second line is vertical
                return new double[] { l1x1, Math.min(l2y1, l2y2) };
            } else {
                double intersectY = solveForY(l2x1, l2y1, l2x2, l2y2, l1x1);
                return new double[] { l1x1, intersectY };
            }
        }
        if (l2x1 == l2x2) { // The second line is vertical
            double yIntersect = solveForY(l1x1, l1y1, l1x2, l1y2, l2x1);
            return new double[] { l2x1, yIntersect };
        }
        // Here we solve the simultaneous equation to get the intersection
        double[] firstLine = TrigUtil.getLineEquation(l1x1, l1y1, l1x2,
                l1y2);
        double[] secondLine = TrigUtil.getLineEquation(l2x1, l2y1, l2x2,
                l2y2);
        double coefficient1 = firstLine[0];
        double shift1 = firstLine[1];
        double coefficient2 = secondLine[0];
        double shift2 = secondLine[1];
        double xIntersect = (shift1 - shift2)
                / (coefficient2 - coefficient1);
        double yIntersect = solveForY(l2x1, l2y1, l2x2, l2y2, xIntersect);

        return new double[] { xIntersect, yIntersect };
    }
    /**
     * Solves the equation of the line described by the point (x1,y1) and rotation for Y given
     * the value of x provided.
     * 
     * If the ray is not solvable for x, the Double.NaN is returned.  Since we are solving
     * for a ray and not a line there are some values of x which do not yield an y value.
     * 
     * @param rotation the rotation, in radians, clockwise from the pointing up position
     * @param x1 First x coordinate
     * @param y1 First y coordinate
     * @param x The value of x
     * @return The value of y for this line, given x or Double.Nan if there is no solution
     */
    public static double solveForY(double rotation, double x1, double y1,
            double x) {
        if (isBetween(rotation, 0, Math.PI) && x < x1) { // Facing right
            return Double.NaN;
        } else if (isBetween(rotation, Math.PI, Math.PI * 2) && x > x1) { // Facing left
            return Double.NaN;
        }
        double[] line = getLineEquation(rotation, x1, y1);
        double coefficient = line[0];
        double shift = line[1];
        return (coefficient * x) + shift;
    }
    /**
     * Solves the equation of the line described by the pair of points {(x1,y1),(x2,y2)} for Y given
     * the value of x provided.
     * 
     * @param x1 First x coordinate
     * @param y1 First y coordinate
     * @param x2 Second x coordinate
     * @param y2 Second y coordinate
     * @param x The value of x
     * @return The value of y for this line, given x
     */
    public static double solveForY(double x1, double y1, double x2,
            double y2, double x) {
        double[] line = getLineEquation(x1, y1, x2, y2);
        double coefficient = line[0];
        double shift = line[1];
        return (coefficient * x) + shift;
    }
    /**
     * Given two points {(x1,y1),(x2,y2)} returns {m,b} from the equation y = mx + b for a line
     * which passes through both points.
     * 
     * @param x1 First x coordinate
     * @param y1 First y coordinate
     * @param x2 Second x coordinate
     * @param y2 Second y coordinate
     * @return The slope and y intercept of the line passing through the points provided
     */
    public static double[] getLineEquation(double x1, double y1, double x2,
            double y2) {
        double coefficient = (y2 - y1) / (x2 - x1);
        double shift = -(coefficient * x1) + y1;
        return new double[] { coefficient, shift };
    }
    /**
     * Given a rotation (in radians) and a single point (x,y) returns {m,b} from the equation y = mx + b
     * for a line which passes through (x,y) and is oriented by rotation many radians clockwise from the
     * pointing straight up position.
     * 
     * @param rotation The rotated orientation of the line from the straight up position
     * @param x The x coordinate
     * @param y The y coordinate
     * @return The slope and y intercept of the line passing through the point provided with the provided rotation
     */
    public static double[] getLineEquation(double rotation, double x,
            double y) {
        double coefficient = -(Math.cos(rotation) / Math.sin(rotation));
        double shift = -(coefficient * x) + y;
        return new double[] { coefficient, shift };
    }
    /**
     * Indicates if the value x is between x1 and x2.
     * 
     * If x is NaN then I am currently assuming that it will never lie between any
     * two double values.  Surprisingly couldn't easily find a reference to how
     * weird double comparisons behave in Java :)
     * 
     * @param x The value for testing
     * @param x1 First boundary value
     * @param x2 Second boundary value
     * @return true if the x is between x1 and x2, false otherwise
     */
    public static boolean isBetween(double x, double x1, double x2) {
        if (x <= x1 && x >= x2) {
            return true;
        }
        if (x <= x2 && x >= x1) {
            return true;
        }
        return false;
    }
}

Related Tutorials