Не получается нарисовать куб
Я использую tkinter только чтобы отрисовать куб, в этом проблем нету. Поэтому tkinter к вопросу вообще не относится. Программа косячит в вычислениях... Вот:
from math import atan;
def XYZtoXY(x, y, z, camera_x, camera_y, camera_z, fov, width, height):
pitch = atan((x - camera_x) // (y - camera_y));
yaw = atan((z - camera_z) // (y - camera_y));
x = round(width // 2 + (pitch * (width // fov)));
y = round(height // 2 + (yaw * (height // fov)));
return (x, y);
__position__ = (0, 0, 0);
__fov__ = 1;
def camera(x=0, y=0, z=0, fov=180):
global __position__, __fov__;
__position__ = (x, y, z);
__fov__ = fov;
def cube(canvas, x, y, z, width, height, length):
coords = [];
coords.append((x - width // 2, y + height // 2, z - length // 2));
coords.append((x + width // 2, y + height // 2, z - length // 2));
coords.append((x - width // 2, y - height // 2, z - length // 2));
coords.append((z + width // 2, y - height // 2, z - length // 2));
coords2D = map(lambda xyz: XYZtoXY(*xyz, *__position__, __fov__, canvas.winfo_width(), canvas.winfo_height()), coords);
canvas.create_polygon(*coords2D);
import tkinter as tk;
root = tk.Tk();
canv = tk.Canvas(bg='white');
canv.pack(expand=True, fill=tk.BOTH);
camera(1, 1, 1, 1);
cube(canv, 50, 50, 50, 100, 100, 100);
root.mainloop();
Ответы (1 шт):
У вас функция cube вызывается до фактического создания окна, поэтому canvas возвращает размеры 1 x 1 пиксель. Можно добавить задержку:
root.after(50, lambda: cube(canv, 50, 50, 50, 100, 100, 100))
Или добавить вызов root.update() до вызова функции cube.
Если что-то "косячит", нужно проверять входные-выходные данные функций, например с помощью отладочного вывода. Пример:
def XYZtoXY(x, y, z, camera_x, camera_y, camera_z, fov, width, height):
print(x, y, z, camera_x, camera_y, camera_z, fov, width, height)
...
return (x, y);
__position__ = (0, 0, 0);
__fov__ = 1;
def camera(x=0, y=0, z=0, fov=180):
global __position__, __fov__;
__position__ = (x, y, z);
__fov__ = fov;
def cube(canvas, x, y, z, width, height, length):
print(x, y, z, width, height, length)
coords = [];
...
print(coords)
coords2D = ...;
coords2D = list(coords2D)
print(coords2D)
canvas.create_polygon(*coords2D);
При запуске программа дает такой вывод:
50 50 50 100 100 100
[(0, 100, 0), (100, 100, 0), (0, 0, 0), (100, 0, 0)]
0 100 0 1 1 1 1 1 1
100 100 0 1 1 1 1 1 1
0 0 0 1 1 1 1 1 1
100 0 0 1 1 1 1 1 1
[(-1, -1), (1, -1), (1, 1), (-2, 1)]
Тут видно, что в XYZtoXY размеры холста приходят 1 x 1 пиксель (последние две единицы в строках типа 0 100 0 1 1 1 1 1 1). Если добавить задержку, размеры приходят уже более реалистичные:
50 50 50 100 100 100
[(0, 100, 0), (100, 100, 0), (0, 0, 0), (100, 0, 0)]
0 100 0 1 1 1 1 380 267
100 100 0 1 1 1 1 380 267
0 0 0 1 1 1 1 380 267
100 0 0 1 1 1 1 380 267
[(-108, -77), (488, -77), (488, 343), (-403, 343)]