Tests if a line intersects with a rectangle. - Java java.lang

Java examples for java.lang:Math Geometry Line

Description

Tests if a line intersects with a rectangle.

Demo Code


//package com.java2s;
import java.awt.geom.*;

public class Main {
    /**//from   w ww  . ja v  a  2s.co m
     * Tests if a line intersects with a rectangle. This method differs from
     * Rectangle2D in that it accepts empty rectangles, i.e. the passed
     * rectangle can have a height or a width of 0. Returns false if the
     * line lies completely within the rectangle.
     * @param x0 Start point of the line. Horizontal coordinate.
     * @param y0 Start point of the line. Vertical coordinate.
     * @param x1 End point of the line. Horizontal coordinate.
     * @param y1 End point of the line. Vertical coordinate.
     * @param r The rectangle to test. Can be empty, i.e. the height or width
     * can be 0.
     * @return True if the line intersects with any of the four border lines
     * of the rectangle, false otherwise.
     */
    public static boolean lineIntersectsRectangle(double x0, double y0,
            double x1, double y1, Rectangle2D r) {

        // use the Rectangle2D.intersectsLine() method.
        boolean intersection = r.intersectsLine(x0, y0, x1, y1);
        if (intersection) {
            return true;
        }

        // Rectangle2D.intersectsLine returns false when the rectangle is empty,
        // i.e. its width or height is zero.
        if (r.isEmpty()) {
            final double minX = r.getMinX();
            final double minY = r.getMinY();
            final double maxX = r.getMaxX();
            final double maxY = r.getMaxY();

            // test for intersection with lower horizontal line
            if (linesIntersect(x0, y0, x1, y1, minX, minY, maxX, minY) > 0
                    // test for intersection with right vertical line
                    || linesIntersect(x0, y0, x1, y1, maxX, minY, maxX,
                            maxY) > 0
                    // test for intersection with upper horizontal line
                    || linesIntersect(x0, y0, x1, y1, minX, maxY, maxX,
                            maxY) > 0
                    // test for intersection with left vertical line
                    || linesIntersect(x0, y0, x1, y1, minX, minY, minX,
                            maxY) > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * Check if two lines intersect.
     * Line definition :
     * Line 1  (x0,y0)-(x1,y1)
     * Line 2  (x2,y2)-(x3,y3)
     * The return values depend on the intersection type:
     * 0: no intersection
     * 1: legal intersection
     * 2: point on line
     * 3: point on point
     * 4: line on line
     * @param x0 Start point of line 1. Horizontal coordinate.
     * @param y0 Start point of line 1. Vertical coordinate.
     * @param x1 End point of line 1. Horizontal coordinate.
     * @param y1 End point of line 1. Vertical coordinate.
     * @param x2 Start point of line 2. Horizontal coordinate.
     * @param y2 Start point of line 2. Vertical coordinate.
     * @param x3 End point of line 2. Horizontal coordinate.
     * @param y4 End point of line 2. Vertical coordinate.
     * @return 0 if no intersection; 1 if intersection; 2 if point on line;
     * 3 if point on point; 4 if line on line.
     */
    public static int linesIntersect(double x0, double y0, double x1,
            double y1, double x2, double y2, double x3, double y3) {

        int k03_01, k01_02, k20_23, k23_21;
        int pos, neg, nul;

        k03_01 = SIGNTEST((x3 - x0) * (y1 - y0) - (y3 - y0) * (x1 - x0));
        k01_02 = SIGNTEST((x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0));
        k20_23 = SIGNTEST((x0 - x2) * (y3 - y2) - (y0 - y2) * (x3 - x2));
        k23_21 = SIGNTEST((x3 - x2) * (y1 - y2) - (y3 - y2) * (x1 - x2));

        pos = neg = nul = 0;

        if (k03_01 < 0) {
            neg++;
        } else if (k03_01 > 0) {
            pos++;
        } else {
            nul++;
        }

        if (k01_02 < 0) {
            neg++;
        } else if (k01_02 > 0) {
            pos++;
        } else {
            nul++;
        }

        if (k20_23 < 0) {
            neg++;
        } else if (k20_23 > 0) {
            pos++;
        } else {
            nul++;
        }

        if (k23_21 < 0) {
            neg++;
        } else if (k23_21 > 0) {
            pos++;
        } else {
            nul++;
        }

        if (nul == 0) {
            if (neg == 4 || pos == 4) {
                return 1;
            } // legal intersection
            else {
                return 0;
            } // no intersection
        } else {
            if (neg == 3 || pos == 3) {
                return 2;
            } // point on line
            else if (neg == 2 || pos == 2) {
                return 3;
            } // point on point
            else {
                return 4;
            } // line on line
        }
    }

    private static int SIGNTEST(double a) {
        return ((a) > 0.) ? 1 : ((a) < 0.) ? -1 : 0;
    }
}

Related Tutorials