您好,如果有人可以提供有关如何解决我的问题的见解,那就太好了!
我正在寻找计算 3D 体积和 2D 平面之间的相交面积。3D 体积:由 6 个点定义(始终是类似于厚三角形的 3D 楔形) 2D 平面:由 3 个点定义
有什么建议?有没有可以执行此任务的开源软件?
非常感谢克里斯
您好,如果有人可以提供有关如何解决我的问题的见解,那就太好了!
我正在寻找计算 3D 体积和 2D 平面之间的相交面积。3D 体积:由 6 个点定义(始终是类似于厚三角形的 3D 楔形) 2D 平面:由 3 个点定义
有什么建议?有没有可以执行此任务的开源软件?
非常感谢克里斯
这个问题不会有灵丹妙药的答案。在某些时候,您只需要接受它并考虑所有情况。我曾经不得不计算一个三角形和一个圆的交点……这太可怕了。由于您的 3D 形状具有某些对称性(例如,它始终是一个三棱柱)有助于极大地缩小可能性。
这些确实是唯一的高级情况,显然需要应用对称减少(在情况 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 坐标中工作,那么您可以将它们直接提供给这样的函数以获取该区域。
我应该补充一点,有一种明显的愚蠢方法,即在切割平面中选择一个合适的大区域,并随机采样点并检查它们是否在棱镜中(这很便宜,因为它是凸面的)。然后,您可以将面积计算为内部点与总点的比率乘以采样区域的面积。如果您真的不关心准确性,那么这可能会更快,但除此之外,分析方法不应该慢很多,尽管它的组合复杂。