Last active
August 29, 2015 14:15
-
-
Save juliusmh/5e48b05fd447e8202b3d to your computer and use it in GitHub Desktop.
Python Projections, printet in Tkinter Canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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