提交 6308694f 编写于 作者: 小康2022's avatar 小康2022 👍

version 0.4

上级 2d60d163
from math import atan, cos, hypot, pi, sin,sqrt
import numpy as np
from math import atan, cos, pi, sin
def arctan(n1: float, n2: float) -> float:
......@@ -11,6 +10,15 @@ def arctan(n1: float, n2: float) -> float:
return -pi/2
def dot(m1: list[list[float]], m2: list[float, float, float]) -> list[float]:
""" 矩阵相乘 """
out = [0] * 3
for i in range(3):
for j in range(3):
out[i] += m1[i][j]*m2[j]
return out
class Point:
""" 点 """
......@@ -18,79 +26,50 @@ class Point:
self.x = x
self.y = y
self.z = z
self.α = 0
self.β = 0
self.γ = 0
self.dis = 0
self.update(True)
def translate(self, dx: float, dy: float, dz: float) -> None:
""" 三维平移 """
self.x += dx
self.y += dy
self.z += dz
self.update(True)
def rotate(self, : float, : float, : float) -> None:
""" 三维旋转 """
self.α +=
self.β +=
self.γ +=
self.update(False)
def update(self, flag: bool) -> None:
""" 更新数据 """
if flag:
self.α = arctan(self.z, self.y)
self.β = arctan(self.x, self.z)
self.γ = arctan(self.y, self.x)
self.dis = hypot(self.x, self.y, self.z)
else:
self.x = self.dis * sqrt(1 / (1/cos(self.γ)**2 + 1/sin(self.β)**2 - 1))
self.y = self.dis * sqrt(1 / (1/cos(self.α)**2 + 1/sin(self.γ)**2 - 1))
self.z = self.dis * sqrt(1 / (1/cos(self.β)**2 + 1/sin(self.α)**2 - 1))
if cos(self.γ) < 0 or sin(self.β) < 0:
self.x = -self.x
if cos(self.α) < 0 or sin(self.γ) < 0:
self.y = -self.y
if cos(self.β) < 0 or sin(self.α) < 0:
self.z = -self.z
# self.x = self.dis * sin(self.β) * cos(self.γ)
# self.y = self.dis * sin(self.γ) * cos(self.α)
# self.z = self.dis * sin(self.α) * cos(self.β)
# k = (self.dis / hypot(self.x, self.y, self.z))
# self.x *= k
# self.y *= k
# self.z *= k
sa, sb, sc = sin(), sin(), sin()
ca, cb, cc = cos(), cos(), cos()
M = [[cc*cb, cc*sb*sa-sc*ca, cc*sb*ca+sc*sa],
[sc*cb, sc*sb*sa+cc*ca, sc*sb*ca-cc*sa],
[-sb, cb*sa, cb*ca]]
self.x, self.y, self.z = dot(M, [self.x, self.y, self.z])
def project(self, dis: float) -> tuple[float, float]:
""" 返回二维坐标 """
k = dis / (dis - self.x)
k = dis / (dis - self.x / 3)
return self.y*k, self.z*k
def print(self) -> None:
""" 打印结果 """
print('distance:', self.dis)
print('x:', self.x, 'y:', self.y, 'z:', self.z)
print('α:', self.α/pi*180, 'β:', self.β/pi*180, 'γ:', self.γ/pi*180)
class BaseSide:
""" 面 """
class Cube:
""" 正方体 """
def __init__(self, x: float, y: float, z: float, r: float) -> None:
k = r, -r
self.points = [Point(x+a, y+b, z+c) for a in k for b in k for c in k]
def __init__(self, *args: tuple[float, float, float]) -> None:
self.points = [Point(x, y, z) for x, y, z in args]
self.update_xs()
def translate(self, dx: float, dy: float, dz: float) -> None:
""" 三维平移 """
for point in self.points:
point.translate(dx, dy, dz)
self.update_xs()
def rotate(self, dx: float, dy: float, dz: float) -> None:
""" 三维旋转 """
for point in self.points:
point.rotate(dx, dy, dz)
self.update_xs()
def update_xs(self) -> None:
""" 更新self.xs """
self.xs = [point.x for point in self.points]
def project(self, dis: float) -> tuple[tuple[float, float]]:
""" 二维投影 """
......
icon.ico

73.4 KB

