Я в процессе настройки относительно простого мира на основе вокселей для игры. Идея высокого уровня состоит в том, чтобы сначала сгенерировать местоположения вокселей в соответствии с сеткой Фибоначчи, затем повернуть кубы так, чтобы внешняя поверхность сетки Фибоначчи напоминала сферу, и, наконец, размер кубов так, чтобы они примерно покрывали поверхность сферы (перекрытие - это хорошо). См. Ниже код для генерации вокселей по сетке Фибоначчи:
public static Voxel[] CreateInitialVoxels(int numberOfPoints, int radius)
{
float goldenRatio = (1 + Mathf.Sqrt(5)) / 2;
Voxel[] voxels = new Voxel[numberOfPoints];
for (int i = 0; i < numberOfPoints; i++)
{
float n = i - numberOfPoints / 2; // Center at zero
float theta = 2 * Mathf.PI * n / goldenRatio;
float phi = (Mathf.PI / 2) + Mathf.Asin(2 * n / numberOfPoints);
voxels[i] = new Voxel(new Location(theta, phi, radius));
}
return voxels;
}
Это создает сферу, которая выглядит примерно как лестница
Итак, мой текущий подход к тому, чтобы это выглядело немного более сферически, заключается в том, чтобы в основном вращать каждый куб в каждой паре осей, а затем объединять все вращения:
private void DrawVoxel(Voxel voxel, GameObject voxelContainer)
{
GameObject voxelObject = Instantiate<GameObject>(GetVoxelPrefab());
voxelObject.transform.position = voxel.location.cartesianCoordinates;
voxelObject.transform.parent = voxelContainer.transform;
Vector3 norm = voxel.location.cartesianCoordinates.normalized;
float xyRotationDegree = Mathf.Atan(norm.y / norm.x) * (180 / Mathf.PI);
float zxRotationDegree = Mathf.Atan(norm.z / norm.x) * (180 / Mathf.PI);
float yzRotationDegree = Mathf.Atan(norm.z / norm.y) * (180 / Mathf.PI);
Quaternion xyRotation = Quaternion.AngleAxis(xyRotationDegree, new Vector3(0, 0, 1));
Quaternion zxRotation = Quaternion.AngleAxis(zxRotationDegree, new Vector3(0, 1, 0));
Quaternion yzRotation = Quaternion.AngleAxis(yzRotationDegree, new Vector3(1, 0, 0));
voxelObject.transform.rotation = zxRotation * yzRotation * xyRotation;
}
Главное, что я Я понимаю, что каждое из этих вращений, кажется, отлично работает для меня по отдельности, но при их объединении все имеет тенденцию go немного сбиться с пути (изображения ниже). Я не совсем уверен, в чем проблема. Я предполагаю, что я сделал некоторые несоответствия знака / поворота в моих поворотах, поэтому они не сочетаются правильно. Я могу заставить работать два, но никогда все три вместе.
Выше приведены изображения одного и двух успешных вращений, за которыми следует режим ошибки, когда я пытаюсь их объединить. Любая помощь в том, чтобы сказать мне, что подход, которому я следую, слишком запутанный, или помочь мне понять, как правильно комбинировать эти вращения, была бы очень полезна. Преобразование декартовых координат ниже для справки.
[System.Serializable]
public struct Location
{
public float theta, phi, r;
public Vector3 polarCoordinates;
public float x, y, z;
public Vector3 cartesianCoordinates;
public Location(float theta, float phi, float r)
{
this.theta = theta;
this.phi = phi;
this.r= r;
this.polarCoordinates = new Vector3(theta, phi, r);
this.x = r * Mathf.Sin(phi) * Mathf.Cos(theta);
this.y = r * Mathf.Sin(phi) * Mathf.Sin(theta);
this.z = r * Mathf.Cos(phi);
this.cartesianCoordinates = new Vector3(x, y, z);
}
}