在对数刻度轴上只能近似正确

时间:2016-12-19 12:48:32

标签: matlab point-in-polygon

当使用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

enter image description here

1 个答案:

答案 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

看看这个放大的结果(点击放大):

enter image description here

这是因为多边形在欧几里德空间中定义,并且它被定义为由线链接的点。如果你想在日志空间工作,事情可能会变得复杂。数值近似的一种方法是我为绘图做的反向。在日志空间上创建足够密集的采样直线,将其转换为线性空间,并使用结果点定义高顶点多边形。然后使用inpolygon