2015-04-27 12 views
7

Sto cercando di sistemare i punti più o meno uniformemente lungo la superficie di una sfera unitaria.Sistemare uniformemente punti su una sfera usando i reticoli Fibonacci

I'm told che mentre questo problema è difficile, Fibonacci Lattices fornisce un'ottima soluzione.

Ho cercato per un paio di giorni di seguire il metodo molto semplice fornito nel documento collegato, ma semplicemente non riesco a farlo sembrare corretto.

Sto usando javascript e ho una serie di oggetti e, ognuno dei quali presenta un parametro lat e lon. Ecco la funzione che uso per organizzare i punti sulla sfera: (assumere per ora che il numero di punti è sempre dispari)

function arrangeEntries(e) 
{ 
    var p = e.length; 
    var N = (p - 1)/2; 

    for (var i = -N; i <= N; i++) 
    { 
     e[i + N].lat = Math.asin((2 * i)/(2 * N + 1)); 
     e[i + N].lon = mod(i, 1.618034) * 3.883222; 
    } 
} 

con

function mod(a, b) 
{ 
    return a - Math.floor(a/b) * b; 
} 

differenza nel documento, il mio lat e lon sono in radianti, non in gradi. Questo è così che posso tracciarli successivamente usando le coordinate X/Y/Z che ottengo usando le funzioni javascript e Math.cos, che accettano i radianti non gradi.

La prima riga per lo lat è abbastanza semplice. Tralascio il fattore 180/Pi nel documento perché voglio mantenere il risultato in radianti.

La seconda riga per lo lon prende il modulo dell'indice utilizzando la sezione aurea e invece di moltiplicare per un fattore di 360/Phi per dare la risposta in gradi, mi moltiplico per (360/Phi) * (Pi/180) per dare la risposta in radianti.

Dal momento che le funzioni trigonometriche non importa ciò che la gamma radianti prendono, non ho bisogno di assicurarsi lat e lon sono nel range (-pi, pi]

per rendere i punti:.

function render(e) 
{ 
    var offsetX = Math.floor(canvas.width/2); 
    var offsetY = Math.floor(canvas.height/2); 

    var r = Math.min(canvas.width, canvas.height) * 0.4; 

    ctx.clearRect(0, 0, canvas.width, canvas.height); 

    for (var i = 0; i < e.length; i++) 
    { 
     var x = Math.cos(e[i].lat) * Math.sin(e[i].lon); 
     var y = Math.sin(e[i].lat) * Math.sin(e[i].lon); 
     var z = Math.cos(e[i].lon); 

     // Make z go from 0.1 to 1 for scaling: 
     z += 1; 
     z /= 2; 
     z *= 0.9; 
     z += 0.1; 

     ctx.beginPath(); 
     ctx.arc(r * x + offsetX, r * y + offsetY, z*5, 0, 2 * Math.PI, false); 
     ctx.fillStyle = "#990000"; 
     ctx.fill(); 
     ctx.lineWidth = 2; 
     ctx.strokeStyle = "#FF0000"; 
     ctx.stroke(); 
     ctx.closePath(); 
    } 
} 

per dare un'illusione di profondità fino metto a rotazione, moltiplico il raggio dei punti dalla coordinata z, che linearmente scalabili in [0.1,1.0].

Ecco un JSFiddle link con tutto il codice: https://jsfiddle.net/wexpwngc/ Se aumenti il ​​numero di punti da 101 a qualcosa di molto più grande come 1001, allora vedrai che ci sono molti blocchi attorno ai poli, e ci sono alcuni punti sparsi sui punti.

Sono stato bloccato su questo per un po 'di tempo. Qualcuno può vedere dove ho sbagliato?

+0

vedere questi collegamenti: [triangolazione a sfera] (http://stackoverflow.com/a/29139125/2521214), [sfera con vertici equidistanti] (http://stackoverflow.com/a/25031737/2521214), [ sphere grid/map] (http://stackoverflow.com/a/25082674/2521214) per alternative più semplici – Spektre

risposta

0

Il tuo e [i + N] .lon è disattivato di un fattore 0,5.

Problemi correlati