如何计算和围绕圆均匀地划分点?

问题描述

大家好!

我正在尝试创建一个变量,您可以在其中放置点的数量和圆的半径,它将围绕圆均匀地划分这些点。 我试图不使用欧拉角来设置旋转或Rotate或RotateAround方法。 但是我没有成功...

这就是直到现在我的代码的样子

public class PowerUps : MonoBehavIoUr
{
    public GameObject PowerUpPrefab;
    public GameObject Player;
    public int PowerUpCount = 3;
    public float PowerUpRadius = 1;
    public Vector3 newPowerupSpace;

    public GameObject[] SpawnPowerUps()
    {
        //get player positin
        Vector3 anchorPoint = Player.transform.position;

        GameObject[] SpawnPowerUps = new GameObject[PowerUpCount];
       

        float angleStep = Mathf.HalfToFloat((ushort)(360.0 / PowerUpCount));

        for (int i = 0; i < PowerUpCount; i++)
        {
            float theta = i * angleStep;
            newPowerupSpace.x = anchorPoint.x + (PowerUpRadius * Mathf.Cos(theta));
            newPowerupSpace.y = anchorPoint.y + (PowerUpRadius * Mathf.Sin(theta));


            SpawnPowerUps[i] = (GameObject)Instantiate(PowerUpPrefab,newPowerupSpace,Quaternion.identity);
        }

        return null;
    }
}

有什么建议吗?

更新:

我改变了

float angleStep = Mathf.HalfToFloat((ushort)(360.0 / PowerUpCount));

float angleStep = ((ushort)((360.0 / PowerUpCount) * Mathf.Deg2Rad));

现在正在工作。 我觉得有点愚蠢。。。

更新2: 做完一些测试后,我注意到一些数字在整个圆上分布不均匀。那是因为我在错误的部分将圆度转换为镭。 代码如下所示:

   public GameObject[] SpawnPowerUps()
    {
        Vector3 anchorPoint = Player.transform.position;
        GameObject[] SpawnPowerUps = new GameObject[PowerUpCount];

        float angleStep = ((ushort)(360.0 / PowerUpCount));
        
        for (int i = 0; i < PowerUpCount; i++)
        {
            float theta = i * angleStep;
            newPowerupSpace.x = anchorPoint.x + (PowerUpRadius * Mathf.Cos(theta * Mathf.Deg2Rad));
            newPowerupSpace.y = anchorPoint.y + (PowerUpRadius * Mathf.Sin(theta * Mathf.Deg2Rad));

        SpawnPowerUps[i] = (GameObject)Instantiate(PowerUpPrefab,Quaternion.identity);
        }

        return null;
    }
}

解决方法

要在3D模式下描述圆,它应该具有三个参数:位置,半径和法线。法线可用于创建从单位圆到3D空间的变换。此示例使用实例方法而不是静态方法进行交叉/点/归一化,但转换为unity3D约定应该很简单。

首先,我们创建一个与法线正交的任意矢量:

    public static Vector3 GetOrthogonal(this Vector3 self)
    {
        self = self.Normalized();
        if (Math.Abs(self.Dot(Vector3.UnitX)) > 0.9)
        {
            return self.Cross(Vector3.UnitY).Normalized();

        }
        return self.Cross(Vector3.UnitX).Normalized();
    }

然后我们可以创建两个与法线正交且彼此正交的向量:

        var xAxis = normal.GetOrthogonal();
        var yAxis = xAxis.Cross(normal).Normalized();

获取点就是简单地将每个坐标与相应的轴相乘:

        var x = xAxis * (PowerUpRadius * Mathf.Cos(theta * Mathf.Deg2Rad));
        var y = yAxis * (PowerUpRadius * Mathf.Sin(theta * Mathf.Deg2Rad));
        newPowerupSpace = x + y + anchorPoint;

您可以通过生成变换矩阵并变换2D点来执行相同操作。但这很简单。