001    package org.agent;
002    
003    import org.util.*;
004    import org.util.xml.io.*;
005    import org.util.xml.element.*;
006    import org.*;
007    import java.awt.*;
008    import javax.swing.*;
009    import java.awt.geom.*;
010    import java.awt.image.*;
011    import java.awt.event.*;
012    
013    public class FieldPanel extends JComponent {
014    
015            private BufferedImage image_;
016            private WorldData world_data_;
017            private double center_x_;
018            private double center_y_;
019            private double zoom_x_ = -1.0;
020            private double zoom_y_ = -1.0;
021            private double pole_rad_view_width_;
022            private double orientation_view_width_;
023            private double agent_view_r_ = 4;
024            private double dot_view_r_ = 2;
025            private Stroke line_stroke_;
026            private Stroke orientation_stroke_;
027            private Graphics2D user_graphics_access_;
028            private Graphics2D user_graphics_access_no_translated_;
029    
030            public FieldPanel() {
031                    setPreferredSize(new Dimension(400, 300));
032                    addComponentListener(new ComponentAdapter(){
033                            public void componentResized(ComponentEvent e) {
034                                    createImage();
035                            }
036                    });
037                    addMouseWheelListener(new MouseWheelListener(){
038                            public void mouseWheelMoved(MouseWheelEvent e) {
039                                    int r = e.getWheelRotation();
040                                    if(r<0) {
041                                            zoom_x_ *= 0.9;
042                                            zoom_y_ *= 0.9;
043                                    } else {
044                                            zoom_x_ *= 1.1;
045                                            zoom_y_ *= 1.1;
046                                    }
047                                    draw();
048                            }
049                    });
050            }
051    
052            public void createImage() {
053                    int w = getWidth();
054                    int h = getHeight();
055                    if(image_==null || image_.getWidth()<w || image_.getHeight()<h)
056                            image_ = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
057                    try{
058                            draw();
059                    }catch(Exception e){
060                            e.printStackTrace();
061                    }
062            }
063            
064            public void update(WorldData world_data) {
065                    world_data_ = world_data;
066                    try{
067                            draw();
068                    }catch(Exception e){
069                            e.printStackTrace();
070                    }
071            }
072            
073            public void draw()  {
074    
075                    int w = getWidth();
076                    int h = getHeight();
077                    center_x_ = w/2;
078                    center_y_ = h/2;
079                    pole_rad_view_width_ = 3;
080                    orientation_view_width_ = 5;
081                    line_stroke_ = new BasicStroke((float)3);
082                    orientation_stroke_ = new BasicStroke((float)2);
083                    
084                    if(image_ == null) {
085                            new Thread(new Runnable(){public void run(){
086                                    createImage();
087                            }}).start();
088                            return;
089                    }
090                    user_graphics_access_ = null;
091                    Graphics2D g2 = (Graphics2D)image_.getGraphics();
092                    Graphics2D g2_no_translated = (Graphics2D)g2.create();
093    //              g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
094                    g2.setColor(Color.green);
095                    g2.fillRect(0, 0, w, h);
096    
097                    if(world_data_ == null) {
098                            g2.setFont(g2.getFont().deriveFont((float)30));
099                            g2.setColor(Color.red);
100                            g2.drawString("No data", 10, 40);
101                            return;
102                    }
103                    
104                    double tblength = world_data_.topRightCorner().sub(world_data_.bottomRightCorner()).dis();
105                    agent_view_r_ = 0.03*tblength;
106                    if(zoom_x_ == -1) {
107                            zoom_y_ = getHeight()/tblength;
108                            zoom_x_ = zoom_y_;
109                    }
110                                    
111                    //g2.rotate(-Math.PI/2);
112    
113                    g2.translate(center_x_, center_y_);
114                    g2.scale(zoom_x_, zoom_y_);
115    
116                    g2.setColor(Color.white);
117                    g2.setStroke(line_stroke_);
118                    drawLine(g2, world_data_.bottomRightCorner(), world_data_.bottomLeftCorner());
119                    drawLine(g2, world_data_.bottomRightCorner(), world_data_.topRightCorner());
120                    drawLine(g2, world_data_.topLeftCorner(), world_data_.topRightCorner());
121                    drawLine(g2, world_data_.topLeftCorner(), world_data_.bottomLeftCorner());
122    
123                    drawLine(g2, world_data_.topCenter(), world_data_.bottomCenter());
124                    
125                    drawLine(g2, world_data_.bottomRightPole(), world_data_.topRightSmallArea());
126                    drawLine(g2, world_data_.topRightSmallArea(), world_data_.bottomRightSmallArea());
127                    drawLine(g2, world_data_.bottomRightSmallArea(), world_data_.topRightPole());
128    
129                    drawLine(g2, world_data_.bottomLeftPole(), world_data_.topLeftSmallArea());
130                    drawLine(g2, world_data_.topLeftSmallArea(), world_data_.bottomLeftSmallArea());
131                    drawLine(g2, world_data_.bottomLeftSmallArea(), world_data_.topLeftPole());
132                    
133                    drawDot(g2, world_data_.bottomLeftGoal(), dot_view_r_);
134                    drawDot(g2, world_data_.bottomRightGoal(), dot_view_r_);
135                    drawDot(g2, world_data_.topLeftGoal(), dot_view_r_);
136                    drawDot(g2, world_data_.topRightGoal(), dot_view_r_);
137                    
138                    g2_no_translated.setColor(Color.black);
139                    g2_no_translated.drawString(String.valueOf(world_data_.time()), 10, 10);
140    
141    
142                    g2.setStroke(orientation_stroke_);
143                    g2.setColor(Color.blue);
144                    AgentState[] team_mate_list = world_data_.teamMates();
145                    for(AgentState team_mate : team_mate_list)
146                            drawAgent(g2, team_mate);
147    
148                    g2.setColor(Color.red);
149                    AgentState[] opponent_list = world_data_.opponents();
150                    for(AgentState opponent : opponent_list)
151                            drawAgent(g2, opponent);
152    
153                    Vector ball = world_data_.ball();
154                    g2.setColor(Color.black);
155                    drawDot(g2, ball, 5);
156                    g2.setColor(Color.white);
157                    drawDot(g2, ball, 4);
158    //              drawString(g2_no_translated, "ball", ball);
159    
160                    g2.setColor(Color.gray);
161                    g2.fill(new Arc2D.Double(-agent_view_r_, -agent_view_r_, agent_view_r_*2, agent_view_r_*2, 0, 360, Arc2D.CHORD));
162    
163                    g2.setColor(Color.black);
164    
165                    user_graphics_access_ = g2;
166                    user_graphics_access_no_translated_ = g2_no_translated;
167    
168                    repaint();
169            }
170            
171            /**
172             * you can set Color, Strock or RenderingHints for your draw.
173             */
174            public Graphics2D getUserGraphicsAccess() throws Exception {
175                    if(user_graphics_access_ == null) throw new Exception("cannot write while drawing by system.");
176                    return user_graphics_access_;
177            }
178            
179            
180            
181            /**
182             * repaint() have to call after this method.
183             */
184            private void drawLine(Graphics2D g2, Vector v1, Vector v2) {
185    //              g2.draw(new Line2D.Double(v1.calcX(), v1.calcY(), v2.calcX(), v2.calcY()));
186                    g2.draw(new Line2D.Double(v1.calcY(), -v1.calcX(), v2.calcY(), -v2.calcX()));
187            }
188            private void drawDot(Graphics2D g2, Vector v, double r) {
189    //              g2.fill(new Arc2D.Double(v.calcX()-r, v.calcY()-r-1, r+r+1, r+r+1, 0, 360, Arc2D.CHORD));
190                    g2.fill(new Arc2D.Double(v.calcY()-r, -v.calcX()-r-1, r+r+1, r+r+1, 0, 360, Arc2D.CHORD));
191            }
192            private void drawString(Graphics2D g2, String message, Vector v) {
193    //              g2.drawString(message, (int)(v.calcX()*zoom_x_+center_x_+3), (int)(v.calcY()*zoom_y_+center_y_-3));
194                    g2.drawString(message, (int)(v.calcY()*zoom_x_+center_x_+3), (int)(-v.calcX()*zoom_y_+center_y_-3));
195            }
196    
197    
198    
199    
200    
201            private void drawAgent(Graphics2D g2, AgentState agent) {
202                    if(agent==null) return ;
203                    org.util.Vector location = agent.getLocation();
204                    org.util.Vector orientation = agent.getOrientation();
205                    if(location == null) return ;
206                    double r = agent_view_r_;
207                    Color c = g2.getColor();
208                    g2.setColor(Color.black);
209                    drawDot(g2, location, r+1);
210                    g2.setColor(c);
211                    drawDot(g2, location, r);
212                    g2.setColor(Color.black);
213                    drawLine(g2, location, location.add(orientation.normalize(10)));
214                    g2.setColor(c);
215            }
216    
217            
218            public void drawLine(Vector v1, Vector v2) {
219                    try{
220                            Graphics2D g2 = getUserGraphicsAccess();
221                            drawLine(g2, v1, v2);
222                            repaint();
223                    }catch(Exception e){
224                            e.printStackTrace();
225                    }
226            }
227            public void drawDot(Vector v) {
228                    try{
229                            Graphics2D g2 = getUserGraphicsAccess();
230                            drawDot(g2, v, 3);
231                            repaint();
232                    }catch(Exception e){
233                            e.printStackTrace();
234                    }
235            }
236            public void drawString(String message, Vector v) {
237                    try{
238                            Graphics2D g2 = getUserGraphicsAccess();
239                            g2 = user_graphics_access_no_translated_;
240                            drawString(g2, message, v);
241                            repaint();
242                    }catch(Exception e){
243                            e.printStackTrace();
244                    }
245            }
246    
247            public void paint(Graphics g) {
248                    int w = getWidth();
249                    int h = getHeight();
250                    if(image_ == null) {
251                            g.drawString("now loading...", 10, 10);
252                            new Thread(new Runnable(){public void run(){
253                                    createImage();
254                            }}).start();
255                    } else
256                            g.drawImage(image_, 0, 0, this);
257            }
258    
259            public static void alert(Object message) {
260                    System.out.println(message);
261            }
262    }
263    
264    /*
265    <WorldData>
266       <time>5.25131</time>
267       <agent_id>0</agent_id>
268       <nickname>player1</nickname>
269       <status>found</status>
270       <max_agent>2</max_agent>
271       <playMode>play on</playMode>
272       <score>
273          <yellow>0</yellow>
274          <blue>0</blue>
275       </score>
276       <wheel_velocities>
277          <right>0</right>
278          <left>0</left>
279       </wheel_velocities>
280       <ball>
281          <dist>117</dist>
282          <angle>39</angle>
283       </ball>
284       <teamMate>
285          <id>1</id>
286          <nickname>player2</nickname>
287          <status>found</status>
288          <dist>89</dist>
289          <angle>48</angle>
290          <orientation>107</orientation>
291       </teamMate>
292       <opponent>
293          <id>5</id>
294          <nickname>player7</nickname>
295          <status>found</status>
296          <dist>167</dist>
297          <angle>46</angle>
298          <orientation>161</orientation>
299       </opponent>
300       <flag>
301          <id>top_left_pole</id>
302          <dist>152</dist>
303          <angle>-59</angle>
304       </flag>
305       <flag>
306          <id>bottom_left_pole</id>
307          <dist>116</dist>
308          <angle>-83</angle>
309       </flag>
310       <flag>
311          <id>top_right_pole</id>
312          <dist>310</dist>
313          <angle>57</angle>
314       </flag>
315       <flag>
316          <id>bottom_right_pole</id>
317          <dist>294</dist>
318          <angle>69</angle>
319       </flag>
320       <flag>
321          <id>top_left_corner</id>
322          <dist>236</dist>
323          <angle>-40</angle>
324       </flag>
325       <flag>
326          <id>bottom_left_corner</id>
327          <dist>126</dist>
328          <angle>-133</angle>
329       </flag>
330       <flag>
331          <id>top_right_corner</id>
332          <dist>359</dist>
333          <angle>41</angle>
334       </flag>
335       <flag>
336          <id>bottom_right_corner</id>
337          <dist>298</dist>
338          <angle>89</angle>
339       </flag>
340       <flag>
341          <id>top_left_goal</id>
342          <dist>148</dist>
343          <angle>-8</angle>
344       </flag>
345       <flag>
346          <id>bottom_left_goal</id>
347          <dist>14</dist>
348          <angle>85</angle>
349       </flag>
350       <flag>
351          <id>top_right_goal</id>
352          <dist>224</dist>
353          <angle>36</angle>
354       </flag>
355       <flag>
356          <id>bottom_right_goal</id>
357          <dist>169</dist>
358          <angle>78</angle>
359       </flag>
360       <flag>
361          <id>top_left_small_area</id>
362          <dist>83</dist>
363          <angle>-74</angle>
364       </flag>
365       <flag>
366          <id>bottom_left_small_area</id>
367          <dist>128</dist>
368          <angle>-48</angle>
369       </flag>
370       <flag>
371          <id>top_right_small_area</id>
372          <dist>259</dist>
373          <angle>68</angle>
374       </flag>
375       <flag>
376          <id>bottom_right_small_area</id>
377          <dist>277</dist>
378          <angle>55</angle>
379       </flag>
380       <flag>
381          <id>middle_center</id>
382          <dist>117</dist>
383          <angle>39</angle>
384       </flag>
385       <flag>
386          <id>top_center</id>
387          <dist>229</dist>
388          <angle>11</angle>
389       </flag>
390       <flag>
391          <id>bottom_center</id>
392          <dist>112</dist>
393          <angle>112</angle>
394       </flag>
395    </WorldData>
396    */