简体   繁体   中英

Generate smoke/genie shape randomly in Python

I want to produce shapes like these in Python:

#  # # #  #
  #   #
        # #  
     # #
  #
   #

   # # # #   #
#   # #
   #   #
         #  
     #
   #
      #

x items scattered across a grid height × width randomly, with a greater probability to appear in the topmost rows, and most likely to be near but offset from the previous row in each new row.

I can only think of trying to align bell curve-shaped distributions for each row, and offset the mean by a little bit from the previous row's for the next row's. What might be a less mathematical and more programmatic and readable solution?

I had a play and came up with the following code:

import numpy as np

def smokey_motif(rows: int, cols: int) -> str:
    # convolution used for next row
    # a bit of smoothing and edge detection seems good
    conv = np.array([1, 2, 0, 2, 1])
    # generating rows in reverse order, starting with
    # a single particle somewhere near the middle
    row = np.zeros(cols, dtype=int)
    row[np.random.binomial(cols, 0.5)] = 1
    result = [row]
    for _ in range(rows):
        # add some randomness into state after smoothing 
        state = np.convolve(row, conv, 'same') * np.random.uniform(0.5, 2, row.shape)
        # increase number of particles a bit
        n = sum(row) + np.random.binomial(2, 0.2)
        row = np.zeros_like(row)
        row[np.argsort(-state)[:n]] = 1
        result.append(row)
    # turn arrays of numbers into a string
    return '\n'.join(
        ' '.join(' #'[v] for v in row)
        for row in reversed(result)
    )

np.random.seed(3)
print(smokey_motif(8, 8))

producing:

#   #   #   #  
  #   #   #    
    #   #   #  
      #   #   #
        #   #  
          #    
        #      
      #        
        #      

I found it easier to start from the bottom, and playing with the constants gives quite a bit of control which could obviously be exposed by turning into parameters. It'll produce something weird occasionally, but produces something nice the majority of the time.

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