Живой 3d вид, пов-рэй и ткинтер - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь сделать GUI в python (ткинтер). Я успешно создал приложение так, что у меня есть сцена, отрисованная POV-ray. Я нажимаю кнопку «Переместить влево», и это меняет местоположение камеры в файле .pov, повторно отображает сцену и показывает ее в GUI (то же самое для поворота и увеличения / уменьшения).

Но я бы хотел сделать интерактивным. т. е. использовать мышь, чтобы полностью взаимодействовать со сценой точно так же, как трехмерный график matplotlib, но для визуализации лучей.

Как go решить эту проблему?

Сцены имеют значения местоположения как

Местоположение Img_1 <0,0, -10>

Местоположение Img_2 <0, -10, -10>

Местоположение Img_3 <25,0, -10>

PS

Я не пытаюсь импортировать сюжет matplotlib в моем GUI. Это просто для того, чтобы поделиться тем, что я хочу достичь с моими отрисованными сценами.

[img1] img1 1

[img2] img2 2

[img3] img3 3

1 Ответ

0 голосов
/ 10 января 2020

Вы можете использовать события мыши <Motion> и <Button-1>, (и другие) для запуска функций, которые изменят содержимое в окне.


РЕДАКТИРОВАТЬ: Примеры показывают, как использовать bind() для запуска функций, когда вы используете мышь, и как вычислять diff_x, diff_y для перемещения объектов. Вы должны использовать собственные функции с bind(), которые будут использовать diff_x, diff_y для перемещения камеры POVRay и рендеринга нового изображения. И тогда вам придется заменить изображение на холсте. Но я буду использовать объекты canvas вместо POVRay, чтобы показать, как они могут изменяться при перемещении мыши.


В этом примере при перемещении мыши перемещается прямоугольник, а при нажатии кнопки - его цвет.
Но вы можете запускать функции, которые перемещают, увеличивают или поворачивают визуализированное изображение.

import tkinter as tk

# --- functions ---

def move_item(event):
    canvas.coords(item, event.x-50, event.y-50, event.x+50, event.y+50)

def change_item(event):
    if canvas.itemcget(item, 'fill') == 'red':
        canvas.itemconfig(item, fill='blue')
    else:        
        canvas.itemconfig(item, fill='red')

# --- main ---

root = tk.Tk()

canvas = tk.Canvas(root, width=500, height=300)
canvas.pack()

item = canvas.create_rectangle(0, 0, 100, 100, fill='red')

canvas.bind("<Button-1>", change_item)
canvas.bind("<Motion>", move_item)

root.mainloop()

РЕДАКТИРОВАТЬ: Пример, который использует <B1-Motion>, <Shift-B1-Motion>, <Control-B1-Motion> для перемещения объекты:

  • во всех направлениях (left mouse button),
  • только по горизонтали (Shift + left mouse button)
  • только по вертикали (Control + left mouse button).

Код:

import tkinter as tk

# --- functions ---

def move_item(event):
    global old_x
    global old_y    
    diff_x = event.x - old_x
    diff_y = event.y - old_y
    for item in items:
        canvas.move(item, diff_x, diff_y)
    old_x = event.x
    old_y = event.y

def move_horizontal(event):
    global old_x
    diff_x = event.x - old_x
    for item in items:
        canvas.move(item, diff_x, 0)
    old_x = event.x

def move_vertical(event):
    global old_y
    diff_y = event.y - old_y
    for item in items:
        canvas.move(item, 0, diff_y)
    old_y = event.y

def save_position(event):
    global old_x
    global old_y    
    old_x = event.x
    old_y = event.y

# --- main ---

old_x = 0
old_y = 0
# init
root = tk.Tk()

# create canvas
canvas = tk.Canvas(root, width=500, height=300)
canvas.pack()

# create objects
items = [
    canvas.create_rectangle(100, 100, 130, 130, fill='red'),
    canvas.create_rectangle(200, 100, 230, 130, fill='blue'),
    canvas.create_rectangle(100, 200, 130, 230, fill='yellow'),
]

canvas.bind("<Button-1>", save_position)
canvas.bind("<B1-Motion>", move_item)
canvas.bind("<Shift-B1-Motion>", move_horizontal)
canvas.bind("<Control-B1-Motion>", move_vertical)
# start program
root.mainloop()
...