Math 如何在高维超球面上均匀分布点?
我感兴趣的是在3维或更高维的球体表面上均匀分布N个点 更具体地说:Math 如何在高维超球面上均匀分布点?,math,geometry,pseudocode,n-dimensional,Math,Geometry,Pseudocode,N Dimensional,我感兴趣的是在3维或更高维的球体表面上均匀分布N个点 更具体地说: 给定点数N和维数D(其中D>1,N>1) 每个点到原点的距离必须为1 任意两点之间的最小距离应尽可能大 每个点到最近邻点的距离不一定必须对每个点都相同(事实上,它不可能是相同的,除非点的数量形成柏拉图式实体的顶点,或者如果N作为部分答案,你可以用来计算f的逆。在牛顿迭代中使用x作为初始点是一个不错的选择,因为f(x)与x的距离永远不会超过1个单位。下面是一个Python实现: import math def f(x):
- 给定点数N和维数D(其中D>1,N>1)
- 每个点到原点的距离必须为1
- 任意两点之间的最小距离应尽可能大
- 每个点到最近邻点的距离不一定必须对每个点都相同(事实上,它不可能是相同的,除非点的数量形成柏拉图式实体的顶点,或者如果N作为部分答案,你可以用来计算f的逆。在牛顿迭代中使用
作为初始点是一个不错的选择,因为x
与f(x)
的距离永远不会超过1个单位。下面是一个Python实现:x
import math def f(x): return x + 0.5*math.sin(2*x) def f_inv(x,tol = 1e-8): xn = x y = f(xn) while abs(y-x) > tol: xn -= (y-x)/(1+math.cos(2*xn)) y = f(xn) return xn
关于牛顿方法的这个应用,一个很好的事实是,每当
(如果你要除以0),你就会自动得到cos(2*x)=-1
,因此sin(2*x)=0
。在这种情况下,不会输入while循环,并且f(x)=x
只返回原始的x。我们有n个点,它们是P1,…,Pn。我们有一个维度号d。每个(i=1,n)点可以表示为: π=(π(x1),…,π(xd)) 我们知道 D(Pi,0)=1 sqrt((pi(x1)-pj(x1))^2+…+(pi(xd)-pj(xd))^2)=1 任意点之间的最小距离,MD是 无限大f_inv
- 每边的长度相似
如果定义f(x)的倒数,可以确定f(x)=x的倒数-0.5sin2x。你会得到x的多项式序列。非常有趣的问题。我想把它实现为,因为我很好奇它看起来会是什么样子,但我太懒了,不能从数学方面处理ND超越的问题 相反,我对这个问题提出了不同的解决方案。它不是一个斐波那契关系!!!相反,我将a的参数方程展开为超螺旋,然后只拟合螺旋参数,使点的距离大致相等 我知道这听起来很可怕,但它并没有那么难,在解决了一些愚蠢的打字错误(复制/粘贴错误)后,结果对我来说是正确的(最后:) 其主要思想是使用超球体的n维参数方程从角度和半径计算其表面点。此处实现:
import math
def f(x):
return x + 0.5*math.sin(2*x)
def f_inv(x,tol = 1e-8):
xn = x
y = f(xn)
while abs(y-x) > tol:
xn -= (y-x)/(1+math.cos(2*xn))
y = f(xn)
return xn
screws=r/d
。点数也可以推断为points=area/d^2=PI*r^2/d^2
因此,我们可以简单地将2D螺旋线写成:
t = <0.0,1.0>
a = 2.0*M_PI*screws*t;
x = r*t*cos(a);
y = r*t*sin(a);
3D:
screws=1.0/d; // radius/d
points=M_PI/(d*d); // surface_area/d^2
a = 2.0*M_PI*t*screws;
x = t*cos(a);
y = t*sin(a);
screws=M_PI/d; // half_circumference/d
points=4.0*M_PI/(d*d); // surface_area/d^2
a= M_PI*t;
b=2.0*M_PI*t*screws;
x=cos(a) ;
y=sin(a)*cos(b);
z=sin(a)*sin(b);
screws = M_PI/d;
points = 3.0*M_PI*M_PI*M_PI/(4.0*d*d*d);
a= M_PI*t;
b= M_PI*t*screws;
c=2.0*M_PI*t*screws*screws;
x=cos(a) ;
y=sin(a)*cos(b) ;
z=sin(a)*sin(b)*cos(c);
w=sin(a)*sin(b)*sin(c);
4D:
screws=1.0/d; // radius/d
points=M_PI/(d*d); // surface_area/d^2
a = 2.0*M_PI*t*screws;
x = t*cos(a);
y = t*sin(a);
screws=M_PI/d; // half_circumference/d
points=4.0*M_PI/(d*d); // surface_area/d^2
a= M_PI*t;
b=2.0*M_PI*t*screws;
x=cos(a) ;
y=sin(a)*cos(b);
z=sin(a)*sin(b);
screws = M_PI/d;
points = 3.0*M_PI*M_PI*M_PI/(4.0*d*d*d);
a= M_PI*t;
b= M_PI*t*screws;
c=2.0*M_PI*t*screws*screws;
x=cos(a) ;
y=sin(a)*cos(b) ;
z=sin(a)*sin(b)*cos(c);
w=sin(a)*sin(b)*sin(c);
现在注意4D的点只是我的假设。我根据经验发现它们与常量/d^3
有关,但并不完全相同。每个角度的螺钉都不同。我的假设是除了螺钉^I
之外没有其他比例,但它可能需要一些常量调整(未对生成的点云进行分析,因为我认为结果正常)
现在我们可以从单个参数t=
生成螺旋上的任意点
请注意,如果您颠倒方程式,那么d=f(点)
您可以将点作为输入值,但请注意,它只是近似的点数,并不精确t
进行二元搜索,结果点距离上一点d
较远。只需生成点t=0
,然后在估计位置附近进行二元搜索,直到距离起点d
较远。然后重复直到