程序生成-加速网格上对象的随机位置



目前我正在做以下事情,我确信这是一种缓慢的方式。基本上,我通过一个网格来确定a)星星是否存在b)如果有的话是什么类型。我认为我应该做的是使用我的已知值(例如current_star_density * 0.25),并使用它来绘制一系列点。我想我不确定的部分是,当我绘制这个数量时,我如何防止重复。

任何帮助都将感激不尽。这是代码的相关部分。

for (var z = 0; z < gridZ; z++) 
{
    for (var x= 0; x < gridX; x++) 
    {       
        star_chance = Random.value * 1000;   // * 1000      
        if (star_chance <= current_star_density)
        {
            star_class = Random.value * 100;
            if (star_class <=1) // add in the other star types etc
            {
                new_star = Instantiate(prefab_o, Vector3(x * 10 + transform.position.x - 500, 0, z * 10 + transform.position.z - 500), Quaternion.identity);
                new_star.transform.parent = this.transform;
                new_star.name = String.Format("O:{0}.{1}:{2}.{3}",galaxy_X,x,galaxy_Y,z);
            } 
            else if (star_class <=2) 
            {
                new_star = Instantiate(prefab_b, Vector3(x * 10 + transform.position.x - 500, 0, z * 10 + transform.position.z - 500), Quaternion.identity);
                new_star.transform.parent = this.transform;
                new_star.name = String.Format("B:{0}.{1}:{2}.{3}",galaxy_X,x,galaxy_Y,z);
            }
            else if (star_class <=5) 
            {
                new_star = Instantiate(prefab_a, Vector3(x * 10 + transform.position.x - 500, 0, z * 10 + transform.position.z - 500), Quaternion.identity);
                new_star.transform.parent = this.transform;
                new_star.name = String.Format("A:{0}.{1}:{2}.{3}",galaxy_X,x,galaxy_Y,z);
            } 
            else if (star_class <=10) 
            {
                new_star = Instantiate(prefab_f, Vector3(x * 10 + transform.position.x - 500, 0, z * 10 + transform.position.z - 500), Quaternion.identity);
                new_star.transform.parent = this.transform;
                new_star.name = String.Format("F:{0}.{1}:{2}.{3}",galaxy_X,x,galaxy_Y,z);
            } 
            else if (star_class <=20) 
            {
                new_star = Instantiate(prefab_g, Vector3(x * 10 + transform.position.x - 500, 0, z * 10 + transform.position.z - 500), Quaternion.identity);
                new_star.transform.parent = this.transform;
                new_star.name = String.Format("G:{0}.{1}:{2}.{3}",galaxy_X,x,galaxy_Y,z);
            } 
            else if (star_class <=40) 
            {
                new_star = Instantiate(prefab_k, Vector3(x * 10 + transform.position.x - 500, 0, z * 10 + transform.position.z - 500), Quaternion.identity);
                new_star.transform.parent = this.transform;
                new_star.name = String.Format("K:{0}.{1}:{2}.{3}",galaxy_X,x,galaxy_Y,z);
            }
            else if (star_class <=80) 
            {
                new_star = Instantiate(prefab_m, Vector3(x * 10 + transform.position.x - 500, 0, z * 10 + transform.position.z - 500), Quaternion.identity);
                new_star.transform.parent = this.transform;
                new_star.name = String.Format("M:{0}.{1}:{2}.{3}",galaxy_X,x,galaxy_Y,z);
            }
        }   
    }
}

我真的不确定你想要达到什么样的最终结果,但你可能是指这样的东西(伪代码)吗?

star_density是一个介于0和1之间的数字,1表示全密度,0表示无密度。

// We have a fixed amount of stars based on the grid size and density
// You could add a small random multiplier if you wish
for (var i = 0; i < gridX * gridZ * star_density; ++i) {
    // Pick a random position until we find an empty one
    do {
        var x = floor(Random.value * gridX);
        var z = floor(Random.value * gridY);
    } while (grid[z][x].containsStar());
    var new_star = /* Do all the star initialization stuff and randomization */
    grid[z][x] = new_star;
}

假设您可以使用网格来执行查找星号的存在。我没有看到你在哪里存储星星,但即使你目前没有一个实际的网格,你也可以使用一个临时数组来放置算法。

当碰撞不太可能发生时,这应该在低恒星密度下更有效(例如,低于30% -完全编造的数字,需要一些实验),但在某些时候,它会比你现在的运行更糟糕,因为找到一个空闲槽的可能性很低,并且使用两个随机值而不是你的一个。另一个缺点是,如果RNG很糟糕,理论上这可能会进入一个带有大网格和非常高密度的无限循环。您可以通过简单地根据密度选择使用哪种算法来应对最坏情况的性能。

相关内容

  • 没有找到相关文章

最新更新