【问题标题】:fast calculation of the intersection area of a triangle and the unit square快速计算三角形与单位正方形的交面积
【发布时间】:2014-05-03 06:17:18
【问题描述】:

在我当前的项目中,我需要计算三角形和无限网格中单位正方形的交集面积。

对于每个三角形(由三对浮点数给出),我需要知道它与其相交的每个正方形的共同区域(在区间 (0,1] 内)。

现在我将(三角形和正方形)都转换为多边形并使用Sutherland-Hodgman polygon clipping 计算相交多边形,然后将其用于calculate its area。

这种方法现在显示为我的应用程序的性能瓶颈。我想更专业的(分析)算法会快得多。这个问题有标准的解决方案吗,或者你有什么想法吗?我只需要区域,而不需要交叉点的形状。

【问题讨论】:

  • 你最好指定使用场景——例如是方集常量等等。
  • 好的,谢谢。我希望在我编辑后现在更清楚了。
  • 是的,很明显,问题与最初的表述完全不同;)稍后会尝试详细说明一些线索
  • 你能解释一下你是如何描述三角形顶点的坐标的吗?您使用的是整数(像素?)还是浮点变量?
  • 感谢您的评论。坐标是浮点数。我相应地编辑了我的问题。

标签: geometry polygon intersection


【解决方案1】:

你的多边形是凸的。有一些凸多边形算法比一般算法更快。我已经成功使用了 O'Rourke 算法(code from his book here,我相信存在很好的描述)。请注意,可能会为您的方格预先计算一些值。

如果您的多边形并不总是相交,那么您可以首先使用分离轴方法检查相交的事实。

另一个尝试的选项 - Liang-Barski algorithm 用于按正方形裁剪每个三角形边缘。

编辑:您可以使用Amanatides and Woo(example in grid traversal section here)的算法快速找到三角形边缘与网格的所有交点

【讨论】:

  • 谢谢。我想相交两个凸多边形对于我非常简单的形状来说仍然是一种矫枉过正。但如果没有更好的弹出,我可能会听从你的建议。
  • 是的,正方形的修改更简单,但 O'Rourke 算法的一般原理 - 有序交替遍历边 - 是适用的。
  • Amanatides-and-Woo-thing 看起来很有希望,谢谢。你能告诉我你将如何使用它来实现我的目标吗?
  • 这可能有助于加快寻找交叉点。
  • 是的,这部分会变得更快。但是对于相交的单元格,我仍然需要计算重叠区域的大小。
【解决方案2】:

要以高性能处理此任务,我建议对 华帝线扫剪裁。 http://en.wikipedia.org/wiki/Vatti_clipping_algorithm

从三角形的最小 Y 顶点开始执行以下步骤:

  1. 按 Y 坐标排序顶点
  2. 将 Y 提高到 MIN(nextVertex.Y, nextGridBottom)
  3. 计算网格与边缘的交点。
  4. 采集电流梯形
  5. 从第 2 步开始重复直到 Y 坐标最高的顶点。
  6. 如果需要,按 X 坐标分割梯形。

这里是X方向梯形化的例子 http://www.personal.kent.edu/~rmuhamma/Compgeometry/MyCG/PolyPart/polyPartition.htm

它说明了线扫描算法的主要思想。祝你好运。

【讨论】:

    【解决方案3】:

    你没有提到你在寻找什么精度。如果您正在寻找一种分析方法,请忽略此答案,但如果您只想进行抗锯齿,我建议 Kiia Kallio 提供scanline edge-flag algorithm。我已经用过几次了,它的速度非常快,并且可以设置为非常高的精度。如果您有兴趣,我有一个 java 实现。

    【讨论】:

    • 听起来很有趣,但最初我正在寻找一个分析解决方案。
    【解决方案4】:

    您可以利用正方形的规则图案。

    我假设这是一个瓶颈的原因是因为您必须等待您的算法找到与任何三角形相交的所有正方形并计算所有相交区域。因此,我们将计算所有区域,但对每个三角形分批计算,以便从最少的计算中获得最多的信息。

    首先,正如其他人所解释的,对于三角形的每条边,您可以找到该边穿过的正方形序列,以及它穿过正方形的每个垂直或水平边的点。

    对所有三个边执行此操作,保留您遇到的所有方格的列表,但每个方格只保留一份副本。将正方形存储在多个列表中可能很有用,这样给定行上的所有正方形都保存在同一个列表中。

    当您找到三角形边缘通过的所有正方形时,如果其中两个正方形位于同一行,则这两个正方形之间不在列表中的任何正方形都完全在三角形内,因此每个正方形的 100%那些方块被覆盖了。

    对于其他正方形,面积的计算取决于正方形中有多少个三角形顶点(0、1、2 或 3)以及三角形边与正方形边的交点。你可以用几张纸笔画来总结所有的案例,并为每一个案例进行计算。例如,当三角形的一条边与正方形的两条边相交时,正方形的一个角在边的“外侧”,该角是小三角形的一个角,被较大的那条边“截断”三角形;使用正方形边上的交点计算小三角形的面积,然后从正方形的面积中减去。如果两个点而不是一个点在“外面”,则您有一个梯形,其两个底长是从交点找到的,其高度是正方形的宽度;从平方中减去它的面积。如果三个点在外面,减去整个正方形的面积,然后加上小三角形的面积。

    大三角形的一个顶点在正方形里面,正方形的三个角在那个角度之外:从剩下的角到三角形的顶点画一条线,所以你有两个小三角形,减去整个正方形并添加这些三角形'领域。正方形的两个角外角,画线到顶点得到三个小三角形等

    我这样说是为了让您始终假设您从正方形的整个区域开始,然后根据三角形的边缘与正方形的相交方式将面积减少一些。这样,在三角形的边与正方形相交两次以上的情况下——比如一条边穿过正方形的一个角,另一条边穿过另一个角,你可以只减去被第一条边,再减去第二条边截去的面积。

    这将是相当多的特殊情况,尽管您可以利用对称性;例如,“在一个角上切掉一个三角形”的完整计算不必写四遍。

    与仅将某人的凸多边形库从货架上拿下来相比,您将编写更多的代码,并且您需要测试它的生活日光以确保您没有忘记编写任何案例,但是一旦你让它工作起来,不应该花更多的精力让它相当快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-29
      • 2010-10-07
      • 2011-01-09
      • 2023-03-24
      • 1970-01-01
      • 2017-06-30
      • 2017-11-21
      相关资源
      最近更新 更多