【问题标题】:Algorithm for partially filling a polygonal mesh部分填充多边形网格的算法
【发布时间】:2013-01-20 13:34:46
【问题描述】:

概述:
我有一个由 3D 多边形网格表示的简单塑料沙箱。在将特定量的水倒入沙箱后,我需要能够确定水位。

  • 浇水时水从上方均匀分布
  • 没有流体模拟,水倒得很慢
  • 需要快速

问题:
我可以使用什么样的技术/算法来解决这个问题?

我不是在寻找可以做到这一点的程序或类似的东西,我只是在寻找算法 - 我会做实现。

【问题讨论】:

  • 根据地表的不同,水可能会也可能不会找到到达最低水位的方式。您是否需要考虑这一点,或者您只是想找到水平面,其中封闭在平面下方的空间体积等于水的体积?
  • 我只是想找到水平面——非常基本。但我真的很想要一些灵感:)
  • 如果在高度 z 处添加一个平面,是否有一种简单的方法来计算封闭体积?
  • 假设答案是@A。韦伯的问题是“不,我不需要考虑这一点”,如果你可以计算低于某个高度 y 的网格体积,你就可以这样做(然后,例如,预先计算几个预定的高度,并进行二分搜索以找到给您一定体积的y,并通过插值来猜测您计算的y之间的体积)。我有点羞于承认我不知道如何计算网格的面积,但 heresome links 可能有帮助也可能没有帮助。
  • @BlueRaja-DannyPflughoeft 这对我来说听起来不错,也有可能并行完成。从网格线性插值的外观来看,对于导致快速收敛的大部分部分来说可能是不错的。

标签: algorithm 3d geometry simulation theory


【解决方案1】:

只是一个想法:

首先计算所有鞍点。离散莫尔斯理论或拓扑持久性等工具可能在这里有用,但我对它们知之甚少,无法确定。接下来,您迭代所有鞍点,从最低点开始,并计算水开始穿过该点的时间点。这是两个相邻盆地的较浅(就体积与表面积而言)达到与该鞍点高度相匹配的水平的时间。从那时起,倾倒在该表面上的水将流向另一个盆地并增加其水位,直到两个盆地达到相等的水位。之后,它们将被视为一个单独的盆地。在此过程中,您可能必须更正到达其他鞍点的时间,因为与盆地相关的区域会发生变化。您按时间增加的顺序进行迭代,而不是增加高度(例如,使用带有减少键操作的堆)。一旦最后一对盆的高度相等,就完成了;之后就只剩下一个盆地了。

总体而言,这为您提供了一系列“有趣”的时间,其中事情发生了根本性的变化。在这两者之间,问题将更加局部,因为您只需考虑单个盆地的形状即可计算其水位。在这个局部问题中,您知道该盆地中包含的水量,因此您可以例如使用二分法找到合适的水平。相邻的“有趣”时间可能会为您的二等分提供有用的终点。

要计算三角形多面体的 volume,您可以使用 shoelace formula 的 3D 版本:对于每个三角形,您需要它的三个顶点并计算它们的行列式。将它们加起来除以 6,就得到了封闭空间的体积。确保所有三角形的方向一致,即要么全部从内部看,要么全部从外部看。选择决定整体标志,试试看哪个是哪个。

请注意,您的问题可能需要细化:当盆地中的水位达到两个完全相同高度的鞍点时,水会流向哪里?我猜,如果没有流体模拟,这并没有很好的定义。你可以争辩说它应该在所有相邻的盆地之间平均分配。您可能会争辩说,这种情况不太可能发生在真实数据中,因此可以任意选择一个邻居,这意味着这个鞍点的高度比其他鞍点的高度要小得多。或者你可以想出一些其他的解决方案。如果您对此案例感兴趣,那么您可能需要澄清您的期望。

【讨论】:

    【解决方案2】:

    想到一个简单的解决方案: 对不同高度的水进行二分搜索,计算所含的水量。 IE。 从沙盒深度 D 的水高度的上估计开始。 请注意,由于沙子是多孔的,因此最大体积将是装满水的盒子; 在我们假设的后院里,任何更多的水都会喷回到草丛中。 另请注意,这意味着您无需担心解决方案中的鞍点或多个水位; 同样,我们假设这里是普通的多孔沙子,而不是由岩石构成的山脉。 计算高度 D 所包含的水的体积。 如果它在您的近似阈值内,请退出。 否则,用不同的高度调整您的估计值,然后重复。

    请注意,对于任何给定的三角形沙子,计算沙子表面上方的水量很容易。 它是三棱柱的体积加上与沙子接触的四面体的体积:

    请注意,沙线以下的水量会以类似方式计算,但体积会更小,因为其中一部分会被沙子占据。 我建议在互联网上搜索典型的沙子含气量或持水量。 或者任何短语都会返回一个理智的结果。 另请注意,如果沙子高于吃水线,则某些三角形的沙子上方的水可能为零。

    一旦您获得了网格中单个三角形的沙线上方和下方的水量,您只需遍历所有三角形即可获得给定高度下整个沙盒的总体积。

    请注意,这是一个非常愚蠢的算法,但我怀疑与尝试做任何更聪明的花哨的 schmancier 算法相比,它会有不错的性能。 请记住,这只是每个三角形的少量乘法和求和,并且带有少量 if 语句或其他流控制的盲循环往往会快速执行,因为处理器可以很好地流水线化。

    如果您有一个高度详细的沙盒网格,并且希望将计算推送到多个核心中,则此方法可以轻松并行化,而不是在每个三角形上循环。 或者保留循环,并将不同的高度推入每个核心。 或者是其他东西;我将并行化和加速留给读者作为练习。

    【讨论】:

      猜你喜欢
      • 2013-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-07
      • 1970-01-01
      • 2012-09-09
      • 2014-01-01
      相关资源
      最近更新 更多