【发布时间】:2012-01-18 00:15:44
【问题描述】:
我有以下问题:我需要生成 3d 模型的 2d 视图。在正常情况下,这当然是微不足道的:只需使用画家算法或类似技术将所有内容渲染到屏幕上。不幸的是,输出需要是 2d 几何,以便可以发送到 CAD 包。这意味着必须在向量级别而不是像素级别上进行隐藏表面的去除,这会导致大多数标准方法(画家算法、z-buffer 等)无法使用。
我发现执行对象空间隐藏表面移除的最常用技术是使用 BSP 树,理论上它工作得很好。所以我实现了它,但性能甚至无法接受,考虑到它的 O(n2) 复杂性,这并不完全令人惊讶。我正在使用的测试场景在背面剔除后有大约 4800 个三角形,但我预计该算法将需要处理大约 5 或 10 倍数量的场景,当您需要对其进行平方时,它很快就会变得相当大。我们几何库的(缺乏)速度也无济于事。
我已经尝试了不同的方法来解决这个性能问题,主要是基于将三角形分成较小的组以减少 O(n2) 的影响的想法,例如八叉树(超过一半的多边形存储在根节点中)并将 2d 投影场景划分为 10x10 网格以减少每平方的三角形数量(有效,但多边形交叉点的减少超过了重复该过程 100 次)。
今天我又进行了一次尝试,将所有三角形投影到 2D 中,并通过首先测试边界正方形是否重叠然后测试两个多边形的每个组合的每个边缘交叉点 (3x3 = 9) 来查看哪些三角形相交。对于线交点,我使用here 描述的算法绕过了几何库。总共执行了大约 1160 万个线交叉点,大约需要 30 秒,这仍然太长了(我会说绝对最大运行时间约为 5 秒),别介意这只是算法的一部分。
我开始对如何解决这个性能问题没有想法,希望你们中的任何人都对更好的算法有一些好的想法。我能想到的都是O(n2)。
【问题讨论】:
-
您能否提供更多实现细节(语言、库等...)?
-
在 2D 视图中实际可见的表面的典型数量是多少?
-
我正在使用 C#。几何库是由我工作的公司编写的,不是开源的。它也是用 C# 编写的,并支持诸如多边形相交之类的基本操作,尽管速度不是很快。几何库并不是特别重要,因为我可以忽略它并在需要时直接使用三角形点的 x、y 和 z 坐标。我认为语言也不是很重要。问题主要是算法之一。将任何解决方案移植到 C# 应该是相当简单的。
-
前面提到的 4,800 个面向相机的三角形可能与平均情况差不多。我不知道其中有多少被其他表面遮挡,但我想说最终视图中可见三角形的平均数量约为 3,000 个左右,最坏的情况可能是大约 30,000 个三角形。我使用的测试对象是一个具有相当复杂轮廓的窗口+框架,这意味着大多数三角形位于模型的边缘。玻璃板所在的部分只有几个多边形。
-
@FalconNL:我的回答对你最初的问题有什么影响吗?您没有提供反馈。
标签: performance algorithm surface