Advertisement
Guest User

Untitled

a guest
Jun 27th, 2017
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.70 KB | None | 0 0
  1. import random
  2.  
  3.  
  4. class Coordinates:
  5. def __init__(self, x, y):
  6. self.x = x
  7. self.y = y
  8.  
  9.  
  10. class Obstacle:
  11. def __init__(self, x, y, radius):
  12. self.center = Coordinates(x, y)
  13. self.radius = radius
  14.  
  15.  
  16. class Disturbance:
  17. def __init__(self, x, y, dx, dy):
  18. self.start = Coordinates(x, y)
  19. self.size = Coordinates(dx, dy)
  20.  
  21.  
  22. def create_particles_field(field_size, density):
  23. random.seed()
  24. return [[int(0 < x < field_size.x - 1 and 0 < y < field_size.y - 1 and random.random() > density)
  25. for x in range(field_size.x)] for y in range(field_size.y)]
  26.  
  27.  
  28. def create_bounds_field(field_size):
  29. return [[int((x == 0 or x == field_size.x - 1) or (y == 0 or y == field_size.y - 1))
  30. for x in range(field_size.x)] for y in range(field_size.y)]
  31.  
  32.  
  33. def circle_coord_generator(size, center, radius):
  34. radius -= 1
  35. for x in range(max(center - radius, 1), min(center + radius, size - 1) + 1):
  36. yield x
  37.  
  38.  
  39. def fill_obstacle(particles_field, bounds_field, field_size, obstacle):
  40. sqr_radius = obstacle.radius**2
  41. for y in circle_coord_generator(field_size.y - 1, obstacle.center.y, obstacle.radius):
  42. for x in circle_coord_generator(field_size.x - 1, obstacle.center.x, obstacle.radius):
  43. if (x - obstacle.center.x)**2 + (y - obstacle.center.y)**2 <= sqr_radius:
  44. particles_field[y][x] = 0
  45. bounds_field[y][x] = 1
  46.  
  47.  
  48. def fill_fields(field_size, density, obstacle):
  49. particles_field = create_particles_field(field_size, density)
  50. bounds_field = create_bounds_field(field_size)
  51.  
  52. fill_obstacle(particles_field, bounds_field, field_size, obstacle)
  53. return particles_field, bounds_field
  54.  
  55.  
  56. def calc_block_amount(size, is_odd):
  57. return size // 2 + is_odd
  58.  
  59.  
  60. def get_rotated_diag(block):
  61. main_diagonal = [[1, 0], [0, 1]]
  62. anti_diagonal = [[0, 1], [1, 0]]
  63.  
  64. return {
  65. main_diagonal: anti_diagonal,
  66. anti_diagonal: main_diagonal,
  67. }.get(block, None)
  68.  
  69.  
  70. def copy_block(field, block, actual_coord):
  71. for y in range(2):
  72. for x in range(2):
  73. field[actual_coord.y + y][actual_coord.x + x] = block[y][x]
  74.  
  75.  
  76. def multi_dimensional_slice(arr, start_x, count_x, start_y, count_y):
  77. return [[arr[y][x] for x in range(start_x, start_x + count_x)] for y in range(start_y, start_y + count_y)]
  78.  
  79.  
  80. def multi_dimensional_sum(arr, start_x, count_x, start_y, count_y):
  81. return sum(arr[y][x] for x in range(start_x, start_x + count_x) for y in range(start_y, start_y + count_y))
  82.  
  83.  
  84. def step(particles_field, bounds_field, field_size, is_odd):
  85. is_odd = int(is_odd)
  86. blocks_amount = Coordinates(calc_block_amount(field_size.x, is_odd), calc_block_amount(field_size.y, is_odd))
  87. for y in range(len(blocks_amount.y)):
  88. actual_coord = Coordinates(0, y * 2 + is_odd)
  89. for x in range(len(blocks_amount.x)):
  90. actual_coord.x = x * 2 + is_odd
  91.  
  92. bounds_sum = multi_dimensional_sum(bounds_field, actual_coord.x, 2, actual_coord.y, 2)
  93. if bounds_sum == 0:
  94. block = multi_dimensional_slice(particles_field, actual_coord.x, 2, actual_coord.y, 2)
  95. rotated_diag = get_rotated_diag(block)
  96. if rotated_diag:
  97. copy_block(particles_field, rotated_diag, actual_coord)
  98. else:
  99. flat_block = [block[y][x] for x in range(2) for y in range(2)]
  100. flat_block.reverse()
  101. block = [flat_block[y * 2:y * 2 + 1] for y in range(2)]
  102. copy_block(particles_field, block, actual_coord)
  103.  
  104.  
  105. def averaging(particles_field, field_size, scale):
  106. return [[multi_dimensional_sum(particles_field, x * scale, scale, y * scale, scale)
  107. for x in range(field_size.x // scale)] for y in range(field_size.y // scale)]
  108.  
  109.  
  110. def disturb_coord_gen(size, start, length):
  111. for x in range(max(start, 1), min(start + length, size - 1)):
  112. yield x
  113.  
  114.  
  115. def create_disturbance(particles_field, field_size, disturbance):
  116. for y in disturb_coord_gen(field_size.y, disturbance.start.y, disturbance.size.y):
  117. for x in disturb_coord_gen(field_size.x, disturbance.start.x, disturbance.size.x):
  118. particles_field[y][x] = 1
  119.  
  120.  
  121. def run_simulation(particles_field, bounds_field, field_size, disturbance, scale, stop_cond, is_disturbance):
  122. epochs_amount = 0
  123. while not stop_cond:
  124. step(particles_field, bounds_field, field_size, True)
  125. if is_disturbance:
  126. create_disturbance(particles_field, field_size, disturbance)
  127. averaged = averaging(particles_field, field_size, scale)
  128. epochs_amount += 1
  129.  
  130. print_field(averaged)
  131.  
  132.  
  133. # DEBUG
  134. def print_field(field):
  135. print('\t[' + ', '.join(str(x) for x in range(len(field[0]))) + ']')
  136. for y in range(len(field)):
  137. print(str(y) + '\t' + str(field[y]))
  138. print('\n')
  139.  
  140.  
  141. def main():
  142. field_size = Coordinates(*map(int, input('Введите размеры плоскости: ').split()))
  143.  
  144. density = float(input('Введите плотность распределения: '))
  145.  
  146. obstacle = Obstacle(*map(int, input('Введите координаты препятсвия и его радиус: ').split()))
  147.  
  148. disturbance = Disturbance(*map(int, input('Введите начальные координаты возмущения и его размеры: ').split()))
  149.  
  150. scale = int(input('Введите усреднение: '))
  151.  
  152. particles_field, bounds_field = fill_fields(field_size, density, obstacle)
  153.  
  154. run_simulation(particles_field, bounds_field, field_size, disturbance, scale, False, 10)
  155.  
  156.  
  157. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement