判断点在多边形内——弧长法

判断点在多边形内——弧长法

原创转载说明出处:https://blog.csdn.net/weixin_37946323/article/details/107203712

计算弧长

弧长法要求多边形是有向图,边左侧为多边形内域。

以被测点作单位圆,将多边形边镜像投影到单位圆,所谓单位圆的径向投影,弧长等于半径乘角度,而单位圆半径为1,其实径向投影后的弧长就是多边形的有向边在被测点上转过的夹角([-pi,pi]),逆时针为正转角,顺时针为负转角。如果转角和为0,则点在多边形外;如果转角和为2*pi,则点在多边形内。

弧长计算由象限穿越代替

计算弧长比较费时间,所以用象限穿越代替计算弧长,如有向边自第Ⅰ象限穿越至第Ⅱ象限,则弧长+pi/2,反之则弧长-pi/2,计算量大减。
没写完,有问题留言,我会补充,附程序和结果图。
红为多边形内

代码

Matlab函数,可直接调用

function [flag] = inhull(point,hull_point)
%需要判断的点维度1*2 point  凸包坐标hull_point维度n*2
%flag返回凸包 100.5在凸包上
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% clear
% clc
% point=[7 7];
% hull_point=[1 1
%     8 1
%     4 8
%     1 4
%     1 1];
% plot(hull_point(:,1),hull_point(:,2),'-',point(1),point(2),'ro')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
point_code=[hull_point-point,zeros(size(hull_point,1),1)];

hull_point=hull_point-point;
omp=0;

for i=1:size(hull_point,1)
    zz=hull_point(i,:)==0;
    if isequal(zz,[1 1])
    else
       hull_point(i,:)=zz*0.001+hull_point(i,:);
    end
    zz=hull_point(i,:)==0;
    temp=hull_point(i,:)>0;
    Q=temp(2)+2*temp(1);
    if  isequal(zz,[0 0])
        if Q==3
            point_code(i,3)=1;
        elseif Q==1
            point_code(i,3)=2;
        elseif Q==0
            point_code(i,3)=3;
        elseif Q==2
            point_code(i,3)=4;
        end
    else
        omp=1;
        break
    end    
end
if omp==1
    flag=0.5;
else
    sss=huchanghe(point_code);
    if isnan(sss)
        flag=0.5;
    elseif abs(sss)<0.2
        flag=0;
    elseif abs(sss-2*pi)<0.2
        flag=1;
    else 
        flag=2;
    end
    
    
end
end

function [sss] = huchanghe(ppp)
sss=0;
   for i=1:size(ppp,1)-1
       if ppp(i+1,2)*ppp(i,1)-ppp(i+1,1)*ppp(i,2)==0
           sss=NaN;
           break
       end
       temp=[ppp(i,3),ppp(i+1,3)];
       if isequal(temp,[1 1])
           sss=sss+0;
       elseif isequal(temp,[1 2])
           sss=sss+pi/2;
       elseif isequal(temp,[1 3])
           f=ppp(i+1,2)*ppp(i,1)-ppp(i+1,1)*ppp(i,2);
           if f==0
               sss=NaN;
           else
               f=f/abs(f);
           end
           sss=sss+f*pi;
       elseif isequal(temp,[1 4])
           sss=sss-pi/2;
       elseif isequal(temp,[2 1])
           sss=sss-pi/2;
       elseif isequal(temp,[2 2])
           sss=sss+0;
       elseif isequal(temp,[2 3])
           sss=sss+pi/2;
       elseif isequal(temp,[2 4])
           f=ppp(i+1,2)*ppp(i,1)-ppp(i+1,1)*ppp(i,2);
           if f==0
               sss=NaN;
           else
               f=f/abs(f);
           end
           sss=sss+f*pi;
       elseif isequal(temp,[3 1])
           f=ppp(i+1,2)*ppp(i,1)-ppp(i+1,1)*ppp(i,2);
           if f==0
               sss=NaN;
           else
               f=f/abs(f);
           end
           sss=sss+f*pi;              
  
       elseif isequal(temp,[3 2])
           sss=sss-pi/2;
       elseif isequal(temp,[3 3])
           sss=sss+0;
       elseif isequal(temp,[3 4])
           sss=sss+pi/2;
       elseif isequal(temp,[4 1])
           sss=sss+pi/2;  
       elseif isequal(temp,[4 2])
           f=ppp(i+1,2)*ppp(i,1)-ppp(i+1,1)*ppp(i,2);
%            f=(-ppp(i+1,2)*ppp(i,1)+ppp(i+1,1)*ppp(i,2))/(ppp(i+1,1)-ppp(i,1));
           if f==0
               sss=nan;
               break
           else
               f=f/abs(f);
           end
           sss=sss+f*pi;   
       elseif isequal(temp,[4 3])
           sss=sss-pi/2;
       elseif isequal(temp,[4 4])
           sss=sss+0;          
       end
   end

end

var foo = 'bar';
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值