/** * MovementTracker.java * * @author Zuo Yan * @version 1.0 */ package vehicle; import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.AffineTransform; /** * A MovementTracker tracks the current position and orientation of an object with graphics components. * It mostly handles converting from global to local coordinates for each object. *
* The position and orientation is relative to the orignal center position and orientation of the object. * However, all positions are returned in global coordinates. */ public class MovementTracker { private double startX; // center starting position in global coordinates private double startY; private double posX; // center drawing postion in local coordinates private double posY; private double orientation; //angle from pos x axis in radians private Area container; // outline of the object /** * Creates a tracker */ public MovementTracker() { orientation = 0.0; posX = 0.0; posY = 0.0; startX = 0.0; startY = 0.0; container = new Area(); } /** * Registers a shape as part of this tracker to track. * All shapes created must be registered with their own MovementTracker * in order to move around correctly. * The position of the object might change slightly if shapes are register * while the object is in motion. * * @param s the Shape to add to this tracker */ public void registerShape(Shape s) { Area a = new Area(s); container.add(a); startX = container.getBounds2D().getCenterX(); startY = container.getBounds2D().getCenterY(); } /** * Returns the current x position of the center point * of all the shapes contained in this tracker * * @return x-coordinate of the shapes' center */ public double getX(){ return startX + posX; } /** * Returns the current y position of the center point * of all the shapes contained in this tracker * * @return y-coordinate of the shapes' center */ public double getY(){ return startY + posY; } /** * Gets the orientation changed from the inital drawing * * @return the angle in radians of the change */ public double getOrientation() { return orientation; } /** * Move to (x, y) in the world * * @param x the x-coordinate to move to * @param y the y-coordinate to move to */ public void moveTo(double x, double y) { posX = x - startX; posY = y - startY; } /** * Set the current rotation with postive sign meaning clockwise * * @param theta the angle in radians */ public void setRotation(double theta) { orientation = theta; while (orientation > Math.PI) { orientation -= Math.PI; orientation -= Math.PI; } while (orientation < -Math.PI) { orientation += Math.PI; orientation += Math.PI; } } /** * Move by xoffset and yoffset pixels * * @param xoffset the number of pixels to move in the x-axis direction * @param yoffset the number of pixelse to move in the y-axis direction */ public void moveBy(double xoffset, double yoffset) { posX += xoffset; posY += yoffset; } /** * Rotate shapes by theta with postive sign meaning clockwise * * @param theta the angle in radians */ public void rotateBy(double theta) { orientation += theta; while (orientation > Math.PI) { orientation -= Math.PI; orientation -= Math.PI; } while (orientation < -Math.PI) { orientation += Math.PI; orientation += Math.PI; } } /** * Get the affine transform of this vehicle from global to local space * * @return the affine transform */ public AffineTransform getTransform() { AffineTransform tmp = AffineTransform.getTranslateInstance(startX+posX, startY+posY); tmp.rotate(orientation); tmp.translate(-startX, -startY); return tmp; } /** * Retreives the current outline of the shapes * * @return the outline container of the shapes */ public Area getCurrentContainer() { return container.createTransformedArea(getTransform()); } }