001 /*
002 * SimuCS - Simulator to use with Classifier Systems
003 * MSc project - Oxford University
004 * by Benoit Isaac - Summer 2005
005 */
006
007 package simuLCS;
008 import java.awt.Color;
009 import java.awt.Font;
010 import java.awt.Graphics2D;
011 import java.awt.geom.Point2D;
012
013 /**
014 * The Circular Arena
015 * @author Benoit
016 *
017 */
018 public class Arena extends Entity {
019
020 private static final int sizeGrad = 10;
021
022 private Graphics2D graphics;
023 private int shift;
024
025 public Arena(int s, int sh) {
026 size = s;
027 shift = sh;
028 name = "Arena";
029 }
030 /**
031 * @param g
032 */
033 public void linkGraphics(Graphics2D g) {
034 graphics = g;
035 }
036
037 /**
038 * Paints the Arena and the ticks around
039 */
040 public void paint(Graphics2D g) {
041 g.setColor(Color.BLUE);
042 int x = (int) (- (size / 2));
043 int y = (int) (- (size / 2));
044 g.drawOval(x, y, size, size);
045 g.setColor(Color.BLACK);
046 g.drawRect(x, y, size, size);
047 for (int i = -size / 2; i <= size / 2; i += 3) {
048 g.drawLine(i, 0, i + 1, 0);
049 g.drawLine(0, i, 0, i + 1);
050 }
051
052 for (int i = -size / 2; i <= size / 2; i += 100) {
053 g.drawLine(-size / 2, i, - (size / 2) + sizeGrad, i);
054 g.drawLine(size / 2 - sizeGrad, i, size / 2, i);
055 g.drawLine(i, -size / 2, i, -size / 2 + sizeGrad);
056 g.drawLine(i, size / 2 - sizeGrad, i, size / 2);
057 }
058 }
059
060 private void paintTimeSteps(Graphics2D g, int timeSteps) {
061
062 int width = 300;
063 int height = 15;
064 int x = -size / 2;
065 int y = size / 2 + height + 20;
066 g.setColor(Color.WHITE);
067
068 g.fillRect(x - 1, y - 15 - height, width, height + 10);
069 g.setColor(Color.BLACK);
070 Font current = g.getFont();
071 g.setFont(new Font("SansSerif", Font.BOLD, 26));
072 g.drawString("TIME STEPS: " + timeSteps, x, y - 8);
073 g.setFont(current);
074 }
075
076 /**
077 * Paint the Arena with the indication of the Time Steps
078 * @param g
079 * @param timeSteps
080 */
081 public void paintWithTimeSteps(Graphics2D g, int timeSteps) {
082 paint(g);
083 paintTimeSteps(g, timeSteps);
084 }
085
086 public double getRadius() {
087 return size / 2;
088 }
089
090 public double getRadiusBody() {
091 return 1;
092 }
093
094 public int getShift() {
095 return size / 2 + shift;
096 }
097
098 /**
099 * Returns true if the circle whose center is the point (x,y) and whose
100 * radius is <code>radiusBody</code> is colliding with the Arena
101 * @param x
102 * @param y
103 * @param radiusBody
104 * @return
105 */
106 public boolean isInside(double x, double y, double radiusBody) {
107 double dist_from_center = radiusBody + Math.sqrt((x * x) + (y * y));
108 double r = getRadius();
109 //System.out.println(x+"-"+y+"-s:"+"-"+dist_from_center+"<"+r);
110 boolean test = (dist_from_center < getRadius());
111 return test;
112 }
113
114 /**
115 * Returns true if Agent a collides with the Arena
116 */
117 public boolean collideWithMe(Agent a) {
118 double x_ag = (double) a.getCoord().getX();
119 double y_ag = (double) a.getCoord().getY();
120 double s_ag = (double) a.getSize();
121
122 boolean test =
123 (s_ag + Math.sqrt((x_ag * x_ag) + (y_ag * y_ag)) < getRadius());
124
125 return test;
126 }
127
128 /**
129 * Calculates the distance between a point and the arena
130 * @param p Point inside the arena
131 * @return the distance between the point and the closest wall
132 */
133 public double distanceTo(Point2D p) {
134 double distToCentre =
135 Math.sqrt(p.getX() * p.getX() + p.getY() * p.getY());
136 return getRadius() - distToCentre;
137 }
138
139 /**
140 * Gives the closest point of the Wall to a given point
141 * @param p
142 * @param radiusArenaToConsider
143 * @return
144 */
145 public Point2D closestPointTo(Point2D p, double radiusArenaToConsider) {
146 if (p.getX() == 0) {
147 if (p.getY() > 0) {
148 return new Point2D.Double(0, radiusArenaToConsider);
149 } else if (p.getY() < 0) {
150 return new Point2D.Double(0, -radiusArenaToConsider);
151 } else {
152 return new Point2D.Double(0, -radiusArenaToConsider);
153 }
154 } else {
155 double coeff = p.getY() / p.getX();
156 double x =
157 Math.sqrt(
158 radiusArenaToConsider
159 * radiusArenaToConsider
160 / (1 + coeff * coeff));
161 if (p.getX() < 0) {
162 x = -x;
163 }
164 double y = coeff * x;
165 Point2D closest_point = new Point2D.Double(x, y);
166 return closest_point;
167 }
168 }
169
170 /**
171 * Returns the point of the arena which is the closest to p.
172 * If p = 0,0 - no closest point, functions returns the NORTH one (arbitrary)
173 * @param p the point2D
174 * @return closest Point2D of the arena, - NORTH point if no closest
175 */
176
177 public Point2D closestPointTo(Point2D p) {
178 return closestPointTo(p, getRadius());
179 }
180
181 /**
182 * For the arena, the coordinates used to get the vector
183 * are the coordinates of the closest point of the arena
184 */
185
186 public Point2D getCoordNearTo(Entity otherEntity) {
187 return closestPointTo(otherEntity.getCoord());
188 }
189
190 /**
191 * By convention, the Arena is dangerous.
192 */
193 public boolean isDangerous() {
194 return true;
195 }
196 public boolean isMoving() {
197 return false;
198 }
199 /**
200 * The Arena does not move.
201 * @see Entity#move(Arena,Entity[], int, java.awt.Graphics2D)
202 */
203 public void move(Arena a, Entity[] others, int nbagents, Graphics2D g) {
204 }
205
206 }