简体   繁体   中英

How can I evenly scatter points without overlapping each other?

I'd like to evenly scatter stars to represent a night sky background in a UIView, based on the UIView's width and height. Each star must be at least 20 pixels apart.

I tried the following to generate the X and Y points, but it is highly inefficient and ends up freezing the app because too often the randomly generated numbers are too similar to those in the existing array, causing it to loop again infinitely.

func generateRandomNumber(maxValue: UInt32, uniquePoints: Set<Int>) -> Int {
    let randomNumber = Int(arc4random_uniform(maxValue))

    for point in uniquePoints {
        if(abs(randomNumber - point) < 20) {
            return generateRandomNumber(maxValue, uniquePoints)
        }
    }

    return randomNumber
}

Is there a more efficient way to do this?

The easiest way, if they need to be 20 pixels apart is to divide your area into 20 x 20 squares. Randomly place 1 star in each 20 x 20 cell, but skip every other column and row. So it would look like this:

*-*-*-*-*
|-|-|-|-|
*-*-*-*-*
|-|-|-|-|

etc. In the above illustration, cells with a * in them would have a single star. Cells with either a - or a | would be empty.

If you want to get more complicated, you can look up Poisson Disc . This is a more complicated method that achieves what you want more elegantly. It's a little harder to understand, though, and can often be computationally intensive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM