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

Android examples for java.lang:Math Trigonometric Function

Description

Check if a specified line intersects a specified rectangle.

Demo Code

/*******************************************************************************
 * Copyright (c) 2011 MadRobot./*from   w  w w.  ja  va  2 s.c om*/
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *  Elton Kent - initial API and implementation
 ******************************************************************************/
import java.util.Arrays;
import android.graphics.PointF;

public class Main{
    /**
     * 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(float lx0, float ly0,
            float lx1, float ly1, float x0, float y0, float x1, float y1) {
        // Is one of the line endpoints inside the rectangle
        if (RectangleUtils.isPointInsideRectangle(x0, y0, x1, y1, lx0, ly0)
                || RectangleUtils.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 (isLineIntersectingLine(lx0, ly0, lx1, ly1, x0, y0, x1, y0)) {
            return true;
        }

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

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

        return false;
    }
    /**
     * 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(float x0, float y0,
            float x1, float y1, float x2, float y2, float x3, float y3) {
        float s1 = sameSide(x0, y0, x1, y1, x2, y2, x3, y3);
        float s2 = 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(float x0, float y0, float x1, float y1,
            float px0, float py0, float px1, float py1) {
        int sameSide = 0;

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

        // Cross product of the vector from the endpoint of the line to the
        // point
        float c1 = dx * dy1 - dy * dx1;
        float 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;
    }
    /**
     * Return true if c is between a and b.
     */
    private static boolean isBetween(float a, float b, float c) {
        return b > a ? (c >= a) && (c <= b) : (c >= b) && (c <= a);
    }
}

Related Tutorials