2010-11-02 8 views
22

sto cercando un algoritmo (in pseudo codice) che genera le coordinate 3D di una sfera maglia simile:proceduralmente generare una sfera maglia

alt text

il numero di fette orizzontali e laterali dovrebbe essere configurabile

+2

È questo Homework? –

+4

no, non lo è. è per un progetto personale. – clamp

+0

che si chiama una configurazione palla da discoteca di punti su una sfera per quanto ne so. è la configurazione più semplice. –

risposta

32

Se ci sono linee M di latitudine (orizzontale) e N linee di longitudine (verticali), poi mettere punti nella

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

per ogni m in {0, ..., M} e n in {0, ..., N-1} e disegna i segmenti di linea tra i punti, di conseguenza.

edit: forse regolare M da 1 o 2, come richiesto, perché si dovrebbe decidere se o non contare "linee di latitudine" ai poli

+0

+1, questo è probabilmente ciò che l'OP sta chiedendo. –

+1

+1, perché funziona con qualsiasi libreria grafica. Un'altra domanda: esiste un modo per controllare anche il raggio della sfera? – kiltek

+4

@kiltek: questo fornisce valori per (x, y, z) da 0 a 1. Per ridimensionarlo a qualsiasi raggio, basta moltiplicare ogni punto per il raggio desiderato. – Carrotman42

1

solo una supposizione, probabilmente si potrebbe usare la formula per una sfera centrata a (0,0,0)

x²+y²+z²=1 

risolvere questo per x, quindi esegui il ciclo attraverso un insieme di valori per yez e tracciali con la tua x calcolata.

+0

Non sono sicuro che questa sia una buona idea, a seconda dei requisiti prestazionali del progetto in questione, poiché questo metodo implica sicuramente un 'sqrt()', che credo sia costoso. –

+0

Se qualcuno avesse deciso che volevano provare questo metodo, probabilmente avrebbe anche dovuto essere indirizzato a un articolo su [Marching Cubes] (https://en.wikipedia.org/wiki/Marching_cubes) ... – porglezomp

2

Questa è solo la parte superiore della mia testa senza prove. Potrebbe essere un buon punto di partenza. Questo ti darà i risultati più precisi e personalizzabili con il massimo grado di precisione se usi il doppio.

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. 

} 
+0

bella descrizione – kiltek

0

Si tratta di un codice C# che lavora per la risposta di cui sopra:

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