如何使用Matlab在圆圈中生成一对随机点?

时间:2013-01-31 06:39:08

标签: matlab computational-geometry matlab-figure matlab-deployment

在MATLAB中绘制已知半径的圆。

假设一对随机点,其位置必须根据坐标(x1,y1)(x2,y2)...(xn,yn)确定。对应彼此接近。例如,T1和R1应该在附近。

如图所示,有四个随机对(T1,R1)..(T4,R4)。 需要确定坐标为中心(0,0)。

figure

如何在MATLAB中生成它?

5 个答案:

答案 0 :(得分:1)

使用减少R从圆上均匀分布中选取一个点的最简单方法是使用Gibbs采样。这是代码:

function [x y] = circular uniform (R)
while true
   x = 2*R*rand() - R
   y = 2*R*rand() - R
   if (x*x + y*y) > R*R
       return
   end
end

循环平均运行4次/π次。

答案 1 :(得分:0)

让p变为(0; 0)居中的圆圈 (x,y):x ^ 2 + y ^ 2< = R ^ 2(LE)在圆圈内

x = rand()*2*R - R;  

y应该在间隔中(-sqrt(R ^ 2 - x ^ 2); + sqrt(R ^ 2 - x ^ 2))
所以,让它成为

y = rand()*sqrt(R^2 - x^2)*2-sqrt(R^2 - x^2);  

希望,没错,我没有matlab来测试 希望,你会设法找到你自己的亲密配对 好的,我会花一点时间来提示。 要在区间[a,b]中找到随机数k,请使用

k = rand()*(b-a)+a  

如果我还记得matlab的原理,它应该真的有用。祝好运。

答案 2 :(得分:0)

生成@PheuVerg建议的随机点(带有轻微的矢量化调整)

n = 8; %must be even!
x = rand(n, 1)*2*R - R; 
y = rand(n, 1).*sqrt(R^2 - x.^2).*2-sqrt(R^2 - x.^2);

然后使用kmeans聚类来获得n / 2个中心

[~ c] = kmeans([x y], n/2);

现在你必须遍历每个中心并找到它到每个点的距离

dists = zeros(n, n/2);
for cc = 1:n/2
    for pp = 1:n
        dists(pp, cc) = sqrt((c(cc,1) - x(pp))^2 + (c(cc,2) - y(pp))^2);
    end
end

现在您必须为每个dists列找到最小的2个值

[sorted, idx] = sort(dists);

所以现在每列的前两行是最近的两个点。但可能会发生冲突!即最接近两个不同中心的点。因此,对于重复值,您必须循环并选择交换以获得最小额外距离的点。

示例数据:

x =

    0.7894
   -0.7176
   -0.5814
    0.0708
    0.5198
   -0.2299
    0.2245
   -0.8941

y =

   -0.0800
   -0.3339
    0.0012
    0.9765
   -0.4135
    0.5733
   -0.1867
    0.2094

sorted =

    0.1870         0         0    0.1555
    0.2895    0.5030    0.5030    0.2931
    0.3145    1.1733    0.6715    0.2989
    1.0905    1.1733    0.7574    0.7929
    1.1161    1.2326    0.8854    0.9666
    1.2335    1.2778    1.0300    1.2955
    1.2814    1.4608    1.2106    1.3051
    1.4715    1.5293    1.2393    1.5209

idx =

     5     4     6     3
     7     6     4     2
     1     3     3     8
     6     7     8     6
     3     8     7     7
     2     1     2     4
     4     5     1     5
     8     2     5     1

现在很明显,57是成对的,32是对。但46都重复了。 (在这种情况下很明显,我猜他们也是对!)但我建议将点4留给中心2,将6留给中心{{1} }。然后,我们从第2列开始,看到下一个可用点为3,距离为8。这会使点1.2326与点1配对,但距离中心的距离为6。如果我们将1.21066配对,将84配对,我们的距离分别为10.7574,实际上更少总距离。因此,找到“近距离”对很容易,但找到具有全局最小最小值的对是很难的!这个解决方案很容易让你体面,但是你需要全球最好的,那么我担心你还有很多工作要做:(

最后让我添加一些可视化。首先让(手动)创建一个向量,显示哪些点是配对的:

1.2778

请记住,这取决于您的数据!现在你可以很好地绘制:

   I = [1 2 2 1 3 4 3 4];

希望这能让你接近,并且你可以自己消除我最终的手动配对。获得原油解决方案应该不会太难。

答案 3 :(得分:0)

(编辑问题后完成编辑)。

要完成此任务,我认为您需要结合编辑前提到的不同方法:

  • 要在绿色圆环中生成中心T1,T2,T3,...,使用极坐标(编辑:结果证明这是错误的,此处也必须使用拒绝抽样,否则,分配不均匀!)
  • 要在T1,T2,T3 ......周围的圆圈中生成点R1,R2,R3 ......,但仍在圆环中,请使用rejection sampling

使用这些成分,你应该能够做你需要的一切。这是我写的代码:

d=859.23;
D=1432.05;
R=100;
N=400;

% Generate the angle
theta = 2*pi*rand(N,1);

% Generate the radius
r = d + (D-d)*rand(N,1);

% Get the centers of the circles
Tx = r.*cos(theta);
Ty = r.*sin(theta);

% Generate the R points
Rx=zeros(N,1);
Ry=zeros(N,1);
for i=1:N
    while true
        % Try
        alpha = 2*pi*rand();
        rr = R*rand();

        Rx(i) = Tx(i) + rr*cos(alpha);
        Ry(i) = Ty(i) + rr*sin(alpha);

        % Check if in the correct zone
        if ( (Rx(i)*Rx(i) + Ry(i)*Ry(i) > d*d) && (Rx(i)*Rx(i) + Ry(i)*Ry(i) < D*D) )
           break
        end
    end
end

% Display
figure(1);
clf;
angle=linspace(0,2*pi,1000);
plot( d*cos(angle), d*sin(angle),'-b');
hold on;
plot( D*cos(angle), D*sin(angle),'-b');
for i=1:N
    plot(Tx(i),Ty(i),'gs');
    plot(Rx(i),Ry(i),'rx');
    plot([Tx(i) Rx(i)],[Ty(i) Ry(i)],'-k');
end
hold off;

答案 4 :(得分:0)

这是一种低质量的解决方案,非常易于使用均匀分布的点。假设点的数量很小,效率不应该是一个问题,如果你想要更好的质量,你可以使用比最近邻居更强大的东西:

  1. 虽然你得分少于n分:生成一个随机点
  2. 如果它在圈子中,则将其存储到第1步
  3. 虽然有不成对的点:检查哪个点最接近第一个未配对的点,使它们成为一对
  4. 因此,大多数配对应该是好的,但有些配对可能非常糟糕。我建议你尝试一下,如果需要的话,可以在k-opt或其他一些本地搜索中添加第4步。如果你真的有小点(例如小于20),你当然可以计算所有距离并找到最佳匹配。


    如果你真的不关心均匀分布,这是一个更简单的解决方案:

    1. 虽然你得分少于n分:生成一个随机点
    2. 如果它在圈子中,则将其存储到第1步
    3. 对于这些点中的每一点,在其附近生成一个点
    4. 如果它在圈子中,则将其存储到第3步