C语言 利用转角法判断点是否在多边形内

判断点是否在多边形内——转角法

简介

今天在拜读南京师范大学张宏老师与温永宁老师的书籍《地理信息系统算法基础》时,收获了新的拓扑算法,所以在此记录一下。
在地理学中,探究两个几何对象,点与多边形的拓扑关系时,经常使用两种方法,分别是射线法与转角法,其中射线法更加常用。

射线法

在使用射线法进行点与多边形的拓扑关系判断时,有一个限定条件,即多边形必须是一个简单多边形,这个多边形必须是一个简单的闭合曲线所构成的,在多边形所在的平面中只有两个相互分离的部分,即多边形的外部与多边形的内部;且多边形没有自相交与自重叠;
如果出现了复杂的自重叠多边形,在某些多边形二次重叠的部分,射线法并不能很好的判断点是否在多边形内部,此时,就提出了另一种判断方法,转角法。

转角法

转角法,简单来说就是判断,多边形是否对点产生了环绕,累计在计算过程中的环绕数,如果环绕数为0,则在多边形外部,否则在多边形内部;

原理

设定多边形的边是具有方向的向量,总体是按逆时针方向,如图;
复杂多边形

为了便于理解,同时也为了优化算法,将射线法的算法进行改写,依然从点引出一条向右的射线,但此时与射线法的区别在于,不再是对与多边形相交数的叠加,而是有加有减的计算;
当射线与方向向上的边相交时,环绕数加一;当射线与方向向下的边相交时,环绕数减一,如图所示,即可更好的判断点是否位于多边形内部。
在这里插入图片描述
如图,点A向右引出的射线经过了2-3,及8-9两个方向向上的边,没有经过方向向下的边,所以环绕数为2,可以判断点A在多边形内部;
以点B为端点的射线经过了2-3一个方向向上的边,6-7一个方向向下的边,所以环绕数为0,即可判断点B在多边形外部;
点C的射线只经过了2-3一个方向向上的边,所以环绕数为1,所以点C也在多边形内部;

算法

在转角法的算法中,我用自己定义的结构节点代表了多边形的顶点,并以链表的形式存储,在遍历边进行判断时,顶点号依次递增,并加入了判断边的方向的条件;算法仅供参考,若有错误,欢迎指正。

#include <stdio.h>
#include <math.h>

typedef struct node
{
    int n;
    int x;
    int y;
    struct node *next;
};

int main()
{
    struct node t[10] = {0,0,0,NULL};
    struct node *a = &t[0],*b;
    struct node p;
    int wn = 0;

    for (int i = 1;i < 10;i++) {
        a->next = &t[i];
        a = a->next;
    }

    a->next = &t[0];
    b = &t[1];

    do{
        if((p.x-a->x)*(b->y-a->y)==(b->x-a->x)*(p.y-a->y)&&min(a->x,b->x)<=p.x&&p.x<=max(a->x,b->x)&&min(a->y,b->y)<=p.y&&p.y<=max(a->y,b->y))
        {
            if(b->y > a->y)
            {
                wn++;
            }
            else if (a->y > b->y) {
                wn--;
            }
        }
        a = a->next;
        b = b->next;
    }while (a->n == 0);

    if(wn == 0)
    {
        return 0;
    } else {
        return 1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

airforcetop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值