Вот, пожалуйста. Интересные методы - getIntersections и getIntersection. Первый анализирует все сегменты полигона и проверяет пересечения, последний выполняет фактический расчет. Имейте в виду, что вычисление может быть серьезно оптимизировано и не проверяет деление на 0. Это также будет работать только для полигонов. Его можно адаптировать для работы с другими фигурами, если вы введете вычисления для кубических и квадратичных кривых. Предполагается, что Line2D.Double используется вместо Line2D.Float. Набор используется, чтобы избежать дублирования точек (может произойти на пересечении углов многоугольника).
Пожалуйста, не используйте это без всестороннего тестирования, так как я просто быстро его взломал и не уверен, что он полностью здоров.
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);
}
}