概述:
我有一个简单的塑料沙箱,由3D多边形网格代表。我需要能够在将特定量的水倒入沙箱后确定水位。
问题:
我可以使用哪种技术/算法来解决这个问题?
我不是在寻找可以做到这一点的程序或类似程序,只是算法 - 我会做实现。
答案 0 :(得分:2)
只是一个想法:
首先计算所有马鞍点。像离散莫尔斯理论或拓扑持久性这样的工具可能在这里很有用,但我对它们知之甚少。接下来,从最低点开始迭代所有鞍点,并计算水开始越过该点的时间点。这是两个相邻盆地的较浅(就体积与表面积而言)达到与该鞍点的高度相匹配的水平的时间。从那时起,浇注到该表面上的水将流到另一个盆地并且有助于其水位,直到两个盆地达到相同的水平。之后,它们将被视为一个单一的盆地。在此过程中,您可能需要更正其他鞍点的时间,因为与盆地相关的区域会发生变化。您按照增加时间的顺序进行迭代,而不是增加高度(例如,使用具有减小键操作的堆)。一旦最后一对盆地的高度相等,你就完成了;之后只剩下一个盆。
总的来说,这给你一系列“有趣”的时间,事情从根本上改变了。在这些之间,问题将更加局部,因为您只需要考虑单个盆地的形状来计算其水位。在这个本地问题中,您知道该盆地中包含的水量,因此您可以例如使用二分法找到合适的水平。相邻的“有趣”时间可能为你的二分法提供有用的终点。
要计算三角形多面体的volume,您可以使用shoelace formula的3D版本:对于每个三角形,您可以获取其三个顶点并计算其行列式。求它们除以6,你就得到了封闭空间的体积。确保始终如一地定位所有三角形,即从内部看到的全部或从外部看到的所有三角形。选择决定整体标志,试试看哪一个是哪个。
请注意,您的问题可能需要改进:当水池中的水位达到完全相同的高度时的两个鞍点时,水流在哪里?我猜,如果没有流体模拟,这个定义不明确。你可以说它应该在所有相邻的盆地之间平均分配。你可以说这种情况不太可能发生在真实数据中,因此任意选择一个邻居,这意味着这个鞍点的高度比其他鞍点高得多。或者您可以提出许多其他解决方案。如果您对此案感兴趣,那么您可能需要澄清您的期望。
答案 1 :(得分:1)
想到一个简单的解决方案: 二元搜索通过不同高度的水,计算所含水量。 即 首先估算沙箱深度D的水高度。 请注意,由于砂是多孔的,最大体积将是用水填充到边缘的盒子; 在我们假想的后院里,任何更多的水都会砰砰地回到草丛中。 另请注意,这意味着您无需担心鞍点或解决方案中的多个水位; 我们再次假设这里有规则的多孔沙,而不是用岩石做成的山脉。 计算高度D所含的水量。 如果它在您的近似阈值内,则退出。 否则,请使用不同的高度调整估计值,然后重复。
请注意,对于任何给定的三角形沙子,计算沙子表面上方的水量很容易。 它是三角形prizm的体积加上与沙子接触的四面体的体积:
请注意,砂线以下的水量将以类似方式计算,但体积会更小,因为部分水将被沙子占据。 我建议在互联网上寻找典型的空气含沙量或持水能力。 或者任何短语都会返回一个理智的结果。 另请注意,如果沙子位于水线之上,某些三角形可能在沙子上方没有水。
对于网格的单个三角形,如果在砂线的上方和下方都有水量,则只需在所有三角形上循环以获得整个沙箱的总体积,即给定的高度。 / p>
请注意,这是一个非常愚蠢的算法,但我怀疑它会有一个不错的表现,相比于花哨的schmancier算法,它会尝试做更聪明的事情。
请记住,这只是每个三角形的少数乘法和求和,并且具有少量if
语句或其他流控制的盲循环往往会快速执行,因为处理器可以很好地管道它。
如果您有一个非常详细的沙箱网格,并希望将计算推送到多个核心,则此方法可以轻松并行化,而不是在每个三角形上循环。 或者保持循环,并将不同的高度推入每个核心。 或者是其他东西;我将并行化和加速作为读者的练习。