程序上生成球体网格

时间:2010-11-02 20:40:38

标签: 3d mesh

我正在寻找一种生成球形网格的3d坐标的算法(伪代码):

alt text

水平和横向切片的数量应该是可配置的

5 个答案:

答案 0 :(得分:36)

如果有M行纬度(水平)和N行经度(垂直),则将点放在

(x,y,z)=(sin(Pi * m / M)cos(2Pi * n / N),sin(Pi * m / M)sin(2Pi * n / N),cos(Pi *米/ M))

对于{0,...,M}中的每个m和{0,...,N-1}中的n,并相应地绘制点之间的线段。

编辑:可以根据需要将M调整1或2,因为您应该决定是否计算极点处的“纬度线”

答案 1 :(得分:2)

如果没有测试,这只是我的头脑。这可能是一个很好的起点。 如果您使用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 curcumference point for each circle starting from the top.

    //Stores these points in however format you want and return the data structure. 

}

答案 2 :(得分:1)

只是一个猜测,你可以使用以(0,0,0)

为中心的球体的公式
x²+y²+z²=1

为x解决此问题,然后通过y和z的一组值进行循环,并使用计算出的x绘制它们。

答案 3 :(得分:0)

这是上述答案的有效C#代码:     

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);
        }
    }
}

答案 4 :(得分:-1)

FWIW,您可以使用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"
)

enter image description here