判断点与多边形的关系(1):向量积法

判断点与多边形的关系,是计算几何的经典问题,点与多边形的关系可以分为:点在多边形内(inside)、点在多边形外(outside)以及点在多边形的边上(onside)三种。
在图像处理系统中,如果通过多变形的方式标注感兴趣区域(ROI),在标注结束后需要判断图像中的点哪些在区域内部,以生成Mask文件;同时,在跟踪目标做防入侵报警时,也要根据目标位置与报警区域的关系。
判断是否需要报警。在以下几篇BLOG中,对该问题的解决方案进行探讨。
判断点与多边形关系的一个直接思路是:多边形可看做从某点出发的闭合回路,内部的点永远在回路的同一边。实现以上思想的直接方法就是通过向量积的概念,向量积可参考http://blog.csdn.net/ezhchai/article/details/78841336




在如上图所示多边形中,需要判断点O在多边形内,首先看顶点A和B组成的边AB可看作是一条向量,A指向B,则O在AB的右侧,按照右手定则,向量AO与向量AB的向量积的数值为正,这里可参考博客 http://blog.csdn.net/ezhchai/article/details/78841336给出的公式进行计算。顺时针方向,可以看出向量BO与向量BC的向量积数值为正。以此类推,多边形所有的边与O点按此规律组成的向量积数值都为正。如果按逆时针方向,所有向量积数值均为负。当点在多边形外时,顺次进行向量机计算,符号会出现正负交替。如果向量积为0,说明该点在多边形的这条边上。
在此可进行一般性总结,当点在多边形内部时,按多边形顶点连接顺序与带判断点形成向量积的符号一致。这也就是解决判断点与多边形关系的“向量积法”。
当然,向量积法的使用是有条件的,向量积在计算时是按照向量夹角中的“劣角”(小于180度的角)方向计算,如果存在“优角”(大于180度)方向相反,而凸多边形中不存在优角。因此,向量积法只能在凸多边形的前提下有效。
参考代码如下

int InPolygon_CP(const CZPolygon& polygon, CZPoint_t pt){
    int itNumPt = polygon.size();
    CZPoint_t pt_1, pt_2;
    double duCP_pre = 0.0;
    for (int i=0; i<(itNumPt-1); i++){
        pt_1 = polygon[i];
        //pt_2 = polygon[(i + 1) % itNumPt];
        pt_2 = polygon[i + 1];
        double duCP = CrossProduct(&pt_1, &pt, &pt_2);
        if(0.0 == duCP) 
            return ONSIDE;
        if (0 == i)
            duCP_pre = duCP;
        else
            if (duCP*duCP_pre < 0)
                return OUTSIDE;
    }
    return INSIDE;
}

再贴两张代码实现的效果图片





  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
射线法是一种常用的判断多边形关系的算法。下面是使用 SQL Server 实现射线法判断多边形关系的一种可能方法: 首先,假设我们有一个名为 Points 的表,其中包含多边形的顶坐标,以及一个名为 TestPoint 的表,其中包含要测试的的坐标。 我们可以使用以下 SQL 查询来判断多边形关系: ```sql -- 创建示例表 CREATE TABLE Points ( ID INT, X FLOAT, Y FLOAT ); CREATE TABLE TestPoint ( X FLOAT, Y FLOAT ); -- 插入多边形数据 INSERT INTO Points (ID, X, Y) VALUES (1, 0, 0), (2, 0, 4), (3, 4, 4), (4, 4, 0); -- 插入要测试的数据 INSERT INTO TestPoint (X, Y) VALUES (2, 2); -- 计算射线与多边形的交数量 WITH CTE AS ( SELECT p1.X AS x1, p1.Y AS y1, p2.X AS x2, p2.Y AS y2, tp.X AS tx, tp.Y AS ty FROM Points p1 JOIN Points p2 ON p1.ID = p2.ID + 1 OR (p1.ID = (SELECT MAX(ID) FROM Points) AND p2.ID = 1) CROSS JOIN TestPoint tp ) SELECT COUNT(*) % 2 AS IsInside FROM CTE WHERE CASE WHEN y1 = y2 THEN ty = y1 AND tx > x1 AND tx < x2 ELSE (ty - y1) / (y2 - y1) * (x2 - x1) > (tx - x1) END; ``` 上述查询首先创建了名为 Points 的表,并插入了多边形的顶数据。然后创建了名为 TestPoint 的表,并插入要测试的的数据。 接下来,使用 CTE(通用表达式)来计算射线与多边形的交数量。最后,查询返回一个布尔值 IsInside,表示测试是否在多边形内部。如果 IsInside 的值为 1,则表示多边形内部;如果值为 0,则表示多边形部。 注意,这只是一种实现方式,具体的实现可能因数据库结构和需求而有所不同。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值