我正在寻找一种算法(伪代码)来生成像这样的球体网格的三维坐标:
水平和垂直切片的数量应可配置。
顺便提一句,你可以使用 meshzoo(我开发的一个项目)非常容易地生成球面网格。
如果需要进一步优化,您还可以选择使用optimesh(我另外一个项目)。
import meshzoo
import optimesh
points, cells = meshzoo.icosa_sphere(10)
class Sphere:
def f(self, x):
return (x[0] ** 2 + x[1] ** 2 + x[2] ** 2) - 1.0
def grad(self, x):
return 2 * x
points, cells = optimesh.cvt.quasi_newton_uniform_full(
points, cells, 1.0e-2, 100, verbose=False,
implicit_surface=Sphere(),
# step_filename_format="out{:03d}.vtk"
)
这只是我随意想到的,没有经过测试。它可以成为一个很好的起点。
如果您使用double,这将为您提供最准确和可自定义的结果,具有最高的精度。
public void generateSphere(3DPoint center, 3DPoint northPoint
, int longNum, int latNum){
// Find radius using simple length equation
(distance between center and northPoint)
// Find southPoint using radius.
// Cut the line segment from northPoint to southPoint
into the latitudinal number
// These will be the number of horizontal slices (ie. equator)
// Then divide 360 degrees by the longitudinal number
to find the number of vertical slices.
// Use trigonometry to determine the angle and then the
circumference point for each circle starting from the top.
// Stores these points in however format you want
and return the data structure.
}
using UnityEngine;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ProcSphere : MonoBehaviour
{
private Mesh mesh;
private Vector3[] vertices;
public int horizontalLines, verticalLines;
public int radius;
private void Awake()
{
GetComponent<MeshFilter>().mesh = mesh = new Mesh();
mesh.name = "sphere";
vertices = new Vector3[horizontalLines * verticalLines];
int index = 0;
for (int m = 0; m < horizontalLines; m++)
{
for (int n = 0; n < verticalLines - 1; n++)
{
float x = Mathf.Sin(Mathf.PI * m/horizontalLines) * Mathf.Cos(2 * Mathf.PI * n/verticalLines);
float y = Mathf.Sin(Mathf.PI * m/horizontalLines) * Mathf.Sin(2 * Mathf.PI * n/verticalLines);
float z = Mathf.Cos(Mathf.PI * m / horizontalLines);
vertices[index++] = new Vector3(x, y, z) * radius;
}
}
mesh.vertices = vertices;
}
private void OnDrawGizmos()
{
if (vertices == null) {
return;
}
for (int i = 0; i < vertices.Length; i++) {
Gizmos.color = Color.black;
Gizmos.DrawSphere(transform.TransformPoint(vertices[i]), 0.1f);
}
}
}
仅仅是猜测,你可能可以使用以(0,0,0)为中心的球体公式
x²+y²+z²=1
sqrt()
,我认为这是很昂贵的。 - Victor Zamanian