]> gitweb.hamatoma.de Git - robosim/commitdiff
initial state
authorhama <hama@siduction.net>
Thu, 9 Oct 2014 18:26:28 +0000 (20:26 +0200)
committerhama <hama@siduction.net>
Thu, 9 Oct 2014 18:27:04 +0000 (20:27 +0200)
20 files changed:
.classpath [new file with mode: 0644]
.gitignore [new file with mode: 0644]
.project [new file with mode: 0644]
src/jlecture/simulation/Bar.java [new file with mode: 0644]
src/jlecture/simulation/DimensionRW.java [new file with mode: 0644]
src/jlecture/simulation/ISheet.java [new file with mode: 0644]
src/jlecture/simulation/IWidget.java [new file with mode: 0644]
src/jlecture/simulation/Model.java [new file with mode: 0644]
src/jlecture/simulation/PointRW.java [new file with mode: 0644]
src/jlecture/simulation/RectangleRW.java [new file with mode: 0644]
src/jlecture/simulation/Robot.java [new file with mode: 0644]
src/jlecture/simulation/Simulator.java [new file with mode: 0644]
src/jlecture/simulation/ThingRW.java [new file with mode: 0644]
src/jlecture/swt/PanelSWT.java [new file with mode: 0644]
src/jlecture/swt/RectangleSWT.java [new file with mode: 0644]
src/jlecture/swt/SheetSWT.java [new file with mode: 0644]
src/jlecture/swt/Widget.java [new file with mode: 0644]
src/jlecture/swt/XCross.java [new file with mode: 0644]
test/jlecture/junit/ModelTest.java [new file with mode: 0644]
test/jlecture/junit/WidgetTest.java [new file with mode: 0644]

