Written Collision detection: SAT
This commit is contained in:
parent
4c072dce3e
commit
c6f845dc83
Binary file not shown.
BIN
figures/SAT_intro.pdf
Normal file
BIN
figures/SAT_intro.pdf
Normal file
Binary file not shown.
BIN
figures/SAT_mvp.pdf
Normal file
BIN
figures/SAT_mvp.pdf
Normal file
Binary file not shown.
@ -264,11 +264,67 @@ to the overall polygon.
|
||||
where, $P_{n+1} = P_1$ in the case of $i = n$.
|
||||
|
||||
\subsection{Collision detection}
|
||||
|
||||
Collision detection, as the name suggests, are the algorithms used to detect
|
||||
whether two polygons are colliding. The result of this procedure must be an
|
||||
impact point and a normal vector, that will then be used for the collision
|
||||
resolution \ref{sub:resolution}.
|
||||
|
||||
\subsubsection{Separating Axis Theorem}
|
||||
|
||||
This algorithm was the first one studied for this project and was inspired by
|
||||
the works of David Eberly \cite{convexcollisionsSAT}. The separating axis
|
||||
theorem (SAT) states that if you can draw a line between two convex objects,
|
||||
they do not overlap. We will call this line a \textit{separating line}. More
|
||||
technically, two convex shapes do not overlap if there exists an axis onto which
|
||||
the two objects' projections do not overlap. We'll call this axis a \textit{separating
|
||||
axis}. This concept can be visualized in Figure \ref{fig:SAT-intro}.
|
||||
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\inputtikz[.7]{SAT_intro}
|
||||
\caption{SAT: Separating axis ($A$) vs non-separating axis ($B$), with
|
||||
separating line ($C$)}
|
||||
\label{fig:SAT-intro}
|
||||
\end{figure}
|
||||
|
||||
As we can see in Figure \ref{fig:SAT-intro}, the axis $B$ show that the
|
||||
projections of the both polygons overlap, but we were able to find an axis $A$
|
||||
where this is not the case. As soon as we find an axis for which the projections
|
||||
do not overlap, it means that the polygons are not colliding. For 2D objects, we
|
||||
only need to consider the axes that are orthogonal to each edge. In Figure
|
||||
\ref{fig:SAT-intro}, only two of those axes are shown for better readability,
|
||||
but they would be 7, one for each edge.
|
||||
|
||||
To move (or push) one polygon away from the other, we also need to find a vector
|
||||
that, when added to the polygons position, will make the shapes not overlap. We
|
||||
want the minimum displacement possible, We'll call this vector the minimum push
|
||||
vector (MPV). For 2-dimensional polygons, this vector will lie in some of the
|
||||
orthogonal axes.
|
||||
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\inputtikz[.7]{SAT_mvp}
|
||||
\caption{SAT: Minimum push vector $\vec v_i$ on axis defined by $\vec o_i$,
|
||||
orthogonal to edge $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
|
||||
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.
|
||||
|
||||
\paragraph{Pitfalls of SAT} The issue with the SAT algorithm is that although it
|
||||
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.
|
||||
|
||||
\subsubsection{Vertex collisions}
|
||||
|
||||
\subsection{Collision resolution}
|
||||
\label{sub:resolution}
|
||||
\cite{collision:resolution}
|
||||
\subsubsection{Physics}
|
||||
\subsubsection{Solving for the impulse parameter}
|
||||
|
70
tikzs/SAT_intro.tikz
Normal file
70
tikzs/SAT_intro.tikz
Normal file
@ -0,0 +1,70 @@
|
||||
\begin{tikzpicture}
|
||||
\begin{pgfonlayer}{nodelayer}
|
||||
\node [style=none] (46) at (11.416, 10.2774) {};
|
||||
\node [style=none] (43) at (13.8776, 6.58504) {};
|
||||
\node [style=none] (34) at (6.53846, 16.6923) {};
|
||||
\node [style=none] (0) at (-2, -1) {};
|
||||
\node [style=none] (1) at (2.25, 3.5) {};
|
||||
\node [style=none] (3) at (-8, 7) {};
|
||||
\node [style=none] (4) at (-8, -2) {};
|
||||
\node [style=none] (5) at (8, 8) {};
|
||||
\node [style=none] (6) at (5, 6) {};
|
||||
\node [style=none] (7) at (10, 4) {};
|
||||
\node [style=none] (8) at (-9, -5) {};
|
||||
\node [style=none] (9) at (13, -5) {};
|
||||
\node [style=none] (10) at (-8, -5) {};
|
||||
\node [style=none] (11) at (-8, -4.5) {};
|
||||
\node [style=none] (12) at (-7.5, -5) {};
|
||||
\node [style=none] (13) at (-7.5, -4.5) {};
|
||||
\node [style=none] (14) at (2.25, -5) {};
|
||||
\node [style=none] (15) at (10, -5) {};
|
||||
\node [style=none] (16) at (5, -5) {};
|
||||
\node [style=none] (17) at (-8, -5.25) {};
|
||||
\node [style=none] (18) at (2.25, -5.25) {};
|
||||
\node [style=none] (19) at (10, -5.25) {};
|
||||
\node [style=none] (20) at (5, -5.25) {};
|
||||
\node [style=none] (21) at (-9.75, -5.5) {\Huge$A$};
|
||||
\node [style=none] (22) at (11, 10) {};
|
||||
\node [style=none] (27) at (17, 1) {};
|
||||
\node [style=none] (28) at (5, 19) {};
|
||||
\node [style=none] (32) at (10.625, 9.75) {};
|
||||
\node [style=none] (33) at (11.25, 9.625) {};
|
||||
\node [style=none] (31) at (10.875, 9.375) {};
|
||||
\node [style=none] (35) at (12.0769, 8.38462) {};
|
||||
\node [style=none] (40) at (6.74647, 16.831) {};
|
||||
\node [style=none] (41) at (12.2849, 8.52329) {};
|
||||
\node [style=none] (42) at (13.4615, 6.30769) {};
|
||||
\node [style=none] (47) at (4.25, 19.25) {\Huge$B$};
|
||||
\node [style=none] (48) at (3.5, 10) {};
|
||||
\node [style=none] (49) at (3.5, -6) {};
|
||||
\node [style=none] (50) at (2.75, 10) {\Huge$C$};
|
||||
\end{pgfonlayer}
|
||||
\begin{pgfonlayer}{edgelayer}
|
||||
\draw [style=Very thick] (3.center) to (4.center);
|
||||
\draw (4.center) to (0.center);
|
||||
\draw (0.center) to (1.center);
|
||||
\draw (6.center) to (7.center);
|
||||
\draw (7.center) to (5.center);
|
||||
\draw [style=Very thick] (5.center) to (6.center);
|
||||
\draw (1.center) to (3.center);
|
||||
\draw (8.center) to (9.center);
|
||||
\draw [style=Dashed] (4.center) to (10.center);
|
||||
\draw (11.center) to (13.center);
|
||||
\draw (13.center) to (12.center);
|
||||
\draw [style=Dashed] (1.center) to (14.center);
|
||||
\draw [style=Dashed] (6.center) to (16.center);
|
||||
\draw [style=Dashed] (15.center) to (7.center);
|
||||
\draw [style=Very thick] (17.center) to (18.center);
|
||||
\draw [style=Very thick] (20.center) to (19.center);
|
||||
\draw (28.center) to (27.center);
|
||||
\draw [style=Dashed] (5.center) to (22.center);
|
||||
\draw (32.center) to (31.center);
|
||||
\draw (33.center) to (31.center);
|
||||
\draw [style=Dashed] (3.center) to (34.center);
|
||||
\draw [style=Dashed] (0.center) to (35.center);
|
||||
\draw [style=Very thick] (40.center) to (41.center);
|
||||
\draw [style=Dashed] (7.center) to (42.center);
|
||||
\draw [style=Very thick] (46.center) to (43.center);
|
||||
\draw [style=Very thick] (48.center) to (49.center);
|
||||
\end{pgfonlayer}
|
||||
\end{tikzpicture}
|
45
tikzs/SAT_mvp.tikz
Normal file
45
tikzs/SAT_mvp.tikz
Normal file
@ -0,0 +1,45 @@
|
||||
\begin{tikzpicture}
|
||||
\begin{pgfonlayer}{nodelayer}
|
||||
\node [style=none] (1) at (-2, 4) {};
|
||||
\node [style=none] (2) at (4.5, 0) {};
|
||||
\node [style=none] (3) at (-1, -2) {};
|
||||
\node [style=none] (4) at (4, 3) {};
|
||||
\node [style=none] (5) at (2, -3) {};
|
||||
\node [style=none] (6) at (8, -2) {};
|
||||
\node [style=none] (7) at (8, 0) {};
|
||||
\node [style=none] (8) at (5, 6) {};
|
||||
\node [style=none] (9) at (-4, 9) {};
|
||||
\node [style=none] (10) at (14, 3) {};
|
||||
\node [style=none] (11) at (10.1, 4.3) {};
|
||||
\node [style=none] (12) at (6.35, 5.55) {};
|
||||
\node [style=none] (13) at (-0.7, 7.9) {};
|
||||
\node [style=none] (14) at (-0.620943, 8.13717) {};
|
||||
\node [style=none] (15) at (6.42906, 5.78717) {};
|
||||
\node [style=none] (16) at (5.15811, 6.47434) {};
|
||||
\node [style=none] (17) at (10.2581, 4.77434) {};
|
||||
\node [style=none] (18) at (4.92094, 5.76283) {};
|
||||
\node [style=none] (19) at (6.27094, 5.31283) {};
|
||||
\node [style=none] (20) at (5.25, 5.25) {\Large$\vec v_i$};
|
||||
\node [style=none] (21) at (-3.25, 8.75) {};
|
||||
\node [style=none] (22) at (-3.75, 8.5) {\Large$\vec o_i$};
|
||||
\node [style=none] (23) at (1.75, -2.75) {\Large$i$};
|
||||
\end{pgfonlayer}
|
||||
\begin{pgfonlayer}{edgelayer}
|
||||
\draw (1.center) to (2.center);
|
||||
\draw (2.center) to (3.center);
|
||||
\draw [style=Very thick] (5.center) to (4.center);
|
||||
\draw (4.center) to (7.center);
|
||||
\draw (7.center) to (6.center);
|
||||
\draw (6.center) to (5.center);
|
||||
\draw (1.center) to (3.center);
|
||||
\draw (9.center) to (10.center);
|
||||
\draw [style=Dashed] (4.center) to (8.center);
|
||||
\draw [style=Dashed] (6.center) to (11.center);
|
||||
\draw [style=Dashed] (2.center) to (12.center);
|
||||
\draw [style=Dashed] (1.center) to (13.center);
|
||||
\draw [style=Very thick] (14.center) to (15.center);
|
||||
\draw [style=Very thick] (16.center) to (17.center);
|
||||
\draw [style=Vector] (18.center) to (19.center);
|
||||
\draw [style=Thick Vector] (9.center) to (21.center);
|
||||
\end{pgfonlayer}
|
||||
\end{tikzpicture}
|
Loading…
Reference in New Issue
Block a user