From ce349c56280a57e1448504c7e2b419eb0bdf3904 Mon Sep 17 00:00:00 2001 From: hama Date: Sun, 12 Oct 2014 14:40:08 +0200 Subject: [PATCH] Fix collision check, transformation, refactoring * intersection algorithm was wrong * until now real world coordinates are equal to pixel coordinates * usage of automatic supplementation of 'final' --- src/jlection/robotic/RoboSim.java | 8 +- src/jlection/robotic/RobotModel.java | 21 +++-- src/jlecture/simulation/Barrier.java | 6 +- src/jlecture/simulation/ISheet.java | 9 ++ src/jlecture/simulation/Model.java | 64 ++++++++----- src/jlecture/simulation/Movable.java | 26 +++--- src/jlecture/simulation/RectangleRW.java | 62 +++++++++---- src/jlecture/swing/LineSwing.java | 6 +- src/jlecture/swing/PanelSwing.java | 10 +- src/jlecture/swing/RectangleSwing.java | 2 +- src/jlecture/swing/SheetSwing.java | 25 +++-- src/jlecture/swing/WidgetSwing.java | 7 ++ src/jlecture/swing/XCrossSwing.java | 6 +- test/jlecture/junit/ModelTest.java | 42 ++++----- test/jlecture/junit/WidgetTest.java | 112 ++++++++++++++++------- 15 files changed, 263 insertions(+), 143 deletions(-) diff --git a/src/jlection/robotic/RoboSim.java b/src/jlection/robotic/RoboSim.java index db907c7..cabe893 100644 --- a/src/jlection/robotic/RoboSim.java +++ b/src/jlection/robotic/RoboSim.java @@ -29,7 +29,7 @@ public class RoboSim { * the program arguments */ public static void main(String[] args) { - RoboSim simulator = new RoboSim(); + final RoboSim simulator = new RoboSim(); simulator.exec(); } @@ -37,9 +37,9 @@ public class RoboSim { * Initializes the model and the graphical view. */ public void exec() { - Model model = new RobotModel(new RectangleRW(0, 0, 1000, 800)); - SheetSwing sheet = new SheetSwing(new Point(50, 10), new Dimension( - 1000, 800), "Roboterfeld", model); + final Model model = new RobotModel(new RectangleRW(0, 0, 1000, 800)); + final SheetSwing sheet = new SheetSwing(new Point(50, 10), + new Dimension(1000, 800), "Roboterfeld", model); model.createModel(); SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/src/jlection/robotic/RobotModel.java b/src/jlection/robotic/RobotModel.java index eaa3092..8827408 100644 --- a/src/jlection/robotic/RobotModel.java +++ b/src/jlection/robotic/RobotModel.java @@ -23,7 +23,7 @@ public class RobotModel extends Model { * @param region * the visible real world coordinates (a rectangle) */ - public RobotModel(RectangleRW region) { + public RobotModel(final RectangleRW region) { super(region); } @@ -35,25 +35,28 @@ public class RobotModel extends Model { */ @Override public void createModel() { + final int count = 1000; + final int width = 4; this.things.add(new Barrier(this.sheet.createRectangle(new PointRW(500, 100), new DimensionRW(600, 50), false, this))); this.things.add(new Barrier(this.sheet.createRectangle(new PointRW(500, - 400), new DimensionRW(600, 270), false, this))); + 400), new DimensionRW(600, 50), false, this))); this.things.add(new Barrier(this.sheet.createRectangle(new PointRW(500, 700), new DimensionRW(600, 50), false, this))); this.firstIndexMovables = this.things.size(); - PointRW destination = new PointRW(0, 0); - for (int ix = 0; ix < 2; ix++) { - Movable movable = new Movable(this.sheet.createRectangle( - new PointRW(500, 500), new DimensionRW(10, 10), true, this)); + final PointRW destination = new PointRW(0, 0); + for (int ix = 0; ix < count; ix++) { + final Movable movable = new Movable(this.sheet.createRectangle( + new PointRW(500, 500), new DimensionRW(width, width), true, + this)); movable.getWidget().setCenter(openPosition()); destination.x = movable.getWidget().getCenter().x; destination.y = movable.getWidget().getCenter().y; randomDestination(destination); - double minSecondsForWidth = 25; - double velocity = 1 / minSecondsForWidth * this.region.width * 0.5 - * (1 + this.random.nextDouble()); + final double minSecondsForWidth = 25; + final double velocity = 1 / minSecondsForWidth * this.region.width + * 0.5 * (1 + this.random.nextDouble()); movable.setMove(destination, velocity); this.things.add(movable); } diff --git a/src/jlecture/simulation/Barrier.java b/src/jlecture/simulation/Barrier.java index c1c7cb0..f8f2960 100644 --- a/src/jlecture/simulation/Barrier.java +++ b/src/jlecture/simulation/Barrier.java @@ -27,11 +27,11 @@ public class Barrier extends ThingRW { public boolean clashes(RectangleRW rectangle) { boolean rc = false; if (this.widget.getWidgetType() == WidgetType.RECTANGLE - || this.widget.getWidgetType() == WidgetType.XCROSS) + || this.widget.getWidgetType() == WidgetType.XCROSS) rc = rectangle.intersects(this.widget.getContour()); else throw new RuntimeException( - "Barrier.clashes(RectangleRW): not implemented yet"); + "Barrier.clashes(RectangleRW): not implemented yet"); return rc; } @@ -42,7 +42,7 @@ public class Barrier extends ThingRW { rc = thing.clashes((RectangleRW) this.widget); else throw new RuntimeException( - "Barrier.clashes(ThingRW): not implemented yet"); + "Barrier.clashes(ThingRW): not implemented yet"); return rc; } diff --git a/src/jlecture/simulation/ISheet.java b/src/jlecture/simulation/ISheet.java index 7f4e0de..ed8232c 100644 --- a/src/jlecture/simulation/ISheet.java +++ b/src/jlecture/simulation/ISheet.java @@ -1,5 +1,7 @@ package jlecture.simulation; +import java.awt.Dimension; + /** * Defines a drawing area. * @@ -37,4 +39,11 @@ public interface ISheet { * @return a X cross widget */ IWidget createXCross(PointRW center, DimensionRW dimension, Model model); + + /** + * Returns the width and height of the sheet. + * + * @return the dimension of the sheet + */ + public Dimension getDimension(); } diff --git a/src/jlecture/simulation/Model.java b/src/jlecture/simulation/Model.java index f604219..8c237a8 100644 --- a/src/jlecture/simulation/Model.java +++ b/src/jlecture/simulation/Model.java @@ -3,6 +3,7 @@ */ package jlecture.simulation; +import java.awt.Dimension; import java.awt.Rectangle; import java.util.ArrayList; import java.util.List; @@ -67,7 +68,7 @@ public abstract class Model { * @param region * the visible real world coordinates (a rectangle) */ - public Model(RectangleRW region) { + public Model(final RectangleRW region) { this.region = region; } @@ -83,14 +84,14 @@ public abstract class Model { * we check only the things prior to this index. The other things * can change their position later */ - protected void checkCollision(Movable movable, int lastIndex) { + protected void checkCollision(final Movable movable, final int lastIndex) { // we use the contour of the assigned widget: - if (lastIndex > 3 && movable.getWidget().getCenter().y > 300) - lastIndex += 1; for (int ix = 0; ix < lastIndex; ix++) { - ThingRW thing = this.things.get(ix); + final ThingRW thing = this.things.get(ix); if (movable.clashes(thing)) { movable.setMove(null, 0); + if (thing instanceof Movable) + ((Movable) thing).setMove(null, 0); break; } } @@ -143,7 +144,7 @@ public abstract class Model { * @param message * message to log */ - public void log(String message) { + public void log(final String message) { System.out.println(message); } @@ -159,14 +160,14 @@ public abstract class Model { * @return null: at position there is no other thing
* otherwise: the thing at the position */ - public ThingRW occupied(PointRW point, IWidget exclude) { + public ThingRW occupied(final PointRW point, final IWidget exclude) { ThingRW rc = null; - for (ThingRW current : this.things) + for (final ThingRW current : this.things) if (current != exclude) { - RectangleRW contour = current.widget.getContour(); + final 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) { + && point.x < contour.x + contour.width + && point.y < contour.y + contour.height) { rc = current; break; } @@ -180,11 +181,11 @@ public abstract class Model { * @return a not occupied position */ public PointRW openPosition() { - PointRW rc = new PointRW(0, 0); + final PointRW rc = new PointRW(0, 0); do { rc.x = this.region.x + this.random.nextDouble() * this.region.width; rc.y = this.region.x + this.random.nextDouble() - * this.region.height; + * this.region.height; } while (occupied(rc, null) != null); return rc; } @@ -195,7 +196,7 @@ public abstract class Model { * @param destination * IN/OUT: the point to change */ - protected void randomDestination(PointRW destination) { + protected void randomDestination(final PointRW destination) { switch (this.random.nextInt() % 4) { case 0: destination.x = this.region.x; @@ -218,7 +219,7 @@ public abstract class Model { * @param sheet * the new sheet */ - public void setSheet(ISheet sheet) { + public void setSheet(final ISheet sheet) { this.sheet = sheet; } @@ -239,10 +240,10 @@ public abstract class Model { this.now = System.currentTimeMillis(); // do the moves for (int ix = this.firstIndexMovables; ix < this.things.size(); ix++) { - ThingRW thing = this.things.get(ix); + final ThingRW thing = this.things.get(ix); if (thing instanceof Movable) { - Movable movable = (Movable) thing; - PointRW center = movable.getWidget().getCenter(); + final Movable movable = (Movable) thing; + final PointRW center = movable.getWidget().getCenter(); // moves to the position belonging to the current move: movable.currentPosition(center, this.now); movable.getWidget().setCenter(center); @@ -251,9 +252,9 @@ public abstract class Model { } // each simulated object can do its own simulation step: for (int ix = this.firstIndexMovables; ix < this.things.size(); ix++) { - ThingRW thing = this.things.get(ix); + final ThingRW thing = this.things.get(ix); if (thing instanceof Movable) { - Movable movable = (Movable) thing; + final Movable movable = (Movable) thing; movable.simulationStep(); } } @@ -263,16 +264,29 @@ public abstract class Model { /** * Transforms a real world rectangle to a native rectangle. * + *
+     * deltaX = x - xMin
+     * wRW / wPx = deltaXRW / deltaXPx => deltaPx = deltaXRW * wPx / wRW
+     * xPx = xMinPx + deltaXPx, xMinPx = 0
+     * xPx = deltaPx = deltaXRW * wPx / wRW
+     * xPx = (xRW - xMinRW) * (xMaxRW - xMinRW) / xMaxPx
+     * 
+ * * @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; + public void transform(final RectangleRW rectangleRW, + final Rectangle rectangle) { + final Dimension dimension = this.sheet.getDimension(); + + rectangle.x = (int) ((rectangleRW.x - this.region.x) + * this.region.width / dimension.width); + rectangle.y = (int) ((rectangleRW.y - this.region.y) + * this.region.height / dimension.height); + rectangle.width = (int) (rectangleRW.width * dimension.width / this.region.width); + rectangle.height = (int) (rectangleRW.height * dimension.height / this.region.height); } } diff --git a/src/jlecture/simulation/Movable.java b/src/jlecture/simulation/Movable.java index 336d566..b994297 100644 --- a/src/jlecture/simulation/Movable.java +++ b/src/jlecture/simulation/Movable.java @@ -25,12 +25,12 @@ public class Movable extends ThingRW { /** * The position of the last direction change. */ - private PointRW start = new PointRW(0, 0); + private final PointRW start = new PointRW(0, 0); /** * The destination of the currrent move. */ - private PointRW destination = new PointRW(0, 0); + private final PointRW destination = new PointRW(0, 0); /** * The start time of the current move (in msec). @@ -54,11 +54,11 @@ public class Movable extends ThingRW { public boolean clashes(RectangleRW rectangle) { boolean rc = false; if (this.widget.getWidgetType() == WidgetType.RECTANGLE - || this.widget.getWidgetType() == WidgetType.XCROSS) + || this.widget.getWidgetType() == WidgetType.XCROSS) rc = this.widget.getContour().intersects(rectangle); else throw new RuntimeException( - "Movable.clashes(RectangleRW): not implemented yet"); + "Movable.clashes(RectangleRW): not implemented yet"); ; return rc; } @@ -67,11 +67,11 @@ public class Movable extends ThingRW { public boolean clashes(ThingRW thing) { boolean rc = false; if (this.widget.getWidgetType() == WidgetType.RECTANGLE - || this.widget.getWidgetType() == WidgetType.XCROSS) + || this.widget.getWidgetType() == WidgetType.XCROSS) rc = thing.clashes(this.widget.getContour()); else throw new RuntimeException( - "Movable.clashes(ThingRW): not implemented yet"); + "Movable.clashes(ThingRW): not implemented yet"); return rc; } @@ -93,18 +93,18 @@ public class Movable extends ThingRW { if (currentTime < 0) currentTime = this.startTime - currentTime; // v = s / t => s = v * t - double time = (currentTime - this.startTime) / 1000.0; - double distance = this.getVelocity() * time; + final double time = (currentTime - this.startTime) / 1000.0; + final double distance = this.getVelocity() * 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 = this.destination.x - this.start.x; - double y_diff = this.destination.y - this.start.y; - double c = Math.sqrt(x_diff * x_diff + y_diff * y_diff); - double x_diff2 = distance * x_diff / c; - double y_diff2 = distance * y_diff / c; + final double x_diff = this.destination.x - this.start.x; + final double y_diff = this.destination.y - this.start.y; + final double c = Math.sqrt(x_diff * x_diff + y_diff * y_diff); + final double x_diff2 = distance * x_diff / c; + final double y_diff2 = distance * y_diff / c; point.x = this.start.x + x_diff2; point.y = this.start.y + y_diff2; // Stop if the destination has reached: diff --git a/src/jlecture/simulation/RectangleRW.java b/src/jlecture/simulation/RectangleRW.java index 226b6c9..842d5bc 100644 --- a/src/jlecture/simulation/RectangleRW.java +++ b/src/jlecture/simulation/RectangleRW.java @@ -13,6 +13,40 @@ package jlecture.simulation; * */ public class RectangleRW { + /** + * Checks whether two intervals have at least one common value. + * + * @param x1 + * leftest value of the first interval + * @param width1 + * width of the first interval + * @param x2 + * leftest value of the 2nd interval + * @param width2 + * width of the 2nd interval + * @return true: the invervals overlap
+ * false: the intervals are disjunct + */ + public static boolean overlaps(double x1, double width1, double x2, + double width2) { + double p1, p2, pRight, pLeft; + if (width1 > width2) { + pLeft = x1; + pRight = pLeft + width1; + p1 = x2; + p2 = p1 + width2; + } else { + pLeft = x2; + pRight = pLeft + width2; + p1 = x1; + p2 = p1 + width1; + } + // p2 > pLeft: p2 is the first value outside of the smaller inverval: + final boolean rc = p1 >= pLeft && p1 < pRight || p2 > pLeft + && p2 < pRight; + return rc; + } + static final double NEAR_1 = 1 - 1E-13; /** * x coordinate (horizontal) of the left lower corner @@ -26,6 +60,7 @@ public class RectangleRW { * horizontal dimension */ public double width; + /** * vertical dimension */ @@ -75,9 +110,9 @@ public class RectangleRW { * false: the point is outside */ public boolean inside(double x, double y) { - boolean rc = x >= this.x && x < this.x + this.width && y >= this.y - && y < this.y + this.height; - return rc; + final boolean rc = x >= this.x && x < this.x + this.width + && y >= this.y && y < this.y + this.height; + return rc; } /** @@ -90,9 +125,9 @@ public class RectangleRW { * false: the point is outside */ public boolean inside(PointRW point) { - boolean rc = point.x >= this.x && point.x < this.x + this.width - && point.y >= this.y && point.y < this.y + this.height; - return rc; + final boolean rc = point.x >= this.x && point.x < this.x + this.width + && point.y >= this.y && point.y < this.y + this.height; + return rc; } /** @@ -105,16 +140,11 @@ public class RectangleRW { * false: otherwise */ public boolean intersects(RectangleRW rectangle) { - // the rectangle overlaps if at least one edge of the rectangle is - // inside of the - // instance: - boolean rc = inside(rectangle.x, rectangle.y) - || inside(rectangle.x + RectangleRW.NEAR_1 * rectangle.width, - rectangle.y) - || inside(rectangle.x, rectangle.y + RectangleRW.NEAR_1 - * rectangle.height) - || inside(rectangle.x + RectangleRW.NEAR_1 * rectangle.width, - rectangle.y + RectangleRW.NEAR_1 * rectangle.height); + // Two rectangles overlap if there is at least one common x and one + // common y. + final boolean rc = overlaps(this.x, this.width, rectangle.x, + rectangle.width) + && overlaps(this.y, this.height, rectangle.y, rectangle.height); return rc; } diff --git a/src/jlecture/swing/LineSwing.java b/src/jlecture/swing/LineSwing.java index 27b1967..2093879 100644 --- a/src/jlecture/swing/LineSwing.java +++ b/src/jlecture/swing/LineSwing.java @@ -20,11 +20,11 @@ public class LineSwing extends WidgetSwing { /** * the first point of the line */ - private PointRW from = new PointRW(0, 0); + private final PointRW from = new PointRW(0, 0); /** * the last point of the line */ - private PointRW to = new PointRW(0, 0);; + private final PointRW to = new PointRW(0, 0);; /** * Constructor. @@ -55,7 +55,7 @@ public class LineSwing extends WidgetSwing { public void draw(Graphics2D graphics) { graphics.drawLine(this.contourSwing.x, this.contourSwing.y, this.contourSwing.x + this.contourSwing.width, this.contourSwing.y - + this.contourSwing.height); + + this.contourSwing.height); } diff --git a/src/jlecture/swing/PanelSwing.java b/src/jlecture/swing/PanelSwing.java index 0afbf93..f350940 100644 --- a/src/jlecture/swing/PanelSwing.java +++ b/src/jlecture/swing/PanelSwing.java @@ -26,8 +26,8 @@ class PanelSwing extends JPanel { Model model; private static final long serialVersionUID = 1L; - private Color foreground = Color.black; - private Color background = Color.white; + private final Color foreground = Color.black; + private final Color background = Color.white; /** * Constructor. @@ -46,13 +46,13 @@ class PanelSwing extends JPanel { * the drawing parameter like pencil */ private void doDrawing(Graphics graphics) { - Graphics2D g2d = (Graphics2D) graphics; + final Graphics2D g2d = (Graphics2D) graphics; g2d.setColor(this.foreground); g2d.setBackground(this.background); - for (IWidget item : this.model.getItems()) { - WidgetSwing item2 = (WidgetSwing) item; + for (final IWidget item : this.model.getItems()) { + final WidgetSwing item2 = (WidgetSwing) item; item2.draw(g2d); } } diff --git a/src/jlecture/swing/RectangleSwing.java b/src/jlecture/swing/RectangleSwing.java index 8217325..9dfe6e3 100644 --- a/src/jlecture/swing/RectangleSwing.java +++ b/src/jlecture/swing/RectangleSwing.java @@ -20,7 +20,7 @@ import jlecture.simulation.WidgetType; * */ public class RectangleSwing extends WidgetSwing { - private DimensionRW dimension = new DimensionRW(0, 0); + private final DimensionRW dimension = new DimensionRW(0, 0); private boolean filled = false; diff --git a/src/jlecture/swing/SheetSwing.java b/src/jlecture/swing/SheetSwing.java index b49dba2..a2a89bb 100644 --- a/src/jlecture/swing/SheetSwing.java +++ b/src/jlecture/swing/SheetSwing.java @@ -29,9 +29,11 @@ public class SheetSwing extends JFrame implements ISheet, ActionListener { private static final long serialVersionUID = 1L; private Point position = null; private Dimension dimension = null; + private String title = null; - private Model model; - private Timer timer; + + private final Model model; + private final Timer timer; /** * Constructor. @@ -45,8 +47,8 @@ public class SheetSwing extends JFrame implements ISheet, ActionListener { * @param model * simulator model */ - public SheetSwing(Point position, Dimension dimension, String title, - Model model) { + public SheetSwing(final Point position, final Dimension dimension, + final String title, final Model model) { this.position = position; this.dimension = dimension; this.title = title; @@ -58,7 +60,7 @@ public class SheetSwing extends JFrame implements ISheet, ActionListener { } @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(final ActionEvent e) { if (e.getSource() instanceof Timer) { this.model.simulationStep(); repaint(); @@ -66,17 +68,22 @@ public class SheetSwing extends JFrame implements ISheet, ActionListener { } @Override - public IWidget createRectangle(PointRW center, DimensionRW dimension, - boolean filled, Model model) { + public IWidget createRectangle(final PointRW center, + final DimensionRW dimension, final boolean filled, final Model model) { return new RectangleSwing(center, dimension, filled, model); } @Override - public IWidget createXCross(PointRW center, DimensionRW dimension, - Model model) { + public IWidget createXCross(final PointRW center, + final DimensionRW dimension, final Model model) { return new XCrossSwing(center, dimension, model); } + @Override + public Dimension getDimension() { + return this.dimension; + } + /** * Initializes the user interface. */ diff --git a/src/jlecture/swing/WidgetSwing.java b/src/jlecture/swing/WidgetSwing.java index b7e04f7..059c68c 100644 --- a/src/jlecture/swing/WidgetSwing.java +++ b/src/jlecture/swing/WidgetSwing.java @@ -45,6 +45,8 @@ public abstract class WidgetSwing implements IWidget { */ protected Model model; + static int counter = 0; + /** * Constructor. * @@ -100,7 +102,12 @@ public abstract class WidgetSwing implements IWidget { @Override public void setCenter(PointRW center) { + WidgetSwing.counter++; this.center.clone(center); calculateContour(); + if (Math.abs(center.y - this.contour.y) > this.contour.height / 2) + System.out.println(String.format("%d: x/y: %d/%d %d/%d:", + WidgetSwing.counter, (int) center.x, (int) center.y, + (int) this.contour.x, (int) this.contour.y)); } } diff --git a/src/jlecture/swing/XCrossSwing.java b/src/jlecture/swing/XCrossSwing.java index 88ec74f..f9ef0f1 100644 --- a/src/jlecture/swing/XCrossSwing.java +++ b/src/jlecture/swing/XCrossSwing.java @@ -23,7 +23,7 @@ public class XCrossSwing extends WidgetSwing { * The length of the square (contour). */ private DimensionRW dimension = null; - private RectangleRW contour = new RectangleRW(0, 0, 0, 0); + private final RectangleRW contour = new RectangleRW(0, 0, 0, 0); /** * Constructor. @@ -58,10 +58,10 @@ public class XCrossSwing extends WidgetSwing { this.model.transform(this.contour, this.contourSwing); graphics.drawLine(this.contourSwing.x, this.contourSwing.y, this.contourSwing.x + this.contourSwing.width, this.contourSwing.y - + this.contourSwing.height); + + this.contourSwing.height); graphics.drawLine(this.contourSwing.x + this.contourSwing.width, this.contourSwing.y, this.contourSwing.x, this.contourSwing.y - + this.contourSwing.height); + + this.contourSwing.height); } @Override diff --git a/test/jlecture/junit/ModelTest.java b/test/jlecture/junit/ModelTest.java index d27ccc3..24a034b 100644 --- a/test/jlecture/junit/ModelTest.java +++ b/test/jlecture/junit/ModelTest.java @@ -29,9 +29,9 @@ public class ModelTest extends Model { } private void checkCollision(int ixCandidate, boolean shouldClash) { - Movable movable = (Movable) this.things.get(ixCandidate); + final Movable movable = (Movable) this.things.get(ixCandidate); checkCollision(movable, ixCandidate - 1); - double expected = shouldClash ? 0.0 : ModelTest.SPEED; + final double expected = shouldClash ? 0.0 : ModelTest.SPEED; if (movable.getVelocity() != expected) Assert.assertEquals(expected, movable.getVelocity(), 0.0001); } @@ -53,7 +53,7 @@ public class ModelTest extends Model { } private Movable getMovable(double x, double y) { - Movable movable = new Movable(ModelTest.sheet.createRectangle( + final Movable movable = new Movable(ModelTest.sheet.createRectangle( new PointRW(x, y), new DimensionRW(10, 10), true, this)); movable.setMove(new PointRW(0, y), ModelTest.SPEED); return movable; @@ -77,13 +77,13 @@ public class ModelTest extends Model { @Test public void testMove() { - ISheet sheet = new SheetSwing(new Point(0, 0), - new Dimension(1000, 800), "test", this); - IWidget rectangle = sheet.createRectangle(new PointRW(100, 100), + final ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension( + 1000, 800), "test", this); + final IWidget rectangle = sheet.createRectangle(new PointRW(100, 100), new DimensionRW(20, 20), true, this); - Movable robot = new Movable(rectangle); + final Movable robot = new Movable(rectangle); robot.setMove(new PointRW(0, 100), 20.0); - PointRW point = new PointRW(0, 0); + final PointRW point = new PointRW(0, 0); robot.currentPosition(point, -100); Assert.assertEquals(98.0, point.x, ModelTest.SPEED); Assert.assertEquals(100.0, point.y, ModelTest.SPEED); @@ -118,41 +118,41 @@ public class ModelTest extends Model { @Test public void testOccupied() { - ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, 100), - "test", this); - IWidget rectangle = sheet.createRectangle(new PointRW(100, 100), + final ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, + 100), "test", this); + final IWidget rectangle = sheet.createRectangle(new PointRW(100, 100), new DimensionRW(20, 20), true, this); - Barrier bar = new Barrier(rectangle); + final Barrier bar = new Barrier(rectangle); this.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 == this.widgets.get(0)); - ThingRW thing = this.things.get(0); + final ThingRW thing = this.things.get(0); Assert.assertTrue(bar == thing); } @Test public void testOpenPosition() { - ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, 100), - "test", this); - IWidget rectangle = sheet.createRectangle(new PointRW(100, 100), + final ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, + 100), "test", this); + final IWidget rectangle = sheet.createRectangle(new PointRW(100, 100), new DimensionRW(20, 20), true, this); - Barrier bar = new Barrier(rectangle); + final Barrier bar = new Barrier(rectangle); this.things.add(bar); for (int ix = 0; ix < 1000; ix++) { - PointRW p = openPosition(); + final PointRW p = openPosition(); Assert.assertNull(this.occupied(p, null)); } } @Test public void testOpenTransform() { - ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, 100), - "test", this); + final ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, + 100), "test", this); setSheet(sheet); - Rectangle rect = new Rectangle(0, 0, 0, 0); + final 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); diff --git a/test/jlecture/junit/WidgetTest.java b/test/jlecture/junit/WidgetTest.java index 49dba7a..53e0723 100644 --- a/test/jlecture/junit/WidgetTest.java +++ b/test/jlecture/junit/WidgetTest.java @@ -31,29 +31,43 @@ public class WidgetTest extends RobotModel { super(new RectangleRW(0, 0, 1000, 800)); } + /** + * Intersection is symetric: r1.intersects(r2) == r1.intersects(r1) + * + * @param rect1 + * @param rect2 + */ + private void checkIntersection(boolean expected, RectangleRW rect1, + RectangleRW rect2) { + final boolean rc1 = rect1.intersects(rect2); + Assert.assertTrue(rc1 == expected); + final boolean rc2 = rect2.intersects(rect1); + Assert.assertTrue(rc1 == rc2); + } + @Test public void testBar() { - ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, 100), - "test", this); - IWidget rectangle = sheet.createRectangle(new PointRW(100, 50), + final ISheet sheet = new SheetSwing(new Point(0, 0), new Dimension(200, + 100), "test", this); + final IWidget rectangle = sheet.createRectangle(new PointRW(100, 50), new DimensionRW(20, 20), true, this); - Barrier bar = new Barrier(rectangle); + final Barrier bar = new Barrier(rectangle); this.things.add(bar); Assert.assertTrue(rectangle == this.widgets.get(0)); - ThingRW thing = this.things.get(0); + final ThingRW thing = this.things.get(0); Assert.assertTrue(bar == thing); } @Test public void testDimensionRW() { - DimensionRW dim = new DimensionRW(10, 20); + final DimensionRW dim = new DimensionRW(10, 20); Assert.assertEquals(10, dim.width, 0); Assert.assertEquals(20, dim.height, 0); } @Test public void testPointRW() { - PointRW p = new PointRW(10, 20); + final PointRW p = new PointRW(10, 20); Assert.assertEquals(10, p.x, 0); Assert.assertEquals(20, p.y, 0); } @@ -62,7 +76,7 @@ public class WidgetTest extends RobotModel { public void testRectangleInside() { // adopt the coordinates are integer (discrete). - RectangleRW r = new RectangleRW(10, 20, 30, 40); + final RectangleRW r = new RectangleRW(10, 20, 30, 40); // touching nearly one corner only: /** * Legend: '|' '-' and '_' are borders of the instance, X are the test @@ -145,7 +159,7 @@ public class WidgetTest extends RobotModel { public void testRectangleInsidePoint() { // adopt the coordinates are integer (discrete). - RectangleRW r = new RectangleRW(10, 20, 30, 40); + final RectangleRW r = new RectangleRW(10, 20, 30, 40); // touching nearly one corner only: /** * Legend: '|' '-' and '_' are borders of the instance, X are the test @@ -228,7 +242,7 @@ public class WidgetTest extends RobotModel { public void testRectangleIntersects() { // adopt the coordinates are integer (discrete). - RectangleRW r = new RectangleRW(10, 20, 30, 40); + final RectangleRW r = new RectangleRW(10, 20, 30, 40); // touching nearly one corner only: /** * Legend: '|' '-' and '_' are borders of the instance, X are the test @@ -242,13 +256,13 @@ public class WidgetTest extends RobotModel { * */ // left lower corner: - Assert.assertFalse(r.intersects(new RectangleRW(9, 19, 1, 1))); + checkIntersection(false, r, new RectangleRW(9, 19, 1, 1)); // left upper corner: - Assert.assertFalse(r.intersects(new RectangleRW(9, 60, 1, 1))); + checkIntersection(false, r, new RectangleRW(9, 60, 1, 1)); // right upper corner: - Assert.assertFalse(r.intersects(new RectangleRW(39, 60, 1, 1))); + checkIntersection(false, r, new RectangleRW(39, 60, 1, 1)); // right lower corner: - Assert.assertFalse(r.intersects(new RectangleRW(39, 19, 1, 1))); + checkIntersection(false, r, new RectangleRW(39, 19, 1, 1)); // touching nearly one border /** @@ -261,13 +275,13 @@ public class WidgetTest extends RobotModel { * */ // lower border - Assert.assertFalse(r.intersects(new RectangleRW(9, 25, 1, 3))); + checkIntersection(false, r, new RectangleRW(9, 25, 1, 3)); // right border - Assert.assertFalse(r.intersects(new RectangleRW(40, 25, 1, 3))); + checkIntersection(false, r, new RectangleRW(40, 25, 1, 3)); // upper border - Assert.assertFalse(r.intersects(new RectangleRW(15, 60, 3, 3))); + checkIntersection(false, r, new RectangleRW(15, 60, 3, 3)); // left border - Assert.assertFalse(r.intersects(new RectangleRW(9, 25, 1, 3))); + checkIntersection(false, r, new RectangleRW(9, 25, 1, 3)); // touching minimal one corner only: /** @@ -279,16 +293,16 @@ public class WidgetTest extends RobotModel { * */ // left lower corner: - Assert.assertTrue(r.intersects(new RectangleRW(9, 19, 2, 2))); - Assert.assertTrue(r.intersects(new RectangleRW(10, 20, 1, 1))); + checkIntersection(true, r, new RectangleRW(9, 19, 2, 2)); + checkIntersection(true, r, new RectangleRW(10, 20, 1, 1)); // left upper corner: - Assert.assertTrue(r.intersects(new RectangleRW(9, 59, 2, 1))); - Assert.assertTrue(r.intersects(new RectangleRW(10, 59, 1, 1))); + checkIntersection(true, r, new RectangleRW(9, 59, 2, 1)); + checkIntersection(true, r, new RectangleRW(10, 59, 1, 1)); // right upper corner: - Assert.assertTrue(r.intersects(new RectangleRW(39, 59, 1, 1))); + checkIntersection(true, r, new RectangleRW(39, 59, 1, 1)); // right lower corner: - Assert.assertTrue(r.intersects(new RectangleRW(39, 19, 1, 2))); - Assert.assertTrue(r.intersects(new RectangleRW(39, 20, 1, 1))); + checkIntersection(true, r, new RectangleRW(39, 19, 1, 2)); + checkIntersection(true, r, new RectangleRW(39, 20, 1, 1)); // touching minimal one border /** @@ -301,19 +315,55 @@ public class WidgetTest extends RobotModel { * */ // lower border - Assert.assertTrue(r.intersects(new RectangleRW(9, 25, 2, 3))); + checkIntersection(true, r, new RectangleRW(9, 25, 2, 3)); // right border - Assert.assertTrue(r.intersects(new RectangleRW(39, 25, 1, 3))); + checkIntersection(true, r, new RectangleRW(39, 25, 1, 3)); // upper border - Assert.assertTrue(r.intersects(new RectangleRW(15, 51, 3, 1))); + checkIntersection(true, r, new RectangleRW(15, 51, 3, 1)); // left border - Assert.assertTrue(r.intersects(new RectangleRW(9, 25, 2, 3))); - Assert.assertTrue(r.intersects(new RectangleRW(10, 25, 1, 3))); + checkIntersection(true, r, new RectangleRW(9, 25, 2, 3)); + checkIntersection(true, r, new RectangleRW(10, 25, 1, 3)); + /** + *
+         *  _____
+         *  |   |
+         *  | |-|-|
+         *  --|-| |
+         *    -----
+         * 
+ */ + // 10, 20, 30, 40 + checkIntersection(true, r, new RectangleRW(20, 30, 30, 40)); + /** + *
+         *    ___
+         *   |   |
+         * |-|---|-|
+         * |-|---|-|
+         *   |   |
+         *   -----
+         * 
+ */ + // 10, 20, 30, 40 + checkIntersection(true, r, new RectangleRW(0, 30, 100, 5)); + + /** + *
+         *    _______
+         *   |       |
+         *   | |---| |
+         *   | |   | |
+         *   | ----- |
+         *   ---------
+         * 
+ */ + // 10, 20, 30, 40 + checkIntersection(true, r, new RectangleRW(25, 30, 10, 10)); } @Test public void testRectangleRW() { - RectangleRW r = new RectangleRW(10, 20, 30, 40); + final RectangleRW r = new RectangleRW(10, 20, 30, 40); Assert.assertEquals(10, r.x, 0); Assert.assertEquals(20, r.y, 0); Assert.assertEquals(30, r.width, 0); -- 2.39.5