Check if a specified line intersects a specified rectangle. - Java java.lang

Java examples for java.lang:Math Geometry Line

Description

Check if a specified line intersects a specified rectangle.

Demo Code



public class Main{
    /**//from w  ww  .java  2  s .  c o m
     * Check if a specified line intersects a specified rectangle. Integer
     * domain.
     *
     * @param lx0, ly0 1st end point of line
     * @param ly1, ly1 2nd end point of line
     * @param x0, y0, x1, y1 Upper left and lower right corner of rectangle
     * (inclusive).
     * @return True if the line intersects the rectangle, false otherwise.
     */
    public static boolean isLineIntersectingRectangle(int lx0, int ly0,
            int lx1, int ly1, int x0, int y0, int x1, int y1) {
        // Is one of the line endpoints inside the rectangle
        if (GeometryUtils.isPointInsideRectangle(x0, y0, x1, y1, lx0, ly0)
                || GeometryUtils.isPointInsideRectangle(x0, y0, x1, y1,
                        lx1, ly1)) {
            return true;
        }

        // If it intersects it goes through. Need to check three sides only.

        // Check against top rectangle line
        if (GeometryUtils.isLineIntersectingLine(lx0, ly0, lx1, ly1, x0,
                y0, x1, y0)) {
            return true;
        }

        // Check against left rectangle line
        if (GeometryUtils.isLineIntersectingLine(lx0, ly0, lx1, ly1, x0,
                y0, x0, y1)) {
            return true;
        }

        // Check against bottom rectangle line
        if (GeometryUtils.isLineIntersectingLine(lx0, ly0, lx1, ly1, x0,
                y1, x1, y1)) {
            return true;
        }

        return false;
    }
    /**
     * Check if a specified point is inside a specified rectangle.
     *
     * @param x0, y0, x1, y1 Upper left and lower right corner of rectangle
     * (inclusive)
     * @param x,y Point to check.
     * @return True if the point is inside the rectangle, false otherwise.
     */
    public static boolean isPointInsideRectangle(int x0, int y0, int x1,
            int y1, int x, int y) {
        return x >= x0 && x < x1 && y >= y0 && y < y1;
    }
    /**
     * Check if two line segments intersects. Integer domain.
     *
     * @param x0, y0, x1, y1 End points of first line to check.
     * @param x2, yy, x3, y3 End points of second line to check.
     * @return True if the two lines intersects.
     */
    public static boolean isLineIntersectingLine(int x0, int y0, int x1,
            int y1, int x2, int y2, int x3, int y3) {
        int s1 = GeometryUtils.sameSide(x0, y0, x1, y1, x2, y2, x3, y3);
        int s2 = GeometryUtils.sameSide(x2, y2, x3, y3, x0, y0, x1, y1);

        return s1 <= 0 && s2 <= 0;
    }
    /**
     * Check if two points are on the same side of a given line. Algorithm from
     * Sedgewick page 350.
     *
     * @param x0, y0, x1, y1 The line.
     * @param px0, py0 First point.
     * @param px1, py1 Second point.
     * @return <0 if points on opposite sides. =0 if one of the points is
     * exactly on the line >0 if points on same side.
     */
    private static int sameSide(double x0, double y0, double x1, double y1,
            double px0, double py0, double px1, double py1) {
        int sameSide = 0;

        double dx = x1 - x0;
        double dy = y1 - y0;
        double dx1 = px0 - x0;
        double dy1 = py0 - y0;
        double dx2 = px1 - x1;
        double dy2 = py1 - y1;

        // Cross product of the vector from the endpoint of the line to the point
        double c1 = dx * dy1 - dy * dx1;
        double c2 = dx * dy2 - dy * dx2;

        if (c1 != 0 && c2 != 0) {
            sameSide = c1 < 0 != c2 < 0 ? -1 : 1;
        } else if (dx == 0 && dx1 == 0 && dx2 == 0) {
            sameSide = !isBetween(y0, y1, py0) && !isBetween(y0, y1, py1) ? 1
                    : 0;
        } else if (dy == 0 && dy1 == 0 && dy2 == 0) {
            sameSide = !isBetween(x0, x1, px0) && !isBetween(x0, x1, px1) ? 1
                    : 0;
        }

        return sameSide;
    }
    /**
     * Check if two points are on the same side of a given line. Integer domain.
     *
     * @param x0, y0, x1, y1 The line.
     * @param px0, py0 First point.
     * @param px1, py1 Second point.
     * @return <0 if points on opposite sides. =0 if one of the points is
     * exactly on the line >0 if points on same side.
     */
    private static int sameSide(int x0, int y0, int x1, int y1, int px0,
            int py0, int px1, int py1) {
        return sameSide((double) x0, (double) y0, (double) x1, (double) y1,
                (double) px0, (double) py0, (double) px1, (double) py1);
    }
    /**
     * Return true if c is between a and b.
     */
    private static boolean isBetween(int a, int b, int c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }
    /**
     * Return true if c is between a and b.
     */
    private static boolean isBetween(double a, double b, double c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }
}

Related Tutorials