用matlab生成在单位球面上均匀的100个点几种方法?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用matlab生成在单位球面上均匀的100个点几种方法?相关的知识,希望对你有一定的参考价值。

老师给了我们一代码
生成在单位球面上均匀的100个点;
% rand sample on sphere;
n = 100;
u = 2*pi*rand(1,n);
v = (rand(1,n) - 0.5)*2;
x = cos(u).*sqrt(1 - v.^2);
y = sin(u).*sqrt(1 - v.^2);
z = v;
plot3(x, y, z, 'b.');
axis equal;

他说有两种办法编代码,让我们说出为什么选这种,好处是什么

参考技术A 你们老师给的这方法是产生随机参数theta和z。还可以:
【1】在球面约束条件下,依次产生三个变量。当然,这样得出的点并不均匀,要随机排列下:
xyz = zeros(n, 3);
for i = 1:n
x = 2*rand-1;
y = sqrt(1-x.^2).*(2*rand-1);
z = (2*randi(0:1)-1).*sqrt(1-x.^2-y.^2);
t = [x, y, z];
xyz(i,:) = t(randperm(3));
end
plot3(xyz(:,1), xyz(:,2), xyz(:,3), 'b.');

【2】随机产生theta和beta:
xyz = zeros(n, 3);
for i = 1:n
theta = 2*pi*rand;
beta = 2*pi*rand;
xyz(i,:) = [cos(beta)*[cos(theta) sin(theta)] sin(beta)];
end
plot3(xyz(:,1), xyz(:,2), xyz(:,3), 'b.');

【3】产生两个独立同分布的高斯分布,并归一化到球面上:
S = randn(n, 3);
xyz = bsxfun(@rdivide, S, sqrt(sum(S.*S, 2)));
plot3(xyz(:,1), xyz(:,2), xyz(:,3), 'b.');

最后一种方法最简便也最快捷。

下次请选择问题分类为【编程】。本回答被提问者和网友采纳

球面上点的均匀分布? [复制]

【中文标题】球面上点的均匀分布? [复制]【英文标题】:Uniform distribution of points on the surface of a sphere? [duplicate] 【发布时间】:2014-02-24 01:33:24 【问题描述】:

我正在寻找一种算法来在球体表面上优化分布 N 个点(不是随机的,我说的是Tammes problem 意义上的最优分布)。 我想在 C++ 中做到这一点,但问题不是语言问题,而是算法问题。这是我目前使用的算法(在python中):

# Function to distribute N points on the surface of a sphere 
# (source: http://www.softimageblog.com/archives/115)
def uniform_spherical_distribution(N): 
    pts = []   
    inc = math.pi * (3 - math.sqrt(5)) 
    off = 2 / float(N) 
    for k in range(0, int(N)): 
        y = k * off - 1 + (off / 2) 
        r = math.sqrt(1 - y*y) 
        phi = k * inc 
        pts.append([math.cos(phi)*r, y, math.sin(phi)*r])   
    return pts

对于大量点,视觉效果似乎相当不错,但对于少量点(2 到 10 之间),结果似乎一点也不好(半球中有更多点)。有没有一种方法可以增强算法,使其对于少量点也可以...(答案可以是 C、C++ 或 Python)。

【问题讨论】:

@and 我不确定它是否重复。他想要N<=10最佳 分布。这与我迄今为止阅读的答案不同。如果我弄错了,请指出哪个答案可以计算最佳分布。 @Ali OP 请求在 Tammes 问题的意义上进行打包,提供的链接将其定义为“在球体表面打包给定数量的圆的问题,使得圆之间的最小距离最大化”。 “BlueRaja - Danny Pflughoeft”对我建议作为副本的帖子的评论使用几乎相同的措辞来描述该发布者正在寻找的内容,然后针对该特定问题提供评分最高的答案。 @and 好吧,我不同意:Vincent 要求 最佳 分布,这些答案将给出 一些近似 分布。也请检查我的答案;我在其他地方找不到这些结果。 @Ali 你检查所有答案了吗? @LukaRahne 是的,我看不出我的错误。请明确提供指向该特定答案的链接,该链接提供与我的答案相同的信息,也就是说,它提供了一种获得小 N 的 最佳 分布的方法。This one 很接近,但我没有对文森特的案例没有太大帮助。 【参考方案1】:

如果你只需要少量的点,蛮力可能会起作用。蛮力是指预先计算2..10 的解决方案,如果N<=10 在数组中查找它们。

对于像这样的小Ns,应该可以解决数学优化问题,以最佳方式分配您的点。您需要多启动,但对于较小的Ns,这应该不是问题。这是我在AMPL 中的尝试:

param N;

var x1..N;
var y1..N;
var z1..N;

var d;

param xbest1..N;
param ybest1..N;
param zbest1..N;
param dbest;

maximize obj: d;

all_points_on_the_spherei in 1..N:
  x[i]^2 + y[i]^2 + z[i]^2 = 1;

all_pairsi in 1..N, j in 1..N : i<j:
  (x[i]-x[j])^2 + (y[i]-y[j])^2 + (z[i]-z[j])^2 >= d;

