super(widget);
}
+ /**
+ * Evaluate exactly one simulation step.
+ *
+ * This method is normally overwritten.
+ *
+ * Note: if the current time is necessary, use Model.getNow().
+ */
+ @Override
+ public void simulationStep() {
+
+ }
}
*/
package jlection.robotic;
-import jlecture.simulation.Bar;
+import jlecture.simulation.Barrier;
import jlecture.simulation.DimensionRW;
import jlecture.simulation.Model;
import jlecture.simulation.Movable;
*/
@Override
public void createModel() {
- this.things.add(new Bar(this.sheet.createRectangle(
- new PointRW(500, 100), new DimensionRW(600, 50), false, this)));
- this.things.add(new Bar(this.sheet.createRectangle(
- new PointRW(500, 400), new DimensionRW(600, 50), false, this)));
- this.things.add(new Bar(this.sheet.createRectangle(
- new PointRW(500, 700), new DimensionRW(600, 50), false, this)));
+ 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, 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 < 20; ix++) {
- Movable robot = new Movable(this.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;
+ Movable movable = new Movable(this.sheet.createRectangle(
+ new PointRW(500, 500), new DimensionRW(10, 10), 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());
- robot.setMove(destination, velocity);
- this.things.add(robot);
+ movable.setMove(destination, velocity);
+ this.things.add(movable);
}
this.isReady = true;
- log("model completed");
}
}
+++ /dev/null
-/**
- *
- */
-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);
- }
-
-}
--- /dev/null
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * Implements a stationary element in the model.
+ *
+ * Barriers are objects which can not be passed traversed. Movables must go
+ * arround barriers.
+ *
+ * @author hm
+ *
+ */
+public class Barrier extends ThingRW {
+ /**
+ * Constructor.
+ *
+ * @param widget
+ * the widget in the model view
+ */
+ public Barrier(IWidget widget) {
+ super(widget);
+ }
+
+ @Override
+ public boolean clashes(RectangleRW rectangle) {
+ boolean rc = false;
+ if (this.widget.getWidgetType() == WidgetType.RECTANGLE
+ || this.widget.getWidgetType() == WidgetType.XCROSS)
+ rc = rectangle.intersects(this.widget.getContour());
+ else
+ assert false;
+ return rc;
+ }
+
+ @Override
+ public boolean clashes(ThingRW thing) {
+ boolean rc = false;
+ if (this.widget instanceof RectangleRW)
+ rc = thing.clashes((RectangleRW) this.widget);
+ else
+ assert false;
+ return rc;
+ }
+
+}
*/
public Model getModel();
+ /**
+ * Returns the widget type, e.g. RECTANGLE.
+ *
+ * @return the widget type
+ */
+ public WidgetType getWidgetType();
+
/**
* @param center
* the center to set
*/
public void setCenter(PointRW center);
-
}
* The list of things which are relevant to the simulation.
*/
protected ArrayList<ThingRW> things = new ArrayList<ThingRW>();
+ /**
+ * The lower indices are used for bars.
+ */
+ protected int firstIndexMovables = 0;
/**
* The drawing area (graphical view).
*/
*/
protected Random random = new Random(0x4711);
- private long sumTime = 0;
-
- private long count = 0;
-
- private long max = 0;
+ /**
+ * The current timepoint. Is constant for one simulation step.
+ */
+ protected long now;
/**
* Constructor.
this.region = region;
}
+ /**
+ * Checks whether a given object collides with one of the other simulated
+ * objects.
+ *
+ * If a collision is detected the object will be stopped (velocity = 0).
+ *
+ * @param movable
+ * the object to test
+ * @param lastIndex
+ * we check only the things prior to this index. The other things
+ * can change their position later
+ */
+ protected void checkCollision(Movable movable, int lastIndex) {
+ // we use the contour of the assigned widget:
+ for (int ix = 0; ix < lastIndex; ix++) {
+ ThingRW thing = this.things.get(ix);
+ if (movable.clashes(thing)) {
+ movable.setMove(null, 0);
+ break;
+ }
+ }
+ }
+
/**
* Builds the elements of the simulator.
*
* Creates the simulated things and put it into the variable
- * <code>things</code>. For the movable things it will initialize the
- * velocity and destination.
+ * <code>things</code>. Each movable thing should be initialized the
+ * velocity and the destination.
*/
public abstract void createModel();
return this.widgets;
}
+ /**
+ * @return the now
+ */
+ public long getNow() {
+ return this.now;
+ }
+
/**
* Returns the sheet.
*
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) {
+ && point.x < contour.x + contour.width
+ && point.y < contour.y + contour.height) {
rc = current;
break;
}
return rc;
}
- /**
- * Executes one simulator step.
- *
- * Will be called every 100 milliseconds and calculates the changes which
- * are necessary for one simulation step.
- */
- public void onTimer() {
- if (this.isReady) {
- long start = System.currentTimeMillis();
- // count++;
- // for (int n = 0; n < 1; n++)
- {
- for (ThingRW thing : this.things)
- if (thing instanceof Movable) {
- Movable robot = (Movable) thing;
- PointRW center = robot.getWidget().getCenter();
- // moves to the position belonging to the current move:
- robot.currentPosition(center, start);
- robot.getWidget().setCenter(center);
- }
- }
- // long diff = System.currentTimeMillis() - start;
- // sumTime += diff;
- // if (max < diff)
- // max = diff;
- // if (count % 1 == 0)
- // log(String.format("Count: %d Duration: %f Max: %d", count,
- // (double) sumTime / count, max));
- }
- }
-
/**
* Returns a position not occupied by another model thing.
*
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;
}
this.sheet = sheet;
}
+ /**
+ * Executes one simulation step.
+ *
+ * Will be called every 100 milliseconds.
+ *
+ * Two actions will be done:
+ *
+ * First all movable objects will be moved depending on its prior position
+ * and its velocity.
+ *
+ * After that each simulated object do its own simulation step.
+ */
+ public void simulationStep() {
+ if (this.isReady) {
+ this.now = System.currentTimeMillis();
+ // do the moves
+ for (int ix = this.firstIndexMovables; ix < this.things.size(); ix++) {
+ ThingRW thing = this.things.get(ix);
+ if (thing instanceof Movable) {
+ Movable movable = (Movable) thing;
+ PointRW center = movable.getWidget().getCenter();
+ // moves to the position belonging to the current move:
+ movable.currentPosition(center, this.now);
+ movable.getWidget().setCenter(center);
+ checkCollision(movable, ix);
+ }
+ }
+ // 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);
+ if (thing instanceof Movable) {
+ Movable movable = (Movable) thing;
+ movable.simulationStep();
+ }
+ }
+ }
+ }
+
/**
* Transforms a real world rectangle to a native rectangle.
*
* 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;
+
protected Model model = null;
/**
this.model = widget.getModel();
}
+ @Override
+ public boolean clashes(RectangleRW rectangle) {
+ boolean rc = false;
+ if (this.widget.getWidgetType() == WidgetType.RECTANGLE
+ || this.widget.getWidgetType() == WidgetType.XCROSS)
+ rc = this.widget.getContour().intersects(rectangle);
+ else
+ assert false;
+ return rc;
+ }
+
+ @Override
+ public boolean clashes(ThingRW thing) {
+ boolean rc = false;
+ if (this.widget.getWidgetType() == WidgetType.RECTANGLE
+ || this.widget.getWidgetType() == WidgetType.XCROSS)
+ rc = thing.clashes(this.widget.getContour());
+ else
+ assert false;
+ return rc;
+ }
+
/**
* Calculates the position (for the current move).
*
* otherwise: the current time in milliseconds
*/
public void currentPosition(PointRW point, long currentTime) {
- if (this.velocity == 0.0) {
+ if (this.getVelocity() == 0.0) {
point.x = this.widget.getCenter().x;
point.y = this.widget.getCenter().y;
} else {
currentTime = this.startTime - currentTime;
// v = s / t => s = v * t
double time = (currentTime - this.startTime) / 1000.0;
- double distance = this.velocity * time;
+ double distance = this.getVelocity() * time;
// hypotenuse:
// c = sqrt(x_target _ x_start)**2 + (y_target _ y_start)**2)
// Theory of intersecting lines:
// Stop if the destination has reached:
if (Math.abs(x_diff2) > Math.abs(x_diff)) {
point.x = this.destination.x;
- this.velocity = 0;
+ this.setVelocity(0);
}
if (Math.abs(y_diff2) > Math.abs(y_diff)) {
point.y = this.destination.y;
- this.velocity = 0;
+ this.setVelocity(0);
}
}
}
+ /**
+ * Returns the velocity.
+ *
+ * @return the velocity
+ */
+ public double getVelocity() {
+ return this.velocity;
+ }
+
/**
* @return the widget of the robot
*/
+ @Override
public IWidget getWidget() {
return this.widget;
}
*/
public void setMove(PointRW destination, double velocity) {
this.start.clone(this.widget.getCenter());
- this.destination.clone(destination);
- this.startTime = System.currentTimeMillis();
+ if (destination != null)
+ this.destination.clone(destination);
+ this.startTime = this.model.getNow();
+ this.setVelocity(velocity);
+ }
+
+ /**
+ * Sets the velocity.
+ *
+ * @param velocity
+ * the velocity to set
+ */
+ public void setVelocity(double velocity) {
this.velocity = velocity;
}
public void setWidget(IWidget widget) {
this.widget = widget;
}
+
+ /**
+ * Evaluate exactly one simulation step.
+ *
+ * This method is normally overridden.
+ *
+ * Note: if the current time is necessary, use Model.getNow().
+ */
+ public void simulationStep() {
+ // nothing to do
+ }
}
* Implements a rectangle with real world coordinates containing x, y, width and
* height.
*
+ * The point (x, y) is the left lower edge of the rectangle.
+ *
* @author hm
*
*/
public class RectangleRW {
+ static final double NEAR_1 = 1 - 1E-13;
/**
* x coordinate (horizontal) of the left lower corner
*/
this.height = source.height;
}
+ /**
+ * Tests whether a given point is inside the instance.
+ *
+ * @param x
+ * the x coordinate of the point to test
+ * @param y
+ * the y coordinate of the point to test
+ * @return <code>true</code>: the <code>rectangle</code> is completely
+ * inside the instance<br>
+ * <code>false</code>: 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;
+ }
+
+ /**
+ * Tests whether a given point is inside the instance.
+ *
+ * @param point
+ * the point to test
+ * @return <code>true</code>: the <code>rectangle</code> is completely
+ * inside the instance<br>
+ * <code>false</code>: 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;
+ }
+
+ /**
+ * Tests whether a given rectangle overlaps the instance.
+ *
+ * @param rectangle
+ * the rectangle to test
+ * @return <code>true</code>: the <code>rectangle</code> intersects the
+ * instance<br>
+ * <code>false</code>: 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);
+ return rc;
+ }
+
}
*
* @author hm
*/
-public class ThingRW {
+public abstract class ThingRW {
protected IWidget widget;
/**
this.widget = widget;
widget.getModel().getWidgets().add(widget);
}
+
+ /**
+ * Tests whether a given thing has a common point with the instance.
+ *
+ * @param rectangle
+ * the rectangle to test
+ * @return <code>true</code>: at least one corner is inside the widget<br>
+ * <code>false</code>: otherwise
+ */
+ public abstract boolean clashes(RectangleRW rectangle);
+
+ /**
+ * Tests whether a given thing has a common point with the instance.
+ *
+ * @param thing
+ * the thing to test
+ * @return <code>true</code>: <code>thing</code> has at least one common
+ * point with the instance<br>
+ * <code>false</code>: otherwise
+ */
+ public abstract boolean clashes(ThingRW thing);
+
+ /**
+ * @return the widget
+ */
+ public IWidget getWidget() {
+ return this.widget;
+ }
+
}
--- /dev/null
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * Defines the basic geometric forms.
+ *
+ * @author hm
+ *
+ */
+public enum WidgetType {
+ UNDEF, RECTANGLE, XCROSS, LINE, POINT
+}
import jlecture.simulation.Model;
import jlecture.simulation.PointRW;
+import jlecture.simulation.WidgetType;
/**
* Implements a line in Swing.
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);
}
+ @Override
+ public WidgetType getWidgetType() {
+ return WidgetType.LINE;
+ }
+
}
import jlecture.simulation.DimensionRW;
import jlecture.simulation.Model;
import jlecture.simulation.PointRW;
+import jlecture.simulation.WidgetType;
/**
* Implements a rectangle with real world coordinates.
graphics.drawRect(this.contourSwing.x, this.contourSwing.y,
this.contourSwing.width, this.contourSwing.height);
}
+
+ @Override
+ public WidgetType getWidgetType() {
+ return WidgetType.RECTANGLE;
+ }
}
@Override
public void actionPerformed(ActionEvent e) {
- // if (e.getActionCommand().equals(""))
- {
- this.model.onTimer();
+ if (e.getSource() instanceof Timer) {
+ this.model.simulationStep();
repaint();
}
}
import jlecture.simulation.Model;
import jlecture.simulation.PointRW;
import jlecture.simulation.RectangleRW;
+import jlecture.simulation.WidgetType;
/**
* Implements a cross similar to a 'X' for SWT. These are the diagonals of a
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
+ public WidgetType getWidgetType() {
+ return WidgetType.XCROSS;
}
}
--- /dev/null
+package jlecture.junit;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import jlecture.simulation.Barrier;
+import jlecture.simulation.DimensionRW;
+import jlecture.simulation.ISheet;
+import jlecture.simulation.IWidget;
+import jlecture.simulation.Model;
+import jlecture.simulation.Movable;
+import jlecture.simulation.PointRW;
+import jlecture.simulation.RectangleRW;
+import jlecture.simulation.ThingRW;
+import jlecture.swing.SheetSwing;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ModelTest extends Model {
+ static final double SPEED = 0.01;
+
+ static ISheet sheet = null;
+
+ public ModelTest() {
+ super(new RectangleRW(0, 0, 1000, 800));
+ }
+
+ private void checkCollision(int ixCandidate, boolean shouldClash) {
+ Movable movable = (Movable) this.things.get(ixCandidate);
+ checkCollision(movable, ixCandidate - 1);
+ double expected = shouldClash ? 0.0 : ModelTest.SPEED;
+ if (movable.getVelocity() != expected)
+ Assert.assertEquals(expected, movable.getVelocity(), 0.0001);
+ }
+
+ @Override
+ public void createModel() {
+ this.things.clear();
+ // Rectangle: (x=200, y=50, w=600, h=100)
+ this.things.add(new Barrier(ModelTest.sheet.createRectangle(
+ new PointRW(500, 100), new DimensionRW(600, 50), false, this)));
+ // in front of
+ this.things.add(getMovable(190, 60));
+ // behind
+ this.things.add(getMovable(800, 60));
+ // clashes with barrier
+ this.things.add(getMovable(200, 60));
+ // clashes with first movable:
+ this.things.add(getMovable(190, 55));
+ }
+
+ private Movable getMovable(double x, double y) {
+ 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;
+ }
+
+ @Before
+ public void prepare() {
+ ModelTest.sheet = new SheetSwing(new Point(0, 0), new Dimension(1000,
+ 800), "test", this);
+ setSheet(ModelTest.sheet);
+ }
+
+ @Test
+ public void testcheckCollision() {
+ createModel();
+ checkCollision(1, false);
+ checkCollision(2, false);
+ checkCollision(3, false);
+ checkCollision(4, true);
+ }
+
+ @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),
+ new DimensionRW(20, 20), true, this);
+ Movable robot = new Movable(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, ModelTest.SPEED);
+ Assert.assertEquals(100.0, point.y, ModelTest.SPEED);
+ robot.currentPosition(point, -200);
+ Assert.assertEquals(96.0, point.x, ModelTest.SPEED);
+ Assert.assertEquals(100.0, point.y, ModelTest.SPEED);
+
+ robot.setMove(new PointRW(200, 100), 20.0);
+ robot.currentPosition(point, -100);
+ Assert.assertEquals(102.0, point.x, ModelTest.SPEED);
+ Assert.assertEquals(100.0, point.y, ModelTest.SPEED);
+ robot.currentPosition(point, -200);
+ Assert.assertEquals(104.0, point.x, ModelTest.SPEED);
+ Assert.assertEquals(100.0, point.y, ModelTest.SPEED);
+
+ robot.setMove(new PointRW(100, 0), 20.0);
+ robot.currentPosition(point, -100);
+ Assert.assertEquals(100.0, point.x, ModelTest.SPEED);
+ Assert.assertEquals(98.0, point.y, ModelTest.SPEED);
+ robot.currentPosition(point, -200);
+ Assert.assertEquals(100.0, point.x, ModelTest.SPEED);
+ Assert.assertEquals(96.0, point.y, ModelTest.SPEED);
+
+ robot.setMove(new PointRW(100, 200), 20.0);
+ robot.currentPosition(point, -100);
+ Assert.assertEquals(100.0, point.x, ModelTest.SPEED);
+ Assert.assertEquals(102.0, point.y, ModelTest.SPEED);
+ robot.currentPosition(point, -200);
+ Assert.assertEquals(100.0, point.x, ModelTest.SPEED);
+ Assert.assertEquals(104.0, point.y, ModelTest.SPEED);
+ }
+
+ @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),
+ new DimensionRW(20, 20), true, this);
+ 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);
+ 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),
+ new DimensionRW(20, 20), true, this);
+ Barrier bar = new Barrier(rectangle);
+ this.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 SheetSwing(new Point(0, 0), new Dimension(200, 100),
+ "test", this);
+ setSheet(sheet);
+ 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);
+ }
+}
+++ /dev/null
-package jlecture.junit;
-
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-
-import jlection.robotic.RobotModel;
-import jlecture.simulation.Bar;
-import jlecture.simulation.DimensionRW;
-import jlecture.simulation.ISheet;
-import jlecture.simulation.IWidget;
-import jlecture.simulation.Movable;
-import jlecture.simulation.PointRW;
-import jlecture.simulation.RectangleRW;
-import jlecture.simulation.ThingRW;
-import jlecture.swing.SheetSwing;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class RobotModelTest extends RobotModel {
- public RobotModelTest() {
- super(new RectangleRW(0, 0, 1000, 800));
- }
-
- @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),
- new DimensionRW(20, 20), true, this);
- Movable robot = new Movable(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);
- }
-
- @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),
- new DimensionRW(20, 20), true, this);
- Bar bar = new Bar(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);
- 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),
- new DimensionRW(20, 20), true, this);
- Bar bar = new Bar(rectangle);
- this.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 SheetSwing(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);
- }
-}
import java.awt.Point;
import jlection.robotic.RobotModel;
-import jlecture.simulation.Bar;
+import jlecture.simulation.Barrier;
import jlecture.simulation.DimensionRW;
import jlecture.simulation.ISheet;
import jlecture.simulation.IWidget;
import org.junit.Test;
/**
+ * Tests the low level classes of the package jlecture.simulation.
+ *
* @author hm
*
*/
"test", this);
IWidget rectangle = sheet.createRectangle(new PointRW(100, 50),
new DimensionRW(20, 20), true, this);
- Bar bar = new Bar(rectangle);
+ Barrier bar = new Barrier(rectangle);
this.things.add(bar);
Assert.assertTrue(rectangle == this.widgets.get(0));
ThingRW thing = this.things.get(0);
@Test
public void testDimensionRW() {
DimensionRW dim = new DimensionRW(10, 20);
- Assert.assertEquals(dim.width, 10, 0);
- Assert.assertEquals(dim.height, 20, 0);
+ Assert.assertEquals(10, dim.width, 0);
+ Assert.assertEquals(20, dim.height, 0);
}
@Test
public void testPointRW() {
PointRW p = new PointRW(10, 20);
- Assert.assertEquals(p.x, 10, 0);
- Assert.assertEquals(p.y, 20, 0);
+ Assert.assertEquals(10, p.x, 0);
+ Assert.assertEquals(20, p.y, 0);
+ }
+
+ @Test
+ public void testRectangleInside() {
+ // adopt the coordinates are integer (discrete).
+
+ RectangleRW r = new RectangleRW(10, 20, 30, 40);
+ // touching nearly one corner only:
+ /**
+ * Legend: '|' '-' and '_' are borders of the instance, X are the test
+ * rectangles.
+ *
+ * <pre>
+ * X_____X
+ * | |
+ * |___|
+ * X X
+ * </pre>
+ */
+ // left lower corner:
+ Assert.assertFalse(r.inside(9, 19));
+ // left upper corner:
+ Assert.assertFalse(r.inside(9, 60));
+ // right upper corner:
+ Assert.assertFalse(r.inside(39, 60));
+ // right lower corner:
+ Assert.assertFalse(r.inside(39, 19));
+
+ // touching nearly one border
+ /**
+ * <pre>
+ * __X__
+ * | |
+ * X| |X
+ * |___|
+ * X
+ * </pre>
+ */
+ // lower border
+ Assert.assertFalse(r.inside(9, 25));
+ // right border
+ Assert.assertFalse(r.inside(40, 25));
+ // upper border
+ Assert.assertFalse(r.inside(15, 60));
+ // left border
+ Assert.assertFalse(r.inside(9, 25));
+
+ // Test the corners:
+ /**
+ * <pre>
+ *
+ * X--X
+ * | |
+ * X--X
+ * </pre>
+ */
+ // left lower corner:
+ Assert.assertTrue(r.inside(10, 20));
+ // left upper corner:
+ Assert.assertTrue(r.inside(10, 59));
+ // right upper corner:
+ Assert.assertTrue(r.inside(39, 59));
+ // right lower corner:
+ Assert.assertTrue(r.inside(39, 20));
+
+ // touching minimal one border
+ /**
+ * <pre>
+ * --X--
+ * | |
+ * X X
+ * | |
+ * --X--
+ * </pre>
+ */
+ // lower border
+ Assert.assertTrue(r.inside(10, 25));
+ // right border
+ Assert.assertTrue(r.inside(39, 25));
+ // upper border
+ Assert.assertTrue(r.inside(15, 59));
+ // left border
+ Assert.assertTrue(r.inside(10, 25));
+ }
+
+ @Test
+ public void testRectangleInsidePoint() {
+ // adopt the coordinates are integer (discrete).
+
+ RectangleRW r = new RectangleRW(10, 20, 30, 40);
+ // touching nearly one corner only:
+ /**
+ * Legend: '|' '-' and '_' are borders of the instance, X are the test
+ * rectangles.
+ *
+ * <pre>
+ * X_____X
+ * | |
+ * |___|
+ * X X
+ * </pre>
+ */
+ // left lower corner:
+ Assert.assertFalse(r.inside(new PointRW(9, 19)));
+ // left upper corner:
+ Assert.assertFalse(r.inside(new PointRW(9, 60)));
+ // right upper corner:
+ Assert.assertFalse(r.inside(new PointRW(39, 60)));
+ // right lower corner:
+ Assert.assertFalse(r.inside(new PointRW(39, 19)));
+
+ // touching nearly one border
+ /**
+ * <pre>
+ * __X__
+ * | |
+ * X| |X
+ * |___|
+ * X
+ * </pre>
+ */
+ // lower border
+ Assert.assertFalse(r.inside(new PointRW(9, 25)));
+ // right border
+ Assert.assertFalse(r.inside(new PointRW(40, 25)));
+ // upper border
+ Assert.assertFalse(r.inside(new PointRW(15, 60)));
+ // left border
+ Assert.assertFalse(r.inside(new PointRW(9, 25)));
+
+ // touching minimal one corner only:
+ /**
+ * <pre>
+ *
+ * X--X
+ * | |
+ * X--X
+ * </pre>
+ */
+ // left lower corner:
+ Assert.assertTrue(r.inside(new PointRW(10, 20)));
+ // left upper corner:
+ Assert.assertTrue(r.inside(new PointRW(10, 59)));
+ // right upper corner:
+ Assert.assertTrue(r.inside(new PointRW(39, 59)));
+ // right lower corner:
+ Assert.assertTrue(r.inside(new PointRW(39, 20)));
+
+ // touching minimal one border
+ /**
+ * <pre>
+ * --X--
+ * | |
+ * X X
+ * | |
+ * --X--
+ * </pre>
+ */
+ // lower border
+ Assert.assertTrue(r.inside(new PointRW(10, 25)));
+ // right border
+ Assert.assertTrue(r.inside(new PointRW(39, 25)));
+ // upper border
+ Assert.assertTrue(r.inside(new PointRW(15, 51)));
+ // left border
+ Assert.assertTrue(r.inside(new PointRW(10, 25)));
+ }
+
+ @Test
+ public void testRectangleIntersects() {
+ // adopt the coordinates are integer (discrete).
+
+ RectangleRW r = new RectangleRW(10, 20, 30, 40);
+ // touching nearly one corner only:
+ /**
+ * Legend: '|' '-' and '_' are borders of the instance, X are the test
+ * rectangles.
+ *
+ * <pre>
+ * X_____X
+ * | |
+ * |___|
+ * X X
+ * </pre>
+ */
+ // left lower corner:
+ Assert.assertFalse(r.intersects(new RectangleRW(9, 19, 1, 1)));
+ // left upper corner:
+ Assert.assertFalse(r.intersects(new RectangleRW(9, 60, 1, 1)));
+ // right upper corner:
+ Assert.assertFalse(r.intersects(new RectangleRW(39, 60, 1, 1)));
+ // right lower corner:
+ Assert.assertFalse(r.intersects(new RectangleRW(39, 19, 1, 1)));
+
+ // touching nearly one border
+ /**
+ * <pre>
+ * __X__
+ * | |
+ * X| |X
+ * |___|
+ * X
+ * </pre>
+ */
+ // lower border
+ Assert.assertFalse(r.intersects(new RectangleRW(9, 25, 1, 3)));
+ // right border
+ Assert.assertFalse(r.intersects(new RectangleRW(40, 25, 1, 3)));
+ // upper border
+ Assert.assertFalse(r.intersects(new RectangleRW(15, 60, 3, 3)));
+ // left border
+ Assert.assertFalse(r.intersects(new RectangleRW(9, 25, 1, 3)));
+
+ // touching minimal one corner only:
+ /**
+ * <pre>
+ *
+ * X--X
+ * | |
+ * X--X
+ * </pre>
+ */
+ // left lower corner:
+ Assert.assertTrue(r.intersects(new RectangleRW(9, 19, 2, 2)));
+ Assert.assertTrue(r.intersects(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)));
+ // right upper corner:
+ Assert.assertTrue(r.intersects(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)));
+
+ // touching minimal one border
+ /**
+ * <pre>
+ * --X--
+ * | |
+ * X X
+ * | |
+ * --X--
+ * </pre>
+ */
+ // lower border
+ Assert.assertTrue(r.intersects(new RectangleRW(9, 25, 2, 3)));
+ // right border
+ Assert.assertTrue(r.intersects(new RectangleRW(39, 25, 1, 3)));
+ // upper border
+ Assert.assertTrue(r.intersects(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)));
}
@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);
+ Assert.assertEquals(10, r.x, 0);
+ Assert.assertEquals(20, r.y, 0);
+ Assert.assertEquals(30, r.width, 0);
+ Assert.assertEquals(40, r.height, 0);
}
}