Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / examples / Simulator / DOVEBrowser / NavigationVisComp.java
blob1d2c2118b57ecacdfeacbd472468d6fed577f661
1 //
2 // = FILENAME
3 // NavigationVisComp.java
4 //
5 // = AUTHOR
6 // Seth Widoff (core functionality)
7 // Michael Kircher (mk1@cs.wustl.edu)
8 //
9 // = DESCRIPTION
10 // This is a Visualization Component for displaying navigation.
12 // ============================================================================
16 import java.awt.*;
17 import java.io.*;
19 public class NavigationVisComp extends Panel implements VisComp
21 private Alt_Horizon alt_hor_ = new Alt_Horizon ();
22 private Position pos_ = new Position ();
24 public NavigationVisComp ()
26 setLayout (new BorderLayout (0, 2));
27 add ("Center", alt_hor_);
28 add ("South", pos_);
31 public void setName (String title) {
34 public int getProperty () {
35 return Properties.NAVIGATION;
38 public void update (java.util.Observable observable, java.lang.Object obj) {
39 Navigation navigation_ = null;
40 try {
41 navigation_ = (Navigation) obj;
43 catch (Exception excp) {
44 System.out.println (excp);
45 System.out.println ("Visualization Component received wrong data type!");
47 if (navigation_ != null) {
48 // make sure all the values are in the proper range.
49 navigation_.roll = (navigation_.roll > 180 || navigation_.roll < -180) ?
50 0 : navigation_.roll;
51 navigation_.pitch = (navigation_.pitch > 90 || navigation_.pitch < -90) ?
52 0 : navigation_.pitch;
54 // update the artificial horizon
55 alt_hor_.update_display (navigation_.roll, navigation_.pitch);
57 navigation_.pitch = (navigation_.position_latitude > 90 || navigation_.position_latitude < -90) ?
58 0 : navigation_.position_latitude;
59 navigation_.pitch = (navigation_.position_longitude > 100 || navigation_.position_longitude < 00) ?
60 0 : navigation_.position_longitude;
61 navigation_.pitch = (navigation_.altitude > 90 || navigation_.altitude < -90) ?
62 0 : navigation_.altitude;
63 navigation_.pitch = (navigation_.heading > 180 || navigation_.heading < -180) ?
64 0 : navigation_.heading;
66 // update the position display
67 pos_.update_display (navigation_.position_latitude,
68 navigation_.position_longitude,
69 navigation_.altitude,
70 navigation_.heading);
75 class Alt_Horizon
76 extends Canvas
78 private final static Color GREEN = new Color (0, 100, 0),
79 BLUE = new Color (30, 144, 255);
81 private Graphics offgraphics_;
82 private Image offscreen_;
83 private Dimension offscreensize_;
85 private int roll_ = 0, pitch_ = 0;
87 public void update_display (int roll, int pitch)
89 roll_ = roll;
90 pitch_ = pitch;
92 repaint ();
95 public Dimension getPreferredSize ()
97 return new Dimension (180, 180);
100 public Dimension getMinimumSize ()
102 return new Dimension (80, 80);
105 public void paint (Graphics g)
107 update (g);
110 public void update (Graphics g)
112 Dimension d = getSize ();
113 int rad, angles[] = { 180, 0 };
114 Point center;
116 if ((offscreen_ == null) || (d.width != offscreensize_.width) ||
117 (d.height != offscreensize_.height))
119 offscreen_ = createImage (d.width, d.height);
120 offscreensize_ = new Dimension (d.width, d.height);
121 offgraphics_ = offscreen_.getGraphics ();
122 offgraphics_.setFont (getFont());
124 // g.setColor (Color.lightGray);
125 // g.draw3DRect (0, 0, d.width - 1, d.height - 1, true);
126 // g.draw3DRect (1, 1, d.width - 3, d.height - 3, true);
127 // g.draw3DRect (2, 2, d.width - 5, d.height - 5, true);
130 offgraphics_.setColor (getBackground());
131 offgraphics_.fillRect (0, 0, d.width, d.height);
132 offgraphics_.setColor (BLUE);
134 // Calculate from the dimensions, the largest square.
135 center = new Point (d.width / 2, d.height / 2);
136 rad = ((center.x < center.y) ? center.x : center.y);
138 // Draw a circle of blue
139 offgraphics_.fillOval (center.x - rad, center.y - rad,
140 2*rad, 2*rad);
142 // Roll the horizon based on the roll angle
143 if (roll_ != 0)
144 roll_horizon (rad, angles);
146 // Pitch the horizon based on the pitch angle
147 if (pitch_ != 0)
148 pitch_horizon (rad, angles);
150 // Draw the resulting terrain
151 draw_horizon (rad, center, angles);
153 // Draw the plotted Image.
154 g.drawImage (offscreen_, 0, 0, null);
157 private void draw_horizon (int rad, Point center, int[] angles)
159 // Draw an arc
160 int arc_angle =
161 ((angles[0] > angles[1]) ?
162 (360 - angles[0]) + angles[1] :
163 (angles[1] - angles[0]));
165 Polygon remainder = new Polygon ();
167 offgraphics_.setColor (GREEN);
168 offgraphics_.fillArc (center.x - rad, center.y - rad,
169 2*rad, 2*rad,
170 angles[0], arc_angle);
172 if (pitch_ != 0)
174 if ((pitch_ > 0 && Math.abs (roll_) < 90) ||
175 (pitch_ < 0 && Math.abs (roll_) >= 90))
176 offgraphics_.setColor (BLUE);
178 int cover_angle = (angles[0] + arc_angle/2 + ((arc_angle < 180) ? 180 : 0)) % 360;
180 // System.out.println (points[0] + " " + points[1]);
182 // System.out.println (accepted_point);
184 remainder.addPoint (center.x + polar_to_rect_x (rad, cover_angle),
185 center.y - polar_to_rect_y (rad, cover_angle));
186 remainder.addPoint (center.x + polar_to_rect_x (rad, angles[0]),
187 center.y - polar_to_rect_y (rad, angles[0]));
188 remainder.addPoint (center.x + polar_to_rect_x (rad, angles[1]),
189 center.y - polar_to_rect_y (rad, angles[1]));
190 offgraphics_.fillPolygon (remainder);
191 //offgraphics_.setColor (getBackground ());
192 //offgraphics_.drawPolygon (remainder);
196 private void pitch_horizon (int rad, int[] angles)
198 boolean upside_down = Math.abs (roll_) >= 90;
199 int angle_shift = (int) Math.round ((double)(90 - (Math.abs (roll_) % 180)) / 90.0 * pitch_);
201 // System.out.println ("angle_shift " + angle_shift);
203 angles[0] += angle_shift;
204 angles[1] -= angle_shift;
209 private void roll_horizon (int rad, int[] angles)
211 // Roll the left and right points of the terrain.
212 angles[0] += roll_;
213 angles[1] += roll_;
215 if (angles[0] < 0)
216 angles[0] += 360;
218 if (angles[1] < 0)
219 angles[1] += 360;
222 private int polar_to_rect_x (int rad, int angle)
224 return (int) Math.round (rad * Math.cos ((double)angle * Math.PI/180.0));
227 private int polar_to_rect_y (int rad, int angle)
229 return (int) Math.round (rad * Math.sin ((double)angle * Math.PI/180.0));
232 private double caclulate_slope (int rad, int[] angles)
234 int x1 = polar_to_rect_x (rad, angles[0]),
235 x2 = polar_to_rect_x (rad, angles[1]),
236 y1 = polar_to_rect_y (rad, angles[0]),
237 y2 = polar_to_rect_y (rad, angles[1]);
239 return ((double) (y2 - y1)) / ((double) (x2 - x1));
242 private Point[] line_circle_intesect (int rad, double y_intercept, double slope)
244 double r_2 = (double)(rad * rad),
245 s_2 = slope * slope,
246 a_x = s_2 + 1,
247 b_x = 2.0 * slope * y_intercept,
248 c_x = y_intercept * y_intercept - r_2;
249 int[] x_roots = quad_eq (a_x, b_x, c_x),
250 y_roots = { (int) Math.round ((double)((double) x_roots[0])*slope + y_intercept),
251 (int) Math.round ((double)((double) x_roots[1])*slope + y_intercept) };
252 Point[] points = new Point [2];
254 points[0] = new Point (x_roots[0], y_roots[0]);
255 points[1] = new Point (x_roots[1], y_roots[1]);
257 return points;
260 private int calculate_angle (int rad, int x, int y)
263 double angle = 0,
264 sin_value = Math.asin ((double)y / (double)rad),
265 tan_value = Math.atan ((double)y / (double)x);
267 if (x >= 0)
268 angle = (x != 0) ? tan_value : sin_value +
269 ((y < 0) ? 2*Math.PI : 0);
270 else
271 angle = Math.PI + tan_value;
273 return (int) Math.round (angle * 180.0 / Math.PI);
276 double angle = 0.0,
277 sin_value = Math.asin ((double)Math.abs (y) / (double)rad);
279 if (x >= 0 && y >= 0)
280 angle = sin_value;
281 else if (x < 0 && y >= 0)
282 angle = sin_value + Math.PI/2.0;
283 else if (x < 0 && y < 0)
284 angle = sin_value + Math.PI;
285 else if (x >= 0 && y < 0)
286 angle = sin_value + 3.0*Math.PI/2.0;
288 return (int) Math.round (angle * 180.0 / Math.PI);
291 private int[] quad_eq (double a, double b, double c)
293 int[] roots = new int [2];
294 double body = Math.sqrt (b*b - 4.0*a*c);
296 roots[0] = (int) Math.round ((-b + body) / (2.0 * a));
297 roots[1] = (int) Math.round ((-b - body) / (2.0 * a));
299 return roots;
302 private int distance (Point point1, Point point2)
304 double xdiff = point1.x - point2.x,
305 ydiff = point1.y - point2.y;
307 return (int) Math.round (Math.sqrt (xdiff*xdiff + ydiff*ydiff));
311 class Position extends Panel
313 private final static Font FONT = new Font ("Dialog", Font.BOLD, 12);
314 private final static char DEGREE = '\u00B0';
316 private Label lat_ = new Label ("0" + DEGREE + " N", Label.RIGHT),
317 long_ = new Label ("0" + DEGREE + " S", Label.RIGHT),
318 alt_ = new Label ("0 Kft", Label.RIGHT),
319 heading_ = new Label ("0" + DEGREE + " ", Label.RIGHT);
321 public Position ()
323 Panel grid_panel = new Panel ();
325 lat_.setFont (FONT);
326 long_.setFont (FONT);
327 alt_.setFont (FONT);
328 heading_.setFont (FONT);
330 setLayout (new GridLayout (1, 4));
331 add (lat_);
332 add (long_);
333 add (heading_);
334 add (alt_);
337 public void update_display (int lat, int lon, int alt, int heading)
339 String lat_str =
340 Math.abs (lat) + "" + DEGREE + ((lat > 0) ? " N" : " S");
341 String long_str =
342 Math.abs (lon) + "" + DEGREE + ((lon > 0) ? " E" : " W");
344 lat_.setText (lat_str);
345 long_.setText (long_str);
346 alt_.setText (alt + " Kft");
347 heading_.setText (heading + "" + DEGREE + " ");