/*
* Copyright (c) 2014 tabletoptool.com team.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* rptools.com team - initial implementation
* tabletoptool.com team - further development
*/
package com.t3.model.vision;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.NoninvertibleTransformException;
import com.t3.model.Token;
import com.t3.model.Vision;
import com.t3.model.Zone;
import com.t3.model.grid.Grid;
public class BlockyRoundVision extends Vision {
public BlockyRoundVision() {
}
public BlockyRoundVision(int distance) {
setDistance(distance);
}
@Override
protected Area createArea(Zone zone, Token token) {
int size = getDistance() * getZonePointsPerCell(zone);
Area area = drawCells(size, zone);
return area;
}
@Override
public Anchor getAnchor() {
return Vision.Anchor.CORNER;
}
@Override
public String toString() {
return "Blocky Round";
}
private enum Quadrant {
NE, NW, SE, SW
}
// TODO: Move this to a more generic location
private static Area drawCells(int distance, Zone zone) {
Area area = new Area();
Area cellShape = new Area(zone.getGrid().getCellShape());
Grid grid = zone.getGrid();
int y = 1;
int x = 1;
while (true) {
int cells = x + y;
int mod = x < y ? x : y;
int diag = (mod / 2) + (mod % 2);
int totalDistance = grid.getSize() * (cells - diag);
if (totalDistance <= distance) {
drawCell(area, cellShape, grid, x, y, Quadrant.NE);
drawCell(area, cellShape, grid, x, y, Quadrant.NW);
drawCell(area, cellShape, grid, x, y, Quadrant.SE);
drawCell(area, cellShape, grid, x, y, Quadrant.SW);
x++;
} else {
if (x == 1) {
break;
}
y++;
x = 1;
}
}
return area;
}
private static void drawCell(Area area, Area cellShape, Grid grid, int x, int y, Quadrant quadrant) {
// Adjust the location of the cell based on the quadrant
// these are based on the symmetry of the cells calculated in the SE quadrant
switch (quadrant) {
case NE:
y = -y;
x -= 1;
break;
case NW:
x = -x;
y = -y;
break;
case SE:
x -= 1;
y -= 1;
break;
case SW:
x = -x;
y -= 1;
break;
}
AffineTransform af = new AffineTransform();
af.translate(x * grid.getSize(), y * grid.getSize());
cellShape.transform(af);
area.add(cellShape);
// Symmetry
try {
cellShape.transform(af.createInverse());
} catch (NoninvertibleTransformException e) {
e.printStackTrace();
}
}
}