import tkintertools as tkt
from cube import Cube
from cube import BaseSide
__version__ = '0.3'
__version__ = '0.4'
__author__ = '小康2022'
__update__ = '2023/02/09'
COLOR = 'red', 'yellow', 'blue', 'green', 'orange', 'purple'
class Side(BaseSide):
""" 面 """
class Block(Cube):
""" 方块 """
def __init__(self, canvas: tkt.tkinter.Canvas, color: str, *args: tuple[float, float, float]) -> None:
self.canvas = canvas
BaseSide.__init__(self, *args)
p = [i+350 for p in self.project(300) for i in p]
self.polygon = canvas.create_polygon(*p, fill=color)
def update(self) -> None:
""" 更新图像 """
BaseSide.update_xs(self)
p = [i+350 for p in self.project(300) for i in p]
self.canvas.coords(self.polygon, *p)
class Cube:
""" 正方体 """
def __init__(self, x: float, y: float, z: float, r: float, canvas: tkt.Canvas) -> None:
Cube.__init__(self, x, y, z, r)
self.canvas = canvas
p = [(p[0]+350, p[1]+350) for p in self.project(300)]
self.oval = [
canvas.create_polygon(*p[4], *p[5], *p[7], *p[6], fill=COLOR[0]),
canvas.create_polygon(*p[2], *p[3], *p[7], *p[6], fill=COLOR[1]),
canvas.create_polygon(*p[1], *p[3], *p[7], *p[5], fill=COLOR[2]),
canvas.create_polygon(*p[0], *p[1], *p[5], *p[4], fill=COLOR[3]),
canvas.create_polygon(*p[0], *p[4], *p[6], *p[2], fill=COLOR[4]),
canvas.create_polygon(*p[0], *p[1], *p[3], *p[2], fill=COLOR[5])
]
k = r, -r
p = [(x+a, y+b, z+c) for a in k for b in k for c in k]
self.sides = [
Side(canvas, 'red', p[4], p[5], p[7], p[6]),
Side(canvas, 'yellow', p[2], p[3], p[7], p[6]),
Side(canvas, 'blue', p[1], p[3], p[7], p[5]),
Side(canvas, 'green', p[0], p[1], p[5], p[4]),
Side(canvas, 'orange', p[0], p[4], p[6], p[2]),
Side(canvas, 'purple', p[0], p[1], p[3], p[2])]
def rotate(self, dx: float, dy: float, dz: float) -> None:
""" 旋转 """
for side in self.sides:
side.rotate(dx, dy, dz)
def translate(self, dx: float, dy: float, dz: float) -> None:
""" 平移 """
for side in self.sides:
side.translate(dx, dy, dz)
def update(self) -> None:
""" 更新图像 """
p = [(p[0]+350, p[1]+350) for p in self.project(300)]
# self.canvas.coords(self.oval[0], *p[4], *p[5], *p[7], *p[6]) # 背面
# self.canvas.coords(self.oval[1], *p[2], *p[3], *p[7], *p[6]) # 左侧
# self.canvas.coords(self.oval[2], *p[1], *p[3], *p[7], *p[5]) # 下面
# self.canvas.coords(self.oval[3], *p[0], *p[1], *p[5], *p[4]) # 右侧
# self.canvas.coords(self.oval[4], *p[0], *p[4], *p[6], *p[2]) # 上面
self.canvas.coords(self.oval[5], *p[0], *p[1], *p[3], *p[2]) # 正面
""" 更新立方体 """
for side in self.sides:
side.update()
self.lift()
def lift(self) -> None:
""" 前后关系 """
for side in sorted(self.sides, key=lambda s: min(s.xs)):
self.canvas.lift(side.polygon)
class Window:
""" 窗口界面 """
root = tkt.Tk('魔方', 700, 700)
root.iconbitmap('icon.ico')
canvas = tkt.Canvas(root, 700, 700)
canvas.place(x=0, y=0)
def __init__(self) -> None:
self.b = Block(0, 0, 0, 100, self.canvas)
self.timer()
self.event = [None, None]
self.root.bind('<B1-Motion>', self.rotate)
self.root.bind('<Button-1>', self.record)
self.b = Cube(0, 0, 0, 100, self.canvas)
self.root.mainloop()
def timer(self, ind: int = 0) -> None:
""" 计时器 """
self.b.rotate(0.01, 0, 0)
# self.b.translate(0, 0.1, 0)
def record(self, event: tkt.tkinter.Event) -> None:
""" 记录位置 """
self.event = [event.x, event.y]
def rotate(self, event: tkt.tkinter.Event) -> None:
""" 转动魔方 """
k = 100
x, y = event.x, event.y
r_x, r_y = self.event[0]-x, self.event[1]-y
self.b.rotate(0, r_y/k, -r_x/k)
self.b.update()
self.root.after(30, self.timer, ind+1)
self.event = [x, y]
Window()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册