From f37d791048705348ee76a09457cf47019c7ad70f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:13:21 +0000 Subject: [PATCH 01/13] ftgy --- ark.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 ark.py diff --git a/ark.py b/ark.py new file mode 100644 index 000000000..e75154b7c --- /dev/null +++ b/ark.py @@ -0,0 +1 @@ +print("hello world") \ No newline at end of file From 1fb2fffb9f7e4c4345c0086a043cda54bfb7516d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:13:57 +0000 Subject: [PATCH 02/13] ff --- README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index f1ec59983..000000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Базовый курс (моделирование на python) -Репозиторий для прохождения базового курса по языку программирования python, -в рамках общего цикла лекций "Моделирование на python". From 83711c173cdad06b479ab720a1c20017d6351e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:23:07 +0000 Subject: [PATCH 03/13] dd --- ark.py | 1 - 1 file changed, 1 deletion(-) delete mode 100644 ark.py diff --git a/ark.py b/ark.py deleted file mode 100644 index e75154b7c..000000000 --- a/ark.py +++ /dev/null @@ -1 +0,0 @@ -print("hello world") \ No newline at end of file From 43285f13361872f1333118d50bc52d2ce0400ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Sat, 5 Apr 2025 15:05:20 +0000 Subject: [PATCH 04/13] oioihoih --- rrr.py | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 rrr.py diff --git a/rrr.py b/rrr.py new file mode 100644 index 000000000..a01d628bd --- /dev/null +++ b/rrr.py @@ -0,0 +1,215 @@ +from tkinter import * +import matplotlib.pyplot as plt +import scipy.interpolate as sc +import numpy as np +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # Для встраивания графика в Tkinter + +x = [] +y = [] + +class Paint(Frame): + def __init__(self, parent): + Frame.__init__(self, parent) + self.parent = parent + self.color = "black" + self.brush_size = 1 + self.width = 900 + self.height = 600 + self.setUI() + + def draw(self, event): + self.canv.create_oval(event.x - 2, event.y - 2, event.x + 2, event.y + 2, + fill=self.color, outline=self.color) + + x.append(event.x) + y.append(-event.y) + + def setUI(self): + self.pack(fill=BOTH, expand=1) + self.canv = Canvas(self, bg="white", width=self.width, height=self.height) + self.columnconfigure(0, weight=1) + self.rowconfigure(0, weight=1) + self.canv.grid(padx=1, pady=1, sticky=W+E+N+S) + self.canv.bind("", self.draw) + + # Рисуем сетку + self.draw_grid() + + def draw_grid(self): + """Рисует координатную сетку на Canvas с разметкой.""" + step = 50 # Шаг сетки + width = self.width + height = self.height + + # Вертикальные линии с разметкой + for i in range(0, width+step, step): + self.canv.create_line(i, 0, i, height+step, fill="gray", dash=(1, 5)) + if i != width // 2: # Не рисуем метку для центральной оси Y + self.canv.create_text(i, height - 10, text=str(i - width // 2), fill="black", font=("Arial", 8)) + + # Горизонтальные линии с разметкой + for i in range(0, height+step, step): + self.canv.create_line(0, i, width+step, i, fill="gray", dash=(1, 5)) + if i != height - step: # Не рисуем метку для нижней грани + self.canv.create_text(10, i, text=str(height // 2 - i), fill="black", font=("Arial", 8), anchor=W) + + # Ось X (горизонтальная линия внизу) + self.canv.create_line(0, height//2, width+step, height//2, fill="black", width=2) + + # Ось Y (вертикальная линия по центру) + self.canv.create_line(width // 2, 0, width // 2, height, fill="black", width=2) + + +def calculate_center_of_mass(x, y): + """ + Вычисляет центр масс многоугольника по координатам его вершин. + :param x: Список x-координат вершин. + :param y: Список y-координат вершин. + :return: Координаты центра масс (Cx, Cy). + """ + n = len(x) + A = 0.0 + Cx = 0.0 + Cy = 0.0 + + for i in range(n): + # Циклический индекс + j = (i + 1) % n + # Вычисление детерминанта (удвоенная площадь треугольника) + factor = x[i] * y[j] - x[j] * y[i] + A += factor + Cx += (x[i] + x[j]) * factor + Cy += (y[i] + y[j]) * factor + + A *= 0.5 + Cx /= (6.0 * A) + Cy /= (6.0 * A) + + return Cx, Cy + + +def btn_func(): + # Проверка на наличие данных + if len(x) < 3 or len(y) < 3: + print("Нарисуйте замкнутую фигуру!") + return + + # Закрываем текущее окно рисования + app.destroy() + + # Создаем фигуру matplotlib + fig, ax = plt.subplots(figsize=(9, 6)) + + # Построение нарисованного объекта + x.append(x[0]) # Замыкаем фигуру + y.append(y[0]) + x_arr = np.array(x) + y_arr = np.array(y) + + ax.plot(x_arr, y_arr, label="Original") + + # Аппроксимация нарисованного объекта + step = 1000 + mytck, myu = sc.splprep([x_arr, y_arr], s=0) + xnew, ynew = sc.splev(np.linspace(0, 1, step), mytck) + ax.plot(xnew, ynew, 'red', label="Approximation") + + # Разделение на участки с заданной точностью + acc = 20 + for i in range(0, step, acc): + try: + ax.plot([xnew[i], xnew[i+acc]], [ynew[i], ynew[i+acc]], 'green') + + x_h = (xnew[i] + xnew[i+acc]) / 2 + y_h = (ynew[i] + ynew[i+acc]) / 2 + + # Нормальный вектор (ненормированный) + if xnew[0+acc] < xnew[0]: + x_n = ynew[i+acc] - ynew[i] + y_n = xnew[i] - xnew[i+acc] + else: + x_n = - ynew[i+acc] + ynew[i] + y_n = - xnew[i] + xnew[i+acc] + + # Единичный нормальный вектор + norm = np.sqrt(x_n**2 + y_n**2) + X_n = x_n / norm + Y_n = y_n / norm + + # Конец нормали (отложено от середины) + scale = 20 # Длина нормали + x_end = x_h + scale * X_n + y_end = y_h + scale * Y_n + + # Рисуем нормаль + ax.plot([x_h, x_end], [y_h, y_end], 'black') + except IndexError: + ax.plot([xnew[i], xnew[0]], [ynew[i], ynew[0]], 'green') + + x_h = (xnew[i] + xnew[0]) / 2 + y_h = (ynew[i] + ynew[0]) / 2 + + # Нормальный вектор (ненормированный) + if xnew[0+acc] < xnew[0]: + x_n = ynew[0] - ynew[i] + y_n = xnew[i] - xnew[0] + else: + x_n = - ynew[0] + ynew[i] + y_n = - xnew[i] + xnew[0] + + # Единичный нормальный вектор + norm = np.sqrt(x_n**2 + y_n**2) + X_n = x_n / norm + Y_n = y_n / norm + + # Конец нормали (отложено от середины) + scale = 20 # Длина нормали + x_end = x_h + scale * X_n + y_end = y_h + scale * Y_n + + # Рисуем нормаль + ax.plot([x_h, x_end], [y_h, y_end], 'black') + + # Настройка легенды и заголовка + ax.set_title("Graph with Normals") + + # Вычисляем центр масс + Cx, Cy = calculate_center_of_mass(x, y) + ax.scatter(Cx, Cy, color='blue', label="Center of Mass", zorder=5) + + + # Встраиваем график в Tkinter + canvas = FigureCanvasTkAgg(fig, master=frame1) + canvas.draw() + canvas.get_tk_widget().pack(fill=BOTH, expand=True) + +# Размеры окна +w = 900 +h = 600 + +root = Tk() +w_root = 1200 +h_root = 600 +w_window = root.winfo_screenwidth() // 2 - w_root // 2 +h_window = root.winfo_screenheight() // 2 - h_root // 2 +root.geometry(f"1200x600+{w_window}+{h_window}") +root.title("Рисуйте") +root.resizable(width=False, height=False) + +frame0 = Frame(master=root, width=w, height=h, bg="black") +frame0.pack(fill=BOTH, side=LEFT, expand=True) + +frame1 = Frame(master=frame0, width=w, height=h) +frame1.pack(fill=BOTH, expand=True) + +frame2 = Frame(master=root, width=2, bg="black") +frame2.pack(fill=Y, side=LEFT) + +frame3 = Frame(master=root, width=200, bg="gray") +frame3.pack(fill=BOTH, side=LEFT, expand=True) + +button = Button(master=frame3, text="Сохранить!", command=btn_func) +button.place(x=98, y=500) + +app = Paint(frame1) # Передаем размеры окна +root.mainloop() From ed68c17cf94c8a49d61c6000f0252a12aa2584a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Sat, 5 Apr 2025 15:11:32 +0000 Subject: [PATCH 05/13] ;lm;m --- rrr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rrr.py b/rrr.py index a01d628bd..a2d0e6e11 100644 --- a/rrr.py +++ b/rrr.py @@ -14,7 +14,7 @@ def __init__(self, parent): self.color = "black" self.brush_size = 1 self.width = 900 - self.height = 600 + self.height = 600bbb self.setUI() def draw(self, event): From 1796f78e813dd1ee4d68e5455069088a2ede6360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Sat, 5 Apr 2025 15:11:51 +0000 Subject: [PATCH 06/13] mmk --- rrr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rrr.py b/rrr.py index a2d0e6e11..a01d628bd 100644 --- a/rrr.py +++ b/rrr.py @@ -14,7 +14,7 @@ def __init__(self, parent): self.color = "black" self.brush_size = 1 self.width = 900 - self.height = 600bbb + self.height = 600 self.setUI() def draw(self, event): From af6341f70a6d057770b1757924acfeed80e9dd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Mon, 7 Apr 2025 10:35:59 +0200 Subject: [PATCH 07/13] Update rrr.py --- rrr.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rrr.py b/rrr.py index a01d628bd..131a1ad1f 100644 --- a/rrr.py +++ b/rrr.py @@ -213,3 +213,4 @@ def btn_func(): app = Paint(frame1) # Передаем размеры окна root.mainloop() + From 578eb9394fa992b9776c0881e2215a9b7bf0881f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Sat, 26 Apr 2025 14:21:09 +0000 Subject: [PATCH 08/13] fdfd --- center_mass.py | 26 ++++++++ class_paint.py | 55 +++++++++++++++ const.py | 3 + rrr.py => project.py | 156 +++++++++++++++++++------------------------ 4 files changed, 154 insertions(+), 86 deletions(-) create mode 100644 center_mass.py create mode 100644 class_paint.py create mode 100644 const.py rename rrr.py => project.py (55%) diff --git a/center_mass.py b/center_mass.py new file mode 100644 index 000000000..0dd7e6755 --- /dev/null +++ b/center_mass.py @@ -0,0 +1,26 @@ +def calculate_center_of_mass(x, y): + """ + Вычисляет центр масс многоугольника по координатам его вершин. + :param x: Список x-координат вершин. + :param y: Список y-координат вершин. + :return: Координаты центра масс (Cx, Cy). + """ + n = len(x) + A = 0.0 + Cx = 0.0 + Cy = 0.0 + + for i in range(n): + # Циклический индекс + j = (i + 1) % n + # Вычисление детерминанта (удвоенная площадь треугольника) + factor = x[i] * y[j] - x[j] * y[i] + A += factor + Cx += (x[i] + x[j]) * factor + Cy += (y[i] + y[j]) * factor + + A *= 0.5 + Cx /= (6.0 * A) + Cy /= (6.0 * A) + + return Cx, Cy \ No newline at end of file diff --git a/class_paint.py b/class_paint.py new file mode 100644 index 000000000..e5a0350d2 --- /dev/null +++ b/class_paint.py @@ -0,0 +1,55 @@ +from tkinter import * + +class Paint(Frame): + def __init__(self, parent, x, y): + Frame.__init__(self, parent) + self.parent = parent + self.color = "black" + self.brush_size = 1 + self.width = 900 + self.height = 600 + self.setUI() + self.x = x + self.y = y + + def draw(self, event): + self.canv.create_oval(event.x - 2, event.y - 2, event.x + 2, event.y + 2, + fill=self.color, outline=self.color) + + self.x.append(event.x) + self.y.append(-event.y) + + def setUI(self): + self.pack(fill=BOTH, expand=1) + self.canv = Canvas(self, bg="white", width=self.width, height=self.height) + self.columnconfigure(0, weight=1) + self.rowconfigure(0, weight=1) + self.canv.grid(padx=1, pady=1, sticky=W+E+N+S) + self.canv.bind("", self.draw) + + # Рисуем сетку + self.draw_grid() + + def draw_grid(self): + """Рисует координатную сетку на Canvas с разметкой.""" + step = 50 # Шаг сетки + width = self.width + height = self.height + + # Вертикальные линии с разметкой + for i in range(0, width+step, step): + self.canv.create_line(i, 0, i, height+step, fill="gray", dash=(1, 5)) + if i != width // 2: # Не рисуем метку для центральной оси Y + self.canv.create_text(i, height - 10, text=str(i - width // 2), fill="black", font=("Arial", 8)) + + # Горизонтальные линии с разметкой + for i in range(0, height+step, step): + self.canv.create_line(0, i, width+step, i, fill="gray", dash=(1, 5)) + if i != height - step: # Не рисуем метку для нижней грани + self.canv.create_text(10, i, text=str(height // 2 - i), fill="black", font=("Arial", 8), anchor=W) + + # Ось X (горизонтальная линия внизу) + self.canv.create_line(0, height//2, width+step, height//2, fill="black", width=2) + + # Ось Y (вертикальная линия по центру) + self.canv.create_line(width // 2, 0, width // 2, height, fill="black", width=2) diff --git a/const.py b/const.py new file mode 100644 index 000000000..065767d11 --- /dev/null +++ b/const.py @@ -0,0 +1,3 @@ +b = 0.0029 # м*К +c = 2.998 * 10**8 # м/с +h = 6.626 * 10**(-34) \ No newline at end of file diff --git a/rrr.py b/project.py similarity index 55% rename from rrr.py rename to project.py index 131a1ad1f..f52a2e8d8 100644 --- a/rrr.py +++ b/project.py @@ -4,94 +4,27 @@ import numpy as np from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # Для встраивания графика в Tkinter +from const import * +from class_paint import Paint +from center_mass import calculate_center_of_mass + x = [] y = [] -class Paint(Frame): - def __init__(self, parent): - Frame.__init__(self, parent) - self.parent = parent - self.color = "black" - self.brush_size = 1 - self.width = 900 - self.height = 600 - self.setUI() - - def draw(self, event): - self.canv.create_oval(event.x - 2, event.y - 2, event.x + 2, event.y + 2, - fill=self.color, outline=self.color) - - x.append(event.x) - y.append(-event.y) - - def setUI(self): - self.pack(fill=BOTH, expand=1) - self.canv = Canvas(self, bg="white", width=self.width, height=self.height) - self.columnconfigure(0, weight=1) - self.rowconfigure(0, weight=1) - self.canv.grid(padx=1, pady=1, sticky=W+E+N+S) - self.canv.bind("", self.draw) - - # Рисуем сетку - self.draw_grid() - - def draw_grid(self): - """Рисует координатную сетку на Canvas с разметкой.""" - step = 50 # Шаг сетки - width = self.width - height = self.height - - # Вертикальные линии с разметкой - for i in range(0, width+step, step): - self.canv.create_line(i, 0, i, height+step, fill="gray", dash=(1, 5)) - if i != width // 2: # Не рисуем метку для центральной оси Y - self.canv.create_text(i, height - 10, text=str(i - width // 2), fill="black", font=("Arial", 8)) - - # Горизонтальные линии с разметкой - for i in range(0, height+step, step): - self.canv.create_line(0, i, width+step, i, fill="gray", dash=(1, 5)) - if i != height - step: # Не рисуем метку для нижней грани - self.canv.create_text(10, i, text=str(height // 2 - i), fill="black", font=("Arial", 8), anchor=W) - - # Ось X (горизонтальная линия внизу) - self.canv.create_line(0, height//2, width+step, height//2, fill="black", width=2) - - # Ось Y (вертикальная линия по центру) - self.canv.create_line(width // 2, 0, width // 2, height, fill="black", width=2) - - -def calculate_center_of_mass(x, y): - """ - Вычисляет центр масс многоугольника по координатам его вершин. - :param x: Список x-координат вершин. - :param y: Список y-координат вершин. - :return: Координаты центра масс (Cx, Cy). - """ - n = len(x) - A = 0.0 - Cx = 0.0 - Cy = 0.0 - - for i in range(n): - # Циклический индекс - j = (i + 1) % n - # Вычисление детерминанта (удвоенная площадь треугольника) - factor = x[i] * y[j] - x[j] * y[i] - A += factor - Cx += (x[i] + x[j]) * factor - Cy += (y[i] + y[j]) * factor - - A *= 0.5 - Cx /= (6.0 * A) - Cy /= (6.0 * A) - - return Cx, Cy - +alpha = np.pi/4 def btn_func(): + global temperature_entry + + # Получаем значение температуры из текстового поля + try: + global temperature + temperature = float(temperature_entry.get()) + except ValueError: + return + # Проверка на наличие данных if len(x) < 3 or len(y) < 3: - print("Нарисуйте замкнутую фигуру!") return # Закрываем текущее окно рисования @@ -109,11 +42,14 @@ def btn_func(): ax.plot(x_arr, y_arr, label="Original") # Аппроксимация нарисованного объекта - step = 1000 + step = 1500 mytck, myu = sc.splprep([x_arr, y_arr], s=0) xnew, ynew = sc.splev(np.linspace(0, 1, step), mytck) ax.plot(xnew, ynew, 'red', label="Approximation") + global gamma + gamma = [] + # Разделение на участки с заданной точностью acc = 20 for i in range(0, step, acc): @@ -143,6 +79,7 @@ def btn_func(): # Рисуем нормаль ax.plot([x_h, x_end], [y_h, y_end], 'black') + except IndexError: ax.plot([xnew[i], xnew[0]], [ynew[i], ynew[0]], 'green') @@ -170,18 +107,58 @@ def btn_func(): # Рисуем нормаль ax.plot([x_h, x_end], [y_h, y_end], 'black') + beta = np.arccos((x_end-x_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2))) + if np.arcsin((y_end-y_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2)))<0: + beta = - beta + + if beta >= 0: + if beta >= alpha: + if beta - alpha < np.pi/2: + gamma.append(beta - alpha) + ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + else: + if alpha - beta < np.pi/2: + gamma.append(alpha - beta) + ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + else: + if abs(beta) >= np.pi - alpha: + if 2*np.pi - abs(beta) - alpha < np.pi/2: + gamma.append(2*np.pi - abs(beta) - alpha) + ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + else: + if alpha + abs(beta) < np.pi/2: + gamma.append(alpha + abs(beta)) + ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + # Настройка легенды и заголовка ax.set_title("Graph with Normals") # Вычисляем центр масс Cx, Cy = calculate_center_of_mass(x, y) - ax.scatter(Cx, Cy, color='blue', label="Center of Mass", zorder=5) + ax.scatter(Cx, Cy, color='blue', zorder=5) # Встраиваем график в Tkinter canvas = FigureCanvasTkAgg(fig, master=frame1) canvas.draw() canvas.get_tk_widget().pack(fill=BOTH, expand=True) + energy_calc() + return temperature + + +def energy_calc(): + global temperature + lambda_max = b / temperature + + mu = lambda_max + sigma = mu / 4 + + lambda_array = np.random.normal(mu, sigma, 1000) + impulse_array = [] + for i in range(0, len(gamma)): + impulse_array.append(h / lambda_array[i] * np.cos(gamma[i])) + print(gamma) + print(impulse_array) # Размеры окна w = 900 @@ -199,7 +176,7 @@ def btn_func(): frame0 = Frame(master=root, width=w, height=h, bg="black") frame0.pack(fill=BOTH, side=LEFT, expand=True) -frame1 = Frame(master=frame0, width=w, height=h) +frame1 = Frame(master=frame0) frame1.pack(fill=BOTH, expand=True) frame2 = Frame(master=root, width=2, bg="black") @@ -208,9 +185,16 @@ def btn_func(): frame3 = Frame(master=root, width=200, bg="gray") frame3.pack(fill=BOTH, side=LEFT, expand=True) +# Метка для текстового поля +temperature_label = Label(master=frame3, text="Температура звезды (K):", bg="gray", fg="white") +temperature_label.place(x=20, y=50) + +# Текстовое поле для ввода температуры +temperature_entry = Entry(master=frame3, width=15) +temperature_entry.place(x=20, y=80) + button = Button(master=frame3, text="Сохранить!", command=btn_func) button.place(x=98, y=500) -app = Paint(frame1) # Передаем размеры окна +app = Paint(frame1, x, y) # Передаем размеры окна root.mainloop() - From 4e7a305387d1469cd5a9855cbd31a6ec93238605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Tue, 6 May 2025 21:18:19 +0000 Subject: [PATCH 09/13] rtr --- moment_inert.py | 23 +++++++++++++++++++++++ project.py | 25 ++++++++++++++----------- 2 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 moment_inert.py diff --git a/moment_inert.py b/moment_inert.py new file mode 100644 index 000000000..77f946a1d --- /dev/null +++ b/moment_inert.py @@ -0,0 +1,23 @@ +def calc_moment_inert(x, y): + """ + Рассчитывает момент инерции плоской фигуры относительно оси, + перпендикулярной плоскости фигуры и проходящей через начало координат. + + :param x: список X-координат вершин + :param y: список Y-координат вершин + :return: момент инерции I + """ + n = len(x) + if n < 3: + return 0.0 + + I = 0.0 + for i in range(n): + xi, yi = x[i], y[i] + xj, yj = x[(i + 1) % n], y[(i + 1) % n] + cross = xi * yj - xj * yi + mag_sq = xi**2 + yi**2 + xi*xj + yi*yj + xj**2 + yj**2 + I += cross * mag_sq + + I *= 1 / 12 + return abs(I) \ No newline at end of file diff --git a/project.py b/project.py index f52a2e8d8..9bffd38a8 100644 --- a/project.py +++ b/project.py @@ -6,7 +6,8 @@ from const import * from class_paint import Paint -from center_mass import calculate_center_of_mass +from center_mass import calc_center_mass +from moment_inert import calc_moment_inert x = [] y = [] @@ -42,8 +43,8 @@ def btn_func(): ax.plot(x_arr, y_arr, label="Original") # Аппроксимация нарисованного объекта - step = 1500 - mytck, myu = sc.splprep([x_arr, y_arr], s=0) + step = 1000 + mytck, myu = sc.splprep([x_arr, y_arr]) xnew, ynew = sc.splev(np.linspace(0, 1, step), mytck) ax.plot(xnew, ynew, 'red', label="Approximation") @@ -114,36 +115,38 @@ def btn_func(): if beta >= 0: if beta >= alpha: if beta - alpha < np.pi/2: - gamma.append(beta - alpha) + gamma.append(float(beta - alpha)) ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') else: if alpha - beta < np.pi/2: - gamma.append(alpha - beta) + gamma.append(float(alpha - beta)) ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') else: if abs(beta) >= np.pi - alpha: if 2*np.pi - abs(beta) - alpha < np.pi/2: - gamma.append(2*np.pi - abs(beta) - alpha) + gamma.append(float(2*np.pi - abs(beta) - alpha)) ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') else: if alpha + abs(beta) < np.pi/2: - gamma.append(alpha + abs(beta)) + gamma.append(float(alpha + abs(beta))) ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') # Настройка легенды и заголовка ax.set_title("Graph with Normals") # Вычисляем центр масс - Cx, Cy = calculate_center_of_mass(x, y) + Cx, Cy = calc_center_mass(x, y) ax.scatter(Cx, Cy, color='blue', zorder=5) + # Расчёт момента инерции + moment_of_inertia = round(calc_moment_inert(xnew - Cx, ynew - Cy)) + print(f"Момент инерции: {moment_of_inertia}") # Встраиваем график в Tkinter canvas = FigureCanvasTkAgg(fig, master=frame1) canvas.draw() canvas.get_tk_widget().pack(fill=BOTH, expand=True) energy_calc() - return temperature def energy_calc(): @@ -156,8 +159,8 @@ def energy_calc(): lambda_array = np.random.normal(mu, sigma, 1000) impulse_array = [] for i in range(0, len(gamma)): - impulse_array.append(h / lambda_array[i] * np.cos(gamma[i])) - print(gamma) + impulse_array.append(float(h / lambda_array[i] * np.cos(gamma[i]))) + print(gamma) print(impulse_array) # Размеры окна From a09469f4f6681d7a51ae86993744684542f3a599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Sat, 10 May 2025 11:28:01 +0000 Subject: [PATCH 10/13] hhh --- __pycache__/center_mass.cpython-312.pyc | Bin 0 -> 1096 bytes __pycache__/class_paint.cpython-312.pyc | Bin 0 -> 3780 bytes __pycache__/const.cpython-312.pyc | Bin 0 -> 189 bytes __pycache__/moment_inert.cpython-312.pyc | Bin 0 -> 1249 bytes center_mass.py | 2 +- 5 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 __pycache__/center_mass.cpython-312.pyc create mode 100644 __pycache__/class_paint.cpython-312.pyc create mode 100644 __pycache__/const.cpython-312.pyc create mode 100644 __pycache__/moment_inert.cpython-312.pyc diff --git a/__pycache__/center_mass.cpython-312.pyc b/__pycache__/center_mass.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9358d1f0454ebbb690521e3dd3dc76e6a80db53a GIT binary patch literal 1096 zcma)6&rcIU6rS1bE?b~LiwDrlnxL^pA;v@#LR7>9(WnQbF(!try9@q+7IwF>Ez@L+ zMz<-6#S6s~+%#T@ND({W<~arF0(xS%wEwYHl?x`bcwF9Ddwtll`gV8%X4RqR_I4sVbAyt;AzM# z(-pd?(l4~4f>(j6OFuz&4QNwzk*=yB1#p#q0BM(byw)8w?j6@GZA?w~s&oMa_y85U zqNY#(D|9eBvyYwmPqt+`DJucwH~WWX#XbA;-Ri%unOL4&$N6myUSz2PmjE8-k_Ho9?2_N_S!ay1hM2~#@*q4Vj-AP(@7=-v632gg# z&(oy!#2(jl)9!ho+2)X*Oj)+sqnioGw1&ns+wLCE_-(p2st@f+T5X`ihqBkLCm$bq)2%=D$IaJ2wqjRB| zBjt(t=$tdJy~PX0+$4*h^yCdC?A<9ed3Zx<^d^Aml(aIQF$$CAVb;>clrB#=uv8GX zTA}Gy3`w%ro*#s%Lb7)jRL61-s?dpJ0roeD%XEwY literal 0 HcmV?d00001 diff --git a/__pycache__/class_paint.cpython-312.pyc b/__pycache__/class_paint.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3f816174caa58ef75011408932a9d25d9929cef GIT binary patch literal 3780 zcmb7HO>7&-6`mn?mrIKJvn9r|WJhdl7fc#EO`RB!jQ~n&yEYItY9h;3S`aJlisFw+ zYIbE=EY&)(4-%?Y5>Qmqsq`rnq_$L{!cvf=@+ks(Swb{SEPN=?lhBJ`yO*5$-Y%D< z6&h&fFgtJN&3p6az4yJ@e>OIH2(rNMs_@IQg@K5(l|V zWXD}1I~BU>w77;GlU#t`Ln1&8`fA9Uwt8A7%90c^L}fDMkm+4AK(efcG6EMh-3|)0tGZe-d5-d{$3<0XLM|J>J z(IY#7vP~y42b5sT&5&rbJ+6LN%R|tDl0xTBtsWTHv7E@DFNKwxWOR5qKCC8bn zoC(DxRSl-_&QGT%8Ae6A$#lVK`%EZAy$aoJ@>pz~Yno}A*Osmo#Sn*h&0$MOXzZ0H zWUJ+5G9}fq>IIVOa5j*tEQn5L-yS+5;4rw6NIY)1lH*!Dl29NQxsa5&X*7hGB56u6 zc~gp4V~crVlOaf{l#-AG4t5wxUbzXutD?N_Zq|lVoXn(&w8si59AhS_zk=>IDM56& zXWWm(V+HZplJckUayUnqW4X8fdT!-hzJKNXCjSrDmTTL;)v!JA_27fSov{ZWmtOh) zXFd0N^4k6MdV1eU+{d30>VA*z3&h1l$1oWo{P0AEpxjDH2^o-bG@>a1r{Ne5 zvnE(!cu~v@b7}|^CV;{+my+aLWb0?^SaqV@3p#BS6g*QZekT)L|_!OgC7WV}d<8LH#3imDKrzmhGK(7sXSL+m0@s&0fx* zz2CFmvn_uedk`zO{R|-24H@uA>?(*|Oa0j~UF<4~0duOOAa*SIv%R|50sG6Ti0Ho5 zo9$hbHt0%d!@r_z^sa=bn~LJwH5~I(S^2Zby+~1f!^%3?^-w(W?X1FBFth3}aQE<( zpi@wRqcC}}O+f{XR>>S)Roqgj4lI!6%NR?e!ceG0Of~K-OoVRgT7G?LE zXSIwPl+40&=Q%ser+d!M(08-bw9>vWcxHXePSgQs`tEkht_)XWq0_pr40q5%4KvSd zYYo*Ko>e%kg>?|Jp0~gXTfS{enT9(Q*1T1@|G!MzBN$KRvpWw;n`{g;jeiJ-*R%R& z;giB0{qKcOyYP&_ zwm(O6Z|6_I8{yi{Dc$QYdizVwE%O(b`WLSL_BSZmz2JV-a3VFtcRjiL=B1rM{o`;kHD)Sjs9dG{ zUVOh)pF>jCmutP(k-G>+UfmS7>6UxPr4L@$#bZVB=N9f(xs~kLax~}94dkVjp-ta* zSRc3soDao86P5b{F8s+zz|RK!WO#zX8%cRQj$>~yI5sZDtrheAZ&oI=_%QV13Na;^ zuQ`TZHao;$731?RdE#*MhoAU(zWYg&o9}q)^YPcIwFlYzpwPOs82n%;j3FRfLN4P7 rpJArpZ^R4MiQZvXU=E9*iq&r4Nhy6y+MjV}>2*4N@xKJW=Dz;{p+WzQ literal 0 HcmV?d00001 diff --git a/__pycache__/const.cpython-312.pyc b/__pycache__/const.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9df2d7a933c51113696f53d367b5fb3d068361db GIT binary patch literal 189 zcmX@j%ge<81SekeWH#~H2?`g N5Fy&gSi}aD007C4GTQ(E literal 0 HcmV?d00001 diff --git a/__pycache__/moment_inert.cpython-312.pyc b/__pycache__/moment_inert.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6982254662f0266d1130134ea46382afb6543df GIT binary patch literal 1249 zcma)6O-vI(6rR~-w+j`dD<%Gt)q|voLbz}MgDH^%F`86^K@ugU-5@`0VYiL6nN3PT zSyH0yiE=A9h>58Rv4E7jUUqNI#)F9`ZbUqB^39e;#KicT-FffL_kHut?4)1n>+2B2 zD{}Ffn?>k5EvkW!lS2wwMnN=>hEN=Pm;h6Sz{tS^Omx@;_+=EWvJgRUj&qG6Ob|~1 zOTlp_$Y^YoGVCBs6?F$a8AM2{A&AsmfH{IIqsD6-?FHEc?J@}-q3ZnUo+fAx!Vw_> zu84#1bWDJKt(I`XnuGvdzB1Zc9C6qPs>@eccHeOVBmB;_I>M4#QfG7OL6uz^szHPe zatV=EQF<135VpFjhseXn-oioDNf1WfD44VGTQG`d%1j&Yje@ahrX=H&QG#dF*ri3$ z*oAJ=dKXiX=eb)&NC9#sPw zkT*7fy=~3`@HO-R3X&&R0COo=^v_kO2|$<37l7XY<|1f;l?7XP)A%TXQUS^WwJO<8 zOF*ED(TP->ZNz?cP5BjnNSf)Az~LU)o(0WqY4GOXED6qso`X(hPLkuN$dCVztjN)r z67KrvY4_Xf?9&T6di*ufKE25M^wy6K*s*!r!&>a59JV;cA0Cx0)<2?poEDz3aNNRS z3-?=i%wlHXiPLc$#&L@aC=pe)_>g~eSe;g#AV_b;aU8X_KaVIA>XbhqtL-CxRUQsR zVu~uahaw?49337D%SyCuDsH&~{>i}b$*$rCE$UMJ46h{mDWcjlx;M=yy=8}>ccfzF zv*I_wne=|G7c(8{!5@g@F6+4Lf-2jTna;VgQN34ZXv3Ss*}j}F+nsI6yYk*OyxOp-@=0VnxyOvW{TFu6*I#+g`%lNYHoS5^ixU*OCV!n6PZMv?niEF* Date: Sat, 24 May 2025 15:08:47 +0000 Subject: [PATCH 11/13] fff --- project.py | 245 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 192 insertions(+), 53 deletions(-) diff --git a/project.py b/project.py index 9bffd38a8..c968df394 100644 --- a/project.py +++ b/project.py @@ -1,8 +1,11 @@ from tkinter import * import matplotlib.pyplot as plt import scipy.interpolate as sc +from scipy.integrate import odeint import numpy as np from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # Для встраивания графика в Tkinter +from matplotlib.animation import FuncAnimation +from PIL import Image, ImageTk from const import * from class_paint import Paint @@ -11,20 +14,26 @@ x = [] y = [] +omega = 0 +omega_array = [] +time_array = [] alpha = np.pi/4 def btn_func(): - global temperature_entry - # Получаем значение температуры из текстового поля try: - global temperature - temperature = float(temperature_entry.get()) + global lumin, albedo, a, ro, tau + lumin = float(lumin_entry.get()) + albedo = float(albedo_entry.get()) + a = float(a_entry.get()) + ro = float(ro_entry.get()) + tau = int(tau_entry.get()) except ValueError: return # Проверка на наличие данных + global x, y if len(x) < 3 or len(y) < 3: return @@ -40,23 +49,123 @@ def btn_func(): x_arr = np.array(x) y_arr = np.array(y) - ax.plot(x_arr, y_arr, label="Original") - # Аппроксимация нарисованного объекта step = 1000 mytck, myu = sc.splprep([x_arr, y_arr]) + global xnew, ynew xnew, ynew = sc.splev(np.linspace(0, 1, step), mytck) - ax.plot(xnew, ynew, 'red', label="Approximation") - global gamma + # Вычисляем центр масс + global Cx, Cy + Cx, Cy = calc_center_mass(x, y) + ax.scatter(0, 0, color='blue', zorder=5) + + # Расчёт момента инерции + global moment_of_inertia + moment_of_inertia = round(calc_moment_inert(xnew, ynew)) + + xnew = np.array(xnew) + ynew = np.array(ynew) + xnew -= Cx + ynew -= Cy + + ax.plot(xnew, ynew, 'black') + plt.title("Ваш астероид!") + + # Встраиваем график в Tkinter + canvas = FigureCanvasTkAgg(fig, master=frame1) + canvas.draw() + canvas.get_tk_widget().pack(fill=BOTH, expand=True) + + button.destroy() + + global button_label + button_label = Label(master=frame3, text="Корректно ли всё отображается?", bg="gray", fg="white") + button_label.place(x=20, y=470) + + global button_new + button_new = Button(master=frame3, text="Да!", command=anim_func) + button_new.place(x=20, y=500) + +def anim_func(): + button_label.destroy() + button_new.destroy() + + fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6)) + root.geometry(f"1500x600+5+{h_window}") + + edge = 2*max(xnew) + ax1.set_xlim(-edge, edge) + ax1.set_ylim(-edge, edge) + ax1.set_xlabel("Координаты по OX, м") + ax1.set_ylabel("Координаты по OY, м") + ax1.set_title("Движение астероида") + + ax2.set_xlim(0, 5000) + ax2.set_ylim(0, 0.15*tau/10) + ax2.set_xlabel("Время, с") + ax2.set_ylabel("Угловая скорость, °/с") + ax2.set_title("Изменение ω") + + global asteroid + asteroid, = ax1.plot([], [], '-', color='black') + + global omega_anim, omega_anim_lines + omega_anim_lines, = ax2.plot([], [], '-', color='b') + omega_anim, = ax2.plot([], [], 'o', color='red') + + global ani + ani = FuncAnimation(fig, animate, frames=tau*100, interval=40) + + plt.tight_layout() + ani.save("anim_asteroid.gif") + + del ani + ani = None + + show_gif() + return + +def show_gif(): + for widget in frame1.winfo_children(): + widget.destroy() + + gif = Image.open("anim_asteroid.gif") + frames = [] + + try: + for i in range(gif.n_frames): + gif.seek(i) + frame = ImageTk.PhotoImage(gif.convert("RGBA")) + frames.append(frame) + + except EOFError: + pass + + label = Label(frame1) + label.pack() + + def update(ind): + frame = frames[ind] + ind = (ind + 1) % len(frames) + label.configure(image=frame) + root.after(60, update, ind) + + root.after(0, update, 0) + +def move_func(t): + global xnew, ynew, omega, omega_array, time_array + gamma = [] + x_h_array = [] + y_h_array = [] + time = 10 # Разделение на участки с заданной точностью acc = 20 + step = 1000 for i in range(0, step, acc): try: - ax.plot([xnew[i], xnew[i+acc]], [ynew[i], ynew[i+acc]], 'green') - x_h = (xnew[i] + xnew[i+acc]) / 2 y_h = (ynew[i] + ynew[i+acc]) / 2 @@ -78,12 +187,7 @@ def btn_func(): x_end = x_h + scale * X_n y_end = y_h + scale * Y_n - # Рисуем нормаль - ax.plot([x_h, x_end], [y_h, y_end], 'black') - except IndexError: - ax.plot([xnew[i], xnew[0]], [ynew[i], ynew[0]], 'green') - x_h = (xnew[i] + xnew[0]) / 2 y_h = (ynew[i] + ynew[0]) / 2 @@ -105,9 +209,6 @@ def btn_func(): x_end = x_h + scale * X_n y_end = y_h + scale * Y_n - # Рисуем нормаль - ax.plot([x_h, x_end], [y_h, y_end], 'black') - beta = np.arccos((x_end-x_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2))) if np.arcsin((y_end-y_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2)))<0: beta = - beta @@ -116,52 +217,66 @@ def btn_func(): if beta >= alpha: if beta - alpha < np.pi/2: gamma.append(float(beta - alpha)) - ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + x_h_array.append(x_h) + y_h_array.append(y_h) else: if alpha - beta < np.pi/2: gamma.append(float(alpha - beta)) - ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + x_h_array.append(x_h) + y_h_array.append(y_h) else: if abs(beta) >= np.pi - alpha: if 2*np.pi - abs(beta) - alpha < np.pi/2: gamma.append(float(2*np.pi - abs(beta) - alpha)) - ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + x_h_array.append(x_h) + y_h_array.append(y_h) else: if alpha + abs(beta) < np.pi/2: gamma.append(float(alpha + abs(beta))) - ax.plot([x_h, x_h+50*np.cos(alpha)], [y_h, y_h+50*np.sin(alpha)], 'yellow') + x_h_array.append(x_h) + y_h_array.append(y_h) - # Настройка легенды и заголовка - ax.set_title("Graph with Normals") + dF = 2/3 * (1-albedo) * (lumin * lumin_son) / (4*np.pi*(a*ae)**2) * np.cos(gamma) * (np.pi*acc**2/4) / np.pi + M = 0 + for i in range(0, len(gamma)): + M += dF[i] * np.sqrt((x_h_array[i])**2+(y_h_array[i])**2) - # Вычисляем центр масс - Cx, Cy = calc_center_mass(x, y) - ax.scatter(Cx, Cy, color='blue', zorder=5) - - # Расчёт момента инерции - moment_of_inertia = round(calc_moment_inert(xnew - Cx, ynew - Cy)) - print(f"Момент инерции: {moment_of_inertia}") + epsilon = M / (ro * acc * moment_of_inertia) + omega += epsilon*time + omega = float(omega) + omega_array.append(float(omega*180/np.pi)) - # Встраиваем график в Tkinter - canvas = FigureCanvasTkAgg(fig, master=frame1) - canvas.draw() - canvas.get_tk_widget().pack(fill=BOTH, expand=True) - energy_calc() + x_0 = np.array(xnew) + y_0 = np.array(ynew) + phi_0 = np.array(np.arccos(x_0/np.sqrt((x_0)**2+(y_0)**2))) + for i in range(0, len(phi_0)): + if np.array(np.arcsin(y_0/np.sqrt((x_0)**2+(y_0)**2)))[i]<0: + phi_0[i] = - phi_0[i] + r = np.array(np.sqrt((x_0)**2+(y_0)**2)) + phi = np.array(phi_0 + omega*time) + x = np.array(r * np.cos(phi)) + y = np.array(r * np.sin(phi)) -def energy_calc(): - global temperature - lambda_max = b / temperature + time = time * len(omega_array) + time_array.append(time) - mu = lambda_max - sigma = mu / 4 + xnew, ynew = x,y - lambda_array = np.random.normal(mu, sigma, 1000) - impulse_array = [] - for i in range(0, len(gamma)): - impulse_array.append(float(h / lambda_array[i] * np.cos(gamma[i]))) - print(gamma) - print(impulse_array) + return xnew, ynew, time, float(omega*180/np.pi), time_array, omega_array + +def animate(i): + if ani == None: + raise ValueError() + print(i) + X, Y, Time, Omega, Time_array, Omega_array = move_func(t=i) + + asteroid.set_data(X, Y) + + omega_anim.set_data([Time], [Omega]) + omega_anim_lines.set_data([Time_array],[Omega_array]) + + return asteroid, omega_anim, omega_anim_lines # Размеры окна w = 900 @@ -173,7 +288,7 @@ def energy_calc(): w_window = root.winfo_screenwidth() // 2 - w_root // 2 h_window = root.winfo_screenheight() // 2 - h_root // 2 root.geometry(f"1200x600+{w_window}+{h_window}") -root.title("Рисуйте") +root.title("YORP-эффект") root.resizable(width=False, height=False) frame0 = Frame(master=root, width=w, height=h, bg="black") @@ -189,15 +304,39 @@ def energy_calc(): frame3.pack(fill=BOTH, side=LEFT, expand=True) # Метка для текстового поля -temperature_label = Label(master=frame3, text="Температура звезды (K):", bg="gray", fg="white") -temperature_label.place(x=20, y=50) +lumin_label = Label(master=frame3, text="Светимость звезды (в св. Солнца):", bg="gray", fg="white") +lumin_label.place(x=20, y=50) # Текстовое поле для ввода температуры -temperature_entry = Entry(master=frame3, width=15) -temperature_entry.place(x=20, y=80) +lumin_entry = Entry(master=frame3, width=15) +lumin_entry.place(x=20, y=80) + +albedo_label = Label(master=frame3, text="Альбедо тела:", bg="gray", fg="white") +albedo_label.place(x=20, y=110) + +albedo_entry = Entry(master=frame3, width=15) +albedo_entry.place(x=20, y=140) + +a_label = Label(master=frame3, text="Большая полуось (а.е.):", bg="gray", fg="white") +a_label.place(x=20, y=170) + +a_entry = Entry(master=frame3, width=15) +a_entry.place(x=20, y=200) + +ro_label = Label(master=frame3, text="Плотность тела (кг/м:3):", bg="gray", fg="white") +ro_label.place(x=20, y=230) + +ro_entry = Entry(master=frame3, width=15) +ro_entry.place(x=20, y=260) + +tau_label = Label(master=frame3, text="Время моделирования (10^3 с):", bg="gray", fg="white") +tau_label.place(x=20, y=290) + +tau_entry = Entry(master=frame3, width=15) +tau_entry.place(x=20, y=320) button = Button(master=frame3, text="Сохранить!", command=btn_func) -button.place(x=98, y=500) +button.place(x=20, y=500) app = Paint(frame1, x, y) # Передаем размеры окна root.mainloop() From 80066b8d0b7a1c441c5763ead3b0c590a19374ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Sat, 24 May 2025 15:09:22 +0000 Subject: [PATCH 12/13] dd --- const.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/const.py b/const.py index 065767d11..3be28ca59 100644 --- a/const.py +++ b/const.py @@ -1,3 +1,5 @@ b = 0.0029 # м*К c = 2.998 * 10**8 # м/с -h = 6.626 * 10**(-34) \ No newline at end of file +h = 6.626 * 10**(-34) +lumin_son = 3.88 * 10**26 # Вт +ae = 149.6 * 10**9 # м \ No newline at end of file From aeda8f2cacb51660240fc36f8534515a8708c7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= <111016733+ArkXo@users.noreply.github.com> Date: Tue, 3 Jun 2025 12:22:33 +0000 Subject: [PATCH 13/13] ddd --- project.py | 140 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 44 deletions(-) diff --git a/project.py b/project.py index c968df394..18fb457e5 100644 --- a/project.py +++ b/project.py @@ -20,6 +20,30 @@ alpha = np.pi/4 +def ray_segment_intersection(ray_origin, ray_dir, segment_p1, segment_p2): + """ + ray_origin — начальная точка луча (x, y) + ray_dir — направление луча (dx, dy) + segment_p1, segment_p2 — концы отрезка + Возвращает True, если луч пересекает отрезок + """ + # Работаем с numpy + p0 = np.array(ray_origin) + d = np.array(ray_dir) + p1 = np.array(segment_p1) + p2 = np.array(segment_p2) + + e1 = p1 - p0 + e2 = p2 - p1 + cross_d_e2 = d[0] * e2[1] - d[1] * e2[0] + if abs(cross_d_e2) < 1e-10: + return False # Коллинеарны или параллельны + + t = (e1[0] * e2[1] - e1[1] * e2[0]) / cross_d_e2 + u = (e1[0] * d[1] - e1[1] * d[0]) / cross_d_e2 + + return t >= 0 and 0 <= u <= 1 + def btn_func(): # Получаем значение температуры из текстового поля try: @@ -57,18 +81,19 @@ def btn_func(): # Вычисляем центр масс global Cx, Cy - Cx, Cy = calc_center_mass(x, y) + Cx, Cy = calc_center_mass(xnew, ynew) ax.scatter(0, 0, color='blue', zorder=5) - # Расчёт момента инерции - global moment_of_inertia - moment_of_inertia = round(calc_moment_inert(xnew, ynew)) - xnew = np.array(xnew) ynew = np.array(ynew) xnew -= Cx ynew -= Cy + # Расчёт момента инерции + global moment_of_inertia + moment_of_inertia = round(calc_moment_inert(xnew, ynew)) + + ax.plot(xnew, ynew, 'black') plt.title("Ваш астероид!") @@ -101,10 +126,10 @@ def anim_func(): ax1.set_ylabel("Координаты по OY, м") ax1.set_title("Движение астероида") - ax2.set_xlim(0, 5000) - ax2.set_ylim(0, 0.15*tau/10) - ax2.set_xlabel("Время, с") - ax2.set_ylabel("Угловая скорость, °/с") + ax2.set_xlim(0, 200) + ax2.set_ylim(-0.5, 0.5) + ax2.set_xlabel("Время, года") + ax2.set_ylabel("Угловая скорость, °/час") ax2.set_title("Изменение ω") global asteroid @@ -115,7 +140,7 @@ def anim_func(): omega_anim, = ax2.plot([], [], 'o', color='red') global ani - ani = FuncAnimation(fig, animate, frames=tau*100, interval=40) + ani = FuncAnimation(fig, animate, frames=500, interval=60) plt.tight_layout() ani.save("anim_asteroid.gif") @@ -157,9 +182,11 @@ def move_func(t): global xnew, ynew, omega, omega_array, time_array gamma = [] + beta_aray = [] x_h_array = [] y_h_array = [] - time = 10 + S_array = [] + time = 10**7 # Разделение на участки с заданной точностью acc = 20 @@ -209,42 +236,67 @@ def move_func(t): x_end = x_h + scale * X_n y_end = y_h + scale * Y_n - beta = np.arccos((x_end-x_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2))) - if np.arcsin((y_end-y_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2)))<0: - beta = - beta - - if beta >= 0: - if beta >= alpha: - if beta - alpha < np.pi/2: - gamma.append(float(beta - alpha)) - x_h_array.append(x_h) - y_h_array.append(y_h) + sun_dir = np.array([np.cos(alpha), np.sin(alpha)]) + + is_in_shadow = False + for j in range(0, step, acc): + + p1 = [xnew[j], ynew[j]] + p2 = [xnew[(j + acc) % step], ynew[(j + acc) % step]] + + if ray_segment_intersection((x_h, y_h), sun_dir, p1, p2): + is_in_shadow = True + break + + if is_in_shadow == False: # Участок не в тени + + beta = np.arccos((x_end-x_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2))) + if np.arcsin((y_end-y_h)/(np.sqrt((x_end-x_h)**2 + (y_end-y_h)**2)))<0: + beta = - beta + + if beta >= 0: + if beta >= alpha: + if beta - alpha < np.pi/2: + gamma.append(float(beta - alpha)) + beta_aray.append(beta) + x_h_array.append(x_h) + y_h_array.append(y_h) + S_array.append(abs(y_n)) + else: + if alpha - beta < np.pi/2: + gamma.append(float(alpha - beta)) + beta_aray.append(beta) + x_h_array.append(x_h) + y_h_array.append(y_h) + S_array.append(abs(y_n)) else: - if alpha - beta < np.pi/2: - gamma.append(float(alpha - beta)) - x_h_array.append(x_h) - y_h_array.append(y_h) - else: - if abs(beta) >= np.pi - alpha: - if 2*np.pi - abs(beta) - alpha < np.pi/2: - gamma.append(float(2*np.pi - abs(beta) - alpha)) - x_h_array.append(x_h) - y_h_array.append(y_h) - else: - if alpha + abs(beta) < np.pi/2: - gamma.append(float(alpha + abs(beta))) - x_h_array.append(x_h) - y_h_array.append(y_h) - - dF = 2/3 * (1-albedo) * (lumin * lumin_son) / (4*np.pi*(a*ae)**2) * np.cos(gamma) * (np.pi*acc**2/4) / np.pi + if abs(beta) >= np.pi - alpha: + if 2*np.pi - abs(beta) - alpha < np.pi/2: + gamma.append(float(2*np.pi - abs(beta) - alpha)) + beta_aray.append(beta) + x_h_array.append(x_h) + y_h_array.append(y_h) + S_array.append(abs(y_n)) + else: + if alpha + abs(beta) < np.pi/2: + gamma.append(float(alpha + abs(beta))) + beta_aray.append(beta) + x_h_array.append(x_h) + y_h_array.append(y_h) + S_array.append(abs(y_n)) + + dF = 2/3 * (1-albedo) * (lumin * lumin_son) / (4*np.pi*(a*ae)**2) * np.cos(gamma) / np.pi / c M = 0 for i in range(0, len(gamma)): - M += dF[i] * np.sqrt((x_h_array[i])**2+(y_h_array[i])**2) + if beta_aray[i] >= alpha: + M += dF[i] * S_array[i] * np.sqrt((x_h_array[i])**2+(y_h_array[i])**2) + else: + M -= dF[i] * S_array[i] * np.sqrt((x_h_array[i])**2+(y_h_array[i])**2) - epsilon = M / (ro * acc * moment_of_inertia) + epsilon = M / (ro * moment_of_inertia) omega += epsilon*time omega = float(omega) - omega_array.append(float(omega*180/np.pi)) + omega_array.append(float(omega*180/np.pi*60*60)) x_0 = np.array(xnew) y_0 = np.array(ynew) @@ -259,11 +311,11 @@ def move_func(t): y = np.array(r * np.sin(phi)) time = time * len(omega_array) - time_array.append(time) + time_array.append(time/60/60/24/365) xnew, ynew = x,y - return xnew, ynew, time, float(omega*180/np.pi), time_array, omega_array + return xnew, ynew, float(time/60/60/24/365), float(omega*180/np.pi*60*60), time_array, omega_array def animate(i): if ani == None: @@ -329,7 +381,7 @@ def animate(i): ro_entry = Entry(master=frame3, width=15) ro_entry.place(x=20, y=260) -tau_label = Label(master=frame3, text="Время моделирования (10^3 с):", bg="gray", fg="white") +tau_label = Label(master=frame3, text="Время моделирования (десятки тысяч лет):", bg="gray", fg="white") tau_label.place(x=20, y=290) tau_entry = Entry(master=frame3, width=15)