package jlection.robotic;
+import java.awt.Color;
+
import jlecture.simulation.IWidget;
import jlecture.simulation.Movable;
+import jlecture.simulation.PointRW;
/**
* Implements a robot.
*
*/
public class Robot extends Movable {
+ /**
+ * Returns the sign of a given value.
+ *
+ * @param x
+ * value to inspect
+ * @return 0: x == 0<br>
+ * -1: x < 0<br>
+ * 1: x > 0
+ */
+ static double sign(final double x) {
+ double rc;
+ if (x == 0.0)
+ rc = 0;
+ else
+ rc = x < 0 ? -1 : 1;
+ return rc;
+ }
+
+ private final double smallStep;
+ private final double nearBy;
+ /**
+ * The robot walks from target1 to target2 and back.
+ */
+ public PointRW target1 = new PointRW(0, 0);
+ /**
+ * The robot walks from target1 to target2 and back.
+ */
+ public PointRW target2 = new PointRW(0, 0);
+
+ /**
+ * One of target1 or target2.
+ */
+ private PointRW target = this.target1;
- public Robot(IWidget widget) {
+ /**
+ * Constructor.
+ *
+ * @param widget
+ * the widget used for the view
+ */
+ public Robot(final IWidget widget) {
super(widget);
+ this.smallStep = 5 * Math.max(widget.getContour().width,
+ widget.getContour().height);
+ this.nearBy = Math.max(widget.getContour().width,
+ widget.getContour().height);
+ }
+
+ /**
+ * Executes the strategy first backward (few steps) then forward (many
+ * steps).
+ *
+ * The next (intermediate) target is one of that four: The likelihood of the
+ * for targets is equal (0.25)
+ *
+ * <pre>
+ * Legend: R(obot) T(arget) p: calculated (intermediate) targets
+ * T ------------- p1
+ * | |
+ * p0 ------------ R-p2
+ * |
+ * p3
+ * </pre>
+ *
+ */
+ private void forwardFullBackwardSmall() {
+ final PointRW p = new PointRW(this.target.x, this.target.y);
+ final PointRW center = this.widget.getCenter();
+ int mode = this.model.getRandom().nextInt(4);
+ if (p.y == center.y && mode == 0)
+ mode = 1 + this.model.getRandom().nextInt(3);
+ else if (p.x == center.x && mode == 1) {
+ mode = this.model.getRandom().nextInt(3);
+ if (mode == 1)
+ mode = 3;
+ }
+ switch (mode) {
+ case 0:
+ p.y = center.y;
+ break;
+ case 1:
+ p.x = center.x;
+ break;
+ case 2:
+ p.y = center.y;
+ p.x = sign(center.x - this.target.x) * this.smallStep;
+ break;
+ default:
+ p.x = center.x;
+ p.y = sign(center.y - this.target.y) * this.smallStep;
+ break;
+ }
+ setMove(p, -1);
+ }
+
+ /**
+ * @return the nearBy
+ */
+ public double getNearBy() {
+ return this.nearBy;
+ }
+
+ /**
+ * @return the smallStep
+ */
+ public double getSmallStep() {
+ return this.smallStep;
+ }
+
+ /**
+ * @return the target
+ */
+ public PointRW getTarget() {
+ return this.target;
+ }
+
+ /**
+ * @param useTarget1
+ * <code>true</code>: target will be set to <code>target1</code><br>
+ * <code>false</code>: target will be set to <code>target2</code>
+ */
+ public void setTarget(final boolean useTarget1) {
+ if (useTarget1) {
+ this.widget.setColor(Color.blue);
+ this.target = this.target1;
+ } else {
+ this.widget.setColor(Color.red);
+ this.target = this.target2;
+ }
}
/**
*/
@Override
public void simulationStep() {
-
+ if (nearBy(this.target1))
+ setTarget(false);
+ else if (nearBy(this.target2))
+ setTarget(true);
+ if (this.velocity == 0.0)
+ forwardFullBackwardSmall();
}
+
+}
+
+class Stage {
+ // a temporary target on the way to the final target
+ public PointRW destination;
+ // If the target could not reached one try is left.
+ // If this number of tries are reached the target will be removed
+ public int tries;
}
*/
package jlection.robotic;
+import java.awt.Color;
+
import jlecture.simulation.Barrier;
import jlecture.simulation.DimensionRW;
import jlecture.simulation.Model;
-import jlecture.simulation.Movable;
import jlecture.simulation.PointRW;
import jlecture.simulation.RectangleRW;
@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, 50), false, this)));
- this.things.add(new Barrier(this.sheet.createRectangle(new PointRW(500,
- 700), new DimensionRW(600, 50), false, this)));
+ final int width = 3;
+ Barrier barrier = new Barrier(this.sheet.createRectangle(new PointRW(
+ 500,
+ 100), new DimensionRW(600, 100), false, this));
+ barrier.getWidget().setColorBackground(Color.gray);
+ this.things.add(barrier);
+ barrier = new Barrier(this.sheet.createRectangle(new PointRW(500, 400),
+ new DimensionRW(600, 100), false, this));
+ barrier.getWidget().setColorBackground(Color.gray);
+ this.things.add(barrier);
+ barrier = new Barrier(this.sheet.createRectangle(new PointRW(500, 700),
+ new DimensionRW(600, 100), false, this));
+ barrier.getWidget().setColorBackground(Color.gray);
+ this.things.add(barrier);
this.firstIndexMovables = this.things.size();
final PointRW destination = new PointRW(0, 0);
for (int ix = 0; ix < count; ix++) {
- final Movable movable = new Movable(this.sheet.createRectangle(
+ final Robot robot = new Robot(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;
+ robot.getWidget().setCenter(openPosition());
+ destination.x = robot.getWidget().getCenter().x;
+ destination.y = robot.getWidget().getCenter().y;
randomDestination(destination);
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);
+ * 0.5 * (1 + this.random.nextDouble());
+ robot.setMove(destination, velocity);
+ robot.target1.x = this.region.x + 0.02 * this.region.width;
+ robot.target1.y = this.region.y + 0.02 * this.region.height;
+ robot.target2.x = this.region.x + 0.98 * this.region.width;
+ robot.target2.y = this.region.y + 0.98 * this.region.height;
+ robot.setTarget(this.random.nextBoolean());
+ this.things.add(robot);
}
this.isReady = true;
+ log(String.format("collisions while setting the %d robots: %d", count,
+ this.openPositionCollisions));
}
}
/**
* Implements a stationary element in the model.
*
- * Barriers are objects which can not be passed traversed. Movables must go
- * arround barriers.
+ * Barriers are objects which can not be entered or passed. Movables must go
+ * around barriers.
*
* @author hm
*
* @param widget
* the widget in the model view
*/
- public Barrier(IWidget widget) {
+ public Barrier(final IWidget widget) {
super(widget);
}
@Override
- public boolean clashes(RectangleRW rectangle) {
+ public boolean clashes(final RectangleRW rectangle) {
boolean rc = false;
if (this.widget.getWidgetType() == WidgetType.RECTANGLE
|| 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;
}
@Override
- public boolean clashes(ThingRW thing) {
+ public boolean clashes(final ThingRW thing) {
boolean rc = false;
if (this.widget instanceof RectangleRW)
rc = thing.clashes((RectangleRW) this.widget);
else
throw new RuntimeException(
- "Barrier.clashes(ThingRW): not implemented yet");
+ "Barrier.clashes(ThingRW): not implemented yet");
return rc;
}
package jlecture.simulation;
+import java.awt.Color;
+
/**
* Defines a graphical item.
*
*/
public RectangleRW getContour();
+ /**
+ * Returns the maximum of width/height of the widget.
+ *
+ * @return the maximum of width and height
+ */
+ public double getMaxDimension();
+
/**
* Returns the model of the widget.
*
* the center to set
*/
public void setCenter(PointRW center);
+
+ /**
+ * Sets the color of the border.
+ *
+ * @param color
+ * the color to set
+ */
+ public void setColor(Color color);
+
+ /**
+ * Sets the color inside of the border.
+ *
+ * @param color
+ * the background color to set
+ */
+ public void setColorBackground(Color color);
}
*/
protected long now;
+ /**
+ * Counts the number of collisions inside <code>openPosition()</code>.
+ */
+ public int openPositionCollisions = 0;
+
/**
* Constructor.
*
for (int ix = 0; ix < lastIndex; ix++) {
final ThingRW thing = this.things.get(ix);
if (movable.clashes(thing)) {
+ movable.moveOutside(thing.getWidget());
movable.setMove(null, 0);
if (thing instanceof Movable)
((Movable) thing).setMove(null, 0);
return this.now;
}
+ /**
+ * @return the random
+ */
+ public Random getRandom() {
+ return this.random;
+ }
+
/**
* Returns the sheet.
*
*/
public PointRW openPosition() {
final PointRW rc = new PointRW(0, 0);
+ int count = 0;
do {
+ count++;
rc.x = this.region.x + this.random.nextDouble() * this.region.width;
rc.y = this.region.x + this.random.nextDouble()
* this.region.height;
} while (occupied(rc, null) != null);
+ this.openPositionCollisions += count - 1;
return rc;
}
final PointRW center = movable.getWidget().getCenter();
// moves to the position belonging to the current move:
movable.currentPosition(center, this.now);
+ // outside of the valid region?
+ if (center.x < this.region.x)
+ center.x = this.region.x
+ + movable.getWidget().getMaxDimension() / 2;
+ else if (center.x > this.region.x + this.region.width)
+ center.x = this.region.x + this.region.width
+ - movable.getWidget().getMaxDimension() / 2;
+ if (center.y < this.region.y)
+ center.y = this.region.y
+ + movable.getWidget().getMaxDimension() / 2;
+ else if (center.y > this.region.y + this.region.height)
+ center.y = this.region.y + this.region.height
+ - movable.getWidget().getMaxDimension() / 2;
movable.getWidget().setCenter(center);
checkCollision(movable, ix);
}
/**
* Velocity of the robot in units per second.
*/
- private double velocity = 0.0;
+ protected double maxVelocity = 0.0;
+
+ /**
+ * Velocity of the robot in units per second. This value switch between 0
+ * and <code>maxVelocity</code>.
+ */
+ protected double velocity = 0.0;
/**
* The position of the last direction change.
/**
* The destination of the currrent move.
*/
- private final PointRW destination = new PointRW(0, 0);
+ protected final PointRW destination = new PointRW(0, 0);
/**
* The start time of the current move (in msec).
* @param widget
* the widget in the graphical view
*/
- public Movable(IWidget widget) {
+ public Movable(final IWidget widget) {
super(widget);
this.model = widget.getModel();
}
@Override
- public boolean clashes(RectangleRW rectangle) {
+ public boolean clashes(final 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;
}
@Override
- public boolean clashes(ThingRW thing) {
+ public boolean clashes(final 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;
}
* < 0: relative to the start time (negated)<br>
* otherwise: the current time in milliseconds
*/
- public void currentPosition(PointRW point, long currentTime) {
+ public void currentPosition(final PointRW point, long currentTime) {
if (this.getVelocity() == 0.0)
point.clone(this.widget.getCenter());
else {
- if (this.startTime == 0)
- this.startTime = this.model.getNow();
- if (currentTime < 0)
- currentTime = this.startTime - currentTime;
- // v = s / t => s = v * t
- 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
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:
- if (Math.abs(x_diff2) > Math.abs(x_diff)) {
- point.x = this.destination.x;
- this.setVelocity(0);
- }
- if (Math.abs(y_diff2) > Math.abs(y_diff)) {
- point.y = this.destination.y;
- this.setVelocity(0);
+ if (x_diff != 0 || y_diff != 0) {
+ if (this.startTime == 0)
+ this.startTime = this.model.getNow();
+ if (currentTime < 0)
+ currentTime = this.startTime - currentTime;
+ // v = s / t => s = v * t
+ 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
+ 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:
+ if (Math.abs(x_diff2) > Math.abs(x_diff)) {
+ point.x = this.destination.x;
+ this.setVelocity(0);
+ }
+ if (Math.abs(y_diff2) > Math.abs(y_diff)) {
+ point.y = this.destination.y;
+ this.setVelocity(0);
+ }
}
}
}
+ /**
+ * @return the maxVelocity
+ */
+ public double getMaxVelocity() {
+ return this.maxVelocity;
+ }
+
/**
* Returns the velocity.
*
return this.widget;
}
+ /**
+ * Moves the instance outside of a given widget.
+ *
+ * If the speed is so large that one step is enough to "jump" inside a
+ * barrier this method corrects this mistake.
+ *
+ * <pre>
+ * Before:
+ * ------
+ * Start ------|-R--|---- Destination
+ * ------
+ * After:
+ * ------
+ * Start -----R|----|---- Destination
+ * ------
+ * </pre>
+ *
+ * @param widget
+ * the move must be corrected if the area of this widget is
+ * entered
+ */
+ public void moveOutside(final IWidget widget) {
+ final RectangleRW barrier = widget.getContour();
+ final PointRW center = this.widget.getCenter();
+ if (this.start.x < barrier.x)
+ // left border:
+ center.x = barrier.x - this.widget.getMaxDimension();
+ else if (this.start.y < barrier.y)
+ // upper border:
+ center.y = barrier.y - this.widget.getMaxDimension();
+ else if (this.start.x > barrier.x + barrier.width)
+ // right border:
+ center.x = barrier.x + barrier.width
+ + this.widget.getMaxDimension();
+ else if (this.start.y > barrier.y + barrier.height)
+ // lower border:
+ center.y = barrier.y + barrier.height
+ + this.widget.getMaxDimension();
+ }
+
+ /**
+ * Tests whether the instance is near by a given point.
+ *
+ * @param point
+ * point to inspect
+ * @return <code>true</code>: the distance to <code>point</code> is small<br>
+ * <code>false</code>: otherwise
+ */
+ public boolean nearBy(final PointRW point) {
+ final boolean rc = this.widget.getCenter().nearBy(point,
+ this.widget.getMaxDimension());
+ return rc;
+ }
+
+ /**
+ * @param maxVelocity
+ * the maxVelocity to set
+ */
+ public void setMaxVelocity(final double maxVelocity) {
+ this.maxVelocity = maxVelocity;
+ }
+
/**
* Sets the current move.
*
* the velocity in units per second. A unit is defined by the
* real world coordinates
*/
- public void setMove(PointRW destination, double velocity) {
+ public void setMove(final PointRW destination, double velocity) {
this.start.clone(this.widget.getCenter());
if (destination != null)
this.destination.clone(destination);
this.startTime = this.model.getNow();
+ if (velocity > 0)
+ this.maxVelocity = velocity;
+ else if (velocity < 0)
+ velocity = this.maxVelocity;
this.setVelocity(velocity);
}
* @param velocity
* the velocity to set
*/
- public void setVelocity(double velocity) {
+ public void setVelocity(final double velocity) {
this.velocity = velocity;
}
* @param widget
* the widget to set
*/
- public void setWidget(IWidget widget) {
+ public void setWidget(final IWidget widget) {
this.widget = widget;
}
* @param y
* the y coordinate (vertical)
*/
- public PointRW(double x, double y) {
+ public PointRW(final double x, final double y) {
this.x = x;
this.y = y;
}
* @param source
* the source to clone
*/
- public void clone(PointRW source) {
+ public void clone(final PointRW source) {
this.x = source.x;
this.y = source.y;
}
+
+ /**
+ * Checks whether a given point is near by the instance.
+ *
+ * @param point
+ * point to test
+ * @param maxDistance
+ * near means the distance is lower than this maximum
+ * @return <code>true</code>: <code>point</code> is nearer than
+ * <code>maxDistance</code> <code>false</code>: otherwise
+ *
+ */
+ public boolean nearBy(final PointRW point, final double maxDistance) {
+ // we use the Pythagoras, but not the square root (too expansive)
+ final double diffX = point.x - this.x;
+ final double diffY = point.y - this.y;
+ final boolean rc = diffX * diffX + diffY * diffY < maxDistance
+ * maxDistance;
+ return rc;
+ }
}
*/
package jlecture.swing;
+import java.awt.Color;
import java.awt.Graphics2D;
import jlecture.simulation.Model;
* @param model
* the simulator model
*/
- public LineSwing(PointRW from, PointRW to, Model model) {
+ public LineSwing(final PointRW from, final PointRW to, final Model model) {
super(from, model);
this.from.clone(from);
this.to.clone(to);
}
@Override
- public void draw(Graphics2D graphics) {
+ public void draw(final Graphics2D graphics) {
+ final Color safeColor = graphics.getColor();
+ graphics.setColor(this.color);
graphics.drawLine(this.contourSwing.x, this.contourSwing.y,
this.contourSwing.x + this.contourSwing.width, this.contourSwing.y
+ this.contourSwing.height);
+ graphics.setColor(safeColor);
+ }
+ @Override
+ public double getMaxDimension() {
+ return 0;
}
@Override
*/
package jlecture.swing;
+import java.awt.Color;
import java.awt.Graphics2D;
import jlecture.simulation.DimensionRW;
*/
public class RectangleSwing extends WidgetSwing {
private final DimensionRW dimension = new DimensionRW(0, 0);
-
+ private double maxDimension = 0;
private boolean filled = false;
/**
* @param model
* the simulator model
*/
- public RectangleSwing(PointRW center, DimensionRW dimension,
- boolean filled, Model model) {
+ public RectangleSwing(final PointRW center, final DimensionRW dimension,
+ final boolean filled, final Model model) {
super(center, model);
this.dimension.clone(dimension);
this.filled = filled;
calculateContour();
+ this.maxDimension = Math.max(this.contour.width, this.contour.height);
}
@Override
}
@Override
- public void draw(Graphics2D graphics) {
+ public void draw(final Graphics2D graphics) {
+ final Color safeColor = graphics.getColor();
+ final Color safeBackgroundColor = graphics.getBackground();
+ graphics.setColor(this.color);
+ graphics.setBackground(this.backgroundColor);
if (this.filled)
graphics.fillRect(this.contourSwing.x, this.contourSwing.y,
this.contourSwing.width, this.contourSwing.height);
else
graphics.drawRect(this.contourSwing.x, this.contourSwing.y,
this.contourSwing.width, this.contourSwing.height);
+ graphics.setColor(safeColor);
+ graphics.setBackground(safeBackgroundColor);
+ }
+
+ @Override
+ public double getMaxDimension() {
+ return this.maxDimension;
}
@Override
*/
package jlecture.swing;
+import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
* calculating distance between 2 items.
*/
protected PointRW center = new PointRW(0, 0);
+
/**
* The smallest rectangle containing all parts of the item (in real world
* coordinates).
*/
protected RectangleRW contour = new RectangleRW(0, 0, 0, 0);
+
/**
* The smallest rectangle containing all parts of the item (in pixel
* coordinates).
*/
protected Rectangle contourSwing = new Rectangle();
+ /**
+ * The color of the border.
+ */
+ protected Color color;
+ /**
+ * The color inside of the border.
+ */
+ protected Color backgroundColor;
/**
* Simulator model.
*/
protected Model model;
-
static int counter = 0;
/**
* @param model
* simulator model
*/
- public WidgetSwing(PointRW center, Model model) {
+ public WidgetSwing(final PointRW center, final Model model) {
this.center.clone(center);
this.model = model;
model.getItems().add(this);
}
@Override
- public void setCenter(PointRW center) {
+ public void setCenter(final 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));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jlecture.simulation.IWidget#setColor(int)
+ */
+ @Override
+ public void setColor(final Color color) {
+ this.color = color;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jlecture.simulation.IWidget#setColorBackground(int)
+ */
+ @Override
+ public void setColorBackground(final Color color) {
+ this.backgroundColor = color;
}
}
*/
package jlecture.swing;
+import java.awt.Color;
import java.awt.Graphics2D;
import jlecture.simulation.DimensionRW;
*
*/
public class XCrossSwing extends WidgetSwing {
+ private double maxDimension = 0;
/**
* The length of the square (contour).
*/
* @param model
* the simulation model
*/
- public XCrossSwing(PointRW center, DimensionRW dimension, Model model) {
+ public XCrossSwing(final PointRW center, final DimensionRW dimension,
+ final Model model) {
super(center, model);
this.dimension = dimension;
calculateContour();
+ this.maxDimension = Math.max(this.contour.width, this.contour.height);
}
/**
}
@Override
- public void draw(Graphics2D graphics) {
+ public void draw(final Graphics2D graphics) {
calculateContour();
this.model.transform(this.contour, this.contourSwing);
+ final Color safeColor = graphics.getColor();
+ graphics.setColor(this.color);
+ graphics.setBackground(this.backgroundColor);
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);
+ graphics.setColor(safeColor);
+ }
+
+ @Override
+ public double getMaxDimension() {
+ // TODO Auto-generated method stub
+ return this.maxDimension;
}
@Override