【问题标题】:Point in Polygon 3d (same plane) algorithm多边形中的点 3d(同一平面)算法
【发布时间】:2020-06-19 17:49:10
【问题描述】:

我在 3d 空间的 同一平面 中有一个点和一个多边形,现在我想检查该点是否在多边形中。 有没有一种简单的方法可以从这个线程 Point in Polygon Algorithm 更改算法以适用于 3d 空间? 或者有没有其他算法可以轻松解决这个问题?

如果没有,以下想法是否可行: 检查平面是 XZ 平面还是 YZ 平面,如果是,则忽略另一个轴(即对于 XZ 平面,忽略 y 值)并使用前面提到的线程中的 pip 算法。如果不是,则忽略点和多边形的 z 值并使用 pip 算法。

【问题讨论】:

  • 是的,投影到适当的坐标平面(忽略一个坐标)是最简单的方法。
  • 多边形是凸的还是凹的?
  • @Spektre 它是凹的。

标签: algorithm 3d point-in-polygon


【解决方案1】:

有两种测试平面凹多边形的“基本”方法:

  1. 转换为凸集并测试点和所有面之间的叉积方向

    转换为凸多边形并不容易,但它可以通过三角测量或剪耳或任何方法来实现......之后只需检查叉积......所以如果你的凸多边形有顶点p0,p1,p2,...,p(n-1)并进行测试然后点p

    d0 = cross( p-p0 , p0-p(n-1) );
    for (i=1;i<n;i++)
        {
        di = cross( p-p(i), p(i)-p(i-1) );
        if ( dot ( d0 , di ) <=0.0 ) return false;
        }
    return true;
    

    所以只需检查所有多边形并返回子结果的 OR

  2. 使用命中测试

    你从你的点向平行于你的平面的任何方向投射光线,并计算你的光线对多边形边缘的命中次数。如果它的奇数点在里面,它的偶数点在外面。 您问题中的链接使用此算法。但是在 3D 中,您需要更改方向,使其仍然在平面内……例如,使用多边形的单边 dir=p1-p0 作为您的方向。您还必须为光线直接击中顶点的情况编写一些规则,以便只计算一次而不是多次。此外,命中必须以 3D 形式计算,因此您需要轴/线相交。可以在这里找到:

    只需寻找line closest(axis a0,line l1) 函数。它返回线,它是线和轴之间最近的连接。然后只需检查两个点是否相同(线的长度为零)。

现在为了简化这一点,您可以将 3D 数据移植到 2D

这样可以解决一些与平面四舍五入相关的精度问题...

您只需忽略一个坐标即可完成此操作。这很简单,但可能会带来一些舍入问题,而且结果具有不同的形状(在每个轴上缩放不同),因此指标不再相同,如果将其用于其他目的或任何类型的阈值,则可能会带来其他问题用过。

有更好的方法。我们需要任意 2 个基向量 u,v,它们垂直于每个基向量并且在您的平面内,并且在平面内有一个点 o。这很简单:

o = p0;    // any point from the polygon
u = p1-p0; // any edge of polygon
u /= |u|;  // normalize
v = p2-p1; // any other edge of polygon
v /= |v|;  // normalize
for (;fabs(dot(u,v)>0.75;) // if too parallel
    {
    v=(p(1+rand(n-1))-p0); // chose random "edge"
    v /= |v|;  // normalize
    }
v=cross(u,v); // make u,v perpendicular
v=cross(v,u); // and inside the plane
v /= |v|;     // normalize just in case because of rounding the size might not be unit anymore

现在将点 p(x,y,z) 从 3D 转换为 2D (x,y) 只需这样做:

x = dot(p-o,u);
y = dot(p-o,v);

转换回 3D:

p = o + x*u + y*v;

通过这种转换方式,度量是相同的,所以多边形边的长度和多边形的大小不会改变......

【讨论】:

    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 2012-07-27
    相关资源
    最近更新 更多