package org.newdawn.slick.tests;
import java.util.ArrayList;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Circle;
import org.newdawn.slick.geom.GeomUtil;
import org.newdawn.slick.geom.GeomUtilListener;
import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.geom.Transform;
import org.newdawn.slick.geom.Vector2f;
/**
* A test to try shape cutting
*
* @author Kevin Glass
*/
public class GeomUtilTest extends BasicGame implements GeomUtilListener {
/** The shape we're cutting out of */
private Shape source;
/** The shape we're cutting */
private Shape cut;
/** The resulting shape */
private Shape[] result;
/** The points used */
private ArrayList points = new ArrayList();
/** The points intersected */
private ArrayList marks = new ArrayList();
/** The points excluded */
private ArrayList exclude = new ArrayList();
/** True if we're moving the shape around */
private boolean dynamic;
/** The util under test */
private GeomUtil util = new GeomUtil();
/** The x position of the shape */
private int xp;
/** The y position of the shape */
private int yp;
/** The circle cutting tool */
private Circle circle;
/** The rectangle cutting tool */
private Shape rect;
/** The star cutting tool */
private Polygon star;
/** True if we're in union mode */
private boolean union;
/**
* Create a simple test
*/
public GeomUtilTest() {
super("GeomUtilTest");
}
/**
* Perform the cut
*/
public void init() {
Polygon source = new Polygon();
source.addPoint(100,100);
source.addPoint(150,80);
source.addPoint(210,120);
source.addPoint(340,150);
source.addPoint(150,200);
source.addPoint(120,250);
this.source = source;
circle = new Circle(0,0,50);
rect = new Rectangle(-100,-40,200,80);
star = new Polygon();
float dis = 40;
for (int i=0;i<360;i+=30) {
dis = dis == 40 ? 60 : 40;
double x = (Math.cos(Math.toRadians(i)) * dis);
double y = (Math.sin(Math.toRadians(i)) * dis);
star.addPoint((float) x, (float) y);
}
this.cut = circle;
cut.setLocation(203,78);
xp = (int) cut.getCenterX();
yp = (int) cut.getCenterY();
makeBoolean();
}
/**
* @see BasicGame#init(GameContainer)
*/
public void init(GameContainer container) throws SlickException {
util.setListener(this);
init();
container.setVSync(true);
}
/**
* @see BasicGame#update(GameContainer, int)
*/
public void update(GameContainer container, int delta)
throws SlickException {
if (container.getInput().isKeyPressed(Input.KEY_SPACE)) {
dynamic = !dynamic;
}
if (container.getInput().isKeyPressed(Input.KEY_ENTER)) {
union = !union;
makeBoolean();
}
if (container.getInput().isKeyPressed(Input.KEY_1)) {
cut = circle;
circle.setCenterX(xp);
circle.setCenterY(yp);
makeBoolean();
}
if (container.getInput().isKeyPressed(Input.KEY_2)) {
cut = rect;
rect.setCenterX(xp);
rect.setCenterY(yp);
makeBoolean();
}
if (container.getInput().isKeyPressed(Input.KEY_3)) {
cut = star;
star.setCenterX(xp);
star.setCenterY(yp);
makeBoolean();
}
if (dynamic) {
xp = container.getInput().getMouseX();
yp = container.getInput().getMouseY();
makeBoolean();
}
}
/**
* Make the boolean operation
*/
private void makeBoolean() {
marks.clear();
points.clear();
exclude.clear();
cut.setCenterX(xp);
cut.setCenterY(yp);
if (union) {
result = util.union(source, cut);
} else {
result = util.subtract(source, cut);
}
}
/**
* @see org.newdawn.slick.Game#render(GameContainer, Graphics)
*/
public void render(GameContainer container, Graphics g)
throws SlickException {
g.drawString("Space - toggle movement of cutting shape",530,10);
g.drawString("1,2,3 - select cutting shape",530,30);
g.drawString("Mouse wheel - rotate shape",530,50);
g.drawString("Enter - toggle union/subtract",530,70);
g.drawString("MODE: "+(union ? "Union" : "Cut"),530,200);
g.setColor(Color.green);
g.draw(source);
g.setColor(Color.red);
g.draw(cut);
g.setColor(Color.white);
for (int i=0;i<exclude.size();i++) {
Vector2f pt = (Vector2f) exclude.get(i);
g.drawOval(pt.x-3, pt.y-3, 7,7);
}
g.setColor(Color.yellow);
for (int i=0;i<points.size();i++) {
Vector2f pt = (Vector2f) points.get(i);
g.fillOval(pt.x-1, pt.y-1, 3,3);
}
g.setColor(Color.white);
for (int i=0;i<marks.size();i++) {
Vector2f pt = (Vector2f) marks.get(i);
g.fillOval(pt.x-1, pt.y-1, 3,3);
}
g.translate(0,300);
g.setColor(Color.white);
if (result != null) {
for (int i=0;i<result.length;i++) {
g.draw(result[i]);
}
g.drawString("Polys:"+result.length,10,100);
g.drawString("X:"+xp,10,120);
g.drawString("Y:"+yp,10,130);
}
}
/**
* Entry point to our test
*
* @param argv The arguments passed to the test
*/
public static void main(String[] argv) {
try {
AppGameContainer container = new AppGameContainer(new GeomUtilTest());
container.setDisplayMode(800,600,false);
container.start();
} catch (SlickException e) {
e.printStackTrace();
}
}
public void pointExcluded(float x, float y) {
exclude.add(new Vector2f(x,y));
}
public void pointIntersected(float x, float y) {
marks.add(new Vector2f(x,y));
}
public void pointUsed(float x, float y) {
points.add(new Vector2f(x,y));
}
public void mouseWheelMoved(int change) {
if (dynamic) {
if (change < 0) {
cut = cut.transform(Transform.createRotateTransform((float) Math.toRadians(10), cut.getCenterX(), cut.getCenterY()));
} else {
cut = cut.transform(Transform.createRotateTransform((float) Math.toRadians(-10), cut.getCenterX(), cut.getCenterY()));
}
}
}
}