Merge remote-tracking branch 'origin/master'

This commit is contained in:
Arthur 2021-04-20 15:57:19 +02:00
commit c26d3db76d
13 changed files with 207 additions and 98 deletions

5
.gitignore vendored
View File

@ -15,6 +15,9 @@ hs_err_pid*.log
# log files # log files
rapport/ rapport/
!rapport/rapport.tex !rapport/rapport.tex
!rapport/pics/*.png
!rapport/pics/*.PNG
!rapport/pics/*.jpg
# javadoc files # javadoc files
doc/ doc/
@ -24,4 +27,4 @@ build/
# tests files # tests files
result.txt test*.txt

View File

@ -22,7 +22,7 @@ Pour compiler puis executer le programme, executez la commande: ant run
Pour générer une archive jar dans le répertoire build/, executez la commande: ant packaging Pour générer une archive jar dans le répertoire build/, executez la commande: ant packaging
Pour générer la javadoc dans le répertoire dans le dossier doc/, executez la commande: ant javadoc Pour générer la javadoc dans le dossier doc/, executez la commande: ant javadoc
Ouvrez ensuite le fichier index.html ou overview-summary.html dans un navigateur. Ouvrez ensuite le fichier index.html ou overview-summary.html dans un navigateur.
Pour effectuer les tests, executez la commande: ant tests Pour effectuer les tests, executez la commande: ant tests

View File

@ -58,7 +58,8 @@
<junit printsummary="true" haltonerror="no" haltonfailure="no" showoutput="true"> <junit printsummary="true" haltonerror="no" haltonfailure="no" showoutput="true">
<classpath refid="project.classpath"/> <classpath refid="project.classpath"/>
<formatter type="plain"/> <formatter type="plain"/>
<test fork="true" name="lsystem.TestLSystem" outfile="result" /> <test fork="true" name="lsystem.TestLSystem" outfile="test1" />
<test fork="true" name="lsystem.StressTest" outfile="test2" />
</junit> </junit>
</target> </target>
</project> </project>

BIN
rapport/pics/diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

View File

@ -4,11 +4,11 @@
Ce projet a pour objectif de réaliser une application appliquant des principes de programmation orientée objet en langage de programmation Java. Nous avons eu le choix entre 6 sujets différents et, après études des propositions, notre choix sest finalement porté sur le "Générateurs de flores vidéos-ludiques". Il consiste en la réalisation dun simulateur de L-système végétal produisant une image 2D et 3D de lobjet par le biais de règles de réécritures. Ce projet a pour objectif de réaliser une application appliquant des principes de programmation orientée objet en langage de programmation Java. Nous avons eu le choix entre 6 sujets différents et, après études des propositions, notre choix sest finalement porté sur le "Générateurs de flores vidéos-ludiques". Il consiste en la réalisation dun simulateur de L-système végétal produisant une image 2D et 3D de lobjet par le biais de règles de réécritures.
\info{Pour cela nous avions quelques consignes à respecter : \info{Pour cela nous avions quelques consignes à respecter :
\begin{itemize} \begin{itemize}
\item Intégrer un parser de L-système. \item Intégrer un parser de L-système.
\item Créer un moteur de réécriture. \item Créer un moteur de réécriture.
\item Créer un moteur de rendu graphique. \item Créer un moteur de rendu graphique.
\end{itemize}} \end{itemize}}
Après lecture des consignes, nous avons pu entamer nos recherches. Après lecture des consignes, nous avons pu entamer nos recherches.

View File

@ -29,12 +29,12 @@ Notre alphabet est composés de plusieurs règles et constantes :\\
\end{itemize} \end{itemize}
\subsection{Axiome, règles de réécritures et nombre d'itérations} \subsection{Axiome, règles de réécritures et nombre d'itérations}
Pour l'axiome, les règles de réécritures et le nombre d'itérations, ils seront définis par l'utilisateur dans les zones de textes de l'interface prévus a cet effet. Pour l'axiome, les règles de réécritures et le nombre d'itérations, ils seront définis par l'utilisateur dans les zones de textes de l'interface prévus a cet effet.
Un bouton "Aide" est présent sur cette même interface aidant à comprendre et mettre en place le L-Système. Un bouton "Aide" est présent sur cette même interface aidant à comprendre et mettre en place le L-Système.
\begin{figure}[h!] \begin{figure}[h!]
\centering \centering
\includegraphics[width=0.8\linewidth]{pics/aideGUI.png} \includegraphics[width=0.8\linewidth]{pics/aideGUI.png}
\caption{Fenêtre d'aide} \caption{Fenêtre d'aide}
\label{fig:help_frame} \label{fig:help_frame}
\end{figure} \end{figure}

View File

@ -4,8 +4,10 @@
L'organisation du projet a été soumit a un ordre de priorité car, comme cité dans "Mise en place du projet" (voir section \ref{sec:MEPprog}), certaines parties étaient nécessaires pour que d'autres fonctionnent ou puissent être amorcées : L'organisation du projet a été soumit a un ordre de priorité car, comme cité dans "Mise en place du projet" (voir section \ref{sec:MEPprog}), certaines parties étaient nécessaires pour que d'autres fonctionnent ou puissent être amorcées :
\begin{itemize} \begin{itemize}
\item En premier lieu nous fallait créer l'alphabet de notre L-Système (voir section \ref{sec:Alphabet}). \item En premier lieu nous fallait créer l'alphabet de notre L-Système (voir section \ref{sec:Alphabet}).
\item \item Mise en place de méthode Parser\#isCorrect() pour vérifier certains que la syntaxe du l-système est correcte.
\item \item Mise en place d'un moteur de réécriture.
\item Mis en place d'un parser qui transforme le mot obtenu par le moteur de réécriture en une structure de données plus facilement lisible afin d'être afficher par le moteur graphique.
\item affichage du L-Système dans le moteur graphique
\end{itemize} \end{itemize}
\section{Structure du projet} \section{Structure du projet}
@ -17,13 +19,16 @@ L'organisation du projet a été soumit a un ordre de priorité car, comme cité
\end{itemize} \end{itemize}
\item screen \item screen
\begin{itemize} \begin{itemize}
\item gl3d: Tout les objets relatifs a l'affichage 3d du L-Systeme, voir la section \label{src:interface3d} \item gl3d: Tout les objets relatifs a l'affichage 3d du L-Systeme, voir la section \ref{sec:interface3d}
\item main: Tout les objets relatifs au menu, voir la section \label{sec:menu} \item main: Tout les objets relatifs au menu, voir la section \ref{sec:menu}
\end{itemize} \end{itemize}
\item utils: contient l'objet Pair qui est essentiel au fonctionnement du projet \item utils: contient l'objet Pair qui est essentiel au fonctionnement du projet
\end{itemize} \end{itemize}
À détailler un peu plus \begin{figure}[h!]
\centering
\problem{!!!! Ajouter le diagramme de classe !!!!!} \includegraphics[width=0.7\linewidth]{pics/diagram.png}
\caption{Diagramme de classe de notre projet}
\label{fig:class_diagram}
\end{figure}

View File

@ -1,7 +1,5 @@
\chapter{Élements techniques} \chapter{Élements techniques}
\section{Parser}\label{sec:parser}
\section{Moteur de réécriture} \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. 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.
@ -11,12 +9,76 @@ Le mot est réécrit en 2 temps :\\
\item On change toutes les occurrences du mot à remplacer par \$\{identifiant de la règle\}. \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. \item On remplace toutes les occurrences de \$\{identifiant de la règle\} par la règle associée.
\end{itemize} \end{itemize}
On répète cette opération n fois, pour obtenir le mot final. On répète cette opération n fois, pour obtenir le mot final.\\
\section{Moteur graphique}\label{src:interface3d} L'algorithme de réécriture est séparé en 3 parties:\\
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. \begin{algorithm}
Pour naviguer dans l'espace 3D, voir la section \ref{sec:nav_3d} \DontPrintSemicolon
\KwIn{axiom: $String$, rules : $List[Tuple[String, String]$, recurrence: $Integer$}
\KwOut{Le mot réécrit itérativement: $String$}
\caption{{\sc Rewrite} Fonction principale appelé 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}
\begin{algorithm}
\DontPrintSemicolon
\KwIn{rewritten: $String$, rules : $List[Tuple[String, String]$}
\KwOut{Le mot partiellement réécrit}
\caption{{\sc 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)$\;
$toRwrite \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{{\sc 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é, il construit un arbre grâce la structure de données suivante
\begin{algorithm}
\DontPrintSemicolon
\caption{{\sc Element} Branche de l'arbre, si parent est vide alors, cet element 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.
\begin{figure}[h!] \begin{figure}[h!]
\centering \centering
@ -27,13 +89,13 @@ Pour naviguer dans l'espace 3D, voir la section \ref{sec:nav_3d}
\clearpage \clearpage
\section{Interface principale}\label{sec:menu} \section{Interface principale}
\label{sec:menu}
\subsection{Composition de l'interface} \subsection{Composition de l'interface}
\paragraph{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}.
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} \subsection{Classes de l'interface}
\subsubsection{MainFrame} \subsubsection{MainFrame}
@ -47,5 +109,6 @@ Elle comporte aussi une instance de la classe JTabbedPane \label{jtpane}, un con
\subsubsection{Listener} \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. \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} \section{Pair ou un tuple a 2 entrées en java}

View File

@ -42,13 +42,13 @@ Pour naviguer dans l'espace 3D, vous pouvez utiliser votre clavier ainsi que vot
\item \textbf{E} $\xrightarrow{} Tourner \ la \ caméra \ à \ droite$ \item \textbf{E} $\xrightarrow{} Tourner \ la \ caméra \ à \ droite$
\item \textbf{W} $\xrightarrow{} Prendre \ de \ la \ hauteur$ \item \textbf{W} $\xrightarrow{} Prendre \ de \ la \ hauteur$
\item \textbf{X} $\xrightarrow{} Perde \ de \ la \ hauteur$ \item \textbf{X} $\xrightarrow{} Perde \ de \ la \ hauteur$
\end{itemize} \end{itemize}
\paragraph{Liste des commandes à la souris :} \paragraph{Liste des commandes à la souris :}
\begin{itemize} \begin{itemize}
\item \textbf{Mollette Avant} $\xrightarrow{} Zommer$ \item \textbf{Mollette Avant} $\xrightarrow{} Zommer$
\item \textbf{Mollette Arrière} $\xrightarrow{} Dézoomer$ \item \textbf{Mollette Arrière} $\xrightarrow{} Dézoomer$
\item \textbf{Clic Droit} $\xrightarrow{} Maintenir \ puis \ bouger \ la \ souris \ pour \ changer \ l'orientation \ de \ la \ caméra$ \item \textbf{Clic Droit} $\xrightarrow{} Maintenir \ puis \ bouger \ la \ souris \ pour \ changer \ l'orientation \ de \ la \ caméra$
\end{itemize} \end{itemize}
\problem{Vous ne pouvez pas utiliser 2 touches ou plus en même temps pour naviguer. Par exemple, enfoncer les touches \textbf{Z} et \textbf{D} pour aller la direction nord-est est impossible, il vous faut tourner votre caméra dans la direction où vous voulez aller puis appuyer sur \textbf{Z}.} \problem{Vous ne pouvez pas utiliser 2 touches ou plus en même temps pour naviguer. Par exemple, enfoncer les touches \textbf{Z} et \textbf{D} pour aller la direction nord-est est impossible, il vous faut tourner votre caméra dans la direction où vous voulez aller puis appuyer sur \textbf{Z}.}

View File

@ -23,6 +23,7 @@
\usepackage[noend]{algpseudocode} \usepackage[noend]{algpseudocode}
\usepackage{listings} \usepackage{listings}
\usepackage{enumitem} \usepackage{enumitem}
\usepackage[linesnumbered,ruled,french,onelanguage]{algorithm2e}
\hyphenpenalty 10000 \hyphenpenalty 10000
\definecolor{link}{HTML}{4169E1} \definecolor{link}{HTML}{4169E1}
@ -34,51 +35,51 @@
\newcommand{\Java}{\textit{Java}} \newcommand{\Java}{\textit{Java}}
\newcommand{\Swing}{\textit{Swing}} \newcommand{\Swing}{\textit{Swing}}
\newmdenv[ \newmdenv[
rightline=false, rightline=false,
topline=false, topline=false,
bottomline=false, bottomline=false,
backgroundcolor=BurntOrange!5, backgroundcolor=BurntOrange!5,
fontcolor=BrickRed, fontcolor=BrickRed,
linecolor=Red, linecolor=Red,
linewidth=1pt]{problemenv} linewidth=1pt]{problemenv}
\newcommand{\problem}[1]{ \newcommand{\problem}[1]{
\begin{problemenv} \begin{problemenv}
\sffamily \sffamily
#1 #1
\end{problemenv} \end{problemenv}
} }
\newmdenv[ \newmdenv[
rightline=false, rightline=false,
topline=false, topline=false,
bottomline=false, bottomline=false,
backgroundcolor=ForestGreen!5, backgroundcolor=ForestGreen!5,
fontcolor=OliveGreen, fontcolor=OliveGreen,
linecolor=Green, linecolor=Green,
linewidth=1pt]{resultenv} linewidth=1pt]{resultenv}
\newcommand{\result}[1]{ \newcommand{\result}[1]{
\begin{resultenv} \begin{resultenv}
\sffamily \sffamily
#1 #1
\end{resultenv} \end{resultenv}
} }
\newmdenv[ \newmdenv[
rightline=false, rightline=false,
topline=false, topline=false,
bottomline=false, bottomline=false,
backgroundcolor=Cyan!5, backgroundcolor=Cyan!5,
fontcolor=Blue, fontcolor=Blue,
linecolor=NavyBlue, linecolor=NavyBlue,
linewidth=1pt]{infoenv} linewidth=1pt]{infoenv}
\newcommand{\info}[1]{ \newcommand{\info}[1]{
\begin{infoenv} \begin{infoenv}
\sffamily \sffamily
#1 #1
\end{infoenv} \end{infoenv}
} }
% Gestion d'abstracts multiples % Gestion d'abstracts multiples
@ -90,12 +91,18 @@
\renewenvironment{abstract}[1] \renewenvironment{abstract}[1]
{\bigskip\selectlanguage{#1}% {\bigskip\selectlanguage{#1}%
\begin{center}\bfseries\abstractname\end{center}} \begin{center}\bfseries\abstractname\end{center}}
{\par\bigskip} {\par\bigskip}
% Gestion des keywords % Gestion des keywords
\newcommand{\keywords}{\sffamily\textit{Keywords : }\bfseries} \newcommand{\keywords}{\sffamily\textit{Keywords : }\bfseries}
\makeatletter
\g@addto@macro{\@algocf@init}{\SetKwInput{KwOut}{Sortie}}
\makeatother
\SetKwRepeat{Struct}{struct \{}{\}}
%Page style %Page style
\pagestyle{headings} \pagestyle{headings}
@ -107,7 +114,7 @@
\titlehead{ \titlehead{
\includegraphics[width=0.25\textwidth]{pics/LOGO-UNICAEN_V-2.1-N.png} \includegraphics[width=0.25\textwidth]{pics/LOGO-UNICAEN_V-2.1-N.png}
\hfill \hfill
%\includegraphics[width=0.25\textwidth]{pics/} %\includegraphics[width=0.25\textwidth]{pics/}
} }
\subject{ \subject{
\small \small
@ -134,31 +141,31 @@
\small \small
\hfill\\ \hfill\\
Antonin \bsc{Boyon}\\ Antonin \bsc{Boyon}\\
Thomas \bsc{Lalong}\\ Thomas \bsc{Lalong}\\
Quentin \bsc{Legot}\\ Quentin \bsc{Legot}\\
Arthur \bsc{Page} Arthur \bsc{Page}
} }
\date{} \date{}
\newcommand{\placeholderwarning}{ \newcommand{\placeholderwarning}{
\problem{CECI EST UN PLACEHOLDER. À REMPLACER AVEC LES DONNÉES INDIQUÉES.} \problem{CECI EST UN PLACEHOLDER. À REMPLACER AVEC LES DONNÉES INDIQUÉES.}
} }
\makeglossary \makeglossary
%redaction guide -> https://docs.google.com/document/d/1YfxGWD0GbRxs-OLxRxoA8Sg8OuVYTSKK8HX1ScFYlFA %redaction guide -> https://docs.google.com/document/d/1YfxGWD0GbRxs-OLxRxoA8Sg8OuVYTSKK8HX1ScFYlFA
\begin{document} \begin{document}
\maketitle \maketitle
\pagenumbering{Roman} \pagenumbering{Roman}
\tableofcontents \tableofcontents
\listoffigures \listoffigures
\clearpage \clearpage
\pagenumbering{arabic} \pagenumbering{arabic}
\input{chapters/chapitre1.tex} \input{chapters/chapitre1.tex}
\input{chapters/chapitre2.tex} \input{chapters/chapitre2.tex}
\input{chapters/chapitre3.tex} \input{chapters/chapitre3.tex}
\input{chapters/chapitre4.tex} \input{chapters/chapitre4.tex}
@ -166,18 +173,18 @@
\input{chapters/chapitre6.tex} \input{chapters/chapitre6.tex}
\cleardoublepage \cleardoublepage
\pagebreak \pagebreak
\pagenumbering{roman} \pagenumbering{roman}
\chapter{Annexes} \chapter{Annexes}
\section{Remerciements} \section{Remerciements}
Triss Jacquiot pour le modèle de rapport bien plus beau que l'original Triss Jacquiot pour le modèle de rapport bien plus beau que l'original
\addcontentsline{toc}{section}{6.2\quad{}Bibliographie} \addcontentsline{toc}{section}{6.2\quad{}Bibliographie}
\begin{thebibliography}{} \begin{thebibliography}{}
\bibitem{ano05} \bibitem{ano05}
A. Nonymous et al.\ 2005 A. Nonymous et al.\ 2005
\bibitem{oe04} \bibitem{oe04}
A.N. Other \& S.O.M. Ebody 2004 A.N. Other \& S.O.M. Ebody 2004
\end{thebibliography} \end{thebibliography}
\end{document} \end{document}

View File

@ -156,7 +156,7 @@ public class Parser {
} }
} }
} }
assert root == null; assert root != null;
return root; return root;
} }

View File

@ -55,7 +55,7 @@ public class Rewrite {
System.out.println(i + " / " + recurrences + " : " + rewritten.length()); System.out.println(i + " / " + recurrences + " : " + rewritten.length());
} }
rewritten = rewritten.replace("[", "Y["); rewritten = rewritten.replace("[", "Y[");
System.out.println(rewritten); // System.out.println(rewritten);
return rewritten; return rewritten;
} }

View File

@ -0,0 +1,30 @@
package lsystem;
import lsystem.engine.Parser;
import lsystem.screen.gl3d.GLCanvas;
import lsystem.utils.Pair;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertNotNull;
public class StressTest {
/**
* require at least 3GB of free ram
*/
@Test
public void stressTest1() {
long millis = System.currentTimeMillis();
GLCanvas joglFrame = new GLCanvas();
Parser parser = new Parser("Y", Arrays.asList("Y=X+[[Y]-Y]-X[-XY]+Y", "X=XX"), 11);
List<Pair<String, String>> lSystemRules = parser.parseRules();
joglFrame.setLSystem(parser.getAxiom(), lSystemRules, parser.getNbIterations());
System.out.println(joglFrame.getLSystem());
System.out.println("time in millisecondes: " + (System.currentTimeMillis() - millis));
assertNotNull("L-System should not be null", joglFrame.getLSystem());
}
}