web-dev-qa-db-fra.com

générer de manière procédurale

je cherche un algorithme (en pseudo-code) qui génère les coordonnées 3D d'un maillage de sphère comme ceci:

alt text

le nombre de tranches horizontales et latérales doit être configurable

26
clamp

S'il y a M lignes de latitude (horizontale) et N lignes de longitude (verticale), placez des points à

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

pour chaque m dans {0, ..., M} et n dans {0, ..., N-1} et tracez les segments de droite entre les points, en conséquence.

edit: peut-être ajuster M par 1 ou 2 selon les besoins, car vous devez décider de compter ou non les "lignes de latitude" aux pôles

35
Jonathan

Ceci est juste au dessus de ma tête sans test. Cela pourrait être un bon point de départ. Cela vous donnera les résultats les plus précis et personnalisables avec le plus de précision possible si vous utilisez 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
bhavinp

juste une supposition, vous pourriez probablement utiliser la formule d'une sphère centrée à (0,0,0)

x²+y²+z²=1

résolvez ceci pour x, puis parcourez un ensemble de valeurs pour y et z et tracez-les avec votre x calculé.

1
John Boker

Ceci est un code C # fonctionnel pour la réponse ci-dessus:

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
yshahak