diff --git a/Analityka.py b/Analityka.py new file mode 100644 index 0000000..e3eb7d1 --- /dev/null +++ b/Analityka.py @@ -0,0 +1,12 @@ + +import numpy as np +def analitycznePolozenie(v0, theta, h0, t): + # wartosc przyspieszenia ziemskiego + g = 9.81 + # stopnie na radiany + theta_rad = np.radians(theta) + + # Rownania parametryczne dla x(t) i y(t) + x = v0 * np.cos(theta_rad) * t + y = h0 + v0 * np.sin(theta_rad) * t - 0.5 * g * t**2 + return x, y diff --git a/Euler.py b/Euler.py new file mode 100644 index 0000000..4c46c4f --- /dev/null +++ b/Euler.py @@ -0,0 +1,24 @@ +# Rozwiazanie numeryczne przy uzyciu metody Eulera +import numpy as np + +def metodaEulera(v0, theta, h0, dt): + # wartosc przyspieszenia ziemskiego + g = 9.81 + theta_rad = np.radians(theta) + + # Inicjalizacja pozycji i predkosci + x, y = 0.0, h0 + vx = v0 * np.cos(theta_rad) + vy = v0 * np.sin(theta_rad) + + # lista punktow trajektorii + trajektoria = [(x, y)] + + # Petla obliczajaca kolejne punkty az do upadku + while y >= 0: + x += vx * dt + y += vy * dt + vy -= g * dt + trajektoria.append((x, y)) + + return np.array(trajektoria) diff --git a/Main.py b/Main.py index e69de29..fdbd612 100644 --- a/Main.py +++ b/Main.py @@ -0,0 +1,12 @@ +from Parametry import v0, theta, h0, dt, dt_list +from Wykresy import rysujTrajektorie, analizaBledu + +def main(): + # Rysowanie trajektorii dla wybranego kroku czasowego + rysujTrajektorie(v0, theta, h0, dt) + + # Analiza wplywu kroku czasowego na dokladnosc symulacji + analizaBledu(v0, theta, h0, dt_list) + +if __name__ == "__main__": + main() diff --git a/Parametry.py b/Parametry.py new file mode 100644 index 0000000..64a9cf5 --- /dev/null +++ b/Parametry.py @@ -0,0 +1,11 @@ +# v0 - predkosc poczatkowa m/s +#theta - kat rzutu +#h0 - wysokosc poczatkowa m +#dt - krok czasowy w sekundach do rysowania trajektori +#dt_list - lista do analizy bledu +# ------------------------------------------------------ +v0 = 2 +theta = 45 +h0 = 0 +dt = 0.01 +dt_list = [0.1, 0.05, 0.01, 0.005, 0.001] diff --git a/README.md b/README.md new file mode 100644 index 0000000..a7b9b4f --- /dev/null +++ b/README.md @@ -0,0 +1,85 @@ + +# Symulacja i analiza rzutu ukośnego + +## Cel projektu + +Celem projektu jest stworzenie programu w Pythonie, który symuluje rzut ukośny w jednorodnym polu grawitacyjnym bez oporu powietrza. Program oblicza: + +- trajektorie ruchu na podstawie **dokładnego rozwiązania analitycznego**, +- przybliżoną trajektorię metodą numeryczną – **metodą Eulera**, +- oraz porównuje obie metody, analizując dokładność w zależności od kroku czasowego `t`. + +--- + +## Wymagania + +Do uruchomienia projektu wymagane są biblioteki: + +``` +pip install numpy matplotlib +``` + +--- + +## Struktura plików + +- `Main.py` – główny plik uruchamiający program +- `Analityka.py` – obliczenia dokładne (analityczne) na podstawie wzorów fizycznych +- `Euler.py` – implementacja metody Eulera +- `Wykresy.py` – rysowanie wykresów porównawczych +- `Parametry.py` – definiowanie parametrów początkowych (v0, kat, h0, dt) + +--- + +## Uruchamianie programu + +Po zainstalowaniu bibliotek, uruchom program wpisując: + +``` +python main.py +``` + +--- + +## Wygenerowane wykresy + +Program generuje dwa wykresy: + +1. Porównanie trajektorii analitycznej i numerycznej (Euler) +2. Wykres błędu w zasięgu w zależności od wielkości kroku czasowego `t` + +### Wykresy: +- Wykres 1: Trajektoria – analityczna vs Euler +- ![img.png](resources/analVsEuler.png) +- Wykres 2: Blad zasięgu vs t +- ![img.png](resources/error.png) + +--- + +## Analiza dokładności + +Program analizuje, jak krok czasowy wpływa na dokładność metody Eulera: + +- im mniejsze t, tym mniejszy błąd w zasięgu rzutu, +- dla zbyt dużych kroków trajektoria znacząco odbiega od wzorcowej. + +--- + +## Wnioski + +- Metoda Eulera przy małych krokach daje zadowalającą dokładność. +- Program pokazuje, jak ważny jest wybór kroku czasowego w metodach numerycznych. +- Prosta implementacja pozwala zrozumieć podstawy całkowania numerycznego i ruchu w fizyce klasycznej. + +--- + +## Uwagi techniczne + +- Symulacja zatrzymuje się automatycznie, gdy ciało spadnie na ziemię (y < 0). +- Dla bardzo małych t program może działać wolniej (więcej iteracji). + +--- + +## Autor + +Patryk Zamorski diff --git a/Readme.txt b/Readme.txt deleted file mode 100644 index 4de76dd..0000000 --- a/Readme.txt +++ /dev/null @@ -1 +0,0 @@ -Zainstalowac pip install numpy matplotlib diff --git a/Wykresy.py b/Wykresy.py new file mode 100644 index 0000000..1a4ee40 --- /dev/null +++ b/Wykresy.py @@ -0,0 +1,58 @@ +# wykresy.py +# Porownanie trajektorii oraz analiza bledu metody Eulera + +import numpy as np +import matplotlib.pyplot as plt +from Analityka import analitycznePolozenie +from Euler import metodaEulera + +# Funkcja rysujaca wykres porownawczy trajektorii +def rysujTrajektorie(v0, theta, h0, dt): + g = 9.81 + theta_rad = np.radians(theta) + + # Czas lotu z rozwiazania analitycznego + t_flight = (v0 * np.sin(theta_rad) + np.sqrt((v0 * np.sin(theta_rad))**2 + 2 * g * h0)) / g + t_vals = np.linspace(0, t_flight, 1000) + + # Obliczenie trajektorii analitycznej i numerycznej + x_anal, y_anal = analitycznePolozenie(v0, theta, h0, t_vals) + traj_num = metodaEulera(v0, theta, h0, dt) + + # Rysowanie wykresu + plt.figure(figsize=(10, 6)) + plt.plot(x_anal, y_anal, label="Analityczna", color='blue') + plt.plot(traj_num[:, 0], traj_num[:, 1], label=f"Euler (dt={dt})", color='red', linestyle='--') + plt.xlabel("x [m]") + plt.ylabel("y [m]") + plt.title("Porownanie trajektorii rzutu ukosnego") + plt.legend() + plt.grid() + plt.show() + +# Funkcja analizujaca blad koncowego zasiegu w zaleznosci od kroku czasowego +def analizaBledu(v0, theta, h0, dt_values): + g = 9.81 + theta_rad = np.radians(theta) + + # Obliczenie analitycznego zasiegu + t_flight = (v0 * np.sin(theta_rad) + np.sqrt((v0 * np.sin(theta_rad))**2 + 2 * g * h0)) / g + t_vals = np.linspace(0, t_flight, 1000) + x_anal, _ = analitycznePolozenie(v0, theta, h0, t_vals) + x_end_anal = x_anal[-1] + + errors = [] + for dt in dt_values: + traj_num = metodaEulera(v0, theta, h0, dt) + x_end_num = traj_num[-1, 0] + error = abs(x_end_num - x_end_anal) + errors.append(error) + + # Rysowanie wykresu bledu wzgledem kroku czasowego + plt.figure(figsize=(8, 5)) + plt.plot(dt_values, errors, marker='o') + plt.xlabel("Krok czasowy t [s]") + plt.ylabel("Blad zasiegu [m]") + plt.title("Zaleznosc bledu od kroku czasowego") + plt.grid() + plt.show() diff --git a/resources/analVsEuler.png b/resources/analVsEuler.png new file mode 100644 index 0000000..6e58f0e Binary files /dev/null and b/resources/analVsEuler.png differ diff --git a/resources/error.png b/resources/error.png new file mode 100644 index 0000000..443c4db Binary files /dev/null and b/resources/error.png differ