判断点在多边形内——弧长法
原创转载说明出处: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返回凸包 1是 0否 0.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';