如何计算 3D 体积和 2D 平面之间的相交面积

计算科学 计算几何
2021-12-10 11:31:31

您好,如果有人可以提供有关如何解决我的问题的见解,那就太好了!

我正在寻找计算 3D 体积和 2D 平面之间的相交面积。3D 体积:由 6 个点定义(始终是类似于厚三角形的 3D 楔形) 2D 平面:由 3 个点定义

有什么建议?有没有可以执行此任务的开源软件?

非常感谢克里斯

1个回答

这个问题不会有灵丹妙药的答案。在某些时候,您只需要接受它并考虑所有情况。我曾经不得不计算一个三角形和一个圆的交点……这太可怕了。由于您的 3D 形状具有某些对称性(例如,它始终是一个三棱柱)有助于极大地缩小可能性。

  1. 找出每个点位于平面的哪一侧。
  2. 如果所有点都在一侧,则完成。
  3. 如果一个点与其他 5 个点被平面隔开,则相交是一个三角形。大概,您有​​连通性信息来告诉您哪些面入射在顶点上,并且您可以计算由于平面-平面相交而产生的 3 条线,然后是相交三角形。最好在相交平面的参数化中完成所有这些操作。
  4. 两个点是分开的,要么都在棱镜的同一个三角形面上,要么它们是相对三角形面上的两个对应点。在任何一种情况下,交点都是四边形。
  5. 对于三个点,它们可能都是同一个三角形面,也可能只有两个。这里有两种情况,用于生成三角形或六边形。

这些确实是唯一的高级情况,显然需要应用对称减少(在情况 5 中,一个点的情况相当于另一个三角形面上的 2 点的情况)。

我给你的一个建议是为你的形状选择一个健壮的表示,并使用健壮的谓词来执行几何测试。对于平面,最好将其表示为平面上的一个点,以及一个单位法向量。棱镜通过定义正交基(三元组)来表示,其中一个轴与棱镜的挤压方向对齐。让一个顶点在原点,三角形面上的另外两个在三元组的 uv 坐标中表示,然后你只需要存储它的高度,以及它的基顶点的全局偏移量。本质上,我在想

struct plane{
    double p[3]; // point on plane
    double n[3]; // unit normal vector to plane
};
struct TriPrism{
    double basis[9]; // 3x3 orthogonal matrix of local coordinate frame (det = +1)
    // Stored columnwise, first two vectors are in the plane of the triangular face)
    // Last vector is parallel to extrusion direction, call the set [u, v, w]
    double base[3]; // global coordinates of base vertex (where the basis vectors are "rooted")
    double buv[2]; // the uv-coordinates of the second point on the triangular face
    double cuv[2]; // third point on triangular face
    // Assume that the "bottom" triangular face is formed by vertices (a,b,c)
    // with base being a, and (b-a) cross (c-a) directed along vector w (instead of against)
    double h; // height of prism ("top" triangular face is h*w offset from the "bottom" face)
};

这种表示对于四处移动棱镜是稳健的,并且除了最病态的情况外,应该保持较高的相对精度。

至于健壮的谓词,我强烈推荐Shewchuk 的健壮谓词,前提是 您使用普通的浮点数。您将主要使用orient3d.

在表示最终输出多边形方面,选择合适的平面参数化。在我看来,最好的选择是首先选择平面中的正交基组,由平面法向量上的 Gram-Schmidt 确定(参见 geom_maketriad3d 此处)。然后,让该 2D 参数平面的原点为棱镜基点在平面中的投影。这可确保您的参数化实际上植根于生成的多边形附近,以确保有效使用所涉及的浮点数的位。如果可能,请使用此参数化进行所有剩余的计算。

通常,由于这些愚蠢的数值考虑,几何计算充满了危险(在上面的案例 5 中,靠近平面的顶点的轻微错误可能会将结果从 4 边形大幅更改为 6 边形)。我建议您一次处理几个案例,并尝试将结果可视化。我在这里有一个相当简单的查看器程序,具有一种类似后记的输入语言功能。您可以倾倒棱镜的刻面并绘制平面,还可以绘制生成的多边形并目视检查它们是否正确。

附录:我忘了你最初想要交叉多边形的面积。这是微不足道的,但如果您不知道,一旦您拥有定义剖切面中多边形边缘的线条集合,您必须将其转换为顶点表示。由于您从平面和平面的交点构建了交点,因此您应该能够跟踪线的顺序,从而跟踪多边形周围的边的顺序。您只需要计算这些线的连续对的交点即可获得顶点。一旦你有了顶点,就很容易得到面积(参见 geom_polygon_area2d 这里)。如果您完全在剖切面的 uv 坐标中工作,那么您可以将它们直接提供给这样的函数以获取该区域。

我应该补充一点,有一种明显的愚蠢方法,即在切割平面中选择一个合适的大区域,并随机采样点并检查它们是否在棱镜中(这很便宜,因为它是凸面的)。然后,您可以将面积计算为内部点与总点的比率乘以采样区域的面积。如果您真的不关心准确性,那么这可能会更快,但除此之外,分析方法不应该慢很多,尽管它的组合复杂。