1   package main;
2   
3   import interfaces.*;
4   
5   import javax.swing.*;
6   import java.awt.*;
7   import java.lang.*;
8   import java.util.*;
9   import java.awt.geom.*;
10  
11  /**
12  * Provides a simple display for any SimWorld
13  *
14  * @author Graham Ritchie
15  */
16  class SimpleDisplay extends SimDisplay
17  {
18      private SimWorld world;
19      private Graphics2D g2;
20      private BasicStroke stroke;
21      private Color color;
22      
23      /**
24      * Sets up this display
25      *
26      * @param s the SimWorld to be displayed
27      */
28      public SimpleDisplay(SimWorld s)
29      {
30          // set world
31          world=s;
32          this.repaint();
33          stroke=new BasicStroke(1.0f,BasicStroke.CAP_SQUARE,BasicStroke.JOIN_BEVEL);
34      }
35      
36      /**
37      * Main repaint method
38      */
39      public void paintComponent(Graphics g)
40      {
41          // paint background
42          super.paintComponent(g);
43          
44          this.setBackground(Color.white);
45                  
46          // cast g to a Graphics2D instance
47          g2=(Graphics2D)g;
48          
49          // get the world's object list
50          LinkedList list=world.getObjectList();
51          
52          // draw a shape for each object
53          for (int i=0;i<list.size();i++)
54          {
55              // get each object in the list in turn
56              SimObject o=(SimObject)list.get(i);
57              
58              // create a shape for this object
59              Shape s=getShape(o);
60              
61              // rotate shape to correct bearing
62              s=rotateShape(s,o.getActualBearingXZ(),o.getXCoord(),o.getZCoord());
63              
64              // draw shape on the screen
65              
66              g2.setPaint(Color.black);
67              
68              Shape outline=stroke.createStrokedShape(s);
69              
70              g2.draw(outline);
71              
72              g2.setPaint(color);
73              
74              g2.fill(s);
75          }
76      }
77      
78      /**
79      * Checks if there is an associated shape for a SimObject. If so it is 
80      * returned. If not then a standard shape of the SimObject's size is returned.
81      *
82      * @param o the SimObject
83      * @return the appropriate java.awt.Shape
84      */
85      public Shape getShape(SimObject o)
86      {
87          // create a new Shape
88          Shape s;
89          
90          // check the SimObject's type
91          if(o.getType().equalsIgnoreCase("robot"))
92          {
93              // SimObject is a robot
94              s=createRobotShape(o.getXCoord(),o.getZCoord(),o.getWidth(),o.getLength());
95          }
96          else if(o.getType().equalsIgnoreCase("light"))
97          {
98              // SimObject is a light
99              s=createLightShape(o.getXCoord(),o.getZCoord(),o.getWidth(),o.getLength());
100         }
101         else if(o.getType().equalsIgnoreCase("sensor"))
102         {
103             // SimObject is a sensor
104             s=createSensorShape(o.getXCoord(),o.getZCoord(),o.getWidth(),o.getLength());
105         }
106         else if (o.getType().equalsIgnoreCase("wall"))
107         {
108             //SimObject is a wall
109             s=createWallShape(o.getXCoord(),o.getZCoord(),o.getWidth(),o.getLength());
110         }
111         else
112         {
113             // unknown SimObject, so create standard shape
114             s=createStandardShape(o.getXCoord(),o.getZCoord(),o.getWidth(),o.getLength());
115         }
116         
117         // return the shape
118         return s;
119     }
120     
121     /**
122     * Rotates a java.awt.Shape around a certain point a certain angle 
123     *
124     * @param shape the shape to be rotated
125     * @param angle the angle by which the shape is to be rotated
126     * @param X the x co-ordinate about which to rotate
127     * @param Z the z co-ordinate about which to rotate
128     * @return the rotated shape, as a new java.awt.Shape
129     */
130     private Shape rotateShape(Shape shape, double angle, double X, double Z)
131     {
132         // convert the angle to radians
133         double theta=Math.toRadians(angle);
134         
135         // create a new affine transform rotator
136         AffineTransform  atx = AffineTransform.getRotateInstance(theta,X,Z); 
137         
138         // create a rotated version of the shape
139         shape = atx.createTransformedShape(shape);
140         
141         // return the shape
142         return shape;
143     }
144     
145     /**
146     * Creates a robot shape
147     *
148     * @param x the x coordinate of the robot
149     * @param z the z coordinate of the robot
150     * @param width the width of the robot
151     * @param length the length of the robot
152     *
153     * @return the robot shape
154     */
155     private Shape createRobotShape(double x, double z, double width, double length)
156     {
157         // size of the 'wheels'
158         double a=5.0;
159         double b=15.0;
160         
161         // establish top left corner of robot
162         double X=(x-(width/2));
163         double Z=(z-(length/2));
164         
165         // make up the shape
166         Rectangle2D.Double body=new Rectangle2D.Double(X,Z,width,length);
167         
168         Rectangle2D.Double wheel1=new Rectangle2D.Double(X-a-1,Z+5,a,b);
169         Rectangle2D.Double wheel2=new Rectangle2D.Double(X-a-1,Z+40,a,b);
170         Rectangle2D.Double wheel3=new Rectangle2D.Double(X+width+1,Z+5,a,b);
171         Rectangle2D.Double wheel4=new Rectangle2D.Double(X+width+1,Z+40,a,b);
172         
173         Area shape=new Area(body);
174         shape.add(new Area(wheel1));
175         shape.add(new Area(wheel2));
176         shape.add(new Area(wheel3));
177         shape.add(new Area(wheel4));
178         
179         color=Color.lightGray;
180         
181         // return the complete shape
182         return (Shape) shape;
183     }
184     
185     /**
186     * Creates a light shape of the appropriate dimesnion
187     */
188     private Shape createLightShape(double x, double z, double width, double length)
189     {
190         // establish top left corner of object
191         double X=(x-(width/2));
192         double Z=(z-(length/2));
193         
194         color=Color.yellow;
195         
196         return new Ellipse2D.Double(X,Z,width,length);
197     }
198     
199     /**
200     * Creates a sensor shape of the appropriate dimension
201     */
202     private Shape createSensorShape(double x, double z, double width, double length)
203     {
204         // establish top left corner of object
205         double X=(x-(width/2));
206         double Z=(z-(length/2));
207         
208         color=Color.cyan;
209         color=color.darker();
210         
211         return new Rectangle2D.Double(X,Z,width,length);
212     }
213     
214     /**
215     * Creates a wall shape of the appropriate dimension
216     */
217     private Shape createWallShape(double x, double z, double width, double length)
218     {
219         // establish top left corner of object
220         double X=(x-(width/2));
221         double Z=(z-(length/2));
222         
223         color=Color.lightGray;
224         color=color.darker();
225         
226         return new Rectangle2D.Double(X,Z,width,length);
227     }
228     
229     /**
230     * Creates a standard shape, currently a rectangle
231     */
232     private Shape createStandardShape(double x, double z, double width, double length)
233     {
234         // establish top left corner of object
235         double X=(x-(width/2));
236         double Z=(z-(length/2));
237         
238         color=Color.black;
239         
240         return new Rectangle2D.Double(X,Z,width,length);
241     }
242 }
243