package org.newdawn.slick.geom;
import java.util.ArrayList;
import java.util.Arrays;
/**
* A polygon implementation meeting the <code>Shape</code> contract.
*
* @author Mark
*/
public class Polygon extends Shape {
/** Allow duplicated points */
private boolean allowDups = false;
/** True if the polygon is closed */
private boolean closed = true;
/**
* Construct a new polygon with 3 or more points.
* This constructor will take the first set of points and copy them after
* the last set of points to create a closed shape.
*
* @param points An array of points in x, y order.
*/
public Polygon(float points[]) {
int length = points.length;
this.points = new float[length];
maxX = -Float.MIN_VALUE;
maxY = -Float.MIN_VALUE;
minX = Float.MAX_VALUE;
minY = Float.MAX_VALUE;
x = Float.MAX_VALUE;
y = Float.MAX_VALUE;
for(int i=0;i<length;i++) {
this.points[i] = points[i];
if(i % 2 == 0) {
if(points[i] > maxX) {
maxX = points[i];
}
if(points[i] < minX) {
minX = points[i];
}
if(points[i] < x) {
x = points[i];
}
}
else {
if(points[i] > maxY) {
maxY = points[i];
}
if(points[i] < minY) {
minY = points[i];
}
if(points[i] < y) {
y = points[i];
}
}
}
findCenter();
calculateRadius();
pointsDirty = true;
}
/**
* Create an empty polygon
*
*/
public Polygon(){
points = new float[0];
maxX = -Float.MIN_VALUE;
maxY = -Float.MIN_VALUE;
minX = Float.MAX_VALUE;
minY = Float.MAX_VALUE;
}
/**
* Indicate if duplicate points are allow
*
* @param allowDups True if duplicate points are allowed
*/
public void setAllowDuplicatePoints(boolean allowDups) {
this.allowDups = allowDups;
}
/**
* Add a point to the polygon
*
* @param x The x coordinate of the point
* @param y The y coordinate of the point
*/
public void addPoint(float x, float y) {
if (hasVertex(x,y) && (!allowDups)) {
return;
}
ArrayList tempPoints = new ArrayList();
for(int i=0;i<points.length;i++) {
tempPoints.add(new Float(points[i]));
}
tempPoints.add(new Float(x));
tempPoints.add(new Float(y));
int length = tempPoints.size();
points = new float[length];
for(int i=0;i<length;i++) {
points[i] = ((Float)tempPoints.get(i)).floatValue();
}
if(x > maxX) {
maxX = x;
}
if(y > maxY) {
maxY = y;
}
if(x < minX) {
minX = x;
}
if(y < minY) {
minY = y;
}
findCenter();
calculateRadius();
pointsDirty = true;
}
/**
* Apply a transformation and return a new shape. This will not alter the current shape but will
* return the transformed shape.
*
* @param transform The transform to be applied
* @return The transformed shape.
*/
public Shape transform(Transform transform) {
checkPoints();
Polygon resultPolygon = new Polygon();
float result[] = new float[points.length];
transform.transform(points, 0, result, 0, points.length / 2);
resultPolygon.points = result;
resultPolygon.findCenter();
resultPolygon.closed = closed;
return resultPolygon;
}
/**
* @see org.newdawn.slick.geom.Shape#setX(float)
*/
public void setX(float x) {
super.setX(x);
pointsDirty = false;
}
/**
* @see org.newdawn.slick.geom.Shape#setY(float)
*/
public void setY(float y) {
super.setY(y);
pointsDirty = false;
}
/**
* @see org.newdawn.slick.geom.Shape#createPoints()
*/
protected void createPoints() {
// This is empty since a polygon must have it's points all the time.
}
/**
* @see org.newdawn.slick.geom.Shape#closed()
*/
public boolean closed() {
return closed;
}
/**
* Indicate if the polygon should be closed
*
* @param closed True if the polygon should be closed
*/
public void setClosed(boolean closed) {
this.closed = closed;
}
/**
* Provide a copy of this polygon
*
* @return A copy of this polygon
*/
public Polygon copy() {
float[] copyPoints = new float[points.length];
System.arraycopy(points, 0, copyPoints, 0, copyPoints.length);
return new Polygon(copyPoints);
}
}