1

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

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

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

数字

如何在 MATLAB 中生成它?

4

5 回答 5

1

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

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/π 次。

于 2013-01-31T08:14:11.213 回答
0

令 R 为 (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 语法,它应该真的很有帮助。祝你好运。

于 2013-01-31T07:01:49.550 回答
0

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

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

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

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

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;
于 2013-01-31T08:31:21.410 回答
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

所以现在很明显5and是对的, and 7that是对的。但是和都是重复的。(在这种情况下,我猜它们显然也是对的!)但我建议将 point与 center和 point与 center 分开。然后我们从第 2 列开始,看到下一个可用点的距离为。这将使点与点配对,但它与中心的距离为。如果我们将 point with和 point with配对,我们将得到 和3246426381.2326161.210668410.75741.2778分别这实际上是更少的总距离。因此,找到“接近”对很容易,但要找到具有全局最小最小值的对集合却很难!这个解决方案很容易让你得到一些不错的东西,但是如果你需要全球最好的,那么恐怕你还有很多工作要做:(

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

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

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

gscatter(x, y, I)

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

于 2013-01-31T07:59:06.470 回答
0

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

  1. 当您的点数少于 n 时:生成一个随机点
  2. 如果在圈内,则存储,否则转到步骤1
  3. 虽然有不成对的点:检查哪个点最靠近第一个不成对的点,使它们成对

因此,大多数对应该是好的,但有些可能真的很糟糕。我建议您尝试一下,如果需要,也许可以使用 k-opt 或其他一些本地搜索添加第 4 步。如果你真的有很少的点(例如少于 20 个),你当然可以只计算所有距离并找到最佳匹配。


如果您并不真正关心均匀分布,这里有一个更简单的解决方案:

  1. 当您的点数少于 n 时:生成一个随机点
  2. 如果在圈内,则存储,否则转到步骤1
  3. 对于这些点中的每一个,在其附近生成一个点
  4. 如果在圈内,则存储,否则转到步骤3
于 2013-01-31T11:18:53.733 回答