取得一个球体内的随机一点的方法及讨论

为了更好地随机出Art of Destiny中的空间装饰物的位置,大地无敌曾经自己写了一个得到一个球体区域内随机一点的方法但是缺点非常明显。大地无敌原来的方法是算出一个随机长度的Z轴向量再绕X、Y轴旋转随机角度,但是这样做的后果是得出的点靠近球体中心的概率比在边沿上大很多。
原方法:

为了更好地随机出Art of Destiny中的空间装饰物的位置,大地无敌曾经自己写了一个得到一个球体区域内随机一点的方法但是缺点非常明显。大地无敌原来的方法是算出一个随机长度的Z轴向量再绕X、Y轴旋转随机角度,但是这样做的后果是得出的点靠近球体中心的概率比在边沿上大很多。
原方法:

假设把一个球分成A、B两区域,如图,得到的点分布在a区域和b区域的概率是相等的,但b区域的体积明显比a区域大
如果得到许多点的话,这些点在a区域中就很密集,而在b区域中就很稀疏,如何才能解决这个问题呢?

这个问题在XNA游戏世界上激起了讨论,F.yo、XnaZero、稀饭等众多高手发表了自己的看法。
原贴http://xna.omgsoft.com.cn/Forums/Thread/1027.aspx
于是大地无敌编写了一个程序进行计算验证,结果如下:

经计算,在球外接AABB立方体内生成随机点,如果点不在球内则重做,这样的方法是最好的(即准确又最快)。
验证程序源码(里面包含各种计算的方法):201002062349566021.rar

如xnazero所言,应该再增加次数并调节CPU优先级,另外F.yo的算法大地无敌也写得有问题,并且运算太繁杂..

1 thought on “取得一个球体内的随机一点的方法及讨论”

  1. fy的算法我只是照他的回帖加了一句 应该比原来用时还多的
    不知道为什么比你的结果少这么多

    大地无敌 于 2/8/2010 10:14:08 PM 回复

    我也正奇怪呢,把d = (float)Random.NextDouble();这句移到do-while循环里之后不仅时间少了一半,而且得到了和开平方一样的结果,而照理说时间应该更长才对…

    xnazero 于 2/9/2010 10:36:25 PM 回复

    得到开平方一样的结果是正常的
    如果你加个K*=K可以得到开立方的曲线

Leave a Reply

Your email address will not be published. Required fields are marked *