Advertisement
XxDLCENERGYxX

Python Spheres!

Sep 1st, 2016
1,409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.05 KB | None | 0 0
  1. import pygame, sys, os, math
  2.  
  3.  
  4. def rotate2d(pos,rad): x,y=pos; s,c = math.sin(rad),math.cos(rad); return x*c-y*s,y*c+x*s
  5.  
  6.  
  7. class Cam:
  8.     def __init__(self,pos=(0,0,0),rot=(0,0)):
  9.         self.pos = list(pos)
  10.         self.rot = list(rot)
  11.  
  12.     def events(self,event):
  13.         if event.type == pygame.MOUSEMOTION:
  14.             x,y = event.rel; x/=200; y/=200
  15.             self.rot[0]+=y; self.rot[1]+=x
  16.  
  17.     def update(self,dt,key):
  18.         s = dt*4
  19.  
  20.         if key[pygame.K_q]: self.pos[1]+=s
  21.         if key[pygame.K_e]: self.pos[1]-=s
  22.  
  23.         x,y = s*math.sin(self.rot[1]),s*math.cos(self.rot[1])
  24.         if key[pygame.K_w]: self.pos[0]+=x; self.pos[2]+=y
  25.         if key[pygame.K_s]: self.pos[0]-=x; self.pos[2]-=y
  26.         if key[pygame.K_a]: self.pos[0]-=y; self.pos[2]+=x
  27.         if key[pygame.K_d]: self.pos[0]+=y; self.pos[2]-=x
  28.  
  29.  
  30.  
  31.  
  32. # ------------------------- Generating Sphere --------------------------- #
  33.  
  34. A,B = 9,18
  35.  
  36. points = [(0,-1,0)]
  37. for zRot in range(A,180,A):
  38.     X,y = rotate2d((0,-1),zRot/180*math.pi)
  39.     for yRot in range(0,360,B):
  40.         z,x = rotate2d((0,X),yRot/180*math.pi)
  41.         points+=[(x,y,z)]
  42. points+=[(0,1,0)]
  43.  
  44. a = len(range(A,180,A)); b = len(range(0,360,B))
  45. n = len(points)-1; n2 = b*(a-1)
  46.  
  47. po = []
  48. for i in range(1,b+1):
  49.     if i==b: po+=[(0,i,1)]
  50.     else: po+=[(0,i,i+1)]
  51. for j in range(0,(a-1)*b,b):
  52.     for i in range(1,b+1):
  53.         if i==b: po+=[(i+j,i+b+j,i+1+j,1+j)]
  54.         else: po+=[(i+j,i+b+j,i+b+1+j,i+1+j)]
  55. for i in range(1,b+1):
  56.     if i==b: po+=[(n,i+n2,1+n2)]
  57.     else: po+=[(n,i+n2,i+1+n2)]
  58.  
  59.  
  60. class Sphere:
  61.     vertices = points
  62.     faces = po
  63.     colors = (255,0,0),(255,255,0),(0,255,255)
  64.  
  65.     def __init__(self,pos=(0,0,0)):
  66.         x,y,z = pos
  67.         self.verts = [(x+X/2,y+Y/2,z+Z/2) for X,Y,Z in self.vertices]
  68.  
  69. # ------------------------- Generated Sphere --------------------------- #
  70.  
  71.  
  72.  
  73.  
  74.  
  75. pygame.init()
  76. w,h = 800,600; cx,cy = w//2,h//2; fov = min(w,h)
  77. os.environ['SDL_VIDEO_CENTERED'] = '1'
  78. pygame.display.set_caption('3D Graphics')
  79. screen = pygame.display.set_mode((w,h))
  80. clock = pygame.time.Clock()
  81. cam = Cam((0,0,0),(math.pi/2,0))
  82. pygame.event.get(); pygame.mouse.get_rel()
  83. pygame.mouse.set_visible(0); pygame.event.set_grab(1)
  84.  
  85. spheres = [Sphere((x,0,z)) for x,z in ((-1,0),(0,0),(1,0))]
  86.  
  87. rot = 0
  88.  
  89. while True:
  90.     dt = clock.tick()/1000
  91.  
  92.     rot+=math.pi*dt*0.5
  93.  
  94.     for event in pygame.event.get():
  95.         if event.type == pygame.QUIT: pygame.quit(); sys.exit()
  96.         if event.type == pygame.KEYDOWN:
  97.             if event.key == pygame.K_ESCAPE: pygame.quit(); sys.exit()
  98.         cam.events(event)
  99.  
  100.     screen.fill((128,128,255))
  101.  
  102.  
  103.     # need to go though all objects, get all faces...
  104.  
  105.     face_list = []; face_color = []; depth = [] # stores all face data
  106.  
  107.     for obj in spheres:
  108.  
  109.         vert_list = []; screen_coords = []
  110.         for x,y,z in obj.verts:
  111.  
  112.             x,z = rotate2d((x,z),rot)
  113.  
  114.             x-=cam.pos[0]; y-=cam.pos[1]; z-=cam.pos[2]
  115.             x,z = rotate2d((x,z),cam.rot[1])
  116.             y,z = rotate2d((y,z),cam.rot[0])
  117.             vert_list += [(x,y,z)]
  118.             f = fov/z if z else fov; x,y = x*f,y*f
  119.             screen_coords+=[(cx+int(x),cy+int(y))]
  120.  
  121.  
  122.         for f in range(len(obj.faces)):
  123.             face = obj.faces[f]
  124.  
  125.             on_screen = False
  126.             for i in face:
  127.                 x,y = screen_coords[i]
  128.                 if vert_list[i][2]>0 and x>0 and x<w and y>0 and y<h: on_screen = True; break
  129.  
  130.             if on_screen:
  131.                 coords = [screen_coords[i] for i in face]
  132.                 face_list += [coords]
  133.                 face_color += [obj.colors[f%3]]
  134.                 depth += [sum(vert_list[i][2] for i in face)/len(face)]
  135.  
  136.  
  137.  
  138.     # final drawing part, all faces from all objects
  139.     order = sorted(range(len(face_list)),key=lambda i:depth[i],reverse=1)
  140.     for i in order:
  141.         try: pygame.draw.polygon(screen,face_color[i],face_list[i])
  142.         except: pass
  143.  
  144.  
  145.  
  146.     pygame.display.flip()
  147.  
  148.  
  149.     key = pygame.key.get_pressed()
  150.     cam.update(dt,key)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement