Matlab,生成并绘制分布在三角形内的点云

时间:2012-12-24 12:25:03

标签: matlab random uniform

我试图在三角形内生成一团2D点(均匀)。到目前为止,我已经实现了以下目标:

Matlab plot

我使用的代码是:

N = 1000;
X = -10:0.1:10;
for i=1:N
    j = ceil(rand() * length(X));
    x_i = X(j);
    y_i = (10 - abs(x_i)) * rand;

    E(:, i) = [x_i y_i];
end

然而,这些点并非均匀分布,如左右角所示。我该如何改善这一结果?我一直试图寻找不同的形状,没有运气。

4 个答案:

答案 0 :(得分:9)

首先应该问问自己,三角形内的点是否会均匀分布。

总而言之,给定三角形的所有三个顶点,您需要转换两个均匀分布的随机值,如下所示:

N = 1000;                    % # Number of points
V = [-10, 0; 0, 10; 10, 0];  % # Triangle vertices, pairs of (x, y)
t = sqrt(rand(N, 1));
s = rand(N, 1);
P = (1 - t) * V(1, :) + bsxfun(@times, ((1 - s) * V(2, :) + s * V(3, :)), t);

这将生成一组均匀分布在指定三角形内的点:

scatter(P(:, 1), P(:, 2), '.')

enter image description here

请注意,此解决方案不涉及对随机数的重复条件操作,因此它不会潜在地陷入无限循环。

如需进一步阅读,请查看this article

答案 1 :(得分:2)

从构建积分的方式来看,这些积分的集中程度是可以预期的。您的点沿X轴均匀分布。在三角形的极端处,三角形的中心存在大约相同数量的点,但它们沿着更小的区域分布。

我能想到的第一个也是最好的方法:蛮力。在更大的区域周围均匀分布点,然后删除您感兴趣的区域之外的点。

N = 1000;
points = zeros(N,2);
n = 0;
while (n < N)
    n = n + 1;
    x_i = 20*rand-10; % generate a number between -10 and 10
    y_i = 10*rand; % generate a number between 0 and 10
    if (y_i > 10 - abs(x_i)) % if the points are outside the triangle
       n = n - 1; % decrease the counter to try to generate one more point
    else % if the point is inside the triangle
       points(n,:) = [x_i y_i]; % add it to a list of points
    end
end

% plot the points generated
plot(points(:,1), points(:,2), '.');
title ('1000 points randomly distributed inside a triangle');

我发布的代码的结果: Plot generated by the code above

一个重要的免责声明:随机分发并不意味着“统一”分发!如果从均匀分布中随机生成数据,则意味着它将沿三角形“均匀分布”。事实上,你会看到一些积分点。

答案 2 :(得分:1)

你可以想象三角形被垂直分成两半,并且移动一半使得它与另一半一起形成一个矩形。现在,您可以在矩形中均匀采样,这很容易,然后将半个三角形移回。

此外,使用单位长度(矩形变为正方形)更容易,然后将三角形拉伸到所需的尺寸。

x = [-10 10]; % //triangle base
y = [0 10]; % //triangle height
N = 1000; %// number of points

points = rand(N,2); %// sample uniformly in unit square
ind = points(:,2)>points(:,1); %// points to be unfolded 
points(ind,:) = [2-points(ind,2) points(ind,1)]; %// unfold them
points(:,1) = x(1) + (x(2)-x(1))/2*points(:,1); %// stretch x as needed
points(:,2) = y(1) + (y(2)-y(1))*points(:,2); %// stretch y as needed
plot(points(:,1),points(:,2),'.')

enter image description here

答案 3 :(得分:0)

我们可以概括这个案例。如果你想从欧几里德空间UNIFORMLY(不一定是三角形 - 它可以是任何凸多面体)中的一些(n - 1)维单形点采样点,只需从参数1的对称n维Dirichlet分布中采样矢量 - 这些是相对于多面体顶点的凸(或重心)坐标。