【发布时间】:2011-01-09 16:09:54
【问题描述】:
如何在环内获得随机点?比如,两个同心圆之间的空间。我自己在代码中制作圆圈,所以我知道半径等。这是我正在开发的一款游戏,我在其中将敌人隔开成波浪,或者与场地中心隔开不同的圆环。我在想唯一的方法是某种检查点或其他东西的循环。 As3
【问题讨论】:
标签: actionscript-3 math random
如何在环内获得随机点?比如,两个同心圆之间的空间。我自己在代码中制作圆圈,所以我知道半径等。这是我正在开发的一款游戏,我在其中将敌人隔开成波浪,或者与场地中心隔开不同的圆环。我在想唯一的方法是某种检查点或其他东西的循环。 As3
【问题讨论】:
标签: actionscript-3 math random
除了fuzzyTew 的另一种解决方案来创建均匀的密度分布而无需循环+拒绝(这对于窄环来说很昂贵),是使用半径的累积分布函数的知识。 (环作为角度的函数均匀分布,因此您可以使用角度的均匀分布。)
内半径为 r1 外半径为 r2 的环的 CDF 与 r2 - r1 成正比2(这是与 r dr 成比例的项的积分,它是半径 r 和极小的厚度 dr 的环的概率密度)。 CDF(r=r1) = 0,CDF(r=r2) = 1,所以CDF(r) = (r2 - r12)/(r22 - r12).
那又怎样?好了,现在我们只需要选取一个均匀分布在 0 和 1 之间的 CDF 值 q,并将 CDF 倒置得到半径 r:
q = (r^2 - r1^2)/(r2^2 - r1^2)
r = sqrt(q*(r2^2 - r1^2) + r1^2)
所以对于一个实现(对于语法错误,我不太熟悉 AS3 与 Javascript)
var angle : Number = Math.random() * Math.PI * 2;
var q : Number = Math.random();
var radius : Number = Math.sqrt(q*(r2*r2-r1*r1) + r1*r1);
var x : Number = Math.cos( angle ) * radius;
var y : Number = Math.sin( angle ) * radius;
【讨论】:
一种解决方案是考虑极坐标中的点。随机化角度,然后随机化到中心的距离:
var angle : Number = Math.random() * Math.PI * 2;
var radius : Number = Math.random() * (outerRadius - innerRadius) + innerRadius;
var x : Number = Math.cos( angle ) * radius;
var y : Number = Math.sin( angle ) * radius;
但是,上述极性解决方案将增加朝向内环选择的点的密度。如果您需要精确均匀分布,一种解决方案是在环周围的正方形中随机选取点,丢弃不在环中的点:
var x : Number;
var y : Number;
var radiusSquared : Number;
var outerRadiusSquared : Number = outerRadius * outerRadius;
var innerRadiusSquared : Number = innerRadius * innerRadius;
do {
x = Math.random() * outerRadius * 2 - outerRadius;
y = Math.random() * outerRadius * 2 - outerRadius;
radiusSquared = x * x + y * y;
} while ( radiusSquared > outerRadiusSquared || radiusSquared < innerRadiusSquared );
或者,可以对极性溶液进行加权以给出均匀分布。我认为这是怎么做的,但我不确定:
var angle : Number = Math.random() * Math.PI * 2;
var outerRadiusSquared : Number = outerRadius * outerRadius;
var innerRadiusSquared : Number = innerRadius * innerRadius;
var radius : Number = Math.sqrt( outerRadiusSquared + Math.random() * (innerRadiusSquared - outerRadiusSquared) )
var x : Number = Math.cos( angle ) * radius;
var y : Number = Math.sin( angle ) * radius;
【讨论】: