/** Computes a list of the valid locations in this cluster. */ public static List<SceneLocation> getClusterLocs(Cluster cluster) { List<SceneLocation> list = Lists.newArrayList(); // convert our tile coordinates into a cartesian coordinate system // with units equal to one fine coordinate in size int fx = cluster.x * _metrics.finegran + 1, fy = cluster.y * _metrics.finegran + 1; int fwid = cluster.width * _metrics.finegran - 2, fhei = cluster.height * _metrics.finegran - 2; int cx = fx + fwid / 2, cy = fy + fhei / 2; // if it's a 1x1 cluster, return one location in the center of the // cluster if (cluster.width == 1) { StageLocation loc = new StageLocation( MisoUtil.toFull(cluster.x, 2), MisoUtil.toFull(cluster.y, 2), (byte) DirectionCodes.SOUTHWEST); list.add(new SceneLocation(loc, 0)); return list; } double radius = (double) fwid / 2; int clidx = cluster.width - 2; if (clidx >= CLUSTER_METRICS.length / 2 || clidx < 0) { log.warning("Requested locs from invalid cluster " + cluster + ".", new Exception()); return list; } for (double angle = CLUSTER_METRICS[clidx * 2]; angle < Math.PI * 2; angle += CLUSTER_METRICS[clidx * 2 + 1]) { int sx = cx + (int) Math.round(Math.cos(angle) * radius); int sy = cy + (int) Math.round(Math.sin(angle) * radius); // obtain the orientation facing toward the center int orient = 2 * (int) (Math.round(angle / (Math.PI / 4)) % 8); orient = DirectionUtil.rotateCW(DirectionCodes.SOUTH, orient); orient = DirectionUtil.getOpposite(orient); // convert them back to full coordinates for the location int tx = MathUtil.floorDiv(sx, _metrics.finegran); sx = MisoUtil.toFull(tx, sx - (tx * _metrics.finegran)); int ty = MathUtil.floorDiv(sy, _metrics.finegran); sy = MisoUtil.toFull(ty, sy - (ty * _metrics.finegran)); StageLocation loc = new StageLocation(sx, sy, (byte) orient); list.add(new SceneLocation(loc, 0)); } return list; }
/** * Converts a non-isometric orientation (where north points toward the top of the screen) to an * isometric orientation where north points toward the upper-left corner of the screen. */ public static int toIsoDirection(int dir) { if (dir != DirectionCodes.NONE) { // rotate the direction clockwise (ie. change SOUTHEAST to // SOUTH) dir = DirectionUtil.rotateCW(dir, 2); } return dir; }
/** * Given two points in screen coordinates, return the isometrically projected compass direction * that point B lies in from point A. * * @param ax the x-position of point A. * @param ay the y-position of point A. * @param bx the x-position of point B. * @param by the y-position of point B. * @return the direction specified as one of the <code>Sprite</code> class's direction constants, * or <code>DirectionCodes.NONE</code> if point B is equivalent to point A. */ public static int getProjectedIsoDirection(int ax, int ay, int bx, int by) { return toIsoDirection(DirectionUtil.getDirection(ax, ay, bx, by)); }