检查3D点是否位于3D柏拉图实体内部?

问题描述 投票:3回答:4

是否有任何已知方法可快速有效地确定3D点是否位于已知大小的柏拉图体积内?

这似乎很容易与立方体(六面体)或圆形(椭圆体)做。对于四面体,八面体,十二面体或二十面体,我似乎无法弄清楚。我猜测可能可以将形状分解为几个子实体,然后检查每个子实体,但我想尽可能避免使用任何一种迭代求解器。

c++ algorithm geometry computational-geometry
4个回答
5
投票

一种简单的方法是将实体表示为半空间的交集。

3d中的平面具有隐式方程:

ax + by + cz + d = 0

其中(a, b, c)是平面法线,d是该平面的任何点的-(a*x + b*y + c*z)值(计算出的值将不取决于您选择的点)。

对于在平面的一侧上的空间中的点,a*x+ b*y + c*z + d的结果将为负,而在另一侧的结果将为正。

柏拉图式实体(任何凸形实体)可以表示为所有面的非正侧的空间点,即

a[i]*x + b[i]*y + c[i]*z + d[i] <= 0

因此,合理的快速测试可能是:

struct Plane {
    double a, b, c, d;
};

struct Point {
    double x, y, z;
};

int side(const Point pt, const Plane& pl) {
    double v = pt.x*pl.a + pt.y*pl.b + pt.z*pl.c + pl.d;
    if (v < -EPS) return -1;
    if (v > EPS) return 1;
    return 0;
}

struct ConvexSolid {
    std::vector<Plane> planes;

    bool contains(const Point& pt) const {
        return std::all_of(planes.begin(), planes.end(),
                           [&](const Plane& pl){
                               return side(pt, pl) <= 0;
                           });
    }
};

此外,如果您知道大多数要点都将包含在实体中,则添加快速接受测试可能是个好主意。考虑中心和距面的距离...如果您的点位于以中心为中心且具有该半径的球体内,则也肯定也位于实体内部。

因此,如果您希望许多点位于该范围内,那么首先检查它可能是一项不错的投资,因为只需检查一下即可

 r2 = (x-xc)*(x-xc) + (y-yc)*(y-yc) + (z-zc)*(z-zc)

应该比检查一架飞机的成本略高。

但是请注意,如果大多数点不在该球体内,那么执行此检查确实是一种悲观。

另一种加速方法是还要考虑边界球具有相同的中心 ...,在这种情况下,您只能使用相同的r2计算来进行“带”检查,并且您将需要运行仅在r2 > r2min(即,该点不在内球体内部)和r2 < r2max(即,该点不在外球体外部)时进行完整检查。


3
投票

如果您正在寻找一种优化的算法,则可以尝试检查该点是否在实体的边界球之外,并仅在不存在边界的情况下才对曲面进行检查。


1
投票

point in polygon在确定2D点是否位于任何类型的多边形(2D空间)内的情况下是众所周知的问题。参见例如

[polyhedra(3D)中的点问题是-对于任何类型的多面体来说-都有些棘手。但是,在您的情况下,您严格考虑使用convex多面体,因为所有柏拉图式固体都是后一种。

在这种情况下,我可以为您指出解决此问题的两种方法。

1 :(任何凸面

polytope

的通用方法))您可以将问题视为查找某个点是否在一组已知点的convex hull内,在这种情况下,您的点就是顶点柏拉图式的实体,它们准确地描述了自己的凸包(由于凸性,没有“内部”顶点)。例如,已经讨论了如何实现该问题的一般解决方案。在这里:

2:如上所述,对多边形中的2D点进行了深入研究,甚至可以为其找到C ++代码in the SO link I provided above。由于您正在考虑3D中的凸多面体,因此我们知道切穿这种多面体的2D平面的交点将描述凸多边形。因此,对于要调查的每个点,您将创建一个包含该点并且与多面体(您的柏拉图式实体)相交的平面:然后,剩下的问题是求解

“”多边形问题中的2D点“]这架飞机。


0
投票
从该点到形状外部的某点画一条线,并计算它穿过的表面数量。如果数字为奇数,则该点在内部,否则在外部。
© www.soinside.com 2019 - 2024. All rights reserved.