Skip to content

Commit

Permalink
Merge pull request #1231 from RoiEXLab/fixRouteDrawer
Browse files Browse the repository at this point in the history
Fix this thing aka RouteDrawer again...
  • Loading branch information
DanVanAtta committed Sep 14, 2016
2 parents 968bc06 + 75a1a70 commit ab10cf0
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 52 deletions.
12 changes: 5 additions & 7 deletions src/games/strategy/triplea/ui/MapRouteDrawer.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,13 @@ public void drawRoute(final Graphics2D graphics, final RouteDescription routeDes
final int numTerritories = route.getAllTerritories().size();
final int xOffset = mapPanel.getXOffset();
final int yOffset = mapPanel.getYOffset();

Point[] routePoints = getRoutePoints(routeDescription, mapData);
Point[] points = routeOptimizer.normalizeForHorizontalWrapping(routePoints).toArray(new Point[routePoints.length]);

final Point[] points = routeOptimizer.getTranslatedRoute(getRoutePoints(routeDescription, mapData));
final boolean tooFewTerritories = numTerritories <= 1;
final boolean tooFewPoints = points.length <= 2;
final double scale = mapPanel.getScale();
if (tooFewTerritories || tooFewPoints) {
if (routeDescription.getEnd() != null) {// AI has no End Point
drawDirectPath(graphics, points[0], points[points.length-1], xOffset, yOffset, scale);
drawDirectPath(graphics, routeDescription.getStart(), routeDescription.getEnd(), xOffset, yOffset, scale);
} else {
drawDirectPath(graphics, points[0], points[points.length - 1], xOffset, yOffset, scale);
}
Expand Down Expand Up @@ -120,7 +117,7 @@ private void drawCustomCursor(final Graphics2D graphics, final RouteDescription
final int yOffset, final double scale) {
final BufferedImage cursorImage = (BufferedImage) routeDescription.getCursorImage();
if (cursorImage != null) {
for (Point[] endPoint : routeOptimizer.getAllPoints(routeDescription.getEnd())) {
for (Point[] endPoint : routeOptimizer.getAllPoints(routeOptimizer.getLastEndPoint())) {
graphics.drawImage(cursorImage,
(int) (((endPoint[0].x - xOffset) - (cursorImage.getWidth() / 2)) * scale),
(int) (((endPoint[0].y - yOffset) - (cursorImage.getHeight() / 2)) * scale), null);
Expand All @@ -143,7 +140,8 @@ private void drawCustomCursor(final Graphics2D graphics, final RouteDescription
*/
private void drawDirectPath(final Graphics2D graphics, final Point start, final Point end, final int xOffset,
final int yOffset, final double scale) {
for (Point[] newPoints : routeOptimizer.getAllPoints(start, end)) {
final Point[] points = routeOptimizer.getTranslatedRoute(start, end);
for (Point[] newPoints : routeOptimizer.getAllPoints(points)) {
drawLineWithTranslate(graphics, new Line2D.Float(newPoints[0], newPoints[1]), xOffset,
yOffset, scale);
if (newPoints[0].distance(newPoints[1]) > arrowLength) {
Expand Down
144 changes: 99 additions & 45 deletions src/games/strategy/triplea/ui/RouteOptimizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,59 +22,114 @@ public class RouteOptimizer {
private static final int commonAdditionalScreens = 2;
private static final int minAdditionalScreens = 0;

private final double gameMapWidth;
private Point endPoint;
private int mapWidth;
private int mapHeight;

public RouteOptimizer(MapData mapData, MapPanel mapPanel) {
checkNotNull(mapData);
this.mapPanel = checkNotNull(mapPanel);
mapWidth = mapPanel.getImageWidth();
mapHeight = mapPanel.getImageHeight();

isInfiniteY = mapData.scrollWrapY();

isInfiniteX = mapData.scrollWrapX();

gameMapWidth = mapData.getMapDimensions().getWidth();

}

List<Point> normalizeForHorizontalWrapping(Point... route) {
final boolean crossesMapSeam = crossMapSeam(route);
final List<Point> points = Arrays.asList(route);

if (crossesMapSeam) {
final int minX = minX(route);
for (Point p : points) {
if ((p.x - minX) > mapPanel.getWidth()) {
p.x -= this.gameMapWidth;
/**
* Algorithm for finding the shortest path for the given Route
*
* @param route The joints on the Map
* @return A Point array which goes through Map Borders if necessary
*/
public Point[] getTranslatedRoute(Point... route) {
mapWidth = mapPanel.getImageWidth();
mapHeight = mapPanel.getImageHeight();
if (route == null || route.length == 0) {
// Or the array is too small

}
return route;
}
if (!isInfiniteX && !isInfiniteY) {
// If the Map is not infinite scrolling, we can safely return the given Points
endPoint = route[route.length - 1];
return route;
}
List<Point> result = new ArrayList<>();
Point previousPoint = null;
for (Point point : route) {
if (previousPoint == null) {
previousPoint = point;
result.add(point);
continue;
}
Point closestPoint = getClosestPoint(previousPoint, getPossiblePoints(point));
result.add(closestPoint);
previousPoint = closestPoint;
}
return points;
}

private boolean crossMapSeam(Point... route) {
final int minX = minX(route);
return Arrays.stream(route).filter(point -> (point.x - minX) > mapPanel.getWidth()).findAny().isPresent();
endPoint = result.get(result.size() - 1);
return result.toArray(new Point[result.size()]);
}

private static int minX(Point... route) {
int minX = Integer.MAX_VALUE;
for (Point p : Arrays.asList(route)) {
if (p.x < minX) {
minX = p.x;
/**
* Returns the Closest Point out of the given Pool
*
* @param source the reference Point
* @param pool Point2D List with all possible options
* @return the closest point in the Pool to the source
*/
private Point getClosestPoint(Point source, List<Point2D> pool) {
double closestDistance = Double.MAX_VALUE;
Point closestPoint = null;
for (Point2D possibleClosestPoint : pool) {
if (closestPoint == null) {
closestDistance = source.distance(possibleClosestPoint);
closestPoint = normalizePoint(getPoint(possibleClosestPoint));
} else {
double distance = source.distance(possibleClosestPoint);
if (closestDistance > distance) {
closestPoint = getPoint(possibleClosestPoint);
closestDistance = distance;
}
}
}
return minX;
return closestPoint;
}

private Point normalizePoint(Point point) {
return new Point(point.x % mapWidth, point.y % mapHeight);
}

/**
* Method for getting Points, which are a mapHeight/Width away from the actual Point
* Used to display routes with higher offsets than the map width/height
*
* @param point The Point to "clone"
* @return A List of all possible Points depending in map Properties
* size may vary
*/
private List<Point2D> getPossiblePoints(Point2D point) {
List<Point2D> result = new ArrayList<>();
result.add(point);
if (isInfiniteX && isInfiniteY) {
result.addAll(Arrays.asList(
new Point2D.Double(point.getX() - mapWidth, point.getY() - mapHeight),
new Point2D.Double(point.getX() - mapWidth, point.getY() + mapHeight),
new Point2D.Double(point.getX() + mapWidth, point.getY() - mapHeight),
new Point2D.Double(point.getX() + mapWidth, point.getY() + mapHeight)));
}
if (isInfiniteX) {
result.addAll(Arrays.asList(
new Point2D.Double(point.getX() - mapWidth, point.getY()),
new Point2D.Double(point.getX() + mapWidth, point.getY())));

}
if (isInfiniteY) {
result.addAll(Arrays.asList(
new Point2D.Double(point.getX(), point.getY() - mapHeight),
new Point2D.Double(point.getX(), point.getY() + mapHeight)));

}
return result;
}

/**
* Helper Method to convert a {@linkplain Point2D} to a {@linkplain Point}
*
Expand All @@ -85,6 +140,10 @@ public static Point getPoint(Point2D point) {
return new Point((int) point.getX(), (int) point.getY());
}

public Point getLastEndPoint() {
return endPoint;
}

/**
* Gives a List of Point arrays (Routes) which are the offset equivalent of the given points
* Size may vary depending on MapProperties
Expand All @@ -101,21 +160,20 @@ private List<Point[]> getAlternativePoints(Point... points) {
}
int counter = 0;
for (Point point : points) {
Point normalizedPoint = normalizePoint(point);
if (isInfiniteX) {
alternativePoints.get(0)[counter] = new Point(normalizedPoint.x - mapWidth, normalizedPoint.y);
alternativePoints.get(1)[counter] = new Point(normalizedPoint.x + mapWidth, normalizedPoint.y);
alternativePoints.get(0)[counter] = new Point(point.x - mapWidth, point.y);
alternativePoints.get(1)[counter] = new Point(point.x + mapWidth, point.y);
}
if (isInfiniteY) {
int index = altArrayCount == maxAdditionalScreens ? 2 : 0;
alternativePoints.get(index)[counter] = new Point(normalizedPoint.x, normalizedPoint.y - mapHeight);
alternativePoints.get(index + 1)[counter] = new Point(normalizedPoint.x, normalizedPoint.y + mapHeight);
alternativePoints.get(index)[counter] = new Point(point.x, point.y - mapHeight);
alternativePoints.get(index + 1)[counter] = new Point(point.x, point.y + mapHeight);
}
if (isInfiniteX && isInfiniteY) {
alternativePoints.get(4)[counter] = new Point(normalizedPoint.x - mapWidth, normalizedPoint.y - mapHeight);
alternativePoints.get(5)[counter] = new Point(normalizedPoint.x - mapWidth, normalizedPoint.y + mapHeight);
alternativePoints.get(6)[counter] = new Point(normalizedPoint.x + mapWidth, normalizedPoint.y - mapHeight);
alternativePoints.get(7)[counter] = new Point(normalizedPoint.x + mapWidth, normalizedPoint.y + mapHeight);
alternativePoints.get(4)[counter] = new Point(point.x - mapWidth, point.y - mapHeight);
alternativePoints.get(5)[counter] = new Point(point.x - mapWidth, point.y + mapHeight);
alternativePoints.get(6)[counter] = new Point(point.x + mapWidth, point.y - mapHeight);
alternativePoints.get(7)[counter] = new Point(point.x + mapWidth, point.y + mapHeight);
}
counter++;
}
Expand All @@ -131,11 +189,7 @@ private List<Point[]> getAlternativePoints(Point... points) {
*/
public List<Point[]> getAllPoints(Point... points) {
List<Point[]> allPoints = getAlternativePoints(points);
Point[] normalizedPoints = new Point[points.length];
for (int i = 0; i < points.length; i++) {
normalizedPoints[i] = normalizePoint(points[i]);
}
allPoints.add(normalizedPoints);
allPoints.add(points);
return allPoints;
}

Expand Down Expand Up @@ -165,7 +219,7 @@ private List<Line2D> getNormalizedLines(double[] xcoords, double[] ycoords) {
List<Line2D> lines = new ArrayList<>();
Point2D previousPoint = null;
for (int i = 0; i < xcoords.length; i++) {
Point2D trimmedPoint = normalizePoint(getPoint(new Point2D.Double(xcoords[i], ycoords[i])));
Point2D trimmedPoint = new Point2D.Double(xcoords[i], ycoords[i]);
if (previousPoint != null) {
lines.add(new Line2D.Double(previousPoint, trimmedPoint));
}
Expand Down

0 comments on commit ab10cf0

Please sign in to comment.