Skip to content

Commit

Permalink
Functions to determine a move from a target location + tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Macbeth committed Jul 8, 2011
1 parent d0012fe commit f432546
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
*/
package uk.ac.imperial.presage2.util.location;


/**
* @author Sam Macbeth
*
*
*/
public abstract class Location implements HasLocation, Cloneable {

Expand All @@ -38,60 +37,89 @@ protected Location clone() throws CloneNotSupportedException {

/**
* Test whether the given location is equal to this one.
* @param l Location to compare to
*
* @param l
* Location to compare to
* @return true iff this Location represents the same Location as l
*/
public abstract boolean equals(Location l);

/**
* Get the distance between this Location and the location l
*
* @param l
* @return
*/
public abstract double distanceTo(Location l);

/**
* Modify this Location by the Move m.
*
* @param m
* @return this (for operation chaining)
* @return this (for operation chaining)
* @deprecated Location is now immutable
*/
@Deprecated
public Location add(Move m) {return this;};

public Location add(Move m) {
return this;
};

/**
* Returns the result of {@link Area#contains(Location)}
* for a and this. Allows more intuitive syntax when
* changing that a {@link Location} is in an {@link Area}.
* Returns the result of {@link Area#contains(Location)} for a and this.
* Allows more intuitive syntax when changing that a {@link Location} is in
* an {@link Area}.
*
* @param a
* @return
*/
public boolean in(Area a) {
return a.contains(this);
}

/**
* Not available in Immutable Location class.
*/
@Override
public void setLocation(Location l) {
throw new UnsupportedOperationException("HasLocation#setLocation() not available in this context.");
throw new UnsupportedOperationException(
"HasLocation#setLocation() not available in this context.");
}

/**
* Static application of a move to a location. This
* implementation ensures no change to the location
* provided.
* Get the {@link Move} required to move from this location to a new
* location l.
*
* @param l
* @return {@link Move}
*/
public abstract Move getMoveTo(Location l);

/**
* Get the {@link Move} required to move from this location to a new
* location l but limited to a maximum magnitude of speed.
*
* @param l
* @param speed
* @return {@link Move}
*/
public abstract Move getMoveTo(Location l, double speed);

/**
* Static application of a move to a location. This implementation ensures
* no change to the location provided.
*
* @param loc
* @param m
* @return
*/
public static Location add(Location loc, Move m) {
// 2D move
if(loc instanceof Location2D<?> && m instanceof Move2D<?>) {
if (loc instanceof Location2D<?> && m instanceof Move2D<?>) {
return Location2D.add((Location2D<?>) loc, (Move2D<?>) m);
}
throw new UnsupportedOperationException("Add "+loc.getClass().getSimpleName()+" and "+m.getClass().getSimpleName());
throw new UnsupportedOperationException("Add "
+ loc.getClass().getSimpleName() + " and "
+ m.getClass().getSimpleName());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
* A {@link Location} which is represented by two numerical coordinates.
*
* @author Sam Macbeth
*
*
*/
public abstract class Location2D<T extends Number> extends Location {

final protected T x;

final protected T y;

/**
* @param x
* @param y
Expand All @@ -47,61 +47,97 @@ public Location getLocation() {

@Override
public String toString() {
return "("+x+","+y+")";
return "(" + x + "," + y + ")";
}

@Override
public boolean equals(Location l) {
if(l instanceof Location2D) {
if (l instanceof Location2D) {
return this.equals((Location2D<?>) l);
} else {
return false;
}
}

public boolean equals(Location2D<?> l) {
try {
return (this.x.equals(l.x) && this.y.equals(l.y));
} catch(NullPointerException e) {
} catch (NullPointerException e) {
return false;
}
}

@Override
public double distanceTo(Location l) {
if(l instanceof Location2D) {
if (l instanceof Location2D) {
return this.distanceTo((Location2D<?>) l);
} else
throw new UnsupportedOperationException("Distance between Locations "+ this.getClass().getSimpleName() +" and "+ l.getClass().getSimpleName());
throw new UnsupportedOperationException(
"Distance between Locations "
+ this.getClass().getSimpleName() + " and "
+ l.getClass().getSimpleName());
}

public double distanceTo(Location2D<?> l) {
if(l.x instanceof Integer) {
final int dx = Math.abs((Integer) l.x - (Integer) this.x);
final int dy = Math.abs((Integer) l.y - (Integer) this.y);
return Math.sqrt(dx*dx + dy*dy);
}
else if(l.x instanceof Double) {
final double dx = Math.abs((Double) l.x - (Double) this.x);
final double dy = Math.abs((Double) l.y - (Double) this.y);
return Math.sqrt(dx*dx + dy*dy);
if (l.x instanceof Integer) {
final int dx = (int) Math.abs(l.x.doubleValue()
- this.x.doubleValue());
final int dy = (int) Math.abs(l.y.doubleValue()
- this.y.doubleValue());
return Math.sqrt(dx * dx + dy * dy);
} else if (l.x instanceof Double) {
final double dx = Math
.abs(l.x.doubleValue() - this.x.doubleValue());
final double dy = Math
.abs(l.y.doubleValue() - this.y.doubleValue());
return Math.sqrt(dx * dx + dy * dy);
} else {
throw new UnsupportedOperationException("Distance between Locations "+
this.getClass().getSimpleName() +
"<"+ this.x.getClass().getSimpleName() +"> and "+
l.getClass().getSimpleName() +
"<"+ this.x.getClass().getSimpleName() +">");
throw new UnsupportedOperationException(
"Distance between Locations "
+ this.getClass().getSimpleName() + "<"
+ this.x.getClass().getSimpleName() + "> and "
+ l.getClass().getSimpleName() + "<"
+ this.x.getClass().getSimpleName() + ">");
}
}

public static Location add(Location2D<?> loc, Move2D<?> m) {
final double x = loc.x.doubleValue() + m.x.doubleValue();
final double y = loc.y.doubleValue() + m.y.doubleValue();
if(Math.floor(x) == x && Math.floor(y) == y) {
if (loc.x instanceof Integer) {
// preserve original location type.
return new Discrete2DLocation((int) x, (int) y);
} else {
return new Continuous2DLocation(x, y);
}
}

@Override
public Move getMoveTo(Location l) {
if (l instanceof Location2D<?>) {
Location2D<?> l2 = (Location2D<?>) l;
final double dx = l2.x.doubleValue() - this.x.doubleValue();
final double dy = l2.y.doubleValue() - this.y.doubleValue();
if (Math.floor(dx) == dx && Math.floor(dy) == dy) {
return new Move2D<Integer>((int) dx, (int) dy);
} else {
return new Move2D<Double>(dx, dy);
}
}
throw new UnsupportedOperationException(
"Cannot move between dimensions!");
}

@Override
public Move getMoveTo(Location l, double speed) {
Move move = this.getMoveTo(l);
if (move.getMagnitude() > speed) {
final Move2D<?> m = (Move2D<?>) move;
final double angle = m.getAngle();
return new Move2D<Double>(Math.cos(angle) * speed, Math.sin(angle)
* speed);
} else
return move;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@

public interface Move extends Action {

public double getMagnitude();

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,17 @@ public Move2D(T x, T y) {

@Override
public String toString() {
return "Move2D: ("+x+","+y+")";
return "Move2D: (" + x + "," + y + ")";
}

@Override
public double getMagnitude() {
return Math.sqrt(x.doubleValue() * x.doubleValue() + y.doubleValue()
* y.doubleValue());
}

public double getAngle() {
return Math.atan2(y.doubleValue(), x.doubleValue());
}

}
Loading

0 comments on commit f432546

Please sign in to comment.