当使用MATLAB的inpolygon
函数确定多边形内的点时,我发现结果对于在线性轴上绘制的多边形是完全正确的,但对于在对数刻度轴上绘制的多边形只是近似正确。虽然我的怀疑倾向于支持MATLAB错误,但我可能忽略了一些东西。
以下代码重现了我在使用其他数据时遇到的问题。结果显示在下图中(底部面板组是顶部面板的缩放视图)。可以理解的是,在对数刻度轴(右)上绘制多边形的情况下,多边形内部有未标记的点,多边形外部有标记点,两者都不应出现。相反,多边形测试对于在线性轴(左)上绘制的多边形是精确的。
n=2E4;
x(:,1)=rand(n,1); y(:,1)=rand(n,1);
x(:,2)=lognrnd(0.5,0.25,n,1); y(:,2)=lognrnd(0.5,0.25,n,1);
for m=1:2
subplot(1,2,m);
scatter(x(:,m),y(:,m),'.'); hold on;
if(m==2)
set(gca,'xscale','log'); set(gca,'yscale','log');
end
p=impoly(gca);
pc=getPosition(p);
in=inpolygon(x(:,m),y(:,m),pc(:,1),pc(:,2));
scatter(x(in,m),y(in,m),20);
end
答案 0 :(得分:6)
我认为你错过了一些东西:正常尺度的线不是对数刻度线。您的多边形未在对数刻度中正确绘制,因为您绘制了2个点并将它们用直线放在一起。
查看日志空间中的真实多边形:
close all
clear
n=2e4;
x(:,1)=rand(n,1); y(:,1)=rand(n,1);
x(:,2)=lognrnd(0.5,0.25,n,1); y(:,2)=lognrnd(0.5,0.25,n,1);
for m=1:2
subplot(1,2,m);
scatter(x(:,m),y(:,m),'.'); hold on;
if(m==2)
set(gca,'xscale','log'); set(gca,'yscale','log');
end
p=impoly(gca);
pc=getPosition(p);
% plot polygon
hold on
for ii=1:size(pc,1)-1
plot(linspace(pc(ii,1),pc(ii+1,1),100),linspace(pc(ii,2),pc(ii+1,2),100),'g')
end
plot(linspace(pc(end,1),pc(1,1),100),linspace(pc(end,2),pc(1,2),100),'g')
in=inpolygon(x(:,m),y(:,m),pc(:,1),pc(:,2));
scatter(x(in,m),y(in,m),20);
end
看看这个放大的结果(点击放大):
这是因为多边形在欧几里德空间中定义,并且它被定义为由线链接的点。如果你想在日志空间工作,事情可能会变得复杂。数值近似的一种方法是我为绘图做的反向。在日志空间上创建足够密集的采样直线,将其转换为线性空间,并使用结果点定义高顶点多边形。然后使用inpolygon
。