如何检查Path2D是否与Line相交?

时间:2014-07-09 03:46:10

标签: java

如何检查Path2D是否与line2d相交。

我应该遍历所有路径段(线,曲线,......)并检查每个路径段是否与线相交(由X1,Y1和X2,Y2定义)。但是如何改变呢?

必须精确,所以没有边界或边界框。

2 个答案:

答案 0 :(得分:0)

对于具有直线段(无曲线)的简单path2D(矩形,三角形),这有效:

public static boolean intersects(Path2D.Double path, Line2D line) {
    double x1 = -1 ,y1 = -1 , x2= -1, y2 = -1;
    for (PathIterator pi = path.getPathIterator(null); !pi.isDone(); pi.next()) 
    {
        double[] coordinates = new double[6];
        switch (pi.currentSegment(coordinates))
        {
        case PathIterator.SEG_MOVETO:
        case PathIterator.SEG_LINETO:
        {
            if(x1 == -1 && y1 == -1 )
            {
                x1= coordinates[0];
                y1= coordinates[1];
                break;
            }               
            if(x2 == -1 && y2 == -1)
            {
                x2= coordinates[0];             
                y2= coordinates[1];
                break;
            }
            break;
        }
        }
        if(x1 != -1 && y1 != -1 && x2 != -1 && y2 != -1)
        {
            Line2D segment = new Line2D.Double(x1, y1, x2, y2);
            if (segment.intersectsLine(line)) 
            {
                return true;
            }
            x1 = -1;
            y1 = -1;
            x2 = -1;
            y2 = -1;
        }
    }
    return false;
} 

答案 1 :(得分:0)

为了将来参考,这里有一个来自BorisT的更强大的算法版本,它也考虑了SEG_CLOSE。

static boolean intersects(Line2D.Double line, Path2D.Double path) {
  if (!navigableArea.contains(line.getP1()) || !navigableArea.contains(line.getP2()))
    return false;
  Point2D.Double start = null;
  Point2D.Double point1 = null;
  Point2D.Double point2 = null;
  for (PathIterator pi = navigableArea.getPathIterator(null); !pi.isDone(); pi.next()) {
    double[] coordinates = new double[6];
    switch (pi.currentSegment(coordinates)) {
    case PathIterator.SEG_MOVETO:
      point2 = new Point2D.Double(coordinates[0], coordinates[1]);
      point1 = null;
      start = (Point2D.Double) point2.clone();
      break;
    case PathIterator.SEG_LINETO:
      point1 = point2;
      point2 = new Point2D.Double(coordinates[0], coordinates[1]);
      break;
    case PathIterator.SEG_CLOSE:
      point1 = point2;
      point2 = start;
      break;
    }
    if (point1 != null) {
      Line2D segment = new Line2D.Double(point1, point2);
      if (segment.intersectsLine(line))
        return true;
    }
  }
  return false;
}