Advertisement
jgtrosh

drawcube.py

Sep 8th, 2012
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.91 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import sys, math
  4. from time import sleep
  5. import os
  6. linux = "linux" in os.sys.platform
  7. if not linux:
  8.     l = [[" "]]
  9.     l_len_y = len(l)
  10.     l_len_x = len(l[0])
  11.  
  12. class point:
  13.     def __init__(self, x, y):
  14.         self.x = x
  15.         self.y = y
  16.  
  17. def out():
  18.     for i in l:
  19.         print(''.join(i))
  20.  
  21. def plot(p, c):
  22.     x = int(p.x); y = int(p.y)
  23.     if linux:
  24.         print("\033[%s;%sH%s%s" % (y, 2*x, c, c))
  25.     else:
  26.         if x < 0 or y < 0: return
  27.         global l_len_y
  28.         global l_len_x
  29.         if y > l_len_y:
  30.             for i in range(l_len_y, y):
  31.                 l.append([" " for n in range(l_len_x)])
  32.             l_len_y = y
  33.         if x > l_len_x:
  34.             for i in range(l_len_y):
  35.                 l[i].extend([" " for n in range(x-l_len_x)])
  36.             l_len_x = x
  37.         l[y-1][x-1] = c
  38.  
  39. def draw_line(p0, p1, c):
  40.     x0 = p0.x; y0 = p0.y
  41.     x1 = p1.x; y1 = p1.y
  42.     del p0, p1
  43.     if x0 < 0 or x1 < 0 or y0 < 0 or y1 < 0:
  44.         print("negative coordinate")
  45.         return
  46.     if x1 == x0:
  47.         for y in range(int(y0), int(y1)):
  48.             plot(point(x0, y), c)
  49.         return
  50.     s = float(y1-y0)/(x1-x0)
  51.     if s < -1 or s > 1:
  52.         if y0 > y1:
  53.             x0, x1 = x1, x0
  54.             y0, y1 = y1, y0
  55.         s = 1/s
  56.         for y in range(int(y0), int(y1)+1):
  57.             x = x0+s*(y-y0)
  58.             plot(point(x, y), c)
  59.     else:
  60.         if x0 > x1:
  61.             x0, x1 = x1, x0
  62.             y0, y1 = y1, y0
  63.         for x in range(int(x0), int(x1+1)):
  64.             y = y0+s*(x-x0)
  65.             plot(point(x, y), c)
  66.     if linux: outchar = "\033[47m \033[0m"
  67.     else: outchar = "*"
  68.     plot(point(x0, y0), outchar)
  69.     plot(point(x1, y1), outchar)
  70.  
  71. class Point3D:
  72.     def __init__(self, x = 0, y = 0, z = 0):
  73.         self.x, self.y, self.z = float(x), float(y), float(z)
  74.  
  75.     def rotateX(self, angle):
  76.         rad = angle * math.pi / 180
  77.         cosa = math.cos(rad)
  78.         sina = math.sin(rad)
  79.         y = self.y * cosa - self.z * sina
  80.         z = self.y * sina + self.z * cosa
  81.         return Point3D(self.x, y, z)
  82.  
  83.     def rotateY(self, angle):
  84.         rad = angle * math.pi / 180
  85.         cosa = math.cos(rad)
  86.         sina = math.sin(rad)
  87.         z = self.z * cosa - self.x * sina
  88.         x = self.z * sina + self.x * cosa
  89.         return Point3D(x, self.y, z)
  90.  
  91.     def rotateZ(self, angle):
  92.         rad = angle * math.pi / 180
  93.         cosa = math.cos(rad)
  94.         sina = math.sin(rad)
  95.         x = self.x * cosa - self.y * sina
  96.         y = self.x * sina + self.y * cosa
  97.         return Point3D(x, y, self.z)
  98.  
  99.     def project(self, win_width, win_height, fov, viewer_distance):
  100.         factor = fov / (viewer_distance + self.z)
  101.         x = self.x * factor + win_width / 2
  102.         y = -self.y * factor + win_height / 2
  103.         return Point3D(x, y, 1)
  104.  
  105. class Simulation:
  106.     def __init__(self):
  107.         self.vertices = [
  108.             [-1, 1,-1], [ 1, 1,-1], [ 1,-1,-1], [-1,-1,-1],
  109.             [-1, 1, 1], [ 1, 1, 1], [ 1,-1, 1], [-1,-1, 1]
  110.         ]
  111.         for n, i in enumerate(self.vertices):
  112.             self.vertices[n] = Point3D(i[0], i[1], i[2])
  113.         self.bones = [
  114.             [1, 5], [4, 5], [5, 6], [0, 1],
  115.             [1, 2], [2, 3], [3, 0], [6, 7],
  116.             [7, 4], [0, 4], [2, 6], [3, 7]
  117.         ]
  118.         self.triangles = [
  119.             [4, 5, 6], [4, 6, 7], [0, 1, 2], [0, 2, 3]
  120.         ]
  121.         self.angleX, self.angleY, self.angleZ = 0, 0, 0
  122.     def run(self):
  123.         from operator import itemgetter
  124.         while 1:
  125.             sleep(0.1)
  126.             if linux:
  127.                 os.system("clear")
  128.             else:
  129.                 global l
  130.                 for na, a in enumerate(l):
  131.                     for nb, b in enumerate(l[na]):
  132.                         l[na][nb] = " "
  133.             if linux: sx = 45;      sy = 50
  134.             else:     sx = l_len_x; sy = l_len_y
  135.             self.plots = []
  136.             self.vd = {}
  137.             for n, v in enumerate(self.vertices):
  138.                 r = v.rotateX(self.angleX).rotateY(self.angleY).rotateZ(self.angleZ)
  139.                 p = r.project(sx, sy, 90, 10)
  140.                 self.plots.append(point(int(p.x)+3, int(p.y)+3))
  141.                 self.vd[n] = math.sqrt(r.x**2+r.y**2+(r.z+10)**2)
  142.             self.vds = [i[0] for i in sorted(self.vd.items(), key=itemgetter(1))][:7]
  143.             for b in self.bones:
  144.                 p0 = self.plots[b[0]]
  145.                 p1 = self.plots[b[1]]
  146.                 if b[0] in self.vds and b[1] in self.vds:
  147.                     if linux: outchar = "*"
  148.                     else: outchar = "."
  149.                     draw_line(p0, p1, outchar)
  150.             self.angleX += 4
  151.             self.angleY += 4
  152.             self.angleZ += 4
  153.             if not linux:
  154.                 os.system("CLS")
  155.                 out()
  156.  
  157.  
  158. Simulation().run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement