写在前面
在解决点云可见性问题时,需在同一视角(z轴正方向)下将点云绕其中心进行N次旋转变换,同时保证随机性(均匀性),所以需求一种生成N个随机旋转变换的采样方法。可以将求旋转变换的问题转化为对一个r=1的单位球面进行均匀采样的问题,因为球面上任意一点可看做是空间向量→v(x,y,z),再用轴(叉乘产生的法向轴)角法计算与向量→z(0,0,1)间旋转变换,从而得到一些列的变换。但是!这样的操作选择性忽略了绕z轴的旋转,不过因为在z轴正方向视角下观察点云,绕z轴旋转并不影响可见性所以可以接受,因此这种方法其实并不是”全空间“的均匀采样。
球面均匀采样
球坐标系采样
为了对单位球面进行均匀采样,第一个想到的就是对球坐标系(r,θ,ϕ)中的θ、ϕ分别进行均匀采样,尝试绘制点云图如下所示,可见两级相较中间密度更大,整体并不均匀
python代码如下:
1 | from numpy import * |
基于斐波那契格点的球面均匀采样
根据参考文献2中所述的方法,尝试利用斐波那契格点进行球面均匀采样,通式如下,其中n为总N个点中第n个点,ϕ为转角系数,ϕ的取值并非任意,其决定了曲面上螺旋的“混乱”程度,对此参考文献3作出了详细的论证,较好的取值有(√5−1)/2≈0.618、√2−1≈0.414
{zn=(2n−1)/N−1xn=√1−z2n⋅cos(2πnϕ)yn=√1−z2n⋅sin(2πnϕ)结果如下图所示
python代码如下:
1 | import math |
代码实现
在通过上述方法得到单位球面均匀采样点后,通过计算→z(0,0,1)与→v(x,y,z)之间的旋转变换来得到一系列旋转变换,代码如下:
sphere_uniform_sampling.h
1 |
|
sphere_uniform_sampling.cpp
1 |
|
用法
1 | RotationSampling gen(100); |