我正在使用THREE.js在球体上创建点,类似于
periodic table of elements example
我的数据集是一个不规则的圆圈,我希望将它们均匀分布在球体表面.在网络上搜索很多小时后,我意识到这比听起来要困难得多.
以下是这个想法的例子:
任何人都可以帮助我指出方向,找到一个可以让我这样做的算法?包装比率不需要超高,理想情况下,在JavaScript中为了在THREE.js(笛卡尔坐标系或坐标系)中渲染而快速而容易地计算.效率是关键.
编辑:圆半径可以差别很大.以下是使用周期表代码的示例:
解决方法
这可能是你可以建立的.它将随机将球体分布在球体上.后来我们将重复这个起点,以获得均匀的分布.
//random point on sphere of radius R var sphereCenters = [] var numSpheres = 100; for(var i = 0; i < numSpheres; i++) { var R = 1.0; var vec = new THREE.Vector3(Math.random(),Math.random(),Math.random()).normalize(); var sphereCenter = new THREE.Vector3().copy(vec).multiplyScalar(R); sphereCenter.radius = Math.random() * 5; // RANDOM SPHERE SIZE,plug in your sizes here sphereCenters.push(sphereCenter); //Create a THREE.js sphere at sphereCenter ... }
然后运行以下代码几次,以有效地打包球体:
for(var i = 0; i < sphereCenters.length; i++) { for(var j = 0; j < sphereCenters.length; j++) { if(i === j) continue; //calculate the distance between sphereCenters[i] and sphereCenters[j] var dist = new THREE.Vector3().copy(sphereCenters[i]).sub(sphereCenters[j]); if(dist.length() < sphereSize) { //move the center of this sphere to to compensate //how far do we have to move? var mDist = sphereSize - dist.length(); //perturb the sphere in direction of dist magnitude mDist var mVec = new THREE.Vector3().copy(dist).normalize(); mVec.multiplyScalar(mDist); //offset the actual sphere sphereCenters[i].add(mVec).normalize().multiplyScalar(R); } } }
多次运行第二部分将“收敛”到您要查找的解决方案中.您必须选择运行多少次才能找到速度和精度之间的最佳平衡.
更新了准确性