Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c10ecfeb15
@ -18,13 +18,21 @@ Ce mot passera ensuite par un moteur graphique dans le but d'être modélisé.
|
||||
\section{Notre L-Système}
|
||||
|
||||
\subsection{Alphabet}
|
||||
Notre alphabet est composés de plusieurs constantes :
|
||||
\begin{itemize}[label=\textbullet]
|
||||
\item Peut
|
||||
\item Etre
|
||||
\item Faire
|
||||
\item Une liste
|
||||
Notre alphabet est composés de plusieurs règles et constantes:\\
|
||||
\begin{itemize}
|
||||
\item X permet de dessiner une branche et Y de dessinera rien, il permet avec certaines règles de contrôler l'évolution de notre L-Système.
|
||||
\item Il est possible de modifier l'angle d'une branche en utilisant par exemple les +, -, -35, +64y, qui donnera
|
||||
respectivement une orientation de 25° et -25° sur l'axe de rotation x, une rotation de -35° sur l'axe X et une orientation de 64° sur l'axe de rotation y; il n'est pas possible de modifier l'orientation de l'axe de rotation Z.
|
||||
\item Enfin il est possible d'utiliser les crochets [] pour contrôler l'évolution et obtenir des branches à votre arbres, ces crochets vont conserver l'état, c'est à dire qu'une rotation appliqué aux crochets s'appliquera a tout les éléments étant à l'intérieur des crochets, par exemple: +[XYX] appliquera une rotation de 25° à XYX. Il est possible d'imbriquer des crochets.
|
||||
\end{itemize}
|
||||
|
||||
\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.
|
||||
Un bouton "Aide" est présent sur cette même interface aidant a 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:my_label}
|
||||
\end{figure}
|
@ -79,21 +79,6 @@ linewidth=1pt]{infoenv}
|
||||
\end{infoenv}
|
||||
}
|
||||
|
||||
\newcommand{\img}[1]{
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{#1}
|
||||
\end{figure}
|
||||
}
|
||||
|
||||
\newcommand{\imgwlegend}[2]{
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{#1}
|
||||
\caption{#2}
|
||||
\end{figure}
|
||||
}
|
||||
|
||||
% Gestion d'abstracts multiples
|
||||
|
||||
\newenvironment{abstractpage}
|
||||
|
@ -179,4 +179,11 @@ public class Parser {
|
||||
}
|
||||
|
||||
|
||||
public int getNbIterations() {
|
||||
return nbIterations;
|
||||
}
|
||||
|
||||
public String getAxiom() {
|
||||
return axiom;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class Constants {
|
||||
+ "\tX = X20yY-X\r\n"
|
||||
+ "\r\n"
|
||||
+ "On ajoute le principe de branches aux expressions, on utilise donc pour ce faire les crochets \"[ ]\".\r\n"
|
||||
+ "Elles permettent de controler l'évolution de l'arbre en appliquant la rotation qu'il lui est appliqué à tout"
|
||||
+ "Elles permettent de controler l'évolution de l'arbre en appliquant la rotation qu'il lui est appliqué à tout\r\n"
|
||||
+ "les elements étant à l'intérieur des crochets"
|
||||
+ "\r\n"
|
||||
+ "Ainsi, dans l'expression:\r\n"
|
||||
|
@ -33,7 +33,7 @@ public abstract class AbstractListener implements GLEventListener {
|
||||
GL2 gl = glAutoDrawable.getGL().getGL2();
|
||||
|
||||
gl.glClearColor(0f, 0f, 0f, 1.0f);
|
||||
|
||||
gl.setSwapInterval(0);
|
||||
new Thread(() -> {
|
||||
while (canvas.frame.isVisible()) {
|
||||
try {
|
||||
|
@ -47,34 +47,6 @@ public class DrawHelper {
|
||||
glut.glutBitmapCharacter(GLUT.BITMAP_HELVETICA_18, 'Z'); // draw the z axis
|
||||
}
|
||||
|
||||
/**
|
||||
* draw the L-System, move the camera and then use recursive call to draw branches of {@code element}
|
||||
* @param listener use to move the camera depending of the size if the L-System
|
||||
* @param gl use to move cursor
|
||||
* @param glut use to draw pre implemented function like {@link GLUT#glutSolidCylinder(double, double, int, int)}
|
||||
* @param element working branch of the {@link Element LSystem}
|
||||
*/
|
||||
public static void drawLSystem(AbstractListener listener, GL2 gl, GLUT glut, Element element) {
|
||||
gl.glPushMatrix();
|
||||
gl.glRotatef(element.rotation[0] * 360, 1f, 0f, 0f);
|
||||
gl.glRotatef(element.rotation[1] * 360, 0f, 1f, 0f);
|
||||
gl.glRotated(-Math.sin(element.rotation[0]) * 180 - Math.sin(element.rotation[1]) * 180, 0f, 0f, 1f);
|
||||
gl.glTranslated(-Math.sin(element.rotation[0]), -Math.sin(element.rotation[1]), -Math.sin(element.rotation[0] + element.rotation[1]));
|
||||
|
||||
if(element.property == ElementProperties.DRAW) {
|
||||
if(listener.firstGen) {
|
||||
listener.canvas.camera[1] += 0.10f;
|
||||
listener.canvas.camera[2] += 0.10f;
|
||||
}
|
||||
glut.glutSolidCylinder(0.25f, 1f, 10, 10);
|
||||
gl.glTranslatef(0f, 0f, 1f);
|
||||
}
|
||||
|
||||
for(Element child : element.children) {
|
||||
drawLSystem(listener, gl, glut, child);
|
||||
}
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void drawDebugInformation(GL2 gl, GLUT glut, AbstractCanvas canvas) {
|
||||
|
@ -3,6 +3,7 @@ package lsystem.screen.gl3d;
|
||||
import com.jogamp.opengl.GL2;
|
||||
import com.jogamp.opengl.GLAutoDrawable;
|
||||
import lsystem.engine.Element;
|
||||
import lsystem.engine.ElementProperties;
|
||||
import lsystem.screen.Constants;
|
||||
|
||||
/**
|
||||
@ -76,9 +77,32 @@ public class GLEventListener extends AbstractListener {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* draw the L-System, move the camera and then use recursive call to draw branches of {@code element}
|
||||
* @param gl use to move cursor
|
||||
* @param element working branch of the {@link Element LSystem}
|
||||
*/
|
||||
@Override
|
||||
public void drawLSystem(GL2 gl, Element element) {
|
||||
DrawHelper.drawLSystem(this, gl, glut, element);
|
||||
gl.glPushMatrix();
|
||||
gl.glRotatef(element.rotation[0] * 360, 1f, 0f, 0f);
|
||||
gl.glRotatef(element.rotation[1] * 360, 0f, 1f, 0f);
|
||||
gl.glRotated(-Math.sin(element.rotation[0]) * 180 - Math.sin(element.rotation[1]) * 180, 0f, 0f, 1f);
|
||||
gl.glTranslated(-Math.sin(element.rotation[0]), -Math.sin(element.rotation[1]), -Math.sin(element.rotation[0] + element.rotation[1]));
|
||||
|
||||
if(element.property == ElementProperties.DRAW) {
|
||||
if(firstGen) {
|
||||
canvas.camera[1] += 0.10f;
|
||||
canvas.camera[2] += 0.10f;
|
||||
}
|
||||
glut.glutSolidCylinder(0.25f, 1f, 10, 10);
|
||||
gl.glTranslatef(0f, 0f, 1f);
|
||||
}
|
||||
|
||||
for(Element child : element.children) {
|
||||
drawLSystem(gl, child);
|
||||
}
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
39
src/lsystem/screen/main/Example.java
Normal file
39
src/lsystem/screen/main/Example.java
Normal file
@ -0,0 +1,39 @@
|
||||
package lsystem.screen.main;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class Example extends JPanel {
|
||||
|
||||
private final MainFrame frame;
|
||||
|
||||
public Example(MainFrame frame) {
|
||||
this.frame = frame;
|
||||
|
||||
JPanel list = new JPanel();
|
||||
list.setLayout(new GridBagLayout());
|
||||
JButton a = new JButton("{axiom=\"Y\",rules:[\"Y=X+[[Y]-Y]-X[-XY]+Y\", \"X=XX\"]}");
|
||||
a.addActionListener(new ExampleListener("a"));
|
||||
JPanel aboveComponents = new JPanel();
|
||||
|
||||
}
|
||||
|
||||
private class ExampleListener implements ActionListener {
|
||||
|
||||
private final String type;
|
||||
|
||||
public ExampleListener(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch(type) {
|
||||
case "a":
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
package lsystem.screen.main;
|
||||
|
||||
import lsystem.Main;
|
||||
import lsystem.engine.Parser;
|
||||
import lsystem.screen.gl3d.AbstractCanvas;
|
||||
import lsystem.utils.Pair;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@ -16,7 +13,6 @@ public class Listener implements ActionListener, KeyListener, MouseWheelListener
|
||||
Integer index;
|
||||
String type;
|
||||
Integer nbAxioms= 0;
|
||||
Thread parserThread = null;
|
||||
ImageIcon staticIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(getClass().getClassLoader().getResource("./loading-gif.gif")));
|
||||
|
||||
|
||||
@ -46,7 +42,9 @@ public class Listener implements ActionListener, KeyListener, MouseWheelListener
|
||||
case "Tab":
|
||||
frame.newTab();
|
||||
break;
|
||||
|
||||
case "example":
|
||||
frame.newExample();
|
||||
break;
|
||||
case "Clear":
|
||||
tab.getTextArea((byte) 0).setText("Axiome : \n");
|
||||
tab.getTextArea((byte) 1).setText("Règles : \n");
|
||||
@ -60,46 +58,13 @@ public class Listener implements ActionListener, KeyListener, MouseWheelListener
|
||||
String axiom3D = tab.getAxiom();
|
||||
List<String> rules3D = tab.getRules();
|
||||
Parser parser3D = new Parser(axiom3D, rules3D, tab.getNbIterations());
|
||||
if(Main.joglFrame.frame.isVisible()) {
|
||||
openDialog("Veuillez fermer la fenêtre 2D ou 3D avant de lancer une nouvelle génération");
|
||||
} else if(Main.joglFrame.parsedState == AbstractCanvas.State.LOAD) {
|
||||
openDialog("Une génération est actuellement en cours, impossible d'en relancer un autre");
|
||||
openDialog("Une génération est actuellement en cours, impossible d'en relancer un autre");
|
||||
} else if (!parser3D.isCorrect()) {
|
||||
openDialog("Vos règles ou votre axiome ne sont pas correctement écrites, veuillez recommencer");
|
||||
} else {
|
||||
tab.submitButton3D.setIcon(staticIcon);
|
||||
tab.submitButton3D.setText("");
|
||||
parserThread = new Thread(() -> {
|
||||
try {
|
||||
List<Pair<String, String>> lSystemRules = parser3D.parseRules();
|
||||
Main.joglFrame.setLSystem(axiom3D, lSystemRules, tab.getNbIterations());
|
||||
|
||||
StringBuilder message = new StringBuilder("L-System 3D - {axiom:\"").append(axiom3D).append("\",rules:[");
|
||||
for(int i = 0; i < lSystemRules.size(); ++i) {
|
||||
Pair<String, String> rule = lSystemRules.get(i);
|
||||
message.append("\"").append(rule.getLeft()).append("=").append(rule.getRight()).append("\"");
|
||||
if(i + 1 != lSystemRules.size())
|
||||
message.append(",");
|
||||
}
|
||||
Main.joglFrame.frame.setTitle(message.append("]} - Nombres d'itérations: ").append(tab.getNbIterations()).toString());
|
||||
|
||||
Main.joglFrame.setVisible(true);
|
||||
} catch (NumberFormatException err) {
|
||||
Main.joglFrame.parsedState = AbstractCanvas.State.FINISH_OR_NULL;
|
||||
openDialog("Une erreur de type " + err.getClass().getSimpleName() + " est survenue lors de l'execution du parser: " + err.getMessage());
|
||||
}
|
||||
tab.submitButton3D.setIcon(null);
|
||||
tab.submitButton3D.setText("Générer en 3D");
|
||||
});
|
||||
parserThread.start();
|
||||
}
|
||||
frame.generateLSystem(this, parser3D, tab.submitButton);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void openDialog(String message) {
|
||||
void openDialog(String message) {
|
||||
JOptionPane.showMessageDialog(null, message);
|
||||
new Listener(null, index, "Clear", tab);
|
||||
}
|
||||
|
@ -1,20 +1,28 @@
|
||||
package lsystem.screen.main;
|
||||
|
||||
|
||||
import lsystem.Main;
|
||||
import lsystem.engine.Parser;
|
||||
import lsystem.screen.Constants;
|
||||
import lsystem.screen.gl3d.AbstractCanvas;
|
||||
import lsystem.utils.Pair;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class MainFrame extends JFrame {
|
||||
private int nbTabs;
|
||||
|
||||
Thread parserThread = null;
|
||||
public int nbTabs;
|
||||
boolean helpWindow = false;
|
||||
private final JPanel basePanel;
|
||||
public final JTabbedPane tabs;
|
||||
private final JButton newGen;
|
||||
private final JButton example;
|
||||
private final JButton help;
|
||||
private final int nbRules;
|
||||
|
||||
@ -32,6 +40,9 @@ public class MainFrame extends JFrame {
|
||||
newGen = new JButton("Nouvelle génération");
|
||||
newGen.addActionListener(new Listener(this,null,"Tab",null));
|
||||
toolBar.add(newGen);
|
||||
example = new JButton("Exemples");
|
||||
example.addActionListener(new Listener(this, null, "example", null));
|
||||
toolBar.add(example);
|
||||
help = new JButton("Aide");
|
||||
help.addActionListener(new Listener(this,null,"Help",null));
|
||||
toolBar.add(help);
|
||||
@ -96,10 +107,10 @@ public class MainFrame extends JFrame {
|
||||
*/
|
||||
public void newTab() {
|
||||
if(nbTabs>2)
|
||||
JOptionPane.showMessageDialog(null, "Nombre maximal de générations atteintes");
|
||||
JOptionPane.showMessageDialog(null, "Nombre maximal d'onglets atteintes");
|
||||
else {
|
||||
nbTabs++;
|
||||
tabs.addTab("Génération" + nbTabs,new Tab(nbTabs,this));
|
||||
tabs.addTab("Génération" + nbTabs,new Tab(this));
|
||||
}
|
||||
|
||||
}
|
||||
@ -113,4 +124,51 @@ public class MainFrame extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
public void newExample() {
|
||||
if(nbTabs > 2)
|
||||
JOptionPane.showMessageDialog(null, "Nombre maximal d'onglets atteintes");
|
||||
else {
|
||||
nbTabs++;
|
||||
tabs.addTab("Exemples", new Example(this));
|
||||
}
|
||||
}
|
||||
|
||||
public void generateLSystem(Listener listener, Parser parser, JButton submitButton) {
|
||||
if(Main.joglFrame.frame.isVisible()) {
|
||||
listener.openDialog("Veuillez fermer la fenêtre 2D ou 3D avant de lancer une nouvelle génération");
|
||||
} else if(Main.joglFrame.parsedState == AbstractCanvas.State.LOAD) {
|
||||
listener.openDialog("Une génération est actuellement en cours, impossible d'en relancer un autre");
|
||||
} else if (!parser.isCorrect()) {
|
||||
listener.openDialog("Vos règles ou votre axiome ne sont pas correctement écrites, veuillez recommencer");
|
||||
} else {
|
||||
String initialText = submitButton.getText();
|
||||
parserThread = new Thread(() -> {
|
||||
try {
|
||||
submitButton.setIcon(listener.staticIcon);
|
||||
submitButton.setText("");
|
||||
List<Pair<String, String>> lSystemRules = parser.parseRules();
|
||||
Main.joglFrame.setLSystem(parser.getAxiom(), lSystemRules, parser.getNbIterations());
|
||||
|
||||
StringBuilder message = new StringBuilder("L-System 3D - {axiom:\"").append(parser.getAxiom()).append("\",rules:[");
|
||||
for(int i = 0; i < lSystemRules.size(); ++i) {
|
||||
Pair<String, String> rule = lSystemRules.get(i);
|
||||
message.append("\"").append(rule.getLeft()).append("=").append(rule.getRight()).append("\"");
|
||||
if(i + 1 != lSystemRules.size())
|
||||
message.append(",");
|
||||
}
|
||||
Main.joglFrame.frame.setTitle(message.append("]} - Nombres d'itérations: ").append(parser.getNbIterations()).toString());
|
||||
|
||||
Main.joglFrame.setVisible(true);
|
||||
} catch (NumberFormatException err) {
|
||||
Main.joglFrame.parsedState = AbstractCanvas.State.FINISH_OR_NULL;
|
||||
listener.openDialog("Une erreur de type " + err.getClass().getSimpleName() + " est survenue lors de l'execution du parser: " + err.getMessage());
|
||||
}
|
||||
submitButton.setIcon(null);
|
||||
submitButton.setText(initialText);
|
||||
});
|
||||
|
||||
parserThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,22 +6,16 @@ import java.util.Arrays;
|
||||
|
||||
public class Tab extends JPanel{
|
||||
|
||||
public int nbTabs;
|
||||
int nbRules;
|
||||
public JSpinner itSpinner;
|
||||
JTextField axiomeField, rulesField;
|
||||
JTextArea axiomList, rulesList;
|
||||
JButton submitButton3D;
|
||||
JButton submitButton;
|
||||
|
||||
/**
|
||||
* A method which create a new instance of the class JPanel ready to be added to the MainFrame's tabs variable (JTabbedPane).
|
||||
* @param nbTabs the number of this tab, useful for the listener.
|
||||
* @param frame the MainFrame instance that is useful to access all the components.
|
||||
*/
|
||||
public Tab(int nbTabs,MainFrame frame) {
|
||||
|
||||
this.nbRules = nbRules;
|
||||
this.nbTabs = nbTabs;
|
||||
public Tab(MainFrame frame) {
|
||||
|
||||
axiomList = textArea("Axiome :");
|
||||
rulesList = textArea("Règles :");
|
||||
@ -35,22 +29,22 @@ public class Tab extends JPanel{
|
||||
JLabel rules = new JLabel("Règles :");
|
||||
|
||||
axiomeField = new JTextField();
|
||||
axiomeField.addKeyListener(new Listener(null,nbTabs,"Axiome",this));
|
||||
axiomeField.addKeyListener(new Listener(null,frame.nbTabs,"Axiome",this));
|
||||
axiomeField.setPreferredSize(new Dimension(120,20));
|
||||
|
||||
rulesField = new JTextField();
|
||||
rulesField.addKeyListener(new Listener(null,nbTabs+10,"Règles",this));
|
||||
rulesField.addKeyListener(new Listener(null,frame.nbTabs + 10,"Règles",this));
|
||||
rulesField.setPreferredSize(new Dimension(120,20));
|
||||
submitButton3D = new JButton("Générer en 3D");
|
||||
submitButton = new JButton("Générer en 3D");
|
||||
JButton clearButton = new JButton("Clear");
|
||||
clearButton.addActionListener(new Listener(null,nbTabs,"Clear",this));
|
||||
clearButton.addActionListener(new Listener(null,frame.nbTabs,"Clear",this));
|
||||
clearButton.setBackground(Color.GREEN);
|
||||
submitButton3D.addActionListener(new Listener(null,nbTabs,"Generate 3D",this));
|
||||
submitButton3D.setBackground(Color.CYAN);
|
||||
submitButton.addActionListener(new Listener(frame, frame.nbTabs,"Generate 3D",this));
|
||||
submitButton.setBackground(Color.CYAN);
|
||||
JButton close = new JButton("Close");
|
||||
close.addActionListener(new Listener(frame,null,"Close",null));
|
||||
close.setBackground(Color.RED);
|
||||
JPanel southComponents = subPanel(submitButton3D,close,null);
|
||||
JPanel southComponents = subPanel(submitButton,close,null);
|
||||
southComponents = subPanel(clearButton, southComponents, null);
|
||||
|
||||
GridBagConstraints gc = new GridBagConstraints();
|
||||
|
Loading…
Reference in New Issue
Block a user