几乎平行的线的交叉点很远

时间:2014-09-10 20:46:28

标签: java geometry

我正在绘制画布上的大量连接边,所有这些边都以这样的方式排列,即这些边的某些特定扩展总是给出与另一个扩展边的交点。这一点是进一步计算所必需的 - 它与画布上显示的内容无关。我的代码适用于一般情况,但如果边缘的相应扩展很远,则交叉点并不总是存在(但是,行不是并行的) - 至少不在此程序的范围内。有没有人有任何想法来提高这段代码的精确度?我实际上是在稍后使用BigDecimals,但是对于绘图步骤我最初认为使用double就足够了。

这个将边缘延伸到两边:

public Line2D.Double ExteLine(Point2D p, Point2D q){
   double slope, y3, y4;
   slope = (q.getY() - p.getY())/(q.getX() - p.getX());
   y3 = (slope * (100000 - p.getX())) + p.getY();
   y4 = (slope * (-100000 - p.getX())) + p.getY();
   Point2D out1 = new Point2D.Double(100000, y3);
   Point2D out2 = new Point2D.Double(-100000, y4);
   Line2D.Double line = new Line2D.Double(out1, out2);
   return line; }

这个找到了交集:

public Point2D.Double getIntersectionPoint(Line2D.Double line1, Line2D.Double line2) {
if (! line1.intersectsLine(line2)) { 
  System.out.println("No intersection"); 
  return null;} 
  double s1 = line1.getX1(),
        sp2 = line1.getY1(),
        rx = line1.getX2()-s1,
        ry = line1.getY2()-sp2;
  double qx = line2.getX1(),
        qy = line2.getY1(),
        sx = line2.getX2()-qx,
        sy = line2.getY2()-qy;
  double det = sx*ry - sy*rx;
  if (det == 0) { System.out.println("Det = 0");
    return null;} 
  else {
    double z = (sx*(qy-sp2)+sy*(s1-qx))/det;
    if (z==0 ||  z==1) return null;  
    return new Point2D.Double(
      (double)(s1+z*rx), (double)(sp2+z*ry));
  }
}

1 个答案:

答案 0 :(得分:1)

使用齐次坐标的投影几何是处理几乎平行或甚至完全平行的线的一种很好的方法。这是一个速成课程:

  • 平面中的点(x,y)将被均匀化为(x,y,1)。
  • 其中的倍数代表相同的点,因此您可以将其写为(2x,2y,2)。
  • 线轴+ + c = 0表示为(a,b,c)。
  • 具有齐次坐标p =(x,y,z)的点位于线g =(a,b,c)上,当且仅当它们的点积p·g = ax + by + cz为零时。 (你可能不需要这个,因为与双打相等的比较总是很棘手,但它解释了为什么其他步骤可以正常工作。)
  • 连接两个点的线可以计算为它们的齐次坐标的叉积。
  • 两条线之间的交点也可以计算为这些线坐标的交叉线。
  • 由于上述步骤总是相乘,如果您将其中的几个组合在一起,您的双倍数字可能会溢出。因此,不时重新调整您的矢量,例如将它们乘以某个标量,使其绝对值最大的条目变为1或其他。
  • 如果要在画布上绘制一个点(x,y,z),则计算(x / z,y / z)并绘制它。
  • 如果z = 0,则无法执行上一步骤。这代表了一个“无限远”的点。
  • 如果x = y = z = 0或a = b = c = 0,则向量不表示点resp。一条线,而是一个退化的情况。例如。你试图计算连接一个点的线。

正如您所看到的,这实现起来相当简单,甚至更好:您无需在任何地方进行任何区分!对于实际的绘图材料,您可能希望将线条与画布的边界相交,然后使用连接这些交叉点的​​线条作为图形基元的定义。