在 MATLAB 中绘制一个已知半径的圆。
假设一对随机点,其位置必须根据坐标 (x1,y1) (x2,y2)..(xn,yn) 确定。对应该彼此靠近。例如 T1 和 R1 应该在附近。
如图所示,有四个随机对 (T1,R1)..(T4,R4)。需要将坐标确定为中心(0,0)。
如何在 MATLAB 中生成它?
在 MATLAB 中绘制一个已知半径的圆。
假设一对随机点,其位置必须根据坐标 (x1,y1) (x2,y2)..(xn,yn) 确定。对应该彼此靠近。例如 T1 和 R1 应该在附近。
如图所示,有四个随机对 (T1,R1)..(T4,R4)。需要将坐标确定为中心(0,0)。
如何在 MATLAB 中生成它?
使用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/π 次。
令 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 语法,它应该真的很有帮助。祝你好运。
(编辑问题后完成编辑)。
要完成此任务,我认为您需要结合编辑之前提到的不同方法:
有了这些成分,你应该能够做你需要的一切。这是我写的代码:
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;
按照@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
所以现在很明显5
and是对的, and 7
that是对的。但是和都是重复的。(在这种情况下,我猜它们显然也是对的!)但我建议将 point与 center和 point与 center 分开。然后我们从第 2 列开始,看到下一个可用点的距离为。这将使点与点配对,但它与中心的距离为。如果我们将 point with和 point with配对,我们将得到 和3
2
4
6
4
2
6
3
8
1.2326
1
6
1.2106
6
8
4
1
0.7574
1.2778
分别这实际上是更少的总距离。因此,找到“接近”对很容易,但要找到具有全局最小最小值的对集合却很难!这个解决方案很容易让你得到一些不错的东西,但是如果你需要全球最好的,那么恐怕你还有很多工作要做:(
最后让我添加一些可视化。首先让(手动)创建一个向量来显示哪些点是成对的:
I = [1 2 2 1 3 4 3 4];
请记住,这将取决于您的数据!现在你可以很好地绘制是这样的:
gscatter(x, y, I)
希望这能让你接近,并且你可以最终自己消除我的手动配对。获得粗略的解决方案应该不会太难。
这是一个低质量的解决方案,非常易于使用均匀分布的点。假设点数很小效率不应该是一个问题,如果你想要更好的质量,你可以使用比最近邻更强大的东西:
因此,大多数对应该是好的,但有些可能真的很糟糕。我建议您尝试一下,如果需要,也许可以使用 k-opt 或其他一些本地搜索添加第 4 步。如果你真的有很少的点(例如少于 20 个),你当然可以只计算所有距离并找到最佳匹配。
如果您并不真正关心均匀分布,这里有一个更简单的解决方案: