Визуализация черной дыры в Tkinter
Задание: Реализуйте отрисовку стимуляции параллельного пучка фотонов, подходящего вблизи черной дыры и искривляющегося под действием ее гравитации.
Вопрос: Как реализовать притяжение фотонов к черной дыре?(По сути должны изменяться координаты фотонов)
В моей реализации я пытался задавать движение в функции movePhoton класса Photon, однако успеха не достиг.
Мой код:
import tkinter as tk
import math
width = 600
height = 600
root = tk.Tk()
c = tk.Canvas(root, width=width, heigh=height, bg="white")
class BlackHole:
"""Класс черной дыры"""
def __init__(self, c, x1, y1, radius, mass, color="black"):
self.c = c
self.x1 = x1
self.y1 = y1
self.radius = radius
self.mass = mass
self.color = color
self.drawBlackHole()
def drawBlackHole(self):
"""Отрисовка черной дыры"""
self.greyField = c.create_oval(self.x1 - self.radius*4, self.y1 - self.radius*4, self.x1 +
self.radius*4, self.y1 + self.radius*4, fill="grey", outline="grey")
self.whiteFieldOne = c.create_oval(self.x1 - self.radius*2.7, self.y1 - self.radius*2.7, self.x1 +
self.radius*2.7, self.y1 + self.radius*2.7, fill="white", outline="white")
self.orangeField = c.create_oval(self.x1 - self.radius*2, self.y1 - self.radius*2, self.x1 +
self.radius*2, self.y1 + self.radius*2, fill="#f3be62", outline="#f3be62")
self.whiteFieldTwo = c.create_oval(self.x1 - self.radius*1.5, self.y1 - self.radius*1.5, self.x1 +
self.radius*1.5, self.y1 + self.radius*1.5, fill="white", outline="white")
self.blackhole = c.create_oval(self.x1 - self.radius, self.y1 - self.radius, self.x1 +
self.radius, self.y1 + self.radius, fill=self.color)
def setMass(self, new_mass):
self.mass = new_mass
class Photon:
"""Класс фотона"""
def __init__(self, x1, y1, massPh, massHole, x2, y2, radiusHole, radius=2):
"""
x1, y1 - координаты фотона
radius - радиус фотона
massPh - масса фотона
massHole - масса черной дыры
distance - расстояние между фотоном и черной дырой
x2, y2 - координаты черной дыры
"""
# Фотон
self.x1 = x1
self.y1 = y1
self.radius = radius
# Дыра
self.x2 = x2
self.y2 = y2
self.radiusHole = radiusHole
self.massPh = massPh
self.massHole = massHole
self.drawPhoton()
def drawPhoton(self):
"""Отрисовка фотона"""
self.photon = c.create_oval(self.x1 - self.radius, self.y1 - self.radius, self.x1 +
self.radius, self.y1 + self.radius, fill="red")
def movePhoton(self):
"""Движение фотона"""
# След фотона
c.create_oval(c.coords(self.photon)[0] + 1, c.coords(self.photon)[1] + 1, c.coords(self.photon)[0] +
1, c.coords(self.photon)[1] + 1, fill="red")
distance = math.sqrt(math.pow((self.x2 - c.coords(self.photon)[0] - self.radius), 2) + math.pow((self.y2 - c.coords(self.photon)[1] + self.radius), 2))
# Притяжение, но не знаю как реализовать
gravity = 0.02*(self.massPh * self.massHole)/ distance
c.move(self.photon, -2, gravity)
root.after(16, self.movePhoton)
def scale_processing(number):
"""Обработка значения ползунка"""
number = int(number)
def main():
root.title("Черная Дыра")
c.pack()
radiusHole = 40
blackhole = BlackHole(c,width/2, height/2, radiusHole, 80)
# Создание фотонов
PhoCount = 4
photon_list = [(Photon(580, 250+i*10, 10, blackhole.mass, blackhole.x1, blackhole.y1, radiusHole)) for i in range(PhoCount)]
for pho in photon_list:
pho.movePhoton()
scale = tk.Scale(
root, from_=0, to=100, resolution=2, command=blackhole.setMass, orient=tk.HORIZONTAL,
)
scale.pack(side=tk.LEFT, padx=5)
root.mainloop()
if __name__ == "__main__":
main()
PS: Знаю, что такое задание было реализована на JavaScript, но данный ЯП не знаю. Поэтому тот код, ничем не поможет.
Чтобы лучше понять какого результата я хочу достигнуть, можете посмотреть результат в видеоролике 2d black hole visualization на ютубе