我試圖沿着單位球體的表面或多或少均勻地排列點。使用斐波那契格來均勻地排列球體上的點
I'm told雖然這個問題很難,Fibonacci Lattices給出了很好的解決方案。
我一直在嘗試幾天來遵循鏈接文檔中提供的非常簡單的方法,但我根本無法讓它看起來正確。
我正在使用javascript,並且我有一個對象數組e
,每個對象都暴露了lat
和lon
參數。下面是我用來安排在球體上的點的功能:(現在假設點的數量始終是奇)
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;
}
不像文檔中,我lat
和lon
以弧度表示,而不是度數。這是我可以稍後使用X/Y/Z座標來繪製它們,我使用javascript Math.sin
和Math.cos
函數來獲得這些函數,該函數接受弧度而不是度數。
lat
的第一行非常簡單。我在文檔中省略了180/Pi因子,因爲我想將結果保持爲弧度。
lon
的第二行用黃金比例表示索引的模數,而不是乘以因子360/Phi以給出答案的度數,我乘以(360/Phi)*(Pi/180)以弧度給出答案。
由於三角函數不在乎範圍弧度拿,我並不需要確保lat
和lon
的範圍是(-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等更大的值,那麼您會發現杆子周圍有很多團塊,並且有些地方的點很稀疏。
我一直堅持這一段時間了。任何人都可以看到我犯了錯誤嗎?
請參閱以下鏈接:[sphere triangulation](http://stackoverflow.com/a/29139125/2521214),[帶等距頂點的球體](http://stackoverflow.com/a/25031737/2521214),[球柵格/地圖](http://stackoverflow.com/a/25082674/2521214)更簡單的替代品 – Spektre