Matlab 如何沿复杂多段线创建随机点?

Matlab 如何沿复杂多段线创建随机点?,matlab,Matlab,我希望在二维绘图上填充随机点,使点位于“C”形多段线附近 我设法用一个相当简单的方形“C”来实现这一点: 我就是这样做的: % Marker color c = 'k'; % Black % Red "C" polyline xl = [8,2,2,8]; yl = [8,8,2,2]; plot(xl,yl,'r','LineWidth',2); hold on; % Axis settings axis equal; axis([0,10,0,10]); set(gca,'xti

我希望在二维绘图上填充随机点,使点位于“C”形多段线附近

我设法用一个相当简单的方形“C”来实现这一点:

我就是这样做的:

% Marker color
c = 'k';    % Black

% Red "C" polyline
xl = [8,2,2,8];
yl = [8,8,2,2];
plot(xl,yl,'r','LineWidth',2);
hold on;

% Axis settings
axis equal;
axis([0,10,0,10]);
set(gca,'xtick',[],'ytick',[]);

step = 0.05;    % Affects point quantity
coeff = 0.9;    % Affects point density

% Top Horizontal segment
x = 2:step:9.5;
y = 8 + coeff*randn(size(x));
scatter(x,y,'filled','MarkerFaceColor',c);

% Vertical segment
y = 1.5:step:8.5;
x = 2 + coeff*randn(size(y));
scatter(x,y,'filled','MarkerFaceColor',c);

% Bottom Horizontal segment
x = 2:step:9.5;
y = 2 + coeff*randn(size(x));
scatter(x,y,'filled','MarkerFaceColor',c);

hold off;
正如您在代码中看到的,对于多段线的每一段,我使用
randn
人工生成散射点坐标

对于上一个示例,可以将多段线拆分为线段并手动生成点。但是,如果我想用一个更复杂的“C”形做实验,比如:

请注意,在我当前的方法中,当多段线的几何复杂性增加时,编码工作也会增加


在进一步讨论之前,是否有更好的方法解决此问题?

一种更简单的方法,可以推广到任何多段线,就是在线段上运行循环。对于每个段,
r
是其长度,
m
是沿该段放置的点数(它与规定的步长非常对应,如果步长不能均匀地划分长度,则会有轻微偏差)。请注意,x和y都受到随机扰动的影响

for n = 1:numel(xl)-1 
    r = norm([xl(n)-xl(n+1), yl(n)-yl(n+1)]);
    m = round(r/step) + 1;
    x = linspace(xl(n), xl(n+1), m) + coeff*randn(1,m);
    y = linspace(yl(n), yl(n+1), m) + coeff*randn(1,m);
    scatter(x,y,'filled','MarkerFaceColor',c);
end
输出:

一个更复杂的例子,使用
coeff=0.4
xl=[8,4,2,2,6,8];
yl=[8,6,8,2,4,2]


如果您认为该点云在端点附近太薄,可以在运行循环之前人为地延长第一个和最后一个线段。但我看不出有什么必要:模糊曲线在末端变细是有道理的

使用最初的方法,可以以不同的概率对与直线距离相同的两个位置进行采样,尤其是在两条直线相交的拐角处。我试图通过重新表述随机实验来解决这个问题。我的代码所做的随机实验是:“选择一个随机点。以
normpdf(d)的概率接受它。你能解释这一部分吗:
y=1.5:step:8.5;
?为什么不
y=2:step:8;
。我认为这才是真正需要概括的问题,因为你可以手动扩展区域以使它“看起来更好”“。你有什么具体的分布吗?没错,丹尼尔,为了布局的目的,我系统地增加了坐标的范围,这样点会从多段线的两端伸出一点,并围绕着它。我使用了
randn
,因为点是正态分布的,但是任何其他分布也可以工作:)所以你没有特别的分布,只是一些与上面的代码大致相似的东西?这非常有效。加上你的算法很简单,实现了两个坐标的随机性,这使得它非常完美。非常感谢莎莉:)
xl = [8,4,2,2,6,8];
yl = [8,6,8,2,4,2];
resolution=50;
points_to_sample=200;
step=.5;
sigma=.4; %lower value to get points closer to the line.
xmax=(max(xl)+2);
ymax=(max(yl)+2);
dist=zeros(xmax*resolution+1,ymax*resolution+1);
x=[];
y=[];
for n = 1:numel(xl)-1 
    r = norm([xl(n)-xl(n+1), yl(n)-yl(n+1)]);
    m = round(r/step) + 1;
    x = [x,round(linspace(xl(n)*resolution+1, xl(n+1)*resolution+1, m*resolution))];
    y = [y,round(linspace(yl(n)*resolution+1, yl(n+1)*resolution+1, m*resolution))];
end
%dist contains the lines:
dist(sub2ind(size(dist),x,y))=1;
%dist contains the normalized distance of each rastered pixel to the line.
dist=bwdist(dist)/resolution;
pseudo_pdf=normpdf(dist,0,sigma);
%scale up to have acceptance rate of 1 for most likely pixels.
pseudo_pdf=pseudo_pdf/max(pseudo_pdf(:));
sampled_points=zeros(0,2);

while size(sampled_points,1)<points_to_sample
    %sample a random point
    sx=rand*xmax;
    sy=rand*ymax;
    %accept it if criteria based on normal distribution matches.
    if pseudo_pdf(round(sx*resolution)+1,round(sy*resolution)+1)>rand
        sampled_points(end+1,:)=[sx,sy];
    end
end
plot(xl,yl,'r','LineWidth',2);
hold on
scatter(sampled_points(:,1),sampled_points(:,2),'filled');