Визуализация черной дыры в 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 на ютубе


Ответы (0 шт):