Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c26d3db76d
5
.gitignore
vendored
5
.gitignore
vendored
@ -15,6 +15,9 @@ hs_err_pid*.log
|
||||
# log files
|
||||
rapport/
|
||||
!rapport/rapport.tex
|
||||
!rapport/pics/*.png
|
||||
!rapport/pics/*.PNG
|
||||
!rapport/pics/*.jpg
|
||||
|
||||
# javadoc files
|
||||
doc/
|
||||
@ -24,4 +27,4 @@ build/
|
||||
|
||||
# tests files
|
||||
|
||||
result.txt
|
||||
test*.txt
|
@ -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 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.
|
||||
|
||||
Pour effectuer les tests, executez la commande: ant tests
|
||||
|
@ -58,7 +58,8 @@
|
||||
<junit printsummary="true" haltonerror="no" haltonfailure="no" showoutput="true">
|
||||
<classpath refid="project.classpath"/>
|
||||
<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>
|
||||
</target>
|
||||
</project>
|
BIN
rapport/pics/diagram.png
Normal file
BIN
rapport/pics/diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 276 KiB |
@ -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 s’est finalement porté sur le "Générateurs de flores vidéos-ludiques". Il consiste en la réalisation d’un simulateur de L-système végétal produisant une image 2D et 3D de l’objet par le biais de règles de réécritures.
|
||||
|
||||
\info{Pour cela nous avions quelques consignes à respecter :
|
||||
\begin{itemize}
|
||||
\begin{itemize}
|
||||
\item Intégrer un parser de L-système.
|
||||
\item Créer un moteur de réécriture.
|
||||
\item Créer un moteur de rendu graphique.
|
||||
\end{itemize}}
|
||||
\end{itemize}}
|
||||
|
||||
Après lecture des consignes, nous avons pu entamer nos recherches.
|
||||
|
||||
|
@ -33,8 +33,8 @@ Pour l'axiome, les règles de réécritures et le nombre d'itérations, ils sero
|
||||
Un bouton "Aide" est présent sur cette même interface aidant à comprendre et mettre en place le L-Système.
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=0.8\linewidth]{pics/aideGUI.png}
|
||||
\caption{Fenêtre d'aide}
|
||||
\label{fig:help_frame}
|
||||
\centering
|
||||
\includegraphics[width=0.8\linewidth]{pics/aideGUI.png}
|
||||
\caption{Fenêtre d'aide}
|
||||
\label{fig:help_frame}
|
||||
\end{figure}
|
||||
|
@ -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 :
|
||||
\begin{itemize}
|
||||
\item En premier lieu nous fallait créer l'alphabet de notre L-Système (voir section \ref{sec:Alphabet}).
|
||||
\item
|
||||
\item
|
||||
\item Mise en place de méthode Parser\#isCorrect() pour vérifier certains que la syntaxe du l-système est correcte.
|
||||
\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}
|
||||
|
||||
\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}
|
||||
\item screen
|
||||
\begin{itemize}
|
||||
\item gl3d: Tout les objets relatifs a l'affichage 3d du L-Systeme, voir la section \label{src:interface3d}
|
||||
\item main: Tout les objets relatifs au menu, voir la section \label{sec:menu}
|
||||
\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 \ref{sec:menu}
|
||||
\end{itemize}
|
||||
\item utils: contient l'objet Pair qui est essentiel au fonctionnement du projet
|
||||
\end{itemize}
|
||||
|
||||
À détailler un peu plus
|
||||
|
||||
\problem{!!!! Ajouter le diagramme de classe !!!!!}
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=0.7\linewidth]{pics/diagram.png}
|
||||
\caption{Diagramme de classe de notre projet}
|
||||
\label{fig:class_diagram}
|
||||
\end{figure}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
\chapter{Élements techniques}
|
||||
|
||||
\section{Parser}\label{sec:parser}
|
||||
|
||||
\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.
|
||||
@ -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 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.
|
||||
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.
|
||||
Pour naviguer dans l'espace 3D, voir la section \ref{sec:nav_3d}
|
||||
\begin{algorithm}
|
||||
\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!]
|
||||
\centering
|
||||
@ -27,12 +89,12 @@ Pour naviguer dans l'espace 3D, voir la section \ref{sec:nav_3d}
|
||||
|
||||
\clearpage
|
||||
|
||||
\section{Interface principale}\label{sec:menu}
|
||||
\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}.
|
||||
\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}
|
||||
|
||||
@ -47,5 +109,6 @@ Elle comporte aussi une instance de la classe JTabbedPane \label{jtpane}, un con
|
||||
|
||||
\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}
|
||||
|
@ -42,9 +42,9 @@ 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{W} $\xrightarrow{} Prendre \ de \ la \ hauteur$
|
||||
\item \textbf{X} $\xrightarrow{} Perde \ de \ la \ hauteur$
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\paragraph{Liste des commandes à la souris :}
|
||||
\begin{itemize}
|
||||
\begin{itemize}
|
||||
\item \textbf{Mollette Avant} $\xrightarrow{} Zommer$
|
||||
\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$
|
||||
|
@ -23,6 +23,7 @@
|
||||
\usepackage[noend]{algpseudocode}
|
||||
\usepackage{listings}
|
||||
\usepackage{enumitem}
|
||||
\usepackage[linesnumbered,ruled,french,onelanguage]{algorithm2e}
|
||||
\hyphenpenalty 10000
|
||||
|
||||
\definecolor{link}{HTML}{4169E1}
|
||||
@ -34,51 +35,51 @@
|
||||
\newcommand{\Java}{\textit{Java}}
|
||||
\newcommand{\Swing}{\textit{Swing}}
|
||||
\newmdenv[
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
backgroundcolor=BurntOrange!5,
|
||||
fontcolor=BrickRed,
|
||||
linecolor=Red,
|
||||
linewidth=1pt]{problemenv}
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
backgroundcolor=BurntOrange!5,
|
||||
fontcolor=BrickRed,
|
||||
linecolor=Red,
|
||||
linewidth=1pt]{problemenv}
|
||||
|
||||
\newcommand{\problem}[1]{
|
||||
\begin{problemenv}
|
||||
\sffamily
|
||||
#1
|
||||
\end{problemenv}
|
||||
\begin{problemenv}
|
||||
\sffamily
|
||||
#1
|
||||
\end{problemenv}
|
||||
}
|
||||
|
||||
\newmdenv[
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
backgroundcolor=ForestGreen!5,
|
||||
fontcolor=OliveGreen,
|
||||
linecolor=Green,
|
||||
linewidth=1pt]{resultenv}
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
backgroundcolor=ForestGreen!5,
|
||||
fontcolor=OliveGreen,
|
||||
linecolor=Green,
|
||||
linewidth=1pt]{resultenv}
|
||||
|
||||
\newcommand{\result}[1]{
|
||||
\begin{resultenv}
|
||||
\sffamily
|
||||
#1
|
||||
\end{resultenv}
|
||||
\begin{resultenv}
|
||||
\sffamily
|
||||
#1
|
||||
\end{resultenv}
|
||||
}
|
||||
|
||||
\newmdenv[
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
backgroundcolor=Cyan!5,
|
||||
fontcolor=Blue,
|
||||
linecolor=NavyBlue,
|
||||
linewidth=1pt]{infoenv}
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
backgroundcolor=Cyan!5,
|
||||
fontcolor=Blue,
|
||||
linecolor=NavyBlue,
|
||||
linewidth=1pt]{infoenv}
|
||||
|
||||
\newcommand{\info}[1]{
|
||||
\begin{infoenv}
|
||||
\sffamily
|
||||
#1
|
||||
\end{infoenv}
|
||||
\begin{infoenv}
|
||||
\sffamily
|
||||
#1
|
||||
\end{infoenv}
|
||||
}
|
||||
|
||||
% Gestion d'abstracts multiples
|
||||
@ -90,12 +91,18 @@
|
||||
\renewenvironment{abstract}[1]
|
||||
{\bigskip\selectlanguage{#1}%
|
||||
\begin{center}\bfseries\abstractname\end{center}}
|
||||
{\par\bigskip}
|
||||
{\par\bigskip}
|
||||
|
||||
% Gestion des keywords
|
||||
|
||||
\newcommand{\keywords}{\sffamily\textit{Keywords : }\bfseries}
|
||||
|
||||
\makeatletter
|
||||
\g@addto@macro{\@algocf@init}{\SetKwInput{KwOut}{Sortie}}
|
||||
\makeatother
|
||||
|
||||
\SetKwRepeat{Struct}{struct \{}{\}}
|
||||
|
||||
%Page style
|
||||
|
||||
\pagestyle{headings}
|
||||
@ -107,7 +114,7 @@
|
||||
\titlehead{
|
||||
\includegraphics[width=0.25\textwidth]{pics/LOGO-UNICAEN_V-2.1-N.png}
|
||||
\hfill
|
||||
%\includegraphics[width=0.25\textwidth]{pics/}
|
||||
%\includegraphics[width=0.25\textwidth]{pics/}
|
||||
}
|
||||
\subject{
|
||||
\small
|
||||
@ -141,7 +148,7 @@
|
||||
\date{}
|
||||
|
||||
\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
|
||||
@ -149,11 +156,11 @@
|
||||
\begin{document}
|
||||
|
||||
|
||||
\maketitle
|
||||
\pagenumbering{Roman}
|
||||
\tableofcontents
|
||||
\listoffigures
|
||||
\clearpage
|
||||
\maketitle
|
||||
\pagenumbering{Roman}
|
||||
\tableofcontents
|
||||
\listoffigures
|
||||
\clearpage
|
||||
|
||||
|
||||
\pagenumbering{arabic}
|
||||
|
@ -156,7 +156,7 @@ public class Parser {
|
||||
}
|
||||
}
|
||||
}
|
||||
assert root == null;
|
||||
assert root != null;
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class Rewrite {
|
||||
System.out.println(i + " / " + recurrences + " : " + rewritten.length());
|
||||
}
|
||||
rewritten = rewritten.replace("[", "Y[");
|
||||
System.out.println(rewritten);
|
||||
// System.out.println(rewritten);
|
||||
return rewritten;
|
||||
}
|
||||
|
||||
|
30
test/lsystem/StressTest.java
Normal file
30
test/lsystem/StressTest.java
Normal 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());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user