使用斐波那契格子在球体上均匀排列点
Posted
技术标签:
【中文标题】使用斐波那契格子在球体上均匀排列点【英文标题】:Uniformly arranging points on a sphere using Fibonacci Lattices 【发布时间】:2015-07-05 08:31:59 【问题描述】:我试图沿单位球体的表面或多或少均匀地排列点。
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
是弧度,而不是度数。这样我可以稍后使用我使用 javascript Math.sin
和 Math.cos
函数获得的 X/Y/Z 坐标绘制它们,它们接受弧度而不是度数。
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、sphere with equidistant vertices、sphere grid/map 以获得更简单的替代方案 请参阅How to distribute points evenly on the surface of hyperspheres in higher dimensions?,了解开箱即用方法的一些灵感。它们在 ND/一般情况下并不准确,但螺旋方法对于2D,3D
是准确的。
【参考方案1】:
你的 e[i + N].lon 偏离了 0.5 倍。
【讨论】:
以上是关于使用斐波那契格子在球体上均匀排列点的主要内容,如果未能解决你的问题,请参考以下文章