Javascript 球面上不规则圆的填充
我使用THREE.js在球体上创建点,类似于 我的数据集是一个大小不规则的圆,我希望将它们均匀地分布在球体的表面上。在网上搜索了好几个小时后,我意识到这比听起来要困难得多 以下是这一想法的实际例子: 有谁能帮我指出一个方向,找到一个算法,让我可以做到这一点?压缩比不需要非常高,理想情况下,它应该是在javascript中快速且易于计算的东西,以便在THREE.js(笛卡尔坐标系或坐标系)中渲染。效率是关键 编辑:圆半径可以变化很大。以下是使用周期表代码的示例:Javascript 球面上不规则圆的填充,javascript,algorithm,three.js,geometry,circle-pack,Javascript,Algorithm,Three.js,Geometry,Circle Pack,我使用THREE.js在球体上创建点,类似于 我的数据集是一个大小不规则的圆,我希望将它们均匀地分布在球体的表面上。在网上搜索了好几个小时后,我意识到这比听起来要困难得多 以下是这一想法的实际例子: 有谁能帮我指出一个方向,找到一个算法,让我可以做到这一点?压缩比不需要非常高,理想情况下,它应该是在javascript中快速且易于计算的东西,以便在THREE.js(笛卡尔坐标系或坐标系)中渲染。效率是关键 编辑:圆半径可以变化很大。以下是使用周期表代码的示例: 您可以使用与元素周期表中相同
您可以使用与元素周期表中相同的代码。 那里的矩形不接触,所以你可以通过使用相同的代码来获得与圆形相同的效果 以下是他们的代码:
var vector = new THREE.Vector3();
for ( var i = 0, l = objects.length; i < l; i ++ ) {
var phi = Math.acos( -1 + ( 2 * i ) / l );
var theta = Math.sqrt( l * Math.PI ) * phi;
var object = new THREE.Object3D();
object.position.x = 800 * Math.cos( theta ) * Math.sin( phi );
object.position.y = 800 * Math.sin( theta ) * Math.sin( phi );
object.position.z = 800 * Math.cos( phi );
vector.copy( object.position ).multiplyScalar( 2 );
object.lookAt( vector );
targets.sphere.push( object );
}
var vector=new THREE.Vector3();
for(var i=0,l=objects.length;i
这里有一种尝试方法:使用模拟斥力进行迭代搜索
算法
首先,通过在曲面上以任何算法排列圆来初始化数据集。这只是为了初始化,所以不必太好。元素周期表代码将很好地工作。此外,使用每个圆的半径作为其质量值,为每个圆指定一个“质量”
现在开始迭代以收敛于一个解决方案。对于每个通过主循环的过程,请执行以下操作:
f = ( k * m[i] * m[j] ) / ( r * r );
你可以试试这个:
f = ( k * m[i] * m[j] ) / pow( r, p );
然后你可以用不同的p值进行实验
您还可以试验初始分布的不同算法
//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
...
}
尝试和错误的数量将取决于您的设计目标。以下是一些您可以建立的东西。它将沿球体随机分布球体。稍后,我们将迭代此起点以获得均匀分布
//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
...
}
//半径为R的球体上的随机点
变量sphereCenters=[]
var numSpheres=100;
对于(变量i=0;i
然后运行以下代码几次,以有效地打包球体:
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);
}
}
}
for(变量i=0;i