2015-04-27 16 views
7

我試圖沿着單位球體的表面或多或少均勻地排列點。使用斐波那契格來均勻地排列球體上的點

I'm told雖然這個問題很難,Fibonacci Lattices給出了很好的解決方案。

我一直在嘗試幾天來遵循鏈接文檔中提供的非常簡單的方法,但我根本無法讓它看起來正確。

我正在使用javascript,並且我有一個對象數組e,每個對象都暴露了latlon參數。下面是我用來安排在球體上的點的功能:(現在假設點的數量始終是奇)

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

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

不像文檔中,我latlon以弧度表示,而不是度數。這是我可以稍後使用X/Y/Z座標來繪製它們,我使用javascript Math.sinMath.cos函數來獲得這些函數,該函數接受弧度而不是度數。

lat的第一行非常簡單。我在文檔中省略了180/Pi因子,因爲我想將結果保持爲弧度。

lon的第二行用黃金比例表示索引的模數,而不是乘以因子360/Phi以給出答案的度數,我乘以(360/Phi)*(Pi/180)以弧度給出答案。

由於三角函數不在乎範圍弧度拿,我並不需要確保latlon的範圍是(-pi,PI]

要渲染的點:

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

爲了讓深度的幻覺,直到我把旋轉,我由z座標,這是我線性擴展到[0.1,1.0]乘點的半徑。

這裏有一個的jsfiddle鏈接所有代碼:https://jsfiddle.net/wexpwngc/ 如果將點數從101增加到1001等更大的值,那麼您會發現杆子周圍有很多團塊,並且有些地方的點很稀疏。

我一直堅持這一段時間了。任何人都可以看到我犯了錯誤嗎?

+0

請參閱以下鏈接:[sphere triangulation](http://stackoverflow.com/a/29139125/2521214),[帶等距頂點的球體](http://stackoverflow.com/a/25031737/2521214),[球柵格/地圖](http://stackoverflow.com/a/25082674/2521214)更簡單的替代品 – Spektre

回答

0

您的e [i + N] .lon的偏差是0.5倍。