A project about my 3D exploring journey
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

80 lines
3.3 KiB

# coding:utf-8
from tkinter import Tk,Canvas
import math,threading,time
class TkCube(object):
def __init__(self):
self.points = [[-1,1,-1], # LeftFrontDown
[1,1,-1], # RFD
[-1,-1,-1], # LBD
[1,-1,-1], # RBD
[-1,1,1], # LFU
[1,1,1], # RFU
[-1,-1,1], # LBU
[1,-1,1]] # RBU
self.pit = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] # point in 2d
self.angle = 0
self.speed = 1 # π/s
self.fps = 60
self.dist = [5,4] # distance between the cube's center and focal point/canvas
self.st = 1/self.fps # sleep time
self.apf = math.pi * self.speed / self.fps # angle per frame
# init canvas
self.tkroot = Tk()
self.cvs = [Canvas(self.tkroot,bg='white',width=800,height=600),Canvas(self.tkroot,bg='white',width=800,height=600)]
self.cvs[0].pack()
self.showingCv = 0
self.hiddenCv = 1
def rotate(self):
self.angle += self.apf
if self.angle > 2*math.pi:
self.angle -= 2*math.pi
radius = math.sqrt(2) # 点旋转的半径
for pair in [[0,4,-math.pi/4],
[1,5,math.pi/4],
[2,6,-math.pi*3/4],
[3,7,math.pi*3/4]]: # rotate in pairs
center = [radius*math.sin(self.angle+pair[2]),radius*math.cos(self.angle+pair[2])]
# x
self.points[pair[0]][0] = center[0]
self.points[pair[1]][0] = center[0]
# y
self.points[pair[0]][1] = center[1]
self.points[pair[1]][1] = center[1]
def draw(self):
# project points into 2D canvas 投影到2D
for pt in range(8):
rate = self.dist[1]/(self.dist[0]+self.points[pt][1])
scale = 200
self.pit[pt][0] = self.points[pt][0]*rate*scale
self.pit[pt][1] = self.points[pt][2]*rate*scale
self.cvs[self.hiddenCv].delete('all')
for dcp,nps in [[1,[0,3,5]], # drawing central point:以1,2,4,7四个点为中心,分别连接相邻的三个点即可绘成正方体
[2,[0,3,6]],
[4,[0,5,6]],
[7,[3,5,6]]]:
for np in nps: # nearby point
self.cvs[self.hiddenCv].create_line(self.pit[dcp][0]+400,self.pit[dcp][1]+300,self.pit[np][0]+400,self.pit[np][1]+300) # 因为坐标原点在左上角,让x和y分别加400和300让画面在窗口中心
# 切换canvas
self.cvs[self.showingCv].pack_forget()
self.cvs[self.hiddenCv].pack()
self.showingCv,self.hiddenCv = self.hiddenCv,self.showingCv
def run(self):
while True:
# self.rotateThread = threading.Thread(target=self.rotate)
# self.rotateThread.run()
# self.drawThread = threading.Thread(target=self.draw)
# self.drawThread.run()
self.rotate()
self.draw()
# print(self.points)
time.sleep(self.st)
def start(self):
self.runThread = threading.Thread(target=self.run)
self.runThread.start()
self.tkroot.mainloop()
if __name__ == '__main__':
tc = TkCube()
tc.start()