diff --git a/.classpath b/.classpath
new file mode 100644 (file)
index 0000000..1b83178
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="test"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..8308dba
--- /dev/null
@@ -0,0 +1,3 @@
+bin/
+.settings/
+
diff --git a/.project b/.project
new file mode 100644 (file)
index 0000000..9aee8c2
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>robosim</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/src/jlecture/simulation/Bar.java b/src/jlecture/simulation/Bar.java
new file mode 100644 (file)
index 0000000..c0b7898
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * Implements a stationary bar in the model.
+ *
+ * @author hm
+ *
+ */
+public class Bar extends ThingRW {
+    /**
+     * Constructor.
+     *
+     * @param widget
+     *            the widget in the model view
+     */
+    public Bar(IWidget widget) {
+        super(widget);
+    }
+
+}
diff --git a/src/jlecture/simulation/DimensionRW.java b/src/jlecture/simulation/DimensionRW.java
new file mode 100644 (file)
index 0000000..64afe20
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+import java.awt.Dimension;
+
+/**
+ * Implements a size definition (width and height) with real world coordinates.
+ *
+ * @author hm
+ *
+ */
+public class DimensionRW extends Dimension {
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+    /**
+     * vertical dimension
+     */
+    public double height;
+    /**
+     * horizontal dimension
+     */
+    public double width;
+
+    /**
+     * Constructor
+     *
+     * @param width
+     * @param height
+     */
+    public DimensionRW(double width, double height) {
+        this.width = width;
+        this.height = height;
+    }
+}
diff --git a/src/jlecture/simulation/ISheet.java b/src/jlecture/simulation/ISheet.java
new file mode 100644 (file)
index 0000000..77f43ff
--- /dev/null
@@ -0,0 +1,31 @@
+package jlecture.simulation;
+
+public interface ISheet {
+
+    /**
+     * Creates a rectangle widget.
+     *
+     * @param center
+     *            the center of the rectangle
+     * @param dimension
+     *            the width/height of the widget
+     * @param model
+     *            the simulator model
+     * @return a X cross widget
+     */
+    IWidget createRectangle(PointRW center, DimensionRW dimension,
+        boolean filled, Model model);
+
+    /**
+     * Creates a X cross widget.
+     *
+     * @param center
+     *            the center of the X cross
+     * @param dimension
+     *            the width/height of the widget
+     * @param model
+     *            the simulator model
+     * @return a X cross widget
+     */
+    IWidget createXCross(PointRW center, DimensionRW dimension, Model model);
+}
diff --git a/src/jlecture/simulation/IWidget.java b/src/jlecture/simulation/IWidget.java
new file mode 100644 (file)
index 0000000..f8cb547
--- /dev/null
@@ -0,0 +1,38 @@
+package jlecture.simulation;
+
+/**
+ * Defines a graphical item.
+ *
+ * @author hm
+ *
+ */
+public interface IWidget {
+    /**
+     * Returns the center of the widget.
+     *
+     * @return
+     */
+    public PointRW getCenter();
+
+    /**
+     * Returns the contour of the item. This is the smallest rectangle which
+     * contains all parts of the item.
+     *
+     * @return the contour of the item
+     */
+    public RectangleRW getContour();
+
+    /**
+     * Returns the model of the widget.
+     *
+     * @return the model of the widget
+     */
+    public Model getModel();
+
+    /**
+     * @param center
+     *            the center to set
+     */
+    public void setCenter(PointRW center);
+
+}
diff --git a/src/jlecture/simulation/Model.java b/src/jlecture/simulation/Model.java
new file mode 100644 (file)
index 0000000..3e56856
--- /dev/null
@@ -0,0 +1,199 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Implements the model of the simulator.
+ *
+ * @author hm
+ *
+ */
+public class Model {
+    private boolean isReady = false;
+    protected ArrayList<IWidget> widgets = new ArrayList<IWidget>();
+    protected ArrayList<ThingRW> things = new ArrayList<ThingRW>();
+    protected ISheet sheet = null;
+    protected RectangleRW region = new RectangleRW(0, 0, 1024, 1024 * 2 / 3);
+
+    Random random = new Random(0x4711);
+
+    /**
+     * Constructor.
+     */
+    public Model() {
+    }
+
+    /**
+     * Builds the elements of the simulator.
+     */
+    public void createModel() {
+        things.add(new Bar(sheet.createRectangle(
+            new PointRW(500, 100), new DimensionRW(600, 50), false, this)));
+        things.add(new Bar(sheet.createRectangle(
+            new PointRW(500, 400), new DimensionRW(600, 50), false, this)));
+        things.add(new Bar(sheet.createRectangle(
+            new PointRW(500, 700), new DimensionRW(600, 50), false, this)));
+
+        PointRW destination = new PointRW(0, 0);
+        for (int ix = 0; ix < 20; ix++) {
+            Robot robot = new Robot(sheet.createRectangle(new PointRW(500,
+                500), new DimensionRW(10, 10), true, this));
+            robot.getWidget().setCenter(openPosition());
+            destination.x = robot.getWidget().getCenter().x;
+            destination.y = robot.getWidget().getCenter().y;
+            randomDestination(destination);
+            // 100 seconds for the whole width:
+            double velocity = 1 / 100.0 * region.width
+                    * (0.5 + random.nextDouble() * 0.5);
+            robot.setMove(destination, velocity);
+            things.add(robot);
+        }
+        isReady = true;
+    }
+
+    /**
+     * Returns the list of items.
+     *
+     * @return the list of items
+     */
+    public List<IWidget> getItems() {
+        return widgets;
+    }
+
+    /**
+     * Returns the sheet.
+     *
+     * @return the sheet
+     */
+    public ISheet getSheet() {
+        return sheet;
+    }
+
+    /**
+     * @return the widgets
+     */
+    public ArrayList<IWidget> getWidgets() {
+        return widgets;
+    }
+
+    /**
+     * Logs a message.
+     *
+     * @param message
+     */
+    public void log(String message) {
+        System.out.println(message);
+
+    }
+
+    /**
+     * Search for the first thing at a given position in the area of the model
+     * except a given thing.
+     *
+     * @param point
+     *            the position to inspect
+     * @param exclude
+     *            null or the thing which will be ignored
+     * @return null: at position there is no other thing<br>
+     *         otherwise: the thing at the position
+     */
+    public ThingRW occupied(PointRW point, IWidget exclude) {
+        ThingRW rc = null;
+        for (ThingRW current : things)
+            if (current != exclude) {
+                RectangleRW contour = current.widget.getContour();
+                if (point.x >= contour.x && point.y >= contour.y
+                        && point.x < contour.x + contour.width
+                        && point.y < contour.y + contour.height) {
+                    rc = current;
+                    break;
+                }
+            }
+        return rc;
+    }
+
+    /**
+     * Will be called every 100 millisec.
+     */
+    public void onTimer() {
+        if (isReady)
+            for (ThingRW thing : things)
+                if (thing instanceof Robot) {
+                    Robot robot = (Robot) thing;
+                    PointRW center = robot.getWidget().getCenter();
+                    // moves to the position belonging to the current move:
+                    robot.currentPosition(center, System.currentTimeMillis());
+                    robot.getWidget().setCenter(center);
+                }
+    }
+
+    /**
+     * Returns a position not occupied by another model thing.
+     *
+     * @return a not occupied position
+     */
+    public PointRW openPosition() {
+        PointRW rc = new PointRW(0, 0);
+        do {
+            rc.x = region.x + random.nextDouble() * region.width;
+            rc.y = region.x + random.nextDouble()
+                    * region.height;
+        } while (occupied(rc, null) != null);
+        return rc;
+    }
+
+    /**
+     * Sets exactly one coordinate to one of the limits (minimum or maximum).
+     *
+     * @param destination
+     *            IN/OUT: the point to change
+     */
+    protected void randomDestination(PointRW destination) {
+        switch (random.nextInt() % 4) {
+        case 0:
+            destination.x = region.x;
+            break;
+        case 1:
+            destination.x = region.x + region.width;
+            break;
+        case 2:
+            destination.y = region.y;
+            break;
+        default:
+            destination.y = region.y + region.height;
+            break;
+        }
+    }
+
+    /**
+     * Sets the sheet of the model.
+     *
+     * @param sheet
+     *            the new sheet
+     */
+    public void setSheet(ISheet sheet) {
+        this.sheet = sheet;
+    }
+
+    /**
+     * Transforms a real world rectangle to a native rectangle.
+     *
+     * @param rectangleRW
+     *            the rectangle to convert
+     * @param rectangle
+     *            OUT: the calculated rectangle
+     */
+    public void transform(RectangleRW rectangleRW, Rectangle rectangle) {
+        rectangle.x = (int) rectangleRW.x;
+        rectangle.y = (int) rectangleRW.y;
+        rectangle.width = (int) rectangleRW.width;
+        rectangle.height = (int) rectangleRW.height;
+    }
+
+}
diff --git a/src/jlecture/simulation/PointRW.java b/src/jlecture/simulation/PointRW.java
new file mode 100644 (file)
index 0000000..6a6cb4f
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * Implements a position definition (x and y) with real world coordinates.
+ *
+ * @author hm
+ *
+ */
+public class PointRW {
+    /**
+     * x coordinate (horizontal)
+     */
+    public double x;
+    /**
+     * y coordinate (vertical)
+     */
+    public double y;
+
+    /**
+     * Constructor.
+     *
+     * @param x
+     * @param y
+     */
+    public PointRW(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+}
diff --git a/src/jlecture/simulation/RectangleRW.java b/src/jlecture/simulation/RectangleRW.java
new file mode 100644 (file)
index 0000000..e499024
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * Implements a rectangle with real world coordinates containing x, y, width and
+ * height.
+ *
+ * @author hm
+ *
+ */
+public class RectangleRW {
+    /**
+     * x coordinate (horizontal) of the left lower corner
+     */
+    public double x;
+    /**
+     * y coordinate (vertical) of the right upper corner
+     */
+    public double y;
+    /**
+     * horizontal dimension
+     */
+    public double width;
+    /**
+     * vertical dimension
+     */
+    public double height;
+
+    /**
+     * Constructor.
+     *
+     * @param x
+     * @param y
+     * @param width
+     * @param height
+     */
+    public RectangleRW(double x, double y, double width, double height) {
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+    }
+
+}
diff --git a/src/jlecture/simulation/Robot.java b/src/jlecture/simulation/Robot.java
new file mode 100644 (file)
index 0000000..0a7bae0
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * @author hm
+ *
+ */
+public class Robot extends ThingRW {
+    /**
+     * Velocity of the robot in units per second.
+     */
+    private double velocity = 0.0;
+
+    /**
+     * The position of the last direction change.
+     */
+    private PointRW start = new PointRW(0, 0);
+
+    /**
+     * The destination of the currrent move.
+     */
+    private PointRW destination = new PointRW(0, 0);
+    /**
+     * The start time of the current move (in msec).
+     */
+    private long startTime = 0L;
+    private Model model = null;
+
+    /**
+     * Constructor.
+     *
+     * @param widget
+     *            the widget in the graphical view
+     */
+    public Robot(IWidget widget) {
+        super(widget);
+        model = widget.getModel();
+    }
+
+    /**
+     * Calculates the position (for the current move).
+     *
+     * @param point
+     *            OUT: the calculated current position
+     * @param currentTime
+     *            < 0: relative to the starttime (negated)<br>
+     *            otherwise: the current time in milliseconds
+     */
+    public void currentPosition(PointRW point, long currentTime) {
+        ;
+        if (velocity == 0.0) {
+            point.x = widget.getCenter().x;
+            point.y = widget.getCenter().y;
+        } else {
+            if (currentTime < 0)
+                currentTime = startTime - currentTime;
+            // v = s / t => s = v * t
+            double time = (currentTime - startTime) / 1000.0;
+            double distance = velocity * time;
+            // hypotenuse:
+            // c = sqrt(x_target _ x_start)**2 + (y_target _ y_start)**2)
+            // Theory of intersecting lines:
+            // x_diff : distance = (x_target - x_start) / c
+            // y_diff : distance = (y_target - y_start) / c
+            double x_diff = destination.x - start.x;
+            double y_diff = destination.y - start.y;
+            double c = Math.sqrt(x_diff * x_diff + y_diff * y_diff);
+            x_diff = distance * x_diff / c;
+            y_diff = distance * y_diff / c;
+            point.x = start.x + x_diff;
+            point.y = start.y + y_diff;
+        }
+    }
+
+    /**
+     * @return the widget
+     */
+    public IWidget getWidget() {
+        return widget;
+    }
+
+    /**
+     * Sets the current move.
+     *
+     * @param destination
+     * @param velocity
+     */
+    public void setMove(PointRW destination, double velocity) {
+        start = widget.getCenter();
+        this.destination = destination;
+        startTime = System.currentTimeMillis();
+        this.velocity = velocity;
+    }
+
+    /**
+     * @param widget
+     *            the widget to set
+     */
+    public void setWidget(IWidget widget) {
+        this.widget = widget;
+    }
+}
diff --git a/src/jlecture/simulation/Simulator.java b/src/jlecture/simulation/Simulator.java
new file mode 100644 (file)
index 0000000..5fcde3f
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+import java.awt.Dimension;
+import java.awt.Point;
+
+import javax.swing.SwingUtilities;
+
+import jlecture.swt.SheetSWT;
+
+/**
+ * @author hm
+ *
+ */
+public class Simulator {
+    public static void main(String[] args) {
+        Simulator simulator = new Simulator();
+        simulator.exec();
+    }
+
+    /**
+     * Executes the simulation.
+     */
+    public void exec() {
+        Model model = new Model();
+        SheetSWT sheet = new SheetSWT(new Point(50, 10), new Dimension(1000,
+            800), "Roboterfeld", model);
+        model.createModel();
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                sheet.setVisible(true);
+            }
+        });
+
+    }
+
+}
diff --git a/src/jlecture/simulation/ThingRW.java b/src/jlecture/simulation/ThingRW.java
new file mode 100644 (file)
index 0000000..9bb928e
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * A basic class of any visible thing used in the model.
+ *
+ * @author hm
+ */
+public class ThingRW {
+    protected IWidget widget;
+
+    /**
+     * Constructor.
+     *
+     * @param widget
+     *            the widget in the model view.
+     */
+    public ThingRW(IWidget widget) {
+        this.widget = widget;
+        widget.getModel().getWidgets().add(widget);
+    }
+}
diff --git a/src/jlecture/swt/PanelSWT.java b/src/jlecture/swt/PanelSWT.java
new file mode 100644 (file)
index 0000000..332994e
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ *
+ */
+package jlecture.swt;
+
+/**
+ * @author hm
+ *
+ */
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+
+import javax.swing.JPanel;
+
+import jlecture.simulation.IWidget;
+import jlecture.simulation.Model;
+
+/**
+ * Implements a panel drawing the simulator model view.
+ *
+ * @author hm
+ *
+ */
+class PanelSWT extends JPanel {
+    Model model;
+
+    private static final long serialVersionUID = 1L;
+    private Color foreground = Color.black;
+    private Color background = Color.white;
+
+    /**
+     * Constructor.
+     *
+     * @param model
+     *            the simulator model
+     */
+    public PanelSWT(Model model) {
+        this.model = model;
+    }
+
+    /**
+     * Draws the model view.
+     *
+     * @param graphics
+     *            the drawing parameter like pencil
+     */
+    private void doDrawing(Graphics graphics) {
+        Graphics2D g2d = (Graphics2D) graphics;
+
+        g2d.setColor(this.foreground);
+        g2d.setBackground(this.background);
+
+        for (IWidget item : this.model.getItems()) {
+            Widget item2 = (Widget) item;
+            item2.draw(g2d);
+        }
+    }
+
+    @Override
+    public void paintComponent(Graphics graphics) {
+
+        super.paintComponent(graphics);
+        doDrawing(graphics);
+    }
+}
diff --git a/src/jlecture/swt/RectangleSWT.java b/src/jlecture/swt/RectangleSWT.java
new file mode 100644 (file)
index 0000000..49d37b9
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ *
+ */
+package jlecture.swt;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+
+import jlecture.simulation.DimensionRW;
+import jlecture.simulation.Model;
+import jlecture.simulation.PointRW;
+
+/**
+ * Implements a rectangle with real world coordinates.
+ *
+ * @author hm
+ *
+ */
+public class RectangleSWT extends Widget {
+    private DimensionRW dimension = null;
+
+    private boolean filled = false;
+    private Rectangle contourSWT = new Rectangle();
+
+    /**
+     * Constructor.
+     *
+     * @param center
+     *            the center of the rectangle
+     * @param dimension
+     *            the width/height of the rectangle
+     * @param filled
+     *            true: the border has the maximum size<br>
+     *            false: distinction of border and inner area
+     * @param model
+     *            the simulator model
+     */
+    public RectangleSWT(PointRW center, DimensionRW dimension, boolean filled,
+        Model model) {
+        super(center, model);
+        this.dimension = dimension;
+        this.filled = filled;
+        calculateContour();
+    }
+
+    @Override
+    protected void calculateContour() {
+        this.contour.x = this.center.x - this.dimension.width / 2;
+        this.contour.y = this.center.y - this.dimension.height / 2;
+        this.contour.width = this.dimension.width;
+        this.contour.height = this.dimension.height;
+    }
+
+    @Override
+    public void draw(Graphics2D graphics) {
+        calculateContour();
+        this.model.transform(this.contour, this.contourSWT);
+        if (this.filled)
+            graphics.fillRect(this.contourSWT.x, this.contourSWT.y,
+                this.contourSWT.width, this.contourSWT.height);
+        else
+            graphics.drawRect(this.contourSWT.x, this.contourSWT.y,
+                this.contourSWT.width, this.contourSWT.height);
+    }
+}
diff --git a/src/jlecture/swt/SheetSWT.java b/src/jlecture/swt/SheetSWT.java
new file mode 100644 (file)
index 0000000..337ff14
--- /dev/null
@@ -0,0 +1,90 @@
+package jlecture.swt;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JFrame;
+import javax.swing.Timer;
+
+import jlecture.simulation.DimensionRW;
+import jlecture.simulation.ISheet;
+import jlecture.simulation.IWidget;
+import jlecture.simulation.Model;
+import jlecture.simulation.PointRW;
+
+public class SheetSWT extends JFrame implements ISheet, ActionListener {
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+    Point position = null;
+    Dimension dimension = null;
+    String title = null;
+    Model model;
+    Timer timer;
+
+    /**
+     * Constructor.
+     *
+     * @param position
+     *            the top left corner of the window
+     * @param dimension
+     *            the width and height of the window
+     * @param title
+     *            the window's title
+     */
+    public SheetSWT(Point position, Dimension dimension, String title,
+        Model model) {
+        this.position = position;
+        this.dimension = dimension;
+        this.title = title;
+        this.model = model;
+        this.timer = new Timer(100, this);
+        this.timer.setInitialDelay(2000);
+        model.setSheet(this);
+        initUI();
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        // if (e.getActionCommand().equals(""))
+        {
+            this.model.onTimer();
+            repaint();
+        }
+    }
+
+    @Override
+    public IWidget createRectangle(PointRW center, DimensionRW dimension,
+        boolean filled, Model model) {
+        return new RectangleSWT(center, dimension, filled, model);
+    }
+
+    @Override
+    public IWidget createXCross(PointRW center, DimensionRW dimension,
+        Model model) {
+        return new XCross(center, dimension, model);
+    }
+
+    /**
+     * Initializes the user interface.
+     */
+    private void initUI() {
+
+        setTitle(this.title);
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        add(new PanelSWT(this.model));
+
+        setSize(this.dimension.width, this.dimension.height);
+
+        if (this.position == null)
+            // build the window in the center:
+            setLocationRelativeTo(null);
+        else
+            setLocation(this.position);
+        this.timer.start();
+    }
+}
diff --git a/src/jlecture/swt/Widget.java b/src/jlecture/swt/Widget.java
new file mode 100644 (file)
index 0000000..0c3bf18
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ *
+ */
+package jlecture.swt;
+
+import java.awt.Graphics2D;
+
+import jlecture.simulation.IWidget;
+import jlecture.simulation.Model;
+import jlecture.simulation.PointRW;
+import jlecture.simulation.RectangleRW;
+
+/**
+ * Base class of all 2 dimensional drawing items.
+ *
+ * @author hm
+ *
+ */
+public abstract class Widget implements IWidget {
+    /**
+     * The center of the item in real world coordinates. This simply allows
+     * calculating distance between 2 items.
+     */
+    protected PointRW center;
+    /**
+     * The smallest rectangle containing all parts of the item.
+     */
+    protected RectangleRW contour = new RectangleRW(0, 0, 0, 0);
+
+    /**
+     * Simulator model.
+     */
+    protected Model model;
+
+    /**
+     * Constructor.
+     *
+     * @param sheet
+     *            the drawing sheet
+     */
+    public Widget(PointRW center, Model model) {
+        this.center = center;
+        this.model = model;
+        model.getItems().add(this);
+    }
+
+    /**
+     * Calculates the smallest rectangle containing all parts of the items.
+     */
+    protected abstract void calculateContour();
+
+    /**
+     * Draws the item with the given graphics.
+     *
+     * @param graphics
+     *            properties of the pencil a.s.o
+     */
+    public abstract void draw(Graphics2D graphics);
+
+    /**
+     * @return the center
+     */
+    @Override
+    public PointRW getCenter() {
+        return this.center;
+    }
+
+    /**
+     * Returns the smallest rectangle containing all parts of the item.
+     *
+     * @return the contour
+     */
+    @Override
+    public RectangleRW getContour() {
+        return this.contour;
+    }
+
+    /**
+     * @return the model
+     */
+    @Override
+    public Model getModel() {
+        return this.model;
+    }
+
+    /**
+     * @param center
+     *            the center to set
+     */
+    @Override
+    public void setCenter(PointRW center) {
+        this.center.x = center.x;
+        this.center.y = center.y;
+        calculateContour();
+    }
+}
diff --git a/src/jlecture/swt/XCross.java b/src/jlecture/swt/XCross.java
new file mode 100644 (file)
index 0000000..3931e6b
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ *
+ */
+package jlecture.swt;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+
+import jlecture.simulation.DimensionRW;
+import jlecture.simulation.Model;
+import jlecture.simulation.PointRW;
+import jlecture.simulation.RectangleRW;
+
+/**
+ * Implements a cross similar to a 'X' for SWT. These are the diagonals of a
+ * square.
+ *
+ * @author hm
+ *
+ */
+public class XCross extends Widget {
+    /**
+     * The length of the square (contour).
+     */
+    private DimensionRW dimension = null;
+    private RectangleRW contour = new RectangleRW(0, 0, 0, 0);
+    private Rectangle contourSWT = new Rectangle();
+
+    /**
+     * Constructor.
+     *
+     * @param center
+     *            the center of the X cross
+     * @param dimension
+     *            the width/height
+     * @param model
+     *            the simulation model
+     */
+    public XCross(PointRW center, DimensionRW dimension, Model model) {
+        super(center, model);
+        this.dimension = dimension;
+        calculateContour();
+    }
+
+    /**
+     * Calculates the contour of the X cross.
+     */
+    @Override
+    protected void calculateContour() {
+        this.contour.x = this.center.x - this.dimension.width / 2;
+        this.contour.y = this.center.y - this.dimension.height / 2;
+        this.contour.width = this.dimension.width;
+        this.contour.height = this.dimension.height;
+    }
+
+    @Override
+    public void draw(Graphics2D graphics) {
+        calculateContour();
+        this.model.transform(this.contour, this.contourSWT);
+        graphics.drawLine(this.contourSWT.x, this.contourSWT.y,
+            this.contourSWT.x + this.contourSWT.width, this.contourSWT.y
+            + this.contourSWT.height);
+        graphics.drawLine(this.contourSWT.x + this.contourSWT.width,
+            this.contourSWT.y, this.contourSWT.x, this.contourSWT.y
+            + this.contourSWT.height);
+    }
+}
diff --git a/test/jlecture/junit/ModelTest.java b/test/jlecture/junit/ModelTest.java
new file mode 100644 (file)
index 0000000..a25fc3b
--- /dev/null
@@ -0,0 +1,105 @@
+package jlecture.junit;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import jlecture.simulation.Bar;
+import jlecture.simulation.DimensionRW;
+import jlecture.simulation.ISheet;
+import jlecture.simulation.IWidget;
+import jlecture.simulation.Model;
+import jlecture.simulation.PointRW;
+import jlecture.simulation.RectangleRW;
+import jlecture.simulation.Robot;
+import jlecture.simulation.ThingRW;
+import jlecture.swt.SheetSWT;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ModelTest extends Model {
+    @Test
+    public void testOccupied() {
+        ISheet sheet = new SheetSWT(new Point(0, 0), new Dimension(200, 100),
+            "test", this);
+        IWidget rectangle = sheet.createRectangle(new PointRW(100, 100),
+            new DimensionRW(20, 20), true, this);
+        Bar bar = new Bar(rectangle);
+        things.add(bar);
+        Assert.assertNull(this.occupied(new PointRW(89.9, 89.9), null));
+        Assert.assertNull(this.occupied(new PointRW(110.1, 110.1), null));
+        Assert.assertNotNull(this.occupied(new PointRW(91, 91), null));
+        Assert.assertNotNull(this.occupied(new PointRW(91, 109), null));
+        Assert.assertTrue(rectangle == widgets.get(0));
+        ThingRW thing = things.get(0);
+        Assert.assertTrue(bar == thing);
+    }
+
+    @Test
+    public void testOpenPosition() {
+        ISheet sheet = new SheetSWT(new Point(0, 0), new Dimension(200, 100),
+            "test", this);
+        IWidget rectangle = sheet.createRectangle(new PointRW(100, 100),
+            new DimensionRW(20, 20), true, this);
+        Bar bar = new Bar(rectangle);
+        things.add(bar);
+        for (int ix = 0; ix < 1000; ix++) {
+            PointRW p = openPosition();
+            Assert.assertNull(this.occupied(p, null));
+        }
+    }
+
+    @Test
+    public void testOpenTransform() {
+        ISheet sheet = new SheetSWT(new Point(0, 0), new Dimension(200, 100),
+            "test", this);
+        Rectangle rect = new Rectangle(0, 0, 0, 0);
+        transform(new RectangleRW(1, 2, 3, 4), rect);
+        Assert.assertEquals(1, rect.x);
+        Assert.assertEquals(2, rect.y);
+        Assert.assertEquals(3, rect.width);
+        Assert.assertEquals(4, rect.height);
+    }
+
+    @Test
+    public void testMove() {
+        ISheet sheet = new SheetSWT(new Point(0, 0), new Dimension(1000, 800),
+            "test", this);
+        IWidget rectangle = sheet.createRectangle(new PointRW(100, 100),
+            new DimensionRW(20, 20), true, this);
+        Robot robot = new Robot(rectangle);
+        robot.setMove(new PointRW(0, 100), 20.0);
+        PointRW point = new PointRW(0, 0);
+        robot.currentPosition(point, -100);
+        Assert.assertEquals(98.0, point.x, 0.01);
+        Assert.assertEquals(100.0, point.y, 0.01);
+        robot.currentPosition(point, -200);
+        Assert.assertEquals(96.0, point.x, 0.01);
+        Assert.assertEquals(100.0, point.y, 0.01);
+
+        robot.setMove(new PointRW(200, 100), 20.0);
+        robot.currentPosition(point, -100);
+        Assert.assertEquals(102.0, point.x, 0.01);
+        Assert.assertEquals(100.0, point.y, 0.01);
+        robot.currentPosition(point, -200);
+        Assert.assertEquals(104.0, point.x, 0.01);
+        Assert.assertEquals(100.0, point.y, 0.01);
+
+        robot.setMove(new PointRW(100, 0), 20.0);
+        robot.currentPosition(point, -100);
+        Assert.assertEquals(100.0, point.x, 0.01);
+        Assert.assertEquals(98.0, point.y, 0.01);
+        robot.currentPosition(point, -200);
+        Assert.assertEquals(100.0, point.x, 0.01);
+        Assert.assertEquals(96.0, point.y, 0.01);
+
+        robot.setMove(new PointRW(100, 200), 20.0);
+        robot.currentPosition(point, -100);
+        Assert.assertEquals(100.0, point.x, 0.01);
+        Assert.assertEquals(102.0, point.y, 0.01);
+        robot.currentPosition(point, -200);
+        Assert.assertEquals(100.0, point.x, 0.01);
+        Assert.assertEquals(104.0, point.y, 0.01);
+    }
+}
diff --git a/test/jlecture/junit/WidgetTest.java b/test/jlecture/junit/WidgetTest.java
new file mode 100644 (file)
index 0000000..b1cd072
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ *
+ */
+package jlecture.junit;
+
+import java.awt.Dimension;
+import java.awt.Point;
+
+import jlecture.simulation.Bar;
+import jlecture.simulation.DimensionRW;
+import jlecture.simulation.ISheet;
+import jlecture.simulation.IWidget;
+import jlecture.simulation.Model;
+import jlecture.simulation.PointRW;
+import jlecture.simulation.RectangleRW;
+import jlecture.simulation.ThingRW;
+import jlecture.swt.SheetSWT;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author hm
+ *
+ */
+public class WidgetTest extends Model {
+
+    @Test
+    public void testBar() {
+        ISheet sheet = new SheetSWT(new Point(0, 0), new Dimension(200, 100),
+            "test", this);
+        IWidget rectangle = sheet.createRectangle(new PointRW(100, 50),
+            new DimensionRW(20, 20), true, this);
+        Bar bar = new Bar(rectangle);
+        this.things.add(bar);
+        Assert.assertTrue(rectangle == this.widgets.get(0));
+        ThingRW thing = this.things.get(0);
+        Assert.assertTrue(bar == thing);
+    }
+
+    @Test
+    public void testDimensionRW() {
+        DimensionRW dim = new DimensionRW(10, 20);
+        Assert.assertEquals(dim.width, 10, 0);
+        Assert.assertEquals(dim.height, 20, 0);
+    }
+
+    @Test
+    public void testPointRW() {
+        PointRW p = new PointRW(10, 20);
+        Assert.assertEquals(p.x, 10, 0);
+        Assert.assertEquals(p.y, 20, 0);
+    }
+
+    @Test
+    public void testRectangleRW() {
+        RectangleRW r = new RectangleRW(10, 20, 30, 40);
+        Assert.assertEquals(r.x, 10, 0);
+        Assert.assertEquals(r.y, 20, 0);
+        Assert.assertEquals(r.width, 30, 0);
+        Assert.assertEquals(r.height, 40, 0);
+    }
+}