Advertisement
Guest User

Untitled

a guest
Feb 14th, 2020
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.90 KB | None | 0 0
  1. import numpy
  2. import pprint
  3.  
  4.  
  5. class ImageLayer(object):
  6. """
  7. Represents a layer of an image
  8. """
  9. def __init__(self, x_shape, y_shape, fill_character, left_x, top_y, right_x, bottom_y):
  10. self.x_shape = x_shape
  11. self.y_shape = y_shape
  12. self.fill_character = fill_character
  13. self.canvas = self._build_canvas(left_x, top_y, right_x, bottom_y)
  14.  
  15. def _verify_coords(self, x, y):
  16. # Check that the co-ordinates are valid
  17. if x<0 or x>=self.x_shape or y<0 or y>=self.y_shape:
  18. raise ValueError(f'[{x}, {y}] is outside the bounds')
  19.  
  20. def _build_canvas(self, left_x, top_y, right_x, bottom_y):
  21. self._verify_coords(left_x, top_y)
  22. self._verify_coords(right_x, bottom_y)
  23. # Create the initial canvas for the layer
  24. canvas = numpy.zeros(shape=(self.x_shape, self.y_shape))
  25. canvas[left_x:right_x+1, top_y:bottom_y+1] = numpy.ones(shape=(right_x-left_x+1, bottom_y-top_y+1))
  26. return canvas
  27.  
  28. def erase_area(self, left_x, top_y, right_x, bottom_y):
  29. """
  30. Erase a section of the layer
  31. """
  32. self._verify_coords(left_x, top_y)
  33. self._verify_coords(right_x, bottom_y)
  34. self.canvas[left_x:right_x+1, top_y:bottom_y+1] = numpy.zeros(shape=(right_x-left_x+1, bottom_y-top_y+1))
  35.  
  36. def hit(self, select_x, select_y):
  37. """
  38. Check if the layer has any content at these co-ordinates
  39. """
  40. self._verify_coords(select_x, select_y)
  41. return self.canvas[select_x, select_y] == 1
  42.  
  43. def drag_and_drop(self, move_x, move_y):
  44. """
  45. Roll the canvas to move the position of the rectangle
  46. """
  47. # This will wrap rectanges around the maximums
  48. self.canvas = numpy.roll(self.canvas, move_x, axis=0)
  49. self.canvas = numpy.roll(self.canvas, move_y, axis=1)
  50.  
  51.  
  52. class Image(object):
  53. """
  54. Represents an image with multiple layers
  55. """
  56. def __init__(self, x_shape=10, y_shape=6):
  57. self.x_shape = x_shape
  58. self.y_shape = y_shape
  59. self.layers = []
  60.  
  61. def draw_rectangle(self, fill_character, left_x, top_y, right_x, bottom_y):
  62. """
  63. Creates a new layer on top with the specified rectangle on it
  64. """
  65. new_layer = ImageLayer(
  66. self.x_shape,
  67. self.y_shape,
  68. fill_character,
  69. left_x,
  70. top_y,
  71. right_x,
  72. bottom_y
  73. )
  74. self.layers = [new_layer] + self.layers
  75.  
  76. def erase_area(self, left_x, top_y, right_x, bottom_y):
  77. """
  78. Erase the area on all layers
  79. """
  80. for layer in self.layers:
  81. layer.erase_area(left_x, top_y, right_x, bottom_y)
  82.  
  83. def drag_and_drop(self, select_x, select_y, release_x, release_y):
  84. """
  85. Move the top layer
  86. """
  87. for layer in self.layers:
  88. if layer.hit(select_x, select_y):
  89. layer.drag_and_drop(release_x-select_x, release_y-select_y)
  90. return
  91.  
  92. def bring_to_front(self, select_x, select_y):
  93. """
  94. Move the selected layer to the top of the stack
  95. """
  96. for i, layer in enumerate(self.layers):
  97. if layer.hit(select_x, select_y):
  98. self.layers.pop(i)
  99. self.layers = [layer] + self.layers
  100. return
  101.  
  102. def print_canvas(self):
  103. """
  104. Return an array of arrays with the rendered content
  105. """
  106. canvas = numpy.zeros(shape=(self.x_shape, self.y_shape)).tolist()
  107. for layer in reversed(self.layers):
  108. for i in range(self.x_shape):
  109. for j in range(self.y_shape):
  110. if layer.canvas[i, j] == 1:
  111. canvas[i][j] = layer.fill_character
  112.  
  113. # This can probably done when initializing the canvas.
  114. # The solution is somewhere in the numpy docs.
  115. for i in range(self.x_shape):
  116. for j in range(self.y_shape):
  117. if canvas[i][j] == 0:
  118. canvas[i][j] = ' '
  119. return canvas
  120.  
  121.  
  122. def command_parser():
  123. # Parses the file in to the format:
  124. # ["COMMAND", [*command_args]]
  125. # BELOW IS HARDCODED EXAMPLE I USED FOR DEBUGGING:
  126. return [
  127. ['DRAW_RECTANGLE',['L',1,1,4,4]],
  128. ['DRAW_RECTANGLE',['R',2,1,4,4]],
  129. ['PRINT_CANVAS',[]],
  130. ['ERASE_AREA',[3,2,3,3]],
  131. ['PRINT_CANVAS',[]],
  132. ['DRAW_RECTANGLE',['#',1,3,8,4]],
  133. ['DRAG_AND_DROP',[2,2,6,2]],
  134. ['PRINT_CANVAS',[]],
  135. ['BRING_TO_FRONT',[1,2]],
  136. ['BRING_TO_FRONT',[6,2]],
  137. ['PRINT_CANVAS',[]],
  138. ['DRAG_AND_DROP',[3,3,3,2]],
  139. ['PRINT_CANVAS',[]],
  140. ]
  141.  
  142.  
  143. def main():
  144. # Parse the command list
  145. command_list = command_parser()
  146. # create an empty image
  147. image = Image(10, 6)
  148.  
  149. # For each command apply it to the command list
  150. for command, command_args in command_list:
  151. if command == 'DRAW_RECTANGLE':
  152. image.draw_rectangle(*command_args)
  153. elif command == 'ERASE_AREA':
  154. image.erase_area(*command_args)
  155. elif command == 'DRAG_AND_DROP':
  156. image.drag_and_drop(*command_args)
  157. elif command == 'BRING_TO_FRONT':
  158. image.bring_to_front(*command_args)
  159. elif command == 'PRINT_CANVAS':
  160. pprint.pprint(image.print_canvas())
  161.  
  162.  
  163. if __name__ == '__main__':
  164. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement