Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java- Intersection point of a Polygon and Line

Is there any function that will give me the intersection point of a Polygon and Line2D ?

I have a Polygon and a line segment that I know intersect I want the actual value of the intersection point not a boolean answer.

like image 476
bryan Avatar asked Mar 03 '11 18:03

bryan


2 Answers

Here you are. The interesting methods are getIntersections and getIntersection. The former parses over all polygon segments and checks for intersections, the latter does the actual calculation. Do keep in mind that the calculation can be seriously optimized and doesn't check for division by 0. This will also work only for polygons. It could be adapted to work with other shapes if you introduce calculations for cubic and quadratic curves. It is assumed that Line2D.Double is used instead of Line2D.Float. A Set is used to avoid duplicate points (might occur on polygon corner intersections).

Please don't use this without extensive testing, since I've just hacked it together quickly and am not sure it's completely sound.

package quickpolygontest;

import java.awt.Polygon;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Main {

    public static void main(String[] args) throws Exception {

        final Polygon poly = new Polygon(new int[]{1,2,2,1}, new int[]{1,1,2,2}, 4);
        final Line2D.Double line = new Line2D.Double(2.5, 1.3, 1.3, 2.5);
        final Set<Point2D> intersections = getIntersections(poly, line);
        for(Iterator<Point2D> it = intersections.iterator(); it.hasNext();) {
            final Point2D point = it.next();
            System.out.println("Intersection: " + point.toString());
        }

    }

    public static Set<Point2D> getIntersections(final Polygon poly, final Line2D.Double line) throws Exception {

        final PathIterator polyIt = poly.getPathIterator(null); //Getting an iterator along the polygon path
        final double[] coords = new double[6]; //Double array with length 6 needed by iterator
        final double[] firstCoords = new double[2]; //First point (needed for closing polygon path)
        final double[] lastCoords = new double[2]; //Previously visited point
        final Set<Point2D> intersections = new HashSet<Point2D>(); //List to hold found intersections
        polyIt.currentSegment(firstCoords); //Getting the first coordinate pair
        lastCoords[0] = firstCoords[0]; //Priming the previous coordinate pair
        lastCoords[1] = firstCoords[1];
        polyIt.next();
        while(!polyIt.isDone()) {
            final int type = polyIt.currentSegment(coords);
            switch(type) {
                case PathIterator.SEG_LINETO : {
                    final Line2D.Double currentLine = new Line2D.Double(lastCoords[0], lastCoords[1], coords[0], coords[1]);
                    if(currentLine.intersectsLine(line))
                        intersections.add(getIntersection(currentLine, line));
                    lastCoords[0] = coords[0];
                    lastCoords[1] = coords[1];
                    break;
                }
                case PathIterator.SEG_CLOSE : {
                    final Line2D.Double currentLine = new Line2D.Double(coords[0], coords[1], firstCoords[0], firstCoords[1]);
                    if(currentLine.intersectsLine(line))
                        intersections.add(getIntersection(currentLine, line));
                    break;
                }
                default : {
                    throw new Exception("Unsupported PathIterator segment type.");
                }
            }
            polyIt.next();
        }
        return intersections;

    }

    public static Point2D getIntersection(final Line2D.Double line1, final Line2D.Double line2) {

        final double x1,y1, x2,y2, x3,y3, x4,y4;
        x1 = line1.x1; y1 = line1.y1; x2 = line1.x2; y2 = line1.y2;
        x3 = line2.x1; y3 = line2.y1; x4 = line2.x2; y4 = line2.y2;
        final double x = (
                (x2 - x1)*(x3*y4 - x4*y3) - (x4 - x3)*(x1*y2 - x2*y1)
                ) /
                (
                (x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)
                );
        final double y = (
                (y3 - y4)*(x1*y2 - x2*y1) - (y1 - y2)*(x3*y4 - x4*y3)
                ) /
                (
                (x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)
                );

        return new Point2D.Double(x, y);

    }

}
like image 158
G_H Avatar answered Oct 18 '22 18:10

G_H


There is java.awt.geom.Area.intersect(Area) using the constructor Area(Shape) with your Polygon and passing your Line2D as an Area to intersect will give you the Area which is intersected.

like image 8
initialZero Avatar answered Oct 18 '22 18:10

initialZero