# 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 dcp,nps in [[1,[0,2,5]], # drawing central point:以1,2,4,7四个点为中心,分别连接相邻的三个点即可绘成正方体 [2,[1,3,6]], [0,[3]], [4,[0,5,7]], [7,[3,4,6]], [6,[5]]]: 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()