【问题标题】:Generating a nebula cloud in circle [duplicate]生成圆形星云[重复]
【发布时间】:2014-05-27 00:03:12
【问题描述】:

我正在尝试在Vector2(点)周围的指定半径内生成星云。

目前我正在使用此代码

public static Vector2 GeneratePosition(Vector2 position, float radius)
{
    float X = GenerateScaleFloat() * (GenerateInt(2) == 1 ? 1 : -1);
    float Y = GenerateInt((int)(radius * -(1 - Math.Abs(X))),
                          (int)(radius *  (1 - Math.Abs(X)))) / radius;

    X *= radius;
    Y *= radius;
        
    return new Vector2(X, Y);
}

这给了我这个结果:

(原点:0;0,半径:300,粒子:5000

在我看来,我的代码正在生成一个旋转的正方形。我怎样才能让它在更圆形的图案中(和之内)生成粒子的位置?

GenerateScaleFloat:返回一个介于 0.0 和 1.0 之间的值

GenerateInt:标准的rand.Next

编辑: 这篇文章现在已被标记为重复,这不是我的意图。但是,我会在这里留下我的答案,让其他谷歌用户找到,因为我知道它有多大帮助:

新代码:

public static Vector2 GeneratePosition(Vector2 position, float radius)
{
    float X = GenerateScaleFloat() * (GenerateInt(2) == 1 ? 1 : -1) * radius;
    float Y = float.PositiveInfinity;

    while(Y > Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(X, 2))
        || Y < -Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(X, 2)))
    {
        Y = GenerateScaleFloat() * (GenerateInt(2) == 1 ? 1 : -1) * radius;
    }
                                
    return new Vector2(X, Y) + position;
}

新输出:(原点:0;0,半径 100,粒子:5000)

希望它能帮助别人

【问题讨论】:

    标签: c# windows math xna monogame


    【解决方案1】:

    圆的面积公式是

    x^2 + y^2 <= r^2
    

    给定x,您可以像这样计算y

    y <= +/-sqrt( r^2 - x^2 )
    

    通过对轴应用不同的缩放因子,您可以创建一个椭圆。


    另一种可能性是在矩形中生成点并查看它们是否在椭圆内:

    a = width / 2
    b = height / 2
    (x/a)^2 + (y/b)^2 <= 1    Where the ellipse will be centered on
                              the origin of the coordinate system.
    

    这可能会产生分布更均匀的点。


    编辑:您可以改进您的新代码。而不是比较...

    y > Sqrt(r^2 - x^2) OR y < -Sqrt(r^2 - x^2)
    

    ...你可以比较

    y^2 > r^2 - x^2
    

    y^2 总是正数,因为负数乘以负数就是正数。通常值得转换一个其他正确的数学正确公式,以使其对计算机更有效。计算平方根很昂贵,Math.Pow 也是如此。

    此外,生成 -1 和 +1 之间的 Y 值可以更简单的方式实现,方法是首先生成一个介于 0 和 1 之间的随机数,将其乘以半径的两倍,最后减去半径。

    float y2max = radius * radius - X * X;
    do { 
        Y = 2 * radius * GenerateScaleFloat() - radius;
    } while (Y * Y > y2max);
    

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 2021-08-15
      • 2016-11-04
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      • 2019-06-13
      相关资源
      最近更新 更多