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.
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);
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With