怎么判断某一点在一个不规则的图形内部

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么判断某一点在一个不规则的图形内部相关的知识,希望对你有一定的参考价值。

Python 怎么判断某一点在一个不规则的图形内部(包括凹图形)

假设那个图形是封闭的
假设图形在图片中只有轮廓
假设该图片存储方式为矩阵
那么如果某一点A在图形的内部,在图片的外部取任意的点B,连接AB,则AB与该图形必有交点,那么只要B点360度取都取一次,且与图形都存在交点,那么该点就在图形的内部
当然我这个方法,速度不太快
你可以使用PNPoly算法。
参考技术A 过该点作一条垂直,纵向的扫描线和一条横向的扫描线。令横向扫描线与多边形两个交点为P1,P2 .纵向扫描线与多边形交点为Q1,Q2. 数学方法证明该点同时位于P1和P2间,Q1和Q2间即可。 参考技术B 这是图形学里面的一个知识点。 参考技术C 我觉得吧。。。呃,这个有点难吧。

判断点在多边形内部

  项目的需要,需要判断点在多边形的内部,是整个算法必要的步骤,查了一些资料,中文很少,英文资料已经介绍的很清楚了,这里只是总结一下。

  问题的完整描述是判断平面上一点在多边形的内部、外部或者边界上。

  有两种解决方法:光线投射算法,环绕数法。

光线投射算法

  一个简单的判断方法是从该点想任意固定方向发送射线,求射线于多边形边的交点的个数。如果交点的个数是偶数个,则该点在多边形的外部,如果是交点的个数是奇数,则该点在多边形的外部。这种方法不能判断在多边形上的情况。

  要注意两个问题:

  第一个是当要判断的点离边界太近时,由于浮点数计算的不精确,会造成近似误差。可以通过设置一个点到点断的最小距离来解决这个问题。但是,当算法的速度要求大于精度要求时,这种情况不用考虑。

  另一个问题是在有一些应用中,需要依次判断射线于各个面的交点,用一张图来描述这个问题。这种情况下有一个必须要考虑的问题是,当射线直接穿过多边形的一个顶点,将会与两个线段相交于两个端点。当顶点是最上边的顶点时没有问题,但是如果是最右边的顶点,就需要记录一个交点。

 

这种问题的解决方法:如果射线的交点已经在多边形的顶点,只有当第二个交点位于位于射线的另一侧时才能够计数。等同于判断顶点是否在射线的两侧或者同侧。

  一种光线投射算法实现:

bool PixelInsidePolygon(float x, float y, int* polygonPoints, int count)
{
    // RayCasting method shooting the ray along the x axis, using float
    bool inside = false;
    float xintersection;
    for (int i = 0; i < count; i += 2)
    {
        float p1X = polygonPoints[i];
        float p1Y = polygonPoints[i + 1];
        float p2X = polygonPoints[(i + 2) % count];
        float p2Y = polygonPoints[(i + 3) % count];

        if (y > std::min(p1Y, p2Y) && y <= std::max(p1Y, p2Y) && p1Y != p2Y)
        {
            if (x <= std::max(p1X, p2X))
            {
                xintersection = (y - p1Y)*(p2X - p1X) / (p2Y - p1Y) + p1X;
                if (p1X == p2X || x <= xintersection)
                {
                    // each time intersect, toggle inside
                    inside = !inside;
                }
            }
        }
    }

    return inside;
}

环绕数算法

  另一种算法是计算给定顶点相对于多边形的环绕数。如果环绕数非零,则位于多边形的内部。计算环绕数的方法是多边形中每条边的包角(Subtended angle)累加和。但是,这种方法会引入反三角函数,会使算法的效率很慢。因为所有角度相加是0或者2\\pi ,实际上反三角函数不用计算。

  有一种改进的环绕数算法,给予从左到右或者从右到左的方式计算环绕数,可以在不计算角度的情况下得到正确的结果,速度和光线投射算法相当切可以处理复杂多边形的情况。

 

以上是关于怎么判断某一点在一个不规则的图形内部的主要内容,如果未能解决你的问题,请参考以下文章

求...判断一个点是不是在(不规则)四边形当中

nx二次开发怎么判断线上某一点在面上

非零缠绕规则和奇偶规则

平面坐标系中 如何判断某一点在一矩形区域内?

判断地图某一点在不在范围内

百度地图判断点是否在不规则多边形内部