package uu.mal.skate.model; import java.awt.Color; import java.awt.Graphics; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import uu.mal.skate.view.IDrawable; public class Agent implements IDrawable { public static BufferedImage img; static { try { URL url = Agent.class.getResource( "/res/smiley.png"); img = ImageIO.read(url); } catch (IOException e) { e.printStackTrace(); } } public static final Color DRAW_COLOR = Color.BLUE; public static final Color DRAW_COLLISION_COLOR = Color.RED; public static final int DRAW_WIDTH = 10; private final Options options; private final int id; private int x, y; private int direction; private BufferedImage scaledAndRotatedImage; private AffineTransform smileyTransform; private AffineTransformOp transformOperation; public Agent(Simulation sim, int id){ this.id = id; this.options = sim.getOptions(); } @Override public void draw(Graphics g) { g.setColor(DRAW_COLOR); g.fillOval( x - DRAW_WIDTH / 2, y - DRAW_WIDTH / 2, DRAW_WIDTH, DRAW_WIDTH); g.drawLine( x , y , (int) (x + DRAW_WIDTH * 2 * Math.cos(options.directions[direction])) , (int) (y + DRAW_WIDTH * 2 * Math.sin(options.directions[direction])) ); if(options.subtlyImprove) { smileyTransform = AffineTransform.getScaleInstance( (double)options.agentCollision / img.getWidth(null), (double)options.agentCollision / img.getHeight(null)); smileyTransform.rotate( options.directions[direction], img.getWidth(null) / 2, img.getHeight(null) / 2); transformOperation = new AffineTransformOp(smileyTransform, AffineTransformOp.TYPE_BILINEAR); scaledAndRotatedImage = transformOperation.filter(img, null); g.drawImage( scaledAndRotatedImage, x - scaledAndRotatedImage.getWidth()/2, y - scaledAndRotatedImage.getHeight()/2, scaledAndRotatedImage.getWidth(), scaledAndRotatedImage.getHeight(), null); } else { g.setColor(DRAW_COLLISION_COLOR); g.drawOval( x - options.agentCollision/2 , y - options.agentCollision/2 , options.agentCollision, options.agentCollision); } } public boolean collide(int hx, int hy, Agent[] others) { for(Agent a : others) { if(a == null) continue; if(a.equals(this)) continue; int dx = Math.min(Math.abs(hx - a.x), options.torusWidth - Math.abs(hx - a.x)); int dy = Math.min(Math.abs(hy - a.y), options.torusHeight - Math.abs(hy - a.y)); if(Math.pow(dx, 2) + Math.pow(dy, 2) <= Math.pow(options.agentCollision, 2)) { return true; } } return false; } public int[] planMove(){ return new int[] { (int) (x + options.agentSpeed * Math.cos(options.directions[direction])), (int) (y + options.agentSpeed * Math.sin(options.directions[direction]))}; } public void Move(int px, int py) { setX(px); setY(py); } public int getX() { return x; } public void setX(int x) { if(x < 0) { x = options.torusWidth + x; } else if(x >= options.torusWidth) { x = x - options.torusWidth; } this.x = x; } public int getY() { return y; } public void setY(int y) { if(y < 0) { y = options.torusHeight + y; } else if(y >= options.torusHeight) { y = y - options.torusHeight; } this.y = y; } public int getDirection() { return direction; } public void setDirection(int direction) { this.direction = direction; } public int getId() { return id; } }