Skip to content

Instantly share code, notes, and snippets.

@juliusmh
Last active August 29, 2015 14:15
Show Gist options
  • Save juliusmh/5e48b05fd447e8202b3d to your computer and use it in GitHub Desktop.
Save juliusmh/5e48b05fd447e8202b3d to your computer and use it in GitHub Desktop.
Python Projections, printet in Tkinter Canvas
#PROJECTOR VERSION 2 USING MATPLOTLIB (AKA PYPLOT)
#BY JULIUS HINZE
from math import *
from time import *
from tkinter import *
#UPDATER
master = Tk()
master.title("3D Plotter")
size = [600,600]
label = Label(master, fg="black")
label.pack()
w = Canvas(master, width=size[0], height=size[1] - 20)
w.pack()
button = Button(master, text='Stop', width=100, height=3, command=master.destroy)
button.pack()
class Vector3:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
#Constructor for 2D point or Vector
class Vector2:
def __init__(self, x, y):
self.x = x
self.y = y
#Constructor for SHape
class Face:
def __init__(self, points,color):
self.points = points
self.color = color
#Object Holder for any MESH
class mesh:
pa = ""
ml = []
midpoint = Vector3(0,0,0)
faces = []
points = []
ax = 0
ay = 0
az = 0
def __init__(self, path, mlist , rotation): #READ THE FILE
self.pa = path
self.ml = mlist
self.ax = rotation[0]
self.ay = rotation[1]
self.az = rotation[2]
with open(path) as f:
content = f.readlines()
#IMPORT THE LIST TO REPLACE STH , GET THE KEYS
l = list(mlist)
for r in range(0,len(l)):
print (l[r] + "->" + str(mlist[l[r]]))
#LOOP THROUHG THE LINES
for i in range(0, len(content)):
color = [0,0,0]
color[0] = 255 * (i /len(content))
color[1] = 255 * (i /len(content))
color[2] = 255 * (i /len(content))
tmp = content[i]
#SPLIT THE FILE BY BRCKETS
a = tmp.split('[')
tmppoints = []
#NOW loop THROUGH EVERY "a"
for f in range(0, len(a)):
b = a[f].split(']')
c = b[0].split(',') #THIS IS OUR POINT TRIPLET
if ((len(c)) == 3): #3D - POINT == TRUE
#REPLACE ALL KNOWN VALUES
for r in range(0,len(l)):
c[0] = c[0].replace(str(l[r]), str(mlist[l[r]]))
c[1] = c[1].replace(str(l[r]), str(mlist[l[r]]))
c[2] = c[2].replace(str(l[r]), str(mlist[l[r]]))
#DATA HOLDER FOR CoORDINATES
x = 0
y = 0
z = 0
#PARSE INPUT
#print (c[0] + " -> " + str(eval(c[0])))
x = eval(c[0])
#print (c[1] + " -> " + str(eval(c[1])))
y = eval(c[1])
#print (c[2] + " -> " + str(eval(c[2])))
z = eval(c[2])
#NUMPY ARRAY
p = Vector3(x,y,z)
tmppoints.append(p)
self.points.append(p)
#ADD THE fACE TO THE FACES list
#ROTAtE poINTS
self.faces.append(Face(tmppoints, color))
self.midpoint = calcmiddle(self.points)
for i in range(0, len(self.faces)):
self.faces[i].points = rotatepoints(self.midpoint, self.faces[i].points,self.ax,self.ay,self.az)
def rotate(self,rotation):
self.ax = rotation[0]
self.ay = rotation[1]
self.az = rotation[2]
for i in range(0, len(self.faces)):
self.faces[i].points = rotatepoints(self.midpoint, self.faces[i].points,self.ax,self.ay,self.az)
def draw(self):
drawmesh(self)
#FUNCTION
def importmesh(path, args, r):
f = mesh(path, args , r)
return f
def drawmesh(mesh ):
for i in range(0, len(mesh.faces)):
det = determinant(v3tov2(v3minusv3(mesh.faces[i].points[2] , mesh.faces[i].points[1])) , v3tov2(v3minusv3(mesh.faces[i].points[0] , mesh.faces[i].points[1])))
if (det > 0):
plot(mesh.faces[i] , 'black')
def rotatex(v,alpha):
r = Vector3(0,0,0)
r.x = v.x * 1 + v.y * 0 + v.z * 0
r.y = v.x * 0 + v.y * cos(alpha) + v.z * sin(alpha)
r.z = v.x * 0 + v.y * -sin(alpha) + v.z * cos(alpha)
return r
def rotatey(v,alpha):
r = Vector3(0,0,0)
r.x = v.x * cos(alpha) + v.y * 0 + v.z * sin(alpha)
r.y = v.x * 0 + v.y * 1 + v.z * 0
r.z = v.x * - sin(alpha) + v.y * 0 + v.z * cos(alpha)
return r
def v3minusv3(a,b):
v = Vector3(0,0,0)
v.x = a.x - b.x
v.y = a.y - b.y
v.z = a.z - b.z
return v
def v3tov2(a):
#PROJECTON MATRIX DEFINITION
proj = [[0 for x in range(2)] for x in range(3)]
# ^ >
proj[0][0] = -0.5
proj[0][1] = -0.25
proj[1][0] = 1
proj[1][1] = 0
proj[2][0] = 0
proj[2][1] = 1
#CALCULUS
v = Vector2(0,0) #OUR RESULT Vector2() (!)
v.x = proj[0][0] * a.x + proj[1][0] * a.y + proj[2][0] * a.z
v.y = proj[0][1] * a.x + proj[1][1] * a.y + proj[2][1] * a.z
return v
def determinant(a,b):
v = Vector2(0,0)
calculus = (a.x * b.y) - (a.y * b.x)
return calculus
def v3plusv3(v1,v2):
r = Vector3(0,0,0)
r.x = v1.x + v2.x
r.y = v1.y + v2.y
r.z = v1.z + v2.z
return r
def calcmiddle(pointlist):
v = Vector3(0,0,0)
sum = [0,0,0]
for i in range(0, len(pointlist)):
sum[0] = sum[0] + pointlist[i].x
sum[1] = sum[1] + pointlist[i].y
sum[2] = sum[2] + pointlist[i].z
v.x = sum[0] / len(pointlist)
v.y = sum[1] / len(pointlist)
v.z = sum[2] / len(pointlist)
return v
def drawline(a,b):
w.create_line(a.x + size[0] / 2, a.y + size[0] / 2, b.x + size[0] / 2, b.y + size[0] / 2)
def simplecorss(v3):
up()
goto(v3tov2(v3).x , v3tov2(v3).y)
down()
goto(v3tov2(v3).x + 10 , v3tov2(v3).y + 0)
up()
goto(v3tov2(v3).x + 5 , v3tov2(v3).y + 5)
down()
goto(v3tov2(v3).x + 5 , v3tov2(v3).y - 5)
up()
def plot(face , c):
#color(c , face.color)
#begin_fill()
#up()
list = []
for i in range(0,len(face.points) ):
list.append(v3tov2(face.points[i]))
if (i >0):
drawline(list[i-1], list[i])
#end_fill()
def turtlehide():
up()
goto(1000,1000)
def rotatepoints(midpoint, points,ax,ay,az):
for i in range(0,len(points)):
points[i] = v3minusv3(points[i] , midpoint) #SHIFT POINT TO ORIGIN
#APPLYING MATRIXES TO ROTATE THE FORM
points[i] = rotatex(points[i] , ax )
points[i] = rotatey(points[i] , ay )
#points[i] = rotatez(points[i] , az )
points[i] = v3plusv3(points[i] , midpoint) #SHIFT POINT BACK FROM ORIGIN
return points
def rotatepoint(point,ax,ay,az):
midpoint = calcmiddle(points) #CALC THE GEOMETRIC MIDDLE OF THE POINT LIST
point = v3minusv3(point , midpoint) #SHIFT POINT TO ORIGIN
#APPLYING MATRIXES TO ROTATE THE FORM
point = rotatex(point, ax )
point = rotatey(point, ay )
#points[i] = rotatez(points[i] , az )
point = v3plusv3(point , midpoint) #SHIFT POINT BACK FROM ORIGIN
return point
#CODE STARTS HERE
rotation = [0,0,0]
mesh = importmesh("C:/Users/j.hinze/Desktop/projector_v2/icosa.txt", {'a' : 200} , rotation)
#VARIABLES FOR FRAME COUNTER
counter = 0
def counter_label(label):
def count():
global counter
counter += 1
label.config(text= "Frame: " + str(counter))
label.after(20, count)
w.delete("all")
rotation = [0.0 , 0.05 ,0.0]
mesh.rotate(rotation)
mesh.draw()
count()
counter_label(label) #START THE ANIMATION
master.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment