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())); } } } }