impoly 仅在对数刻度轴上近似正确
impoly only approximately correct on log-scale axes
当使用 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
我想你错过了什么:正常比例的线不是对数比例的线。您的多边形未按对数比例正确绘制,因为您绘制了 2 个点并将它们用一条直线放在一起。
看日志中的真实多边形space:
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
看看这个放大的结果(点击放大):
发生这种情况是因为多边形是用欧几里德 space 定义的,它被定义为由线连接的点。如果你想在 log space 中工作,事情可能会变得复杂。一种在数值上近似它的方法是我为绘图所做的倒数。在 log space 上创建足够密集的采样直线,将其转换为线性 space,并使用生成的点定义高顶点多边形。然后使用 inpolygon
.
当使用 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
我想你错过了什么:正常比例的线不是对数比例的线。您的多边形未按对数比例正确绘制,因为您绘制了 2 个点并将它们用一条直线放在一起。
看日志中的真实多边形space:
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
看看这个放大的结果(点击放大):
发生这种情况是因为多边形是用欧几里德 space 定义的,它被定义为由线连接的点。如果你想在 log space 中工作,事情可能会变得复杂。一种在数值上近似它的方法是我为绘图所做的倒数。在 log space 上创建足够密集的采样直线,将其转换为线性 space,并使用生成的点定义高顶点多边形。然后使用 inpolygon
.