【问题标题】:AS3 Get random point in ringAS3 获取环中的随机点
【发布时间】:2011-01-09 16:09:54
【问题描述】:

如何在环内获得随机点?比如,两个同心圆之间的空间。我自己在代码中制作圆圈,所以我知道半径等。这是我正在开发的一款游戏,我在其中将敌人隔开成波浪,或者与场地中心隔开不同的圆环。我在想唯一的方法是某种检查点或其他东西的循环。 As3

【问题讨论】:

    标签: actionscript-3 math random


    【解决方案1】:

    除了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;
    

    【讨论】:

    • idk,Math.Random() 只返回一个正值,所以也许这就是问题所在,但我的所有观点都是在左侧创建的
    • ??? Math.random() 应该返回一个介于 0 和 1 之间的值。查看角度值——它们应该分布在 0 和 2pi = 大约 6.28318 之间
    【解决方案2】:

    一种解决方案是考虑极坐标中的点。随机化角度,然后随机化到中心的距离:

    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;
    

    【讨论】:

    • 大声笑,对不起,我们还没有在学校学习极坐标图,我本学期应该学习的。但我理解你的代码。
    • 为什么第一个解决方案会增加内环附近的点密度?
    • @adamk :点沿给定圆周均匀分布,半径均匀分布在两个半径之间。内圆周比外圆周短,因此放置在其中的 N 个随机点将比放置在外边缘的 N 个随机点更靠近。想象一个非常小的内半径 - 与放置在外边缘的点相比,放置在其上的点将紧密排列。为了均匀包装,内半径的选择频率必须低于外半径。 @Jason S 的答案有很多很棒的谷歌关键词。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 2019-09-24
    • 2018-03-30
    • 2021-01-22
    • 2012-08-13
    • 2013-03-08
    相关资源
    最近更新 更多