Prosta kinematyka w dwóch wymiarach ---------------------------------------- Stwórz hierarchię klas, które umożliwią proste symulacje fizyczne w dwóch wymiarach Potrzebne elementy składowe (klasy) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. glossary:: **operacje matematyczne** napisz klasę ``Vec2`` udostępniającą podstawowe operacje matematyczne w 2 wymiarach **reprezentacja obiektów** potrzebna będzie hierarchia obiektów, które będą symulowane; np klasa ``Circle`` oraz ``Polygon`` **system** klasa ``System`` powinna zawierać w sobie listę obiektów: ruchomych elementów sceny, obiekty nieruchome oraz zapewniać warunki brzegowe **solver** rozwiązuje równanie ruchu; tu akurat jest to klasa całkująca wg schematu Eulera **observer** odpowiada(ją) za wydruk wyników na ekran 0. Algebra w 2D ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Napisz klasę ``Vec2``, która będzie miała pola prywatne ``__x`` oraz ``__y``, do których dostęp zapewnią settery i gettery zaimplementowane jako dekoratory ``@property`` oraz ``@x.setter``. Zerknij na przykład dekoratorów w *Pythonowe to i owo II*. Klasa powinna posiadać też operatory : ``+=`` ``-=``, metodę ``dp()`` liczącą iloczyn skalarny, metody ``length()`` i ``normalize()`` Napisz też funkcję ``point_on_segment_projection()``, która znajduje najkrótszą odległość punktu do odcinka oraz miejsce przecięcia odcinka z linią prostopadłą, przechodzącą przez dany punkt. .. raw:: html :file: punkt_prosta.html Powyższa interaktywna grafika ilustruje oczekiwany wynik obliczeń. Parametr ``t`` wyznaczający rzut punktu ``p`` na odcinek pomiędzy ``b`` i ``e`` obliczamy ze wzoru: .. math:: t = \frac{(px - b.x)(ex - bx) + (py - by)(ey - by)}{| \vec{b} - \vec{e}|^2}` 1. Napisz klasy ``Atom`` oraz ``Polygon`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Klasa ``Atom`` będzie reprezentowała koła - elementarne obiekty poruszające się na scenie, dziedzicząca po niej klasa ``Polygon`` - wielokąty (trójkąty, prostokąty, itp). Załóż, że każdy wielokąt jest łamaną zamkniętą, którą można przechowywać jako listę kolejnych wierzchołków. 2. Napisz klasę ``System`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Na początku klasa ``System`` będzie zawierała tylko listę kół oraz wielokątów. Wg. jednej z możliwych implementacji, będą to dwie oddzielne listy: jedna przechowująca obiekty poruszające się, druga zaś nieruchome, w tym także pudełko zawierające symulację. 3. Napisz klasę ``Solver`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Klasa ``Solver`` będzie elementem odpowiedzialnym za przeprowadzenie symulacji. Odpowiedzialna ona będzie za: - aktualizację położeń wg wzoru :math:`\vec{x}_{i+1} = \vec{x}_{i} + dt \vec{v}_{i}` - rozwiązywanie zderzeń pomiędzy kołem a bokami wielokąta, przede wszystkim ze ściankami pudełka - rozwiązywanie zderzeń pomiędzy kołami Zderzeń pomiędzy kołem a bokiem wielokąta wymaga wyznaczenia odległości pomiędzy tymi obiektami a także punktu przecięcia ``t`` na odcinku, przez który przechodzi prosta prostopadła do odcinka. Wykorzystaj do obliczeń wzór podany powyżej. Zauważ, że koło zderza się z odcinkiem wtedy i tylko wtedy, kiedy :math:`0 \le t \le 1`. Oznaczając przez :math:`\vec{n}` normalną do odcinka a przez :math:`\vec{v}` vektor prędkości koła przed zderzeniem, nowy wektor prędkości :math:`\vec{v_n}` obliczamy ze wzorów: .. math:: \begin{matrix} \vec{u} & = & \frac{\vec{v} \bullet \vec{n}}{\vec{n} \bullet \vec{n}} \vec{n}\\ \vec{w} & = & \vec{v} - \vec{u}\\ \vec{v_n} & = & \vec{w} - \vec{u}\\ \end{matrix} gdzie :math:`\bullet` oznacza iloczyn skalarny, np. :math:`\vec{n} \bullet \vec{n}` to po prostu kwadrat długości wektora :math:`\vec{n}` Zderzenia pomiędzy dwoma kołami rozpatrujemy wg poniższych wzorów: .. math:: \begin{matrix} \vec{v_1} & = & \vec{v_1} - \frac{2 m_2}{m_1 + m_2} \frac{ (\vec{v_1} - \vec{v_2}) \bullet (\vec{x_1} - \vec{x_2}) }{ |\vec{x_1} - \vec{x_2}|^2} (\vec{x_1} - \vec{x_2})\\ \vec{v_2} & = & \vec{v_2} - \frac{2 m_1}{m_1 + m_2} \frac{ (\vec{v_2} - \vec{v_1}) \bullet (\vec{x_2} - \vec{x_1}) }{ |\vec{x_2} - \vec{x_1}|^2} (\vec{x_2} - \vec{x_1})\\ \end{matrix} (patrz `strona na Wikipedii `_ ) Przy implementacji powyższych wzorów można wprowadzić spore uproszczenie. Ostatecznie wyrażenia te można sprowadzić do: .. math:: \begin{matrix} f & = & \frac{2}{m_1 + m_2} \frac{ (\vec{v_1} - \vec{v_2}) \bullet (\vec{x_1} - \vec{x_2}) }{ |\vec{x_1} - \vec{x_2}|^2}\\ \vec{v_1} & = & \vec{v_1} - m_2 f (\vec{x_1} - \vec{x_2})\\ \vec{v_2} & = & \vec{v_2} + m_1 f (\vec{x_1} - \vec{x_2})\\ \end{matrix}