在给定的球随机点

2023-09-07 17:46:03 作者:|黄花大闺男゜

我要选择一个给定的范围随机点。本页说明它非常好:

http://mathworld.wolfram.com/SpherePointPicking.html (为了获得点,使得在球体上任何小区域...)

但我不能完全肯定,如果我在JavaScript中正确地实现它,因为我已经正确测试它的小方法:

 变种U =随机();
变种ν=随机();
VAR角度1 = 2 * Math.PI * U;
变种ANGLE2 = Math.pow(Math.cos(2 * V  -  1), -  1);
X = X0 +(半径* Math.sin(角度1)* Math.cos(ANGLE2));
Y = Y0 +(半径* Math.sin(角度1)* Math.sin(角度1));
Z = Z0 +(半径* Math.cos(角度1));
 

我特别不确定,如果我了解,COS(-1)正确的,这是我实现的余弦为-1的力量。

解决方案

我认为,一个更简单的算法是

选择一个随机点里面的 [ - 1,1]×[-1,1]×[-1,1] 立方 如果 X * X + Y * Y + Z * Z> 1 1 重复 标准化分 X 以Z 通过的Math.sqrt(X * X + Y * Y + Z * Z)

换句话说,随便挑一个随机点的球球体和项目中。

您可以看到该算法在行动在这个环节。 请注意,如果你使用Chrome将会有围绕赤道,在我看来是的Math.random一个bug,或只是一个低质量的随机生成一些绑定(正常工作的Firefox或Safari浏览器,但同样的问题是可见的还在Android浏览器)。条带是更加明显具有较高数量的点(如:10000,而不是1000点,我用现在保持动画流畅) 编辑:此错误现在已经被固定在镀铬。然而仍然present我N1的Web浏览器中运行的是Android 2.3.6。

教你用Photoshop制作充满质感的玻璃球

请注意,如果你正在寻找一种方法来平均分配分以上的球,你可以通过上述然后只接受一个与从该组已经选择的最大的3D距离选择10个随机点做一些更好点。这仍然是全球范围内随机(即以prescribed半径将得到一分一盘是一样的球体上的所有光盘的probablity),但将分发还好点,如果你需要做球的取样 。此功能是codeD为取值preadPoints()中指向的链接的HTML文件。

您可以看到这两种方法在这里的区别是:

两个球体已引起对它们1000随机点:在左边的球用均匀随机点,右边的球,而不是通过拾取中间10个随机候选的每个点,从已选择的点最大化的距离作出的选择

I want to select random points on a given sphere. This page explains it quite well:

http://mathworld.wolfram.com/SpherePointPicking.html ("To obtain points such that any small area on the sphere...")

But I'm not entirely sure if I'm implementing it correctly in JavaScript, as I have little means of testing it properly:

var u = random();
var v = random();
var angle1 = 2 * Math.PI * u;
var angle2 = Math.pow(Math.cos (2 * v - 1), -1);
X = X0 + (radius * Math.sin(angle1) * Math.cos(angle2));
Y = Y0 + (radius * Math.sin(angle1) * Math.sin(angle1));
Z = Z0 + (radius * Math.cos(angle1));

I'm especially unsure about if I've understood that cos(-1) correctly, which I implemented as "The cosine to the power of -1".

解决方案

I think that an easier algorithm is

Pick a random point inside the [-1,1]x[-1,1]x[-1,1] cube If x*x + y*y + z*z > 1 repeat from 1 Normalize dividing x, y and z by Math.sqrt(x*x + y*y + z*z)

in other words just pick a random point inside the sphere and project on the sphere.

You can see this algorithm in action on this link. Note that if you use chrome there will be some banding around an equator that in my opinion is a bug in Math.random or just a low quality random generator (works fine on Firefox or Safari, but the same problem is visible also on Android browser). The banding is much more visible with an higher number of points (e.g. 10000 instead of the 1000 points I'm using now to keep animation smooth). EDIT: This bug has now been fixed on chrome. It is however still present on the web browser of my N1 running Android 2.3.6.

Note that if you're looking for a method to distribute points evenly over a sphere you can do something nicer by choosing ten random points as described above and then accepting only the one with the biggest 3d distance from the set of already chosen points. This is still globally random (i.e. the probablity that a disc with a prescribed radius will receive a point is the same for all discs on the sphere) but will distribute points better if you need to do a "sampling" of the sphere. This function is coded as spreadPoints() in the html file pointed by the link.

You can see the difference between the two approaches here:

Both spheres have 1000 random points drawn on them: the sphere on the left used uniform random points, the sphere on the right instead made the choice by picking each point among ten random candidates to maximize the distance from already chosen points.

相关推荐
 
精彩推荐
图片推荐