diff --git a/bachelorproject.pdf b/bachelorproject.pdf index 417cff0..560131c 100644 Binary files a/bachelorproject.pdf and b/bachelorproject.pdf differ diff --git a/bachelorproject.tex b/bachelorproject.tex index 406d72e..88ac244 100644 --- a/bachelorproject.tex +++ b/bachelorproject.tex @@ -4,6 +4,7 @@ \usepackage[]{url} \usepackage[]{subcaption} \usepackage[]{float} +\usepackage[]{multicol} \usepackage{tikz} \usepackage{tkz-euclide} @@ -66,6 +67,8 @@ } +\counterwithin{figure}{section} +\counterwithin{equation}{section} \usepackage{subfiles} % Best loaded last in the preamble diff --git a/sections/theoretical_background.tex b/sections/theoretical_background.tex index 838eef9..6180fe2 100644 --- a/sections/theoretical_background.tex +++ b/sections/theoretical_background.tex @@ -306,12 +306,12 @@ orthogonal axes. \centering \inputtikz[.7]{SAT_mvp} \caption{SAT: Minimum push vector $\vec v_i$ on axis defined by $\vec o_i$, - orthogonal to edge $i$} + orthogonal to edge $e_i$} \label{fig:SAT-mpv} \end{figure} The candidate MPVs $\vec v_i$ are the vectors that define the axis $\vec o_i$ -(orthogonal to edge $i$), with $\| \vec o_i \| = 1$, multiplied by the minimum +(orthogonal to edge $e_i$), with $\| \vec o_i \| = 1$, multiplied by the minimum overlap between the two polygons, as shown in \ref{fig:SAT-mpv}. The final MPV is simply the $\vec v_i$ with the smallest norm. @@ -320,11 +320,145 @@ is good to find whether two polygons are colliding and the MPV, it isn't trivial to gather the point of impact, i.e. the vertex that is penetrating the other polygon. It is doable, but during the implementation, it came with some caveats that introduced some bugs, so we decided to switch strategy and go with an -algorithm of our own. +algorithm of our own. Moreover, SAT only supports convex polygons, which limits +the original objective of the project, which was to have any arbitrary polygon. \subsubsection{Vertex collisions} +The solution that was adopted for the project, after trying SAT, was a more +intuitive one, developed by Prof. Carzaniga. The idea is simple: check if a +vertex of a polygon is colliding with an edge of another polygon. + +\begin{figure}[H] + \centering + \inputtikz[.5]{vertex_intro} + \caption{Vertex-edge collision between polygons $A$ and $B$} + \label{fig:vertex-edge} +\end{figure} + +If we have a polygon defined as a set of points $P \subset \mathbb{R}^2$, we +define a vertex as a pair of segments $\left(\overline{V_{i-1}V_i}, + \overline{V_{i+1}V_i}\right)$. To check if vertex $V_i$ of polygon $A$ is inside +polygon $B$, we just check if the both segments $\overline{V_{i-1}V_i}$ and +$\overline{V_{i+1}V_i}$ intersect edge $e_j$. If such is the case, we know that +$V_i$ is inside, and we can use it as impact point. We can now take the vector +perpendicular to the edge $e_j$ and normalize it, which is the normal we need +for the collision resolution. + + +\paragraph{Edge cases} With this approach (and many other collision detection +algorithms), it is easy to see that the case described in the Figure +\ref{fig:vertex-edge} is only a general one. It will ultimately happen most +often, but there are especially two edge cases that are note-worthy and occurred +during the simulation a greater number of times than expected. + +\paragraph{Parallel collision} Parallel collision occur when two edge collide +with each other, an example can be seen in Figure \ref{fig:vertex-parallel}. +This collision does not get detected by the vertex-edge detection method because +the edge of $A$ parallel to the edge of $B$ do not collide, since they are +parallel. + +\begin{figure}[H] + \centering + \inputtikz[.5]{vertex_parallel} + \caption{Parallel edges collision between polygons $A$ and $B$} + \label{fig:vertex-parallel} +\end{figure} + +To determine if polygon $A$ is having a parallel collision with polygon $B$ we +check if only the segment $\overline{V_{i-1}V_i}$ intersects with edge $e_j$ and +if the segment $\overline{V_{i+1}V_i}$ is parallel to edge $e_j$. + +To find the impact point, we first need to find the minimum overlap between the +parallel edges. We can calculate it by projecting the points that make the +parallel edges of $A$ and $B$ on the axis generated by the edge of $A$ (c.f. +Figure \ref{fig:parallel-impact}).Finally, the impact point, is the midpoint of +the said overlap. + +\begin{figure}[H] + \centering + \begin{subfigure}[]{.5\textwidth} + \centering + \inputtikz[.7]{vertex_parallel_full} + \caption{Edge fully contained by other edge} + \end{subfigure} + \begin{subfigure}[]{.49\textwidth} + \centering + \inputtikz[.7]{vertex_parallel_partial} + \caption{Edge partly contained by other edge} + \end{subfigure} + \caption{Parallel collision, finding the impact point} + \label{fig:parallel-impact} +\end{figure} + +The normal vector is given in the same way as the vertex-edge collision, i.e. +taking the perpendicular vector to~$e_j$ and normalizing it. + +% TODO: ask Carza about the possibility of resolving vertex-vertex normal with SAT +\paragraph{Vertex on vertex collision} These collision happen when, at the +moment of the frame, two polygons are "inside each other", i.e. they both have +have a vertex present inside the area of the other polygon, as shown in Figure +\ref{fig:vertex-vertex}. + +\begin{figure}[H] + \centering + \inputtikz[.5]{vertex_vertex} + \caption{Vertex on vertex collision between polygons $A$ and $B$} + \label{fig:vertex-vertex} +\end{figure} + +\noindent +Two problems arise when trying to deal with this edge case: +\begin{enumerate} + \item determining which of the two vertices we chose as the impact point; + \label{itm:impact} + \item determining what normal vector. + \label{itm:normal} +\end{enumerate} + +% \noindent +For point \ref{itm:impact}, it actually doesn't really matter. What is +represented in Figures~\ref{fig:vertex-edge}-\ref{fig:vertex-vertex} are an +over exaggeration of what happens in the engine. Since the time delta between +two frames is so small, the collisions look more like what is in +Figure~\ref{fig:real-vertex-vertex}, where the concerned vertices are located +practically in the same spot, and the difference is negligible. So for convenience +with the general vertex-edge case, we will take the vertex of $A$ being inside +$B$ as the impact point. + +For point \ref{itm:normal}, that's where the real problem of the edge case +occur. We are unable to determine what vectors is supposed to be the normal +vector. One might say "just take the vector that goes from the vertex of $A$ +(that is inside $B$) to the one of $B$ (that is inside $A$)", but it doesn't +work out in general. It works (kind of) when we have non-rotating objects going +straight at each other, but as soon as you have rotational motion, this +reasoning collapses. The solution that was decided (together with advisor Prof. +Carzaniga) was to treat the collision as a vertex-edge collision, and choosing +whatever the first edge of $B$ comes up first in the calculations as the edge to +find the normal. The results look realistic enough to be accepted. + + +\begin{figure}[H] + \centering + \begin{subfigure}[]{.33\textwidth} + \centering + \inputtikz[.7]{vertex_edge_real} + \caption{Realistic vertex-edge collision} + \end{subfigure} + \begin{subfigure}[]{.32\textwidth} + \centering + \inputtikz[.7]{vertex_parallel_real} + \caption{Realistic edge-edge collision} + \end{subfigure} + \begin{subfigure}[]{.34\textwidth} + \centering + \inputtikz[.7]{vertex_vertex_real} + \caption{Realistic vertex-vertex collision} + \label{fig:real-vertex-vertex} + \end{subfigure} + \caption{Realistic collisions} + \label{fig:real-collisions} +\end{figure} + \subsection{Collision resolution} \label{sub:resolution} -\subsubsection{Physics} -\subsubsection{Solving for the impulse parameter}