fix_first_x:  x[1] = 1;
fix_first_y:  y[1] = 0;
fix_first_z:  z[1] = 0;  
fix_second_z: z[2] = 0;

#############################################

option show_stats 1;
option presolve 10;
option substout 1;
option var_bounds 2;
#option nl_comments 0;
#option nl_permute 0;
option display_precision 0;

option solver "/home/ali/ampl/ipopt";

for k in 2..10 
    let N := k;  
    solexpand _con;
    let dbest := -1.0;
    # Multistart
    for 1..2000 
        for j in 1.._snvars
            let _svar[j] := Uniform(-1, 1);
        let d := N;     

        solve;

        if (solve_result_num < 200 and d > dbest) then 
            let dbest := d;
            for i in 1..N 
                let xbest[i] := x[i];
                let ybest[i] := y[i];
                let zbest[i] := z[i];
            
        
    

    print "@@@";
    printf "N=%d, min distance %6f\n", N, sqrt(dbest);

    for i in 1..N
        printf "(%9.6f, %9.6f, %9.6f)\n", xbest[i], ybest[i], zbest[i];

在我的机器上运行这个脚本花了 5 分钟,解决方案是:

N=2,最小距离 2.000000 ( 1.000000, 0.000000, 0.000000) (-1.000000, 0.000000, 0.000000) N=3,最小距离 1.732051 ( 1.000000, 0.000000, 0.000000) (-0.500000, 0.866025, 0.000000) (-0.500000, -0.866025, 0.000000) N=4,最小距离 1.632993 ( 1.000000, 0.000000, 0.000000) (-0.333333, -0.942809, 0.000000) (-0.333333, 0.471405, -0.816497) (-0.333333, 0.471405, 0.816497) N=5,最小距离 1.414214 ( 1.000000, 0.000000, 0.000000) (-0.208840, 0.977950, 0.000000) (-0.000000, 0.000000, 1.000000) (-0.212683, -0.977121, 0.000000) ( 0.000000, 0.000000, -1.000000) N=6,最小距离 1.414214 ( 1.000000, 0.000000, 0.000000) (-1.000000, 0.000000, 0.000000) (0.000000,-0.752754,-0.658302) (0.000000, 0.752754, 0.658302) ( 0.000000, 0.658302, -0.752754) ( 0.000000, -0.658302, 0.752754) N=7,最小距离 1.256870 ( 1.000000, 0.000000, 0.000000) (-0.688059, -0.725655, 0.000000) (0.210138,-0.488836,-0.846689) (0.210138,-0.488836,0.846688) (-0.688059, 0.362827, 0.628435) (-0.688059, 0.362827, -0.628435) (0.210138, 0.977672, 0.000000) N=8,最小距离 1.215563 ( 1.000000, 0.000000, 0.000000) (0.261204,-0.965284,0.000000) (0.261204、0.565450、0.782329) (-0.783612, -0.482642, -0.391165) (0.261204,-0.199917,-0.944355) (0.261204、0.882475、-0.391165) (-0.783612, 0.599750, 0.162026) (-0.477592, -0.399834, 0.782329) N=9,最小距离 1.154701 ( 1.000000, 0.000000, 0.000000) (-0.500000, -0.866025, 0.000000) (0.333333,-0.577350,-0.745356) (-0.500000, 0.866025, 0.000000) (-0.666667, -0.000000, 0.745356) (-0.666667, 0.000000, -0.745356) (0.333333,-0.577350,0.745356) (0.333333, 0.577350, -0.745356) (0.333333, 0.577350, 0.745356) N=10,最小距离 1.091426 ( 1.000000, 0.000000, 0.000000) (-0.605995, 0.795469, 0.000000) (0.404394、0.816443、0.412172) (-0.664045, -0.746251, -0.046407) (0.404394,-0.363508,-0.839242) (-0.664045, 0.002497, 0.747688) (-0.605995, 0.046721, -0.794096) (0.404394,-0.908368,0.106452) (0.255933、0.703344、-0.663179) (0.404394,-0.159620,0.900548)

通过查看数字,很明显可以通过分析计算一些解(我知道 sqrt(2) 和 sqrt(3) 等)。我相信对于 N=2、4 和 6,解决方案是直线 ([-1,0,0], [1,0,0])、四面体、八面体。

没有强烈保证以上是积分的最佳分布。非线性求解器可能陷入局部最优;随着N 的增长,局部最优的数量也在增长。

您可以将上述解决方案放在一个数组中,然后在 Python、C++ 或您使用的任何语言中使用它们。

【讨论】:

以上是关于用matlab生成在单位球面上均匀的100个点几种方法?的主要内容,如果未能解决你的问题,请参考以下文章

球面上点的均匀分布? [复制]

如何在更高维度的超球面上均匀分布点?

如何用matlab画出四个单位球面,两两相切?

用MATLAB怎么画球面

光学基于matlab涡旋光与球面波的干涉含Matlab源码 597期

matlab练习程序(均匀B样条)