2D 将 3D 点云绘制为一组线

2D Plotting a 3D point cloud as set of lines

我有一个三维点阵列。 我需要将它们绘制在 2D [x,z] 网格上,其中每条线都基于范围内的 Y 值。 es。第一行由 0 < y < 1 的点组成,第二行由 1 < y < 2 的点组成,依此类推。

我可以使用此脚本很好地绘制点(为了获得更好看的图形,我还通过在 rgb 三元组内移动来更改每组点的颜色)。 set 是线的范围(在我的例子中,Y 是时间,我需要每 0.1 秒绘制一次)。 i 是我的点数组的索引。

w= 0;
yend = 100;
set = 0.1;
numberOfColors = 1/2*(Yinterval)*(1/set);
incrementOfColor = 1/numberOfColors;
red = 0;
green = 0;
blue = 1;
color=[red green blue];

while w < yend

while y(i)>w&&y(i)<w+set

    figure(1)
    hold on        
    plot(x(i),z(i),'.','Color',color);
    hold on
    i=i+1;
end
    w=w+set;

   if red < 1-incrementOfColor && blue > 0
       red = red + incrementOfColor;
       blue = blue - incrementOfColor;

   end
  if red > incrementOfColor && blue < incrementOfColor
      red = red-incrementOfColor;
      green = green + incrementOfColor;
      blue = 0;
  end
   color = [red green blue];


end

这是结果: http://i.imgur.com/HTyzWai.png 当数据太多时,绘图变得难以阅读,而数据太少时,孤立的点并不能说明什么。 我已经尝试将 "set" 区间内的点转换为数组,但它确实没有成功:

while w < yend

while y(i)>w&&y(i)<w+set
    vX(a,:)=x(i);
    vZ(a,:)=z(i);
    i=i+1;
 a=a+1;
end    


    figure(2)
    hold on        
    plot(vX,vZ,'-','Color',color);

给出了这个结果:imgur.com/S7OasUn.jpg

是我的转换有误还是数组不是处理这个问题的正确方法?如果是这样,我应该使用什么?

我是 matlab 的新手,所以如果这真的很明显或者我以错误的方式问问题,请原谅。

编辑: 这是我想要达到的结果:
imgur.com/jPZTO8E.png 它是使用 Origin 的等高线轮廓工具获得的。 我猜你的意思是功能示例:

myPoints[i]: 
i=0, x = 1, y= 0.03, z = 1
i=1, x = 2, y= 0.06, z = 3
i=2, x = 2.5, y = 0.09, z = 4
i=3, x = 1.2, y = 1.01, z = 3.1
i=4, x = 1.3, y = 1.04, z = 1.1
i=5, x = 1.2, y = 1.06, z = 2.5
i=6, x = 2, y = 1.09, z = 3.1
i=7, x = 1.2, y = 2.02, z = 3.1

等..

我想将点 i 0,1,2 绘制为一条线,将 i 3,4,5 绘制为另一条线,将 i 7 等绘制为第三条线。在我的数据中我有很多点。

这是我正在使用的数据之一。 https://drive.google.com/file/d/0B9GHAkIYepQcRXdBdy03dFJtT1k/view?usp=sharing 其中:

x = myPoints(:,1);
y = myPoints(:,2);
z = myPoints(:,3);

在这种情况下,我只关心y值在85.85和90.85之间的点,我想"place an edge"(?)每0.1

x = myPoints(:,1);
y = myPoints(:,2);
z = myPoints(:,3);
ymin = 85.85;
ymax = 90.85;
set = 0.1;
nbins = (ymax-ymin)/set;
binedge = linspace(ymin, ymax, (nbins + 1));

我想我理解你想要完成的事情,我相信你可以通过矢量化使用 plot 来完成你的任务,而不必遍历你的每个点。

根据您的示例数据,我们可以试一试此方法:

load('mypoints.mat');
x = myPoints(:,1);
y = myPoints(:,2);
z = myPoints(:,3);

% Bin your data by y values
ymin = 85.85;
ymax = 90.85;
set = 0.1;
nbins = (ymax-ymin)/set;
binedge = linspace(ymin, ymax, (nbins + 1));
[~, ~, binidx] = histcounts(y, binedge);
binloop = unique(binidx);

% Fix for error with unique. If you try to use a for loop with a column
% vector it passes the whole vector as your iterator, so you need to
% transpose it to a row vector.
temp = size(binloop);
if temp(1) ~= 1
    binloop = binloop';
end

% Plot
figure
hold on
for ii = binloop
    if ii == 0
        % These fall outside of our bins, don't plot them
        continue
    else
        dataidx = find(binidx == ii);
        % Plot has its own color cycle, or you can add your color changing logic to this loop
        plot(x(dataidx), z(dataidx), '-', 'LineWidth', 0.25);
    end
end
hold off

我在这里所做的是利用 histcounts 的第三个输出对您的 y 数据进行分箱,并 return 为您的 [=15= 中的每个值创建分箱索引]向量。


将代码分解一下:

定义您的 bin 边界:

ymin = 85.85;
ymax = 90.85;
set = 0.1;
nbins = (ymax-ymin)/set;
binedge = linspace(ymin, ymax, (nbins + 1));

linspace 调用 return 每个数据仓的边缘。根据您的示例数据,我们得到 binedge = [86.85, 86.95, 86.05, ..., 90.85]。然后我们将这些边和您的 y 向量插入到 histcounts 以获得我们的 bin 索引:

[~, ~, binidx] = histcounts(y, binedge);

根据文档定义 bin 的位置:

The value X(i) is in the kth bin if edges(k) ≤ X(i) < edges(k+1). The last bin also includes the right bin edge, so that it contains X(i) if edges(end-1) ≤ X(i) ≤ edges(end).

我们可以使用 unique to loop through all of the bins that are present. We can utilize find with MATLAB's logical indexing 在每个循环迭代中绘制来自单个 bin 的所有数据。我忽略了 ii == 0 的位置,因为它指示数据不属于其中一个容器的位置(并且 0 索引在 MATLAB 中是无意义的)。

我还对线条大小进行了一些调整,试图让情节更容易阅读。这里有很多数据可以可视化,但它有一点帮助。由于 x 值回绕,您需要对数据进行一些修剪,但这应该是微不足道的。