Finished collision detection
This commit is contained in:
parent
26545bd50d
commit
db3e1eb850
Binary file not shown.
@ -4,6 +4,7 @@
|
|||||||
\usepackage[]{url}
|
\usepackage[]{url}
|
||||||
\usepackage[]{subcaption}
|
\usepackage[]{subcaption}
|
||||||
\usepackage[]{float}
|
\usepackage[]{float}
|
||||||
|
\usepackage[]{multicol}
|
||||||
|
|
||||||
\usepackage{tikz}
|
\usepackage{tikz}
|
||||||
\usepackage{tkz-euclide}
|
\usepackage{tkz-euclide}
|
||||||
@ -66,6 +67,8 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
\counterwithin{figure}{section}
|
||||||
|
\counterwithin{equation}{section}
|
||||||
|
|
||||||
\usepackage{subfiles} % Best loaded last in the preamble
|
\usepackage{subfiles} % Best loaded last in the preamble
|
||||||
|
|
||||||
|
@ -306,12 +306,12 @@ orthogonal axes.
|
|||||||
\centering
|
\centering
|
||||||
\inputtikz[.7]{SAT_mvp}
|
\inputtikz[.7]{SAT_mvp}
|
||||||
\caption{SAT: Minimum push vector $\vec v_i$ on axis defined by $\vec o_i$,
|
\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}
|
\label{fig:SAT-mpv}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
The candidate MPVs $\vec v_i$ are the vectors that define the axis $\vec o_i$
|
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
|
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.
|
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
|
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
|
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
|
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}
|
\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}
|
\subsection{Collision resolution}
|
||||||
\label{sub:resolution}
|
\label{sub:resolution}
|
||||||
\subsubsection{Physics}
|
|
||||||
\subsubsection{Solving for the impulse parameter}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user