package awb; import java.awt.*; public class Segment extends GraphicsObject { // order is important! Don't change it. public final static int TOP = 1; public final static int LEFT = 2; public final static int BOTTOM = 4; public final static int RIGHT = 8; public static int SIZE = 50; public final static int MPP = Race.MPP; // meters per pixel private RaceCar myCar; private int myIn, myOut; private boolean myBlank; private int myLength; public Segment(int x, int y) { myX = x; myY = y; myBlank = true; myWidth = SIZE; // in terms of pixels, myHeight = SIZE; // not meters } public Segment(int x, int y, int in, int out) { myX = x; myY = y; myIn = in; myOut = out; myHeight = SIZE; myWidth = SIZE; myBlank = false; myLength = findLength(); } public static void setSize(int s) { SIZE = s; } public static int getSize() { return SIZE; } public boolean isTurn() { return (! isStraight()); } public boolean isStraight() { return (((myIn + myOut) == (BOTTOM + TOP)) || ((myIn + myOut) == (LEFT + RIGHT))); } public boolean isLTurn() { // System.out.println("(L) Segment at " + myX + ", " + myY // + " has in " + myIn + " and out " + myOut); return (((myOut * 2) == (myIn)) || ((myIn == TOP) && (myOut == RIGHT))); } public boolean isRTurn() { // System.out.println("(R) Segment at " + myX + ", " + myY // + " has in " + myIn + " and out " + myOut); return (((myIn * 2) == (myOut)) || ((myIn == RIGHT) && (myOut == TOP))); } public int getDir(int x, int y) { if ((myIn == TOP) && (myOut == BOTTOM)) return 180; if ((myIn == BOTTOM) && (myOut == TOP)) return 0; if ((myIn == LEFT) && (myOut == RIGHT)) return 90; if ((myIn == RIGHT) && (myOut == LEFT)) return 270; double r; if ((myIn == RIGHT) && (myOut == BOTTOM)) { r = atan(myHeight-y,myWidth-x); return (180 + toDegrees(r)) % 360; } if ((myIn == TOP) && (myOut == RIGHT)) { r = atan(y, myWidth-x); return (540 - toDegrees(r)) % 360; } if ((myIn == LEFT) && (myOut == TOP)) { r = atan(y,x); return toDegrees(r); } if ((myIn == BOTTOM) && (myOut == LEFT)) { r = atan(myHeight-y, x); return 360 - toDegrees(r); } if ((myIn == BOTTOM) && (myOut == RIGHT)) { r = atan(myHeight-y,myWidth-x); return (360 + toDegrees(r)) % 360; } if ((myIn == RIGHT) && (myOut == TOP)) { r = atan(y,myWidth-x); return 360 - toDegrees(r); } if ((myIn == TOP) && (myOut == LEFT)) { r = atan(y,x); return (180 + toDegrees(r)) % 360; } if ((myIn == LEFT) && (myOut == BOTTOM)) { r = atan(myHeight-y,x); return (540 - toDegrees(r)) % 360; } System.out.println("ERROR!! returning -1 from getDir()"); return -1; // error } public void draw(Graphics g) { g.setColor(Color.green); g.fillRect(myX,myY,myWidth,myHeight); // gridlines: // g.setColor(Color.black); // g.drawRect(myX,myY,myWidth,myHeight); if (myBlank) return; g.setColor(Color.gray); if ((myIn + myOut) == (LEFT + RIGHT)) { g.fillRect(myX,myY+(myHeight/3),myWidth,myHeight/3); return; } if ((myIn + myOut) == (TOP + BOTTOM)) { g.fillRect(myX+(myWidth/3),myY,myWidth/3,myHeight); return; } if ((myIn + myOut) == (BOTTOM + RIGHT)) { int x = myX + (myWidth/3); int y = myY + (myHeight/3); int w = 4 * (myWidth/3); g.setColor(Color.gray); g.fillArc(x,y,w,w,90,90); x = myX + (2 * (myWidth/3)); y = myY + (2 * (myHeight/3)); w = 2 * (myWidth/3); g.setColor(Color.green); g.fillArc(x,y,w,w,90,90); return; } if ((myIn + myOut) == (BOTTOM + LEFT)) { int x = myX - (2 * (myWidth/3)); int y = myY + (myHeight/3); int w = 4 * (myWidth/3); g.setColor(Color.gray); g.fillArc(x,y,w,w,0,90); x = myX - (myWidth/3); y = myY + (2 * (myHeight/3)); w = 2 * (myWidth/3); g.setColor(Color.green); g.fillArc(x,y,w,w,0,90); return; } if ((myIn + myOut) == (TOP + LEFT)) { int x = myX - (2 * (myWidth/3)); int y = myY - (2 * (myHeight/3)); int w = 4 * (myWidth/3); g.setColor(Color.gray); g.fillArc(x,y,w,w,270,90); x = myX - (myWidth/3); y = myY - (myHeight/3); w = 2 * (myWidth/3); g.setColor(Color.green); g.fillArc(x,y,w,w,270,90); return; } if ((myIn + myOut) == (TOP + RIGHT)) { int x = myX + (myWidth/3); int y = myY - (2 *(myHeight/3)); int w = 4 * (myWidth/3); g.setColor(Color.gray); g.fillArc(x,y,w,w,180,90); x = myX + (2 * (myWidth/3)); y = myY - (myHeight/3); w = 2 * (myWidth/3); g.setColor(Color.green); g.fillArc(x,y,w,w,180,90); return; } } public boolean onTrack(int x, int y) { if ((myIn + myOut) == (TOP + BOTTOM)) { return ((x >= (myWidth/3)) && (x <= (2 * (myWidth/3)))); } if ((myIn + myOut) == (LEFT + RIGHT)) { return ((y >= (myHeight/3)) && (y <= (2 * (myHeight/3)))); } int inner = myWidth/3; int outer = 2 * (myWidth/3); if ((myIn + myOut) == (RIGHT + BOTTOM)) { x -= myWidth; y -= myHeight; } if ((myIn + myOut) == (TOP + RIGHT)) { x -= myWidth; } if ((myIn + myOut) == (BOTTOM + LEFT)) { y -= myHeight; } // System.out.println("Segment.onTrack(): x: " + x // + ", y: " + y); int d = (int)Math.sqrt((x*x) + (y*y)); // System.out.println("Segment.onTrack(): d2: " + d // + ", inner: " + inner + ", outer: " + outer); return ((d >= inner) && (d <= outer)); } public int getLeftDist(int x, int y) { // System.out.println(" Segment.getLeftDist()"); // System.out.println(" x,y: " + x + ", " + y); // System.out.println(" w,h: " + myWidth + ", " + myHeight); // System.out.println(" i,o: " + myIn + ", " + myOut); if ((myIn == TOP) && (myOut == BOTTOM)) return ((2*myWidth/3) - x) * MPP; if ((myIn == BOTTOM) && (myOut == TOP)) return (x - (myWidth/3)) * MPP; if ((myIn == LEFT) && (myOut == RIGHT)) return (y - (myHeight/3)) * MPP; if ((myIn == RIGHT) && (myOut == LEFT)) return ((2*myHeight/3) - y) * MPP; int inner = myWidth/3; int outer = 2 * (myWidth/3); if ((myIn + myOut) == (RIGHT + BOTTOM)) { x -= myWidth; y -= myHeight; } if ((myIn + myOut) == (TOP + RIGHT)) { x -= myWidth; } if ((myIn + myOut) == (BOTTOM + LEFT)) { y -= myHeight; } int d = (int)Math.sqrt((x*x) + (y*y)); if (isLTurn()) return (d - inner) * Race.MPP; else return (outer - d) * Race.MPP; } public int getRightDist(int x, int y) { if ((myIn == BOTTOM) && (myOut == TOP)) return ((2*myWidth/3) - x) * MPP; if ((myIn == TOP) && (myOut == BOTTOM)) return (x - (myWidth/3)) * MPP; if ((myIn == RIGHT) && (myOut == LEFT)) return (y - (myHeight/3)) * MPP; if ((myIn == LEFT) && (myOut == RIGHT)) return ((2*myHeight/3) - y) * MPP; int inner = myWidth/3; int outer = 2 * (myWidth/3); if ((myIn + myOut) == (RIGHT + BOTTOM)) { x -= myWidth; y -= myHeight; } if ((myIn + myOut) == (TOP + RIGHT)) { x -= myWidth; } if ((myIn + myOut) == (BOTTOM + LEFT)) { y -= myHeight; } int d = (int)Math.sqrt((x*x) + (y*y)); if (isRTurn()) return (d - inner) * Race.MPP; else return (outer - d) * Race.MPP; } // return length in meters public int getLength() { return myLength; } // given position, find distance to end of segment in meters public int getDistanceToEnd(int x, int y) { if ((myIn == TOP) && (myOut == BOTTOM)) return MPP * (myHeight-y); if ((myIn == BOTTOM) && (myOut == TOP)) return MPP * y; if ((myIn == LEFT) && (myOut == RIGHT)) return MPP * (myWidth-x); if ((myIn == RIGHT) && (myOut == LEFT)) return MPP * x; double angle = 0; if ((myIn + myOut) == (RIGHT + BOTTOM)) angle = atan(myHeight - y, x); if ((myIn + myOut) == (TOP + RIGHT)) angle = atan(myWidth-x, y); if ((myIn + myOut) == (LEFT + TOP)) angle = atan(y,x); if ((myIn + myOut) == (BOTTOM + LEFT)) angle = atan(x,myHeight-y); if (isLTurn()) return (int)((myLength * angle) / (Math.PI / 2)); else return (int)((myLength * ((Math.PI / 2) - angle)) / (Math.PI / 2)); } // used as part of initialization private int findLength() { if (((myIn + myOut) == (TOP + BOTTOM)) || ((myIn + myOut) == (RIGHT + LEFT))) { return MPP * SIZE; } else { return (int)(((Math.PI * SIZE) / 4) * MPP); } } private int toDegrees(double r) { double pipi = 2 * Math.PI; r = (r + pipi) % pipi; // System.out.println(" Segment.toDegrees(): r ==> " + r); return (int)((360 * r) / (pipi)); } private double atan(int y, int x) { return Math.atan((double)y / (double)x); } }