【Unity球面均匀采样】使用黄金分割生成均匀分布于球体表面的小球

Uniform Sampling on Sphere Surface

2023-6-15 16:10:37

When generating uniform spheres on a sphere surface in Unity, I found an interesting solution. This algorithm generates uniform points on the sphere surface by using golden angle.

在这里插入图片描述

The Unity code of generating spheres in C#:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SphereGen : MonoBehaviour
{
    private GameObject Spheres;
    void Start()
    {
        float scaling = 50;
        Vector3[] pts = PointsOnSphere(1000);
        List<GameObject> uspheres = new List<GameObject>();
        Spheres = new GameObject("Spheres");
        Spheres.transform.position = transform.position;
        int i = 0;
        foreach (Vector3 value in pts)
        {
            uspheres.Add(GameObject.CreatePrimitive(PrimitiveType.Sphere));
            uspheres[i].transform.SetParent(Spheres.transform);
            uspheres[i].transform.position = transform.position + value * scaling;// local position
            i++;
        }
    }


    Vector3[] PointsOnSphere(int n)
    {
        List<Vector3> upts = new List<Vector3>();
        float inc = Mathf.PI * (3 - Mathf.Sqrt(5));
        //float inc = Mathf.PI * (Mathf.Sqrt(5) - 1);//golden ratio
        float off = 2.0f / n;
        float x, y, z, r, phi = 0;

        for (var k = 0; k < n; k++)
        {
            y = k * off - 1 + (off / 2);
            r = Mathf.Sqrt(1 - y*y);
            phi = k * inc;
            x = Mathf.Cos(phi) * r;
            z = Mathf.Sin(phi) * r;

            upts.Add(new Vector3(x, y, z));
        }
        Vector3[] pts = upts.ToArray();
        return pts;
    }

    // Update is called once per frame
    void Update()
    {
        //If you change the position of center before running, 
        //the script will still keeps the inital position.
        //Therefore we need to update the current transform.  
        Spheres.transform.position = transform.position;
    }
}

The key point is in function PointsOnSphere(), where firstly calculate inc, which is the radian of golden angle:
i n c = π ( 3 − 5 ) \begin {align*} & inc = \pi(3-\sqrt5) \end {align*} inc=π(35 )
the variable offdivides the whole height of a sphere whose radius equals to 1 into n n n parts. The height of each point then can be calculated:
y = 2 k + 1 n − 1 \begin {align*} & y = \frac{2k+1}{n}-1 \end {align*} y=n2k+11

At each height, the related radius plane can be calculated, according to the triangle in the figure.
r = 1 − y 2 \begin {align*} & r = \sqrt{1-y^2} \end {align*} r=1y2

Then how to get the uniformly distributed x x x and y y y coordinates? The golden angle. This angle is used orderly, generated sequence of points at different heights, or at different angles if they are at the same plane. The angle difference is the golden angle. The generated grid is also called Fibonacci grid. As shown in this figure(source):

img

After that, the x x x and y y y coordinates can be calculated(in Unity using left-hand coordinates):
ϕ = k ∗ i n c x = r cos ⁡ ( ϕ ) z = r sin ⁡ ( ϕ ) \begin {align*} & \phi = k*inc\\ & x=r\cos(\phi)\\ & z=r\sin(\phi) \end {align*} ϕ=kincx=rcos(ϕ)z=rsin(ϕ)
The generated result in Unity:

在这里插入图片描述

I want to illustrate more about the transfer between golden angle and golden ration. Assume a round with radius equasl to 1. We know the golden ratio:
φ = 1 + 5 2 = 1.618 \begin {align*} & \varphi = \frac{1+\sqrt5}{2} = 1.618 \end {align*} φ=21+5 =1.618
Then for in the round, the part of the golden angle could be:
2 π ∗ 1 φ = − π ( 1 − 5 ) 2 \begin {align*} & 2\pi*\frac{1}{\varphi} = -\pi\frac{(1-\sqrt5)}{2} \end {align*} 2πφ1=π2(15 )
Also, the other part of the round can also be defined as golden angle:
2 π − 2 π 1 φ = 2 π ( 1 + 1 − 5 2 ) = π ( 3 − 5 ) \begin {align*} & 2\pi-2\pi\frac{1}{\varphi} = 2\pi(1+ \frac{1-\sqrt5}{2})=\pi(3-\sqrt5) \end {align*} 2π2πφ1=2π(1+215 )=π(35 )

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值