Guest User

Untitled

a guest
Jan 22nd, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.14 KB | None | 0 0
  1. import pygame
  2. from math import sin, cos, pi
  3. from numpy import array, dot
  4. from random import randint
  5.  
  6. def random_color():
  7. return (randint(0, 255), randint(0, 255), randint(0, 255))
  8.  
  9. win_size = (800, 600)
  10. screen = pygame.display.set_mode(win_size)
  11. clock = pygame.time.Clock()
  12.  
  13. class Shape:
  14. def __init__(self, shape, size, colors, pos = (0, 0)):
  15. self.shape = shape
  16. self.colors = colors
  17. self.pos = pos
  18. self.rotated = [0, 0, 0]
  19. half = 'int' in str(type(size)) and [size / 2.0] * 3 or [size[0] / 2.0, size[1] / 2.0, size[2] / 2.0]
  20. vertices = {
  21. 'cube': [
  22. (-half[0], -half[1], -half[2], 0),
  23. (-half[0], half[1], -half[2], 0),
  24. (half[0], half[1], -half[2], 0),
  25. (half[0], -half[1], -half[2], 0),
  26. (-half[0], -half[1], half[2], 0),
  27. (-half[0], half[1], half[2], 0),
  28. (half[0], half[1], half[2], 0),
  29. (half[0], -half[1], half[2], 0)],
  30. 'pyramid': [
  31. (0, -half[1], half[2], 0),
  32. (-half[0], half[1], half[2], 0),
  33. (half[0], half[1], half[2], 0),
  34. (0, 0, -half[2], 0)],
  35. 'diamond': [
  36. (0, 0, half[2] * 3, 0),
  37. (-half[0], -half[1], half[2], 0),
  38. (-half[0], half[1], half[2], 0),
  39. (half[0], half[1], half[2], 0),
  40. (half[0], -half[1], half[2], 0),
  41. (0, 0, -half[2], 0)]}
  42. self.vertices = vertices[shape]
  43.  
  44. def rotate(self, axis, angle):
  45. radians = angle * pi / 180
  46. rotation = [
  47. array([1, 0, 0, 0, 0, cos(radians), -sin(radians), 0, 0, sin(radians), cos(radians), 0, 0, 0, 0, 1]).reshape(4, 4),
  48. array([cos(radians), 0, sin(radians), 0, 0, 1, 0, 0, -sin(radians), 0, cos(radians), 0, 0, 0, 0, 1]).reshape(4, 4),
  49. array([cos(radians), -sin(radians), 0, 0, sin(radians), cos(radians), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]).reshape(4, 4)]
  50. for i in range(len(self.vertices)):
  51. self.vertices[i] = list(dot(list(self.vertices[i]), rotation[axis]))
  52. self.rotated[axis] = (self.rotated[axis] + angle) % 360
  53. return self
  54.  
  55. def draw(self, surface = screen, fov = 256, distance = 300):
  56. faces = {
  57. 'cube': [(0,1,2,3), (4,5,6,7), (0,3,7,4), (1,2,6,5), (0,4,5,1), (3,7,6,2)],
  58. 'pyramid': [(0,1,2), (0,1,3), (0,2,3), (1,2,3)],
  59. 'diamond': [(5,1,2), (5,2,3), (5,3,4), (5,1,4), (0,1,2), (0,2,3), (0,3,4), (0,1,4)]}
  60. self.faces = faces[self.shape]
  61. z_index = {}
  62. for i in range(len(self.faces)):
  63. z_index[i] = 0
  64. for j in range(len(self.faces[i])):
  65. z_index[i] += self.vertices[self.faces[i][j]][2]
  66. z_index[i] /= len(self.faces)
  67. z_index = sorted(z_index, key = z_index.get, reverse = True)
  68. projected = []
  69. for v in self.vertices:
  70. factor = fov / (distance + float(v[2]))
  71. projected.append((v[0] * factor + self.pos[0], v[1] * factor + self.pos[1]))
  72. for f in z_index:
  73. points = tuple([projected[e] for e in self.faces[f]])
  74. pygame.draw.polygon(surface, self.colors[f], points)
  75.  
  76. opts = ['cube', 'pyramid', 'diamond']
  77. shapes = []
  78.  
  79. for i in range(40):
  80. rand_colors = [random_color() for e in range(8)]
  81. shapes.append(Shape(opts[randint(0, 2)], [randint(20, 80) for e in range(3)], rand_colors, (randint(0, win_size[0] * .9), randint(0, win_size[1] * .9))))
  82.  
  83. done = False
  84. keys_down = {}
  85.  
  86. step = 10
  87. rotate_keys = {273: (0, step), 274: (0, -step), 275: (1, step), 276: (1, -step), 122: (2, step), 120: (2, -step)}
  88.  
  89. while not done:
  90. for event in pygame.event.get():
  91. if event.type == pygame.QUIT:
  92. done = True
  93. if event.type == pygame.KEYDOWN:
  94. keys_down[event.key] = True
  95. if event.type == pygame.KEYUP:
  96. del(keys_down[event.key])
  97. for i in keys_down:
  98. if i in rotate_keys:
  99. for s in shapes:
  100. s.rotate(rotate_keys[i][0], rotate_keys[i][1])
  101. screen.fill((0, 0, 0))
  102. for s in shapes:
  103. s.draw()
  104. pygame.display.update()
  105. clock.tick(600)
Add Comment
Please, Sign In to add comment