summaryrefslogtreecommitdiffstats
path: root/logo/src/xlogo/kernel/Turtle.java
diff options
context:
space:
mode:
Diffstat (limited to 'logo/src/xlogo/kernel/Turtle.java')
-rw-r--r--logo/src/xlogo/kernel/Turtle.java434
1 files changed, 434 insertions, 0 deletions
diff --git a/logo/src/xlogo/kernel/Turtle.java b/logo/src/xlogo/kernel/Turtle.java
new file mode 100644
index 0000000..82f3a76
--- /dev/null
+++ b/logo/src/xlogo/kernel/Turtle.java
@@ -0,0 +1,434 @@
+/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Lo�c Le Coq
+ * Copyright (C) 2013 Marko Zivkovic
+ *
+ * Contact Information: marko88zivkovic at gmail dot com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details. You should have received a copy of the
+ * GNU General Public License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ * This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
+ * during his Bachelor thesis at the computer science department of ETH Z�rich,
+ * in the year 2013 and/or during future work.
+ *
+ * It is a reengineered version of XLogo written by Lo�c Le Coq, published
+ * under the GPL License at http://xlogo.tuxfamily.org/
+ *
+ * Contents of this file were initially written by Lo�c Le Coq,
+ * modifications, extensions, refactorings might have been applied by Marko Zivkovic
+ */
+
+/**
+ * Title : XLogo
+ * Description : XLogo is an interpreter for the Logo
+ * programming language
+ *
+ * @author Loïc Le Coq
+ */
+
+package xlogo.kernel;
+
+import java.awt.Toolkit;
+import java.awt.MediaTracker;
+import java.awt.geom.GeneralPath;
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.BasicStroke;
+import java.awt.Stroke;
+import java.util.StringTokenizer;
+
+import xlogo.Logo;
+import xlogo.storage.WSManager;
+import xlogo.storage.user.PenShape;
+import xlogo.storage.user.UserConfig;
+import xlogo.utils.Utils;
+import xlogo.Application;
+
+public class Turtle
+{
+
+ private Application app;
+
+ public Color couleurcrayon = Color.black;
+ public Stroke stroke = new BasicStroke(1);
+
+ Color couleurmodedessin = Color.black;
+
+ public int id = -1;
+
+ BasicStroke crayon = null;
+
+ int police = 12;
+
+ private int labelHorizontalAlignment = 0;
+ protected static final int LABEL_HORIZONTAL_ALIGNMENT_LEFT = 0;
+ protected static final int LABEL_HORIZONTAL_ALIGNMENT_CENTER = 1;
+ protected static final int LABEL_HORIZONTAL_ALIGNMENT_RIGHT = 2;
+
+ private int labelVerticalAlignment = 0;
+ protected static final int LABEL_VERTICAL_ALIGNMENT_BOTTOM = 0;
+ protected static final int LABEL_VERTICAL_ALIGNMENT_CENTER = 1;
+ protected static final int LABEL_VERTICAL_ALIGNMENT_TOP = 2;
+
+ // Image for the turtle
+ // If null then draw the triangle
+
+ Image tort = null;
+
+ GeneralPath triangle;
+ /**
+ * The turtle heading (degree)
+ */
+ public double heading;
+ /**
+ * The turtle roll (degree)
+ */
+ public double roll;
+ /**
+ * The turtle pitch (degree)
+ */
+ public double pitch;
+
+ /**
+ * The X coordinates on the screen
+ */
+ public double corX;
+ /**
+ * The Y coordinates on the screen
+ */
+ public double corY;
+
+ public double angle;
+ /**
+ * The X coordinates in real World (3D or 2D)
+ */
+ public double X = 0;
+ /**
+ * The Y coordinates in real World (3D or 2D)
+ */
+ public double Y = 0;
+ /**
+ * The Z coordinates in real World (3D or 2D)
+ */
+ public double Z = 0;
+ /**
+ * Identity Matrix
+ */
+ private final double[][] identity = new double[3][3];
+ {
+ identity[0][0] = identity[1][1] = identity[2][2] = 1;
+ identity[0][1] = identity[0][2] = identity[1][2] = 0;
+ identity[1][0] = identity[2][1] = identity[2][0] = 0;
+ }
+ /**
+ * This is the rotation Matrix (3x3) in 3D world
+ */
+ private double[][] rotationMatrix = identity;
+
+ int largeur = 0;
+
+ int hauteur = 0;
+
+ int gabarit = 0;
+
+ private boolean pendown = true;
+
+ private boolean penReverse = false;
+
+ private boolean visible = true;
+
+ private int shape = WSManager.getUserConfig().getActiveTurtle();
+
+ private float penWidth = 0; // half
+ // of
+ // the
+ // pen
+ // width
+
+ public Turtle(Application app)
+ {
+ UserConfig uc = WSManager.getUserConfig();
+
+ this.app = app;
+ fixe_taille_crayon(1);
+ String chemin = "tortue" + uc.getActiveTurtle() + ".png";
+ couleurcrayon = uc.getPencolor();
+ couleurmodedessin = uc.getPencolor();
+ if (uc.getActiveTurtle() == 0)
+ {
+ tort = null;
+ largeur = 26;
+ hauteur = 26;
+ }
+ else
+ {
+ // ON teste tout d'abord si le chemin est valide
+ if (null == Utils.class.getResource(chemin))
+ chemin = "tortue1.png";
+ tort = Toolkit.getDefaultToolkit().getImage(Utils.class.getResource(chemin));
+ MediaTracker tracker = new MediaTracker(app.getFrame());
+ tracker.addImage(tort, 0);
+ try
+ {
+ tracker.waitForID(0);
+ }
+ catch (InterruptedException e1)
+ {}
+ largeur = tort.getWidth(app.getFrame());
+ hauteur = tort.getHeight(app.getFrame());
+ double largeur_ecran = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
+ // On fait attention à la résolution de l'utilisateur
+ double facteur = largeur_ecran / 1024.0;
+ if ((int) (facteur + 0.001) != 1)
+ {
+ tort = tort.getScaledInstance((int) (facteur * largeur), (int) (facteur * hauteur), Image.SCALE_SMOOTH);
+ tracker = new MediaTracker(app.getFrame());
+ tracker.addImage(tort, 0);
+ try
+ {
+ tracker.waitForID(0);
+ }
+ catch (InterruptedException e1)
+ {}
+ }
+ largeur = tort.getWidth(app.getFrame());
+ hauteur = tort.getHeight(app.getFrame());
+ }
+ gabarit = Math.max(hauteur, largeur);
+ corX = uc.getImageWidth() / 2;
+ corY = uc.getImageHeight() / 2;
+ angle = Math.PI / 2;
+ heading = 0.0;
+ pitch = 0;
+ roll = 0;
+ X = 0;
+ Y = 0;
+ Z = 0;
+ }
+
+ protected void init()
+ {
+ UserConfig uc = WSManager.getUserConfig();
+
+ corX = uc.getImageWidth() / 2;
+ corY = uc.getImageHeight() / 2;
+ X = 0;
+ Y = 0;
+ Z = 0;
+ heading = 0;
+ pitch = 0;
+ roll = 0;
+ rotationMatrix = identity;
+ angle = Math.PI / 2;
+ pendown = true;
+ stroke = new BasicStroke(1);
+ fixe_taille_crayon(1);
+ couleurcrayon = uc.getPencolor();
+ couleurmodedessin = uc.getPencolor();
+ penReverse = false;
+ }
+
+ void drawTriangle()
+ {
+ if (null == tort)
+ {
+ if (null == triangle)
+ {
+ triangle = new GeneralPath();
+ }
+ else
+ triangle.reset();
+ if (DrawPanel.WINDOW_MODE != DrawPanel.WINDOW_3D)
+ {
+ triangle.moveTo((float) (corX - 10.0 * Math.sin(angle)), (float) (corY - 10.0 * Math.cos(angle)));
+ triangle.lineTo((float) (corX + 24.0 * Math.cos(angle)), (float) (corY - 24.0 * Math.sin(angle)));
+ triangle.lineTo((float) (corX + 10.0 * Math.sin(angle)), (float) (corY + 10.0 * Math.cos(angle)));
+ triangle.lineTo((float) (corX - 10.0 * Math.sin(angle)), (float) (corY - 10.0 * Math.cos(angle)));
+ }
+ else
+ {
+ double[] screenCoord = new double[2];
+ // The triangle has coordinates: (-10,0,0);(0,24,0);(10,0,0)
+ double[] x1 = new double[3];
+ x1[0] = X - 20 * rotationMatrix[0][0];
+ x1[1] = Y - 20 * rotationMatrix[1][0];
+ x1[2] = Z - 20 * rotationMatrix[2][0];
+ screenCoord = app.getDrawPanel().toScreenCoord(x1, false);
+ triangle.moveTo((float) screenCoord[0], (float) screenCoord[1]);
+ x1[0] = X + 48 * rotationMatrix[0][1];
+ x1[1] = Y + 48 * rotationMatrix[1][1];
+ x1[2] = Z + 48 * rotationMatrix[2][1];
+ screenCoord = app.getDrawPanel().toScreenCoord(x1, false);
+ triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]);
+ x1[0] = X + 20 * rotationMatrix[0][0];
+ x1[1] = Y + 20 * rotationMatrix[1][0];
+ x1[2] = Z + 20 * rotationMatrix[2][0];
+ screenCoord = app.getDrawPanel().toScreenCoord(x1, false);
+ triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]);
+ triangle.closePath();
+
+ // the "aileron" has coordinates: (0,10,0);(0,0,10);(0,0,0)
+ x1[0] = X + 15 * rotationMatrix[0][1];
+ x1[1] = Y + 15 * rotationMatrix[1][1];
+ x1[2] = Z + 15 * rotationMatrix[2][1];
+ screenCoord = app.getDrawPanel().toScreenCoord(x1, false);
+ triangle.moveTo((float) screenCoord[0], (float) screenCoord[1]);
+ x1[0] = X + 15 * rotationMatrix[0][2];
+ x1[1] = Y + 15 * rotationMatrix[1][2];
+ x1[2] = Z + 15 * rotationMatrix[2][2];
+ screenCoord = app.getDrawPanel().toScreenCoord(x1, false);
+ triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]);
+ x1[0] = X;
+ x1[1] = Y;
+ x1[2] = Z;
+ screenCoord = app.getDrawPanel().toScreenCoord(x1, false);
+ triangle.lineTo((float) screenCoord[0], (float) screenCoord[1]);
+ }
+ }
+ }
+
+ public void fixe_taille_crayon(float nb)
+ {
+ UserConfig uc = WSManager.getUserConfig();
+
+ if (nb < 0)
+ nb = 1;
+ else if (uc.getMaxPenWidth() != -1 && nb > uc.getMaxPenWidth())
+ nb = 1;
+ if (uc.getPenShape() == PenShape.SQUARE)
+ crayon = new BasicStroke(nb, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER);
+ else
+ crayon = new BasicStroke(nb, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
+ penWidth = nb / 2;
+ }
+
+ public float getPenWidth()
+ {
+ return penWidth;
+ }
+
+ protected int getShape()
+ {
+ return shape;
+ }
+
+ public void setShape(int id)
+ {
+ shape = id;
+ }
+
+ protected boolean isVisible()
+ {
+ return visible;
+ }
+
+ protected void setVisible(boolean b)
+ {
+ visible = b;
+ }
+
+ protected boolean isPenDown()
+ {
+ return pendown;
+ }
+
+ protected void setPenDown(boolean b)
+ {
+ pendown = b;
+ }
+
+ protected boolean isPenReverse()
+ {
+ return penReverse;
+ }
+
+ protected void setPenReverse(boolean b)
+ {
+ penReverse = b;
+ }
+
+ protected void setRotationMatrix(double[][] m)
+ {
+ rotationMatrix = m;
+ }
+
+ protected double[][] getRotationMatrix()
+ {
+ return rotationMatrix;
+ }
+
+ protected double getX()
+ {
+ if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_3D)
+ return X;
+ return corX - WSManager.getUserConfig().getImageWidth() / 2;
+
+ }
+
+ protected double getY()
+ {
+ if (DrawPanel.WINDOW_MODE == DrawPanel.WINDOW_3D)
+ return Y;
+ return WSManager.getUserConfig().getImageHeight() / 2 - corY;
+
+ }
+
+ protected int getLabelHorizontalAlignment()
+ {
+ return labelHorizontalAlignment;
+ }
+
+ protected int getLabelVerticalAlignment()
+ {
+ return labelVerticalAlignment;
+ }
+
+ protected void setFontJustify(String list) throws LogoError
+ {
+ StringTokenizer st = new StringTokenizer(list);
+ int i = 0;
+ while (st.hasMoreTokens())
+ {
+ String s = st.nextToken();
+ try
+ {
+ int j = Integer.parseInt(s);
+ if (j < 0 || j > 2)
+ throw new LogoError(list + " " + Logo.messages.getString("pas_argument"));
+ else
+ {
+ if (i == 0)
+ labelHorizontalAlignment = j;
+ else if (i == 1)
+ labelVerticalAlignment = j;
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ throw new LogoError(list + " " + Logo.messages.getString("pas_argument"));
+ }
+
+ i++;
+ }
+ if (i != 2)
+ throw new LogoError(list + " " + Logo.messages.getString("pas_argument"));
+ }
+
+ public String getFontJustify()
+ {
+ StringBuffer sb = new StringBuffer("[ ");
+ sb.append(labelHorizontalAlignment);
+ sb.append(" ");
+ sb.append(labelVerticalAlignment);
+ sb.append(" ] ");
+ return new String(sb);
+ }
+}