128 lines
6.2 KiB
TeX
128 lines
6.2 KiB
TeX
\chapter{Élements techniques}
|
|
|
|
\section{Moteur de réécriture}
|
|
|
|
Le moteur de réécriture est chargé d'appliquer les règles de réécritures itérativement à partir de l'axiome pour obtenir le mot final.
|
|
Nous avons d'un côté l'axiome qui est le mot de départ et une liste de règles qui contient 2 données : le mot à remplacer et son remplaçant.
|
|
Le mot est réécrit en 2 temps :\\
|
|
\begin{itemize}
|
|
\item On change toutes les occurrences du mot à remplacer par \$\{identifiant de la règle\}.
|
|
\item On remplace toutes les occurrences de \$\{identifiant de la règle\} par la règle associée.
|
|
\end{itemize}
|
|
On répète cette opération n fois, pour obtenir le mot final.\\
|
|
\\
|
|
\\
|
|
\\
|
|
L'algorithme de réécriture est séparé en 3 parties:\\
|
|
|
|
\begin{algorithm}
|
|
\DontPrintSemicolon
|
|
\KwIn{axiom: $String$, rules : $List[Tuple[String, String]$, recurrence: $Integer$}
|
|
\KwOut{Le mot réécrit itérativement: $String$}
|
|
\caption{Rewrite Fonction principale appelée par la fenêtre principale}
|
|
$rewritten \gets \emptyset$\;
|
|
\For{$i \gets 0$ \textbf{à} $recurrence$} {
|
|
$toRewrite \gets replaceRulesByID(rewritten, rules)$\;
|
|
$rewritten \gets = replaceIDByRuleApplication(toRewrite, rules)$\;
|
|
}
|
|
$rewritten = rewritten.replace("[", "Y[")$\;
|
|
\Return{$rewritten$}\;
|
|
\end{algorithm}
|
|
\newpage
|
|
\begin{algorithm}
|
|
\DontPrintSemicolon
|
|
\KwIn{rewritten: $String$, rules : $List[Tuple[String, String]$}
|
|
\KwOut{Le mot partiellement réécrit}
|
|
\caption{replaceRulesByID remplace les occurrences des différentes règles par \$\{id\}}
|
|
$toRewrite \gets rewritten$\;
|
|
\For{$i \gets 0$ \textbf{à} $rules.size()$}{
|
|
$pair \gets rules.get(i)$\;
|
|
$toRewrite \gets toRewrite.replace(pair[0], "\$\{" + i + "\}")$\;
|
|
}
|
|
\Return{$toRewrite$}
|
|
|
|
\end{algorithm}
|
|
|
|
\begin{algorithm}
|
|
\DontPrintSemicolon
|
|
\KwIn{toRewrite: $String$, rules : $List[Tuple[String, String]$}
|
|
\KwOut{Le mot entièrement réécrit}
|
|
\caption{replaceIDByRuleApplication remplace les occurrences \$\{id\} par la définition des différentes règles}
|
|
$rewritten \gets toRewrite$\;
|
|
\For{$i \gets 0$ \textbf{à} $rules.size()$}{
|
|
$rewritten \gets rewritten.replace("\$\{" + i + "\}", rules.get(i)[1]$\;
|
|
}
|
|
\Return{$rewritten$}
|
|
\end{algorithm}
|
|
|
|
\clearpage
|
|
|
|
\section{Parser}
|
|
\label{sec:parser}
|
|
|
|
Le rôle du parser est à partir d'un mot réécrit par le moteur de réécriture de convertir celui-ci en une structure de données plus facilement manipulable afin de l'afficher dans le moteur graphique.
|
|
En appliquant les règles précédemment énoncées, il construit un arbre grâce à la structure de données suivante.
|
|
|
|
\begin{algorithm}
|
|
\DontPrintSemicolon
|
|
\caption{Element Branche de l'arbre, si parent est vide alors, cet élément est la racine}
|
|
\Struct{Element}{
|
|
propery: $ElementProperty$ \Comment{enumérateur, valeurs possibles: $DRAW$ ou $NOTHING$}\;
|
|
parent: $Element$\;
|
|
rotation: $Float[3]$\;
|
|
children: $List[Element]$\;
|
|
}
|
|
\end{algorithm}
|
|
|
|
|
|
\section{Moteur graphique}
|
|
\label{sec:interface3d}
|
|
|
|
Nous utilisons \Java \ OpenGL pour afficher une fenêtre 3D, gl2 pour afficher les lignes de la grille, glu pour placer la caméra et GLUT pour afficher les cylindres.\\
|
|
Pour naviguer dans l'espace 3D, voir la section \ref{sec:nav_3d}.\\
|
|
Pour afficher le L-Système nous utilisons une méthode récursive.
|
|
|
|
Les classes GLKeyboardListener et GLMouseListener écoutent respectivement le clavier et la souris.\\
|
|
|
|
GLCanvas crée la fenêtre (grâce à AbstractCanvas), GLEventListener initialise et affiche l'environnement 3D.\\
|
|
|
|
DrawHelper est une classe utilitaire qui permet d'afficher certains éléments afin d'alléger la méthode display située dans GLEventListener.
|
|
|
|
\begin{figure}[h!]
|
|
\centering
|
|
\includegraphics[width=0.8\linewidth]{pics/3dGUI.png}
|
|
\caption{Fenêtre 3D}
|
|
\label{fig:3d_frame}
|
|
\end{figure}
|
|
|
|
\clearpage
|
|
|
|
\section{Interface principale}
|
|
\label{sec:menu}
|
|
|
|
\subsection{Composition de l'interface}
|
|
|
|
\paragraph{L'interface} utilisateur de notre logiciel a été conçu grâce à la bibliothèque \Swing \ de \Java. Elle se compose de trois classes, une contenant la fenêtre principale \classe{MainFrame}, une autre permettant de créer des onglets, \classe{Tab} et une troisième classe gérant les événements, \classe{Listener}.
|
|
|
|
\subsection{Classes de l'interface}
|
|
|
|
\subsubsection{MainFrame}
|
|
|
|
\paragraph{La classe \classe{MainFrame}} est une classe héritant de la classe JFrame de \Swing. Elle permet de créer une fenêtre de base, de taille prédéfinie, dans laquelle peuvent être placés des composants graphiques. Elle comprend aussi un bouton de fermeture qui, une fois cliqué, permet l'arrêt du programme.\\
|
|
Elle comporte aussi une instance de la classe JTabbedPane \label{jtpane}, un conteneur graphique dont le but est de disposer ses composants sous la forme d'onglets.
|
|
|
|
\subsubsection{Tab}
|
|
|
|
\paragraph{La classe \classe{Tab}} est une classe héritant de la classe JPanel de \Swing. JPanel est un composant de base dans lequel il est possible d'ajouter d'autres composants graphiques. Les instances de \classe{Tab} créées sont ensuite ajoutées par la classe \classe{MainFrame} à son composant de la classe JTabbedPane \ref{jtpane}.
|
|
|
|
\subsubsection{Listener}
|
|
|
|
\paragraph{La classe \classe{Listener}} est une classe implémentant certaines classes Listener de \\\Swing (\classe{ActionListener, KeyListener et MouseWheelListener}). Elle permet de capter toutes les actions effectuées par l'utilisateur et d'appeler les méthodes correspondantes des classes de l'interface. Elle permet ainsi de créer de nouveaux onglets (Nouvelles instances de Tab) mais aussi d'en fermer ou bien encore de lancer la génération du modèle.
|
|
|
|
\section{Pair ou un tuple a 2 entrées en java}
|
|
|
|
Nous avons utilisé les classes génériques afin de créer une classe nommé Pair, elle possède 2 paramètres génériques nous permettant de lui assigner des éléments de n'importe quel type.\\
|
|
Une fois instanciée avec ces 2 éléments, son contenu n'est plus modifiable, ce qui en fait un uplet à 2 éléments (couple).\\
|
|
Nous l'utilisons ici pour stocker les règles, la partie gauche du couple stocke le contenu qui va être remplacé dans l'axiome et la partie droite le remplaçant.\\
|
|
Nous l'utilisons seulement dans ce projet pour stocker des \string mais il est possible de stocker n'importe quelle instance d'un objet.
|