繁体   English   中英

在散点图上的点周围生成曲线

[英]Generating a curve around the point on a scatter plot

我正在生成一个散点图,其中包含来自多个源的数据,如下所示。

散点图

我希望能够生成围绕任意查询点并通过散点图上的点的曲线。 最终目标是计算绘图上线之间的面积。

我已经实现了以下解决方案:使用knnsearch以圆形方式查找点,然后应用hampel滤波器消除噪声。 在下面的示例中,我在蓝色阴影区域的中间选择了一个点。 如您所见,结果远非完美,我需要更高的精度。

效果不是那么完美

我正在寻找类似于boundary函数的东西,但要在点云的内部而不是外部进行工作。

最终目标是计算绘图上线之间的面积。

我会做不同的事情。 只需绘制曲线的任意两条线,即可通过某种数值近似(例如梯形数值积分 )计算曲线下的面积,然后减去面积并获得线之间的面积。

感谢Trilarion的回答中的想法,我能够提出更好的解决方案。

请注意,我对YZ平面而不是XY使用符号(以与机器人坐标系保持一致)。

为每组分散数据生成曲线

% Scatter data is in iy and iz vectors.
curve = fit(iy, iz, 'smoothingspline', 'SmoothingParam', 0.5);
% Remove outliers.
fdata = feval(curve, iy);
I = abs(fdata - iz) > 0.5 * std(iz);
outliers = excludedata(iy, iz, 'indices', I);
% Final curve without outliers.
curve = fit(iy, iz, 'smoothingspline', 'Exclude', outliers, 'SmoothingParam', 0.5);

绘制曲线和散点数据

% Color maps generated by MATLAB's colormap function.
h_curve = plot(curve);
set(h_curve, 'Color', color_map_light(i,:));    
scatter(iy, iz, '.', 'MarkerFaceColor', color_map(i,:))

让用户通过选择点来提供输入

用户选择一个点作为查询点,并选择两个点作为沿Y轴的极限。 这是因为某些曲线接近,但永不相交。

[cs_position.y, cs_position.z] = ginput(1);
[cs_area_limits, ~] = ginput(2);

if cs_area_limits(1) > cs_area_limits(2)
  cs_area_limits = flipud(cs_area_limits);
end

plot_cross_section(cs_position);

最后计算并绘制表面积

本部分使用Doresoom的出色答案

function [ ] = plot_cross_section(query_point)
%PLOT_CROSS_SECTION Calculates and plots cross-section area.
%   query_point  Query point.

  % Find values on query point's Y on each of the curves.
  z_values = cellfun(@(x, y) feval(x, y),...
    curves, num2cell(ones(size(curves)) * query_point.y))

  % Find which curves are right above and below the query point.
  id_top = find(z_values >= query_point.z, 1, 'first')
  id_bottom = find(z_values < query_point.z, 1, 'last')

  if isempty(id_top) || isempty(id_bottom)      
    return
  end

  % Generate points along curves on the range over Y.
  y_range = cs_area_limits(1):0.1:cs_area_limits(2);
  z_top = feval(curves{id_top}, y_range).';
  z_bottom = feval(curves{id_bottom}, y_range).';

  % Plot area.
  Y = [ y_range, fliplr(y_range) ];
  Z = [ z_top, fliplr(z_bottom) ];
  fill(Y, Z, 'b', 'LineStyle', 'none')
  alpha 0.5
  hold on

  % Calculate area and show to user.
  cs_area = polyarea(Y, Z);
  area_string = sprintf('%.2f mm^2', cs_area);
  text(0, -3, area_string, 'HorizontalAlignment', 'center')
end

结果

结果图片

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM