Java Geometry Algorithm findLineSegmentIntersection(Line2D one, Line2D two, Point2D intersection)

Here you can find the source of findLineSegmentIntersection(Line2D one, Line2D two, Point2D intersection)

Description

Compute the intersection between two line segments, or two lines of infinite length.

License

Open Source License

Return

-1 if lines are parallel (x,y unset), -2 if lines are parallel and overlapping (x, y center) 0 if intesrection outside segments (x,y set) +1 if segments intersect (x,y set)

Declaration

public static int findLineSegmentIntersection(Line2D one, Line2D two, Point2D intersection) 

Method Source Code


//package com.java2s;
/*//  w w  w. j  a v a  2 s . co m
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
Author: DarkLilac email:contact@darklilac.com
*/

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

public class Main {
    public final static double LIMIT = 1e-5;
    public final static double INFINITY = 1e10;

    /**
     * Compute the intersection between two line segments, or two lines
     * of infinite length.
     * @return -1 if lines are parallel (x,y unset),
     *       -2 if lines are parallel and overlapping (x, y center)
     *        0 if intesrection outside segments (x,y set)
     *       +1 if segments intersect (x,y set)
    */
    public static int findLineSegmentIntersection(Line2D one, Line2D two, Point2D intersection) {
        final double x0 = one.getX1();
        final double y0 = one.getY1();
        final double x1 = one.getX2();
        final double y1 = one.getY2();
        final double x2 = two.getX1();
        final double y2 = two.getY1();
        final double x3 = two.getX2();
        final double y3 = two.getY2();

        double x, y;

        final double a0 = equals(x0, x1) ? INFINITY : (y0 - y1) / (x0 - x1);
        final double a1 = equals(x2, x3) ? INFINITY : (y2 - y3) / (x2 - x3);

        final double b0 = y0 - a0 * x0;
        final double b1 = y2 - a1 * x2;

        // Check if lines are parallel
        if (equals(a0, a1)) {
            if (!equals(b0, b1)) {
                return -1; // Parallell non-overlapping
            } else {
                if (equals(x0, x1)) {
                    if (Math.min(y0, y1) < Math.max(y2, y3) || Math.max(y0, y1) > Math.min(y2, y3)) {
                        double twoMiddle = y0 + y1 + y2 + y3 - min(y0, y1, y2, y3) - max(y0, y1, y2, y3);
                        y = (twoMiddle) / 2.0;
                        x = (y - b0) / a0;
                    } else {
                        return -1; // Parallell non-overlapping
                    }
                } else {
                    if (Math.min(x0, x1) < Math.max(x2, x3) || Math.max(x0, x1) > Math.min(x2, x3)) {
                        double twoMiddle = x0 + x1 + x2 + x3 - min(x0, x1, x2, x3) - max(x0, x1, x2, x3);
                        x = (twoMiddle) / 2.0;
                        y = a0 * x + b0;
                    } else {
                        return -1;
                    }
                }
                intersection.setLocation(x, y);
                return -2;
            }
        }

        // Find correct intersection point
        if (equals(a0, INFINITY)) {
            x = x0;
            y = a1 * x + b1;
        } else if (equals(a1, INFINITY)) {
            x = x2;
            y = a0 * x + b0;
        } else {
            x = -(b0 - b1) / (a0 - a1);
            y = a0 * x + b0;
        }
        intersection.setLocation(x, y);

        // Then check if intersection is within line segments
        double distanceFrom1 = 0.0;
        if (equals(x0, x1)) {
            if (y0 < y1) {
                distanceFrom1 = y < y0 ? length(x, y, x0, y0) : y > y1 ? length(x, y, x1, y1) : 0.0;
            } else {
                distanceFrom1 = y < y1 ? length(x, y, x1, y1) : y > y0 ? length(x, y, x0, y0) : 0.0;
            }
        } else {
            if (x0 < x1) {
                distanceFrom1 = x < x0 ? length(x, y, x0, y0) : x > x1 ? length(x, y, x1, y1) : 0.0;
            } else {
                distanceFrom1 = x < x1 ? length(x, y, x1, y1) : x > x0 ? length(x, y, x0, y0) : 0.0;
            }
        }

        double distanceFrom2 = 0.0;
        if (equals(x2, x3)) {
            if (y2 < y3) {
                distanceFrom2 = y < y2 ? length(x, y, x2, y2) : y > y3 ? length(x, y, x3, y3) : 0.0;
            } else {
                distanceFrom2 = y < y3 ? length(x, y, x3, y3) : y > y2 ? length(x, y, x2, y2) : 0.0;
            }
        } else {
            if (x2 < x3) {
                distanceFrom2 = x < x2 ? length(x, y, x2, y2) : x > x3 ? length(x, y, x3, y3) : 0.0;
            } else {
                distanceFrom2 = x < x3 ? length(x, y, x3, y3) : x > x2 ? length(x, y, x2, y2) : 0.0;
            }
        }

        return equals(distanceFrom1, 0.0) && equals(distanceFrom2, 0.0) ? 1 : 0;
    }

    public static boolean equals(double a, double b) {
        return Math.abs(a - b) < LIMIT;
    }

    private static double min(double a, double b, double c, double d) {
        return Math.min(Math.min(a, b), Math.min(c, d));
    }

    private static double max(double a, double b, double c, double d) {
        return Math.max(Math.max(a, b), Math.max(c, d));
    }

    public static double max(double a, double b, double c) {
        return Math.max(a, Math.max(b, c));
    }

    public static double length(double x0, double y0, double x1, double y1) {
        final double dx = x1 - x0;
        final double dy = y1 - y0;

        return Math.sqrt(dx * dx + dy * dy);
    }

    public static double length(Line2D line) {
        final double x0 = line.getP1().getX();
        final double y0 = line.getP1().getY();
        final double x1 = line.getP2().getX();
        final double y1 = line.getP2().getY();
        return length(x0, y0, x1, y1);
    }

    public static double length(Point2D p1, Point2D p2) {
        final double x0 = p1.getX();
        final double y0 = p1.getY();
        final double x1 = p2.getX();
        final double y1 = p2.getY();
        return length(x0, y0, x1, y1);
    }
}

Related

  1. findArea(Point2D p1, Point2D p2, Point2D p3)
  2. findDimension(Point2D[] pts)
  3. findDistancedPoint(double t, Point2D sp, Point2D c1, Point2D c2, Point2D ep)
  4. findIntersect(Point2D p1, Point2D p2, Point2D p3, Point2D p4)
  5. findIntersection(Point2D.Double p1, Point2D.Double p2, Point2D.Double p3, Point2D.Double p4)
  6. findMiddlePoint(Point2D p1, Point2D p2)
  7. fitCircle(final Point2D P1, final Point2D P2, final Point2D P3)
  8. forceMouseMove(Point pos)
  9. generateLine(Point2D.Double point, double length, double angle)