]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud_ladr.cxx
09a4070a343653a72a8592c540331a966dc71c86
[flightgear.git] / src / Cockpit / hud_ladr.cxx
1
2 #ifdef HAVE_CONFIG_H
3 #  include "config.h"
4 #endif
5
6 #include <simgear/constants.h>
7
8 #include "hud.hxx"
9 #include "panel.hxx"
10
11
12 //====================== Top of HudLadder Class =======================
13 HudLadder::HudLadder(const string& name,
14                      int      x,
15                      int      y,
16                      UINT     width,
17                      UINT     height,
18                      float    factr,
19                      FLTFNPTR ptch_source,
20                      FLTFNPTR roll_source,
21                      float    span_units,
22                      float    major_div,
23                      float    minor_div,
24                      UINT     screen_hole,
25                      UINT     lbl_pos,
26                      bool     frl_spot,
27                      bool     target,
28                      bool     vel_vec,
29                      bool     drift,
30                      bool     alpha,
31                      bool     energy,
32                      bool     climb,
33                      bool     glide,
34                      float    glide_slope_val,
35                      bool     worm_energy,
36                      bool     waypoint,
37                      bool     working,
38                      int      zenithsymbol,
39                      int      nadirsymbol,
40                      int      hat_marker) :
41     dual_instr_item( x, y, width, height,
42                      ptch_source, roll_source, working, HUDS_RIGHT),
43     width_units         ( (int)(span_units) ),
44     div_units           ( (int)(major_div < 0? -major_div: major_div) ),
45     minor_div           ( (int)(minor_div) ),
46     label_pos           ( lbl_pos      ),
47     scr_hole            ( screen_hole  ),
48     vmax                ( span_units/2 ),
49     vmin                ( -vmax        ),
50     factor              ( factr        ),
51     hudladder_type      ( name         ),
52     frl                 ( frl_spot     ),
53     target_spot         ( target       ),
54     velocity_vector     ( vel_vec      ),
55     drift_marker        ( drift        ),
56     alpha_bracket       ( alpha        ),
57     energy_marker       ( energy       ),
58     climb_dive_marker   ( climb        ),
59     glide_slope_marker  ( glide        ),
60     glide_slope         ( glide_slope_val),
61     energy_worm         ( worm_energy),
62     waypoint_marker     ( waypoint)
63
64
65 {
66     zenith= zenithsymbol;
67     nadir=nadirsymbol;
68     hat= hat_marker;
69
70     if (!width_units)
71         width_units = 45;
72 }
73
74
75 HudLadder::~HudLadder()
76 {
77 }
78
79
80 HudLadder::HudLadder( const HudLadder & image ) :
81     dual_instr_item     ( (dual_instr_item &) image),
82     width_units         ( image.width_units   ),
83     div_units           ( image.div_units     ),
84     label_pos           ( image.label_pos     ),
85     scr_hole            ( image.scr_hole      ),
86     vmax                ( image.vmax ),
87     vmin                ( image.vmin ),
88     factor              ( image.factor        ),
89     hudladder_type      ( image.hudladder_type),
90     frl                 ( image.frl),
91     target_spot         ( image.target_spot),
92     velocity_vector     ( image.velocity_vector),
93     drift_marker        ( image.drift_marker),
94     alpha_bracket       ( image.alpha_bracket),
95     energy_marker       ( image.energy_marker),
96     climb_dive_marker   ( image.climb_dive_marker),
97     glide_slope_marker  ( image.glide_slope_marker),
98     glide_slope         ( image.glide_slope),
99     energy_worm         ( image.energy_worm),
100     waypoint_marker     ( image.waypoint_marker)
101 {
102 }
103
104
105 //
106 //  Draws a climb ladder in the center of the HUD
107 //
108
109 void HudLadder::draw( void )
110 {
111
112     float  x_ini,x_ini2;
113     float  x_end,x_end2;
114     float  y = 0;
115     int count;
116     float cosine, sine, xvvr, yvvr, Vxx = 0.0, Vyy = 0.0, Vzz = 0.0,
117           up_vel, ground_vel, actslope = 0.0;
118     float Axx = 0.0, Ayy = 0.0, Azz = 0.0, total_vel = 0.0, pot_slope, t1,
119           t2 = 0.0, psi = 0.0, alpha,pla;
120     float vel_x = 0.0, vel_y = 0.0, drift;
121     // char     Textaux[8] ;
122     bool  pitch_ladder = false;
123     bool  climb_dive_ladder = false;
124     bool  clip_plane = false;
125
126     GLdouble eqn_top[4] = {0.0,-1.0,0.0,0.0};
127     GLdouble eqn_left[4] = {-1.0,0.0,0.0,100.0};
128     GLdouble eqn_right[4] = {1.0,0.0,0.0,100.0};
129
130     POINT  centroid    = get_centroid();
131     RECT   box         = get_location();
132
133     float   half_span  = box.right / 2.0;
134     float   roll_value = current_ch2();
135     alpha = get_aoa();
136     pla = get_throttleval();
137
138 #ifdef ENABLE_SP_FMDS
139     int lgear,wown,wowm,ilcanclaw,ihook;
140     ilcanclaw = get_iaux2();
141     lgear = get_iaux3();
142     wown = get_iaux4();
143     wowm = get_iaux5();
144     ihook = get_iaux6();
145 #endif
146     float pitch_value = current_ch1() * SGD_RADIANS_TO_DEGREES;
147
148     if (hudladder_type=="Climb/Dive Ladder") {
149         pitch_ladder = false;
150         climb_dive_ladder = true;
151         clip_plane = true;
152     } else {
153         // hudladder_type=="Pitch Ladder"
154         pitch_ladder = true;
155         climb_dive_ladder = false;
156         clip_plane = false;
157     }
158
159     //**************************************************************
160     glPushMatrix();
161     // define (0,0) as center of screen
162     glTranslatef( centroid.x, centroid.y, 0);
163
164     // OBJECT STATIC RETICLE
165     // TYPE FRL
166     // ATTRIB - ALWAYS
167     // Draw the FRL spot and line
168     if (frl) {
169 #define FRL_DIAMOND_SIZE 2.0
170         glBegin(GL_LINE_LOOP);
171         glVertex2f( -FRL_DIAMOND_SIZE, 0.0);
172         glVertex2f(0.0, FRL_DIAMOND_SIZE);
173         glVertex2f( FRL_DIAMOND_SIZE, 0.0);
174         glVertex2f(0.0, -FRL_DIAMOND_SIZE);
175         glEnd();
176
177         glBegin(GL_LINE_STRIP);
178         glVertex2f(0, FRL_DIAMOND_SIZE);
179         glVertex2f(0, 8.0 );
180         glEnd();
181 #undef FRL_DIAMOND_SIZE
182     }
183     // TYPE WATERLINE_MARK (W shaped _    _ )
184     //                                    \/\/
185
186     //****************************************************************
187     // TYPE TARGET_SPOT
188     // Draw the target spot.
189     if (target_spot) {
190 #define CENTER_DIAMOND_SIZE 6.0
191         glBegin(GL_LINE_LOOP);
192         glVertex2f( -CENTER_DIAMOND_SIZE, 0.0);
193         glVertex2f(0.0, CENTER_DIAMOND_SIZE);
194         glVertex2f( CENTER_DIAMOND_SIZE, 0.0);
195         glVertex2f(0.0, -CENTER_DIAMOND_SIZE);
196         glEnd();
197 #undef CENTER_DIAMOND_SIZE
198     }
199
200     //****************************************************************
201     //velocity vector reticle - computations
202     if (velocity_vector) {
203         Vxx = get_Vx();
204         Vyy = get_Vy();
205         Vzz = get_Vz();
206         Axx = get_Ax();
207         Ayy = get_Ay();
208         Azz = get_Az();
209         psi = get_heading();
210
211         if (psi > 180.0)
212             psi = psi - 360;
213
214         total_vel = sqrt(Vxx*Vxx + Vyy*Vyy + Vzz*Vzz);
215         ground_vel = sqrt(Vxx*Vxx + Vyy*Vyy);
216         up_vel = Vzz;
217
218         if (ground_vel < 2.0) {
219             if (fabs(up_vel) < 2.0)
220                 actslope = 0.0;
221             else
222                 actslope = (up_vel/fabs(up_vel))*90.0;
223
224         } else {
225             actslope = atan(up_vel/ground_vel)*SGD_RADIANS_TO_DEGREES;
226         }
227
228         xvvr = (((atan2(Vyy,Vxx)*SGD_RADIANS_TO_DEGREES)-psi)
229                 * (factor/globals->get_current_view()->get_aspect_ratio()));
230         drift = ((atan2(Vyy,Vxx)*SGD_RADIANS_TO_DEGREES)-psi);
231         yvvr = ((actslope - pitch_value)*factor);
232         vel_y = ((actslope -pitch_value) * cos(roll_value) + drift*sin(roll_value))*factor;
233         vel_x = (-(actslope -pitch_value)*sin(roll_value) + drift*cos(roll_value))
234                 * (factor/globals->get_current_view()->get_aspect_ratio());
235         //  printf("%f %f %f %f\n",vel_x,vel_y,drift,psi);
236
237         //****************************************************************
238         // OBJECT MOVING RETICLE
239         // TYPE - DRIFT MARKER
240         // ATTRIB - ALWAYS
241         // drift marker
242         if (drift_marker) {
243             glBegin(GL_LINE_STRIP);
244             glVertex2f((xvvr*25/120)-6, -4);
245             glVertex2f(xvvr*25/120, 8);
246             glVertex2f((xvvr*25/120)+6, -4);
247             glEnd();
248         }
249
250         //****************************************************************
251         // Clipping coordinates for ladder to be input from xml file
252         // Clip hud ladder
253         if (clip_plane) {
254             glClipPlane(GL_CLIP_PLANE0,eqn_top);
255             glEnable(GL_CLIP_PLANE0);
256             glClipPlane(GL_CLIP_PLANE1,eqn_left);
257             glEnable(GL_CLIP_PLANE1);
258             glClipPlane(GL_CLIP_PLANE2,eqn_right);
259             glEnable(GL_CLIP_PLANE2);
260             // glScissor(-100,-240,200,240);
261             // glEnable(GL_SCISSOR_TEST);
262         }
263
264         //****************************************************************
265         // OBJECT MOVING RETICLE
266         // TYPE VELOCITY VECTOR
267         // ATTRIB - ALWAYS
268         // velocity vector
269         glBegin(GL_LINE_LOOP);  // Use polygon to approximate a circle
270         for (count=0; count<50; count++) {
271             cosine = 6 * cos(count * SGD_2PI/50.0);
272             sine =   6 * sin(count * SGD_2PI/50.0);
273             glVertex2f(cosine+vel_x, sine+vel_y);
274         }
275         glEnd();
276
277         //velocity vector reticle orientation lines
278         glBegin(GL_LINE_STRIP);
279         glVertex2f(vel_x-12, vel_y);
280         glVertex2f(vel_x-6, vel_y);
281         glEnd();
282         glBegin(GL_LINE_STRIP);
283         glVertex2f(vel_x+12, vel_y);
284         glVertex2f(vel_x+6, vel_y);
285         glEnd();
286         glBegin(GL_LINE_STRIP);
287         glVertex2f(vel_x, vel_y+12);
288         glVertex2f(vel_x, vel_y+6);
289         glEnd();
290
291 #ifdef ENABLE_SP_FMDS
292         // OBJECT MOVING RETICLE
293         // TYPE LINE
294         // ATTRIB - ON CONDITION
295         if (lgear == 1) {
296             // undercarriage status
297             glBegin(GL_LINE_STRIP);
298             glVertex2f(vel_x+8, vel_y);
299             glVertex2f(vel_x+8, vel_y-4);
300             glEnd();
301
302             // OBJECT MOVING RETICLE
303             // TYPE LINE
304             // ATTRIB - ON CONDITION
305             glBegin(GL_LINE_STRIP);
306             glVertex2f(vel_x-8, vel_y);
307             glVertex2f(vel_x-8, vel_y-4);
308             glEnd();
309
310             // OBJECT MOVING RETICLE
311             // TYPE LINE
312             // ATTRIB - ON CONDITION
313             glBegin(GL_LINE_STRIP);
314             glVertex2f(vel_x, vel_y-6);
315             glVertex2f(vel_x, vel_y-10);
316             glEnd();
317         }
318
319         // OBJECT MOVING RETICLE
320         // TYPE V
321         // ATTRIB - ON CONDITION
322         if (ihook == 1) {
323             // arrestor hook status
324             glBegin(GL_LINE_STRIP);
325             glVertex2f(vel_x-4, vel_y-8);
326             glVertex2f(vel_x, vel_y-10);
327             glVertex2f(vel_x+4, vel_y-8);
328             glEnd();
329         }
330 #endif
331     } // if velocity_vector
332
333
334     //***************************************************************
335     // OBJECT MOVING RETICLE
336     // TYPE - SQUARE_BRACKET
337     // ATTRIB - ON CONDITION
338     // alpha bracket
339 #ifdef ENABLE_SP_FMDS
340     if (alpha_bracket && ihook == 1) {
341         glBegin(GL_LINE_STRIP);
342         glVertex2f(vel_x-20 , vel_y-(16-alpha)*factor);
343         glVertex2f(vel_x-17, vel_y-(16-alpha)*factor);
344         glVertex2f(vel_x-17, vel_y-(14-alpha)*factor);
345         glVertex2f(vel_x-20, vel_y-(14-alpha)*factor);
346         glEnd();
347
348         glBegin(GL_LINE_STRIP);
349         glVertex2f(vel_x+20 , vel_y-(16-alpha)*factor);
350         glVertex2f(vel_x+17, vel_y-(16-alpha)*factor);
351         glVertex2f(vel_x+17, vel_y-(14-alpha)*factor);
352         glVertex2f(vel_x+20, vel_y-(14-alpha)*factor);
353         glEnd();
354     }
355 #endif
356     //printf("xvr=%f,yvr=%f,Vx=%f,Vy=%f,Vz=%f\n",xvvr,yvvr,Vx,Vy,Vz);
357     //printf("Ax=%f,Ay=%f,Az=%f\n",Ax,Ay,Az);
358
359     //****************************************************************
360     // OBJECT MOVING RETICLE
361     // TYPE ENERGY_MARKERS
362     // ATTRIB - ALWAYS
363     //energy markers - compute potential slope
364     if (energy_marker) {
365         if (total_vel < 5.0) {
366             t1 = 0;
367             t2 = 0;
368         } else {
369             t1 = up_vel/total_vel;
370             t2 = asin((Vxx*Axx + Vyy*Ayy + Vzz*Azz)/(9.81*total_vel));
371         }
372         pot_slope = ((t2/3)*SGD_RADIANS_TO_DEGREES)*factor + vel_y;
373         // if (pot_slope < (vel_y - 45)) pot_slope = vel_y-45;
374         // if (pot_slope > (vel_y + 45)) pot_slope = vel_y+45;
375
376         //energy markers
377         glBegin(GL_LINE_STRIP);
378         glVertex2f(vel_x-20, pot_slope-5);
379         glVertex2f(vel_x-15, pot_slope);
380         glVertex2f(vel_x-20, pot_slope+5);
381         glEnd();
382
383         glBegin(GL_LINE_STRIP);
384         glVertex2f(vel_x+20, pot_slope-5);
385         glVertex2f(vel_x+15, pot_slope);
386         glVertex2f(vel_x+20, pot_slope+5);
387         glEnd();
388
389         if (pla > (105.0/131.0)) {
390             glBegin(GL_LINE_STRIP);
391             glVertex2f(vel_x-24, pot_slope-5);
392             glVertex2f(vel_x-19, pot_slope);
393             glVertex2f(vel_x-24, pot_slope+5);
394             glEnd();
395
396             glBegin(GL_LINE_STRIP);
397             glVertex2f(vel_x+24, pot_slope-5);
398             glVertex2f(vel_x+19, pot_slope);
399             glVertex2f(vel_x+24, pot_slope+5);
400             glEnd();
401         }
402     }
403
404     //**********************************************************
405     // ramp reticle
406     // OBJECT STATIC RETICLE
407     // TYPE LINE
408     // ATTRIB - ON CONDITION
409 #ifdef ENABLE_SP_FMDS
410     if (energy_worm && ilcanclaw == 1) {
411         glBegin(GL_LINE_STRIP);
412         glVertex2f(-15, -134);
413         glVertex2f(15, -134);
414         glEnd();
415
416         // OBJECT MOVING RETICLE
417         // TYPE BOX
418         // ATTRIB - ON CONDITION
419         glBegin(GL_LINE_STRIP);
420         glVertex2f(-6, -134);
421         glVertex2f(-6, t2*SGD_RADIANS_TO_DEGREES*4.0 - 134);
422         glVertex2f(+6, t2*SGD_RADIANS_TO_DEGREES*4.0 - 134);
423         glVertex2f(6, -134);
424         glEnd();
425
426         // OBJECT MOVING RETICLE
427         // TYPE DIAMOND
428         // ATTRIB - ON CONDITION
429         glBegin(GL_LINE_LOOP);
430         glVertex2f(-6, actslope*4.0 - 134);
431         glVertex2f(0, actslope*4.0 -134 +3);
432         glVertex2f(6, actslope*4.0 - 134);
433         glVertex2f(0, actslope*4.0 -134 -3);
434         glEnd();
435     }
436 #endif
437
438     //*************************************************************
439     // OBJECT MOVING RETICLE
440     // TYPE DIAMOND
441     // ATTRIB - ALWAYS
442     // Draw the locked velocity vector.
443     if (climb_dive_marker) {
444         glBegin(GL_LINE_LOOP);
445         glVertex2f( -3.0, 0.0+vel_y);
446         glVertex2f(0.0, 6.0+vel_y);
447         glVertex2f( 3.0, 0.0+vel_y);
448         glVertex2f(0.0, -6.0+vel_y);
449         glEnd();
450     }
451
452     //****************************************************************
453
454     if (climb_dive_ladder) { // CONFORMAL_HUD
455         vmin = pitch_value - (float)width_units;
456         vmax = pitch_value + (float)width_units;
457         glTranslatef( vel_x, vel_y, 0);
458
459     } else { // pitch_ladder - Default Hud
460         vmin = pitch_value - (float)width_units * 0.5f;
461         vmax = pitch_value + (float)width_units * 0.5f;
462     }
463
464     glRotatef(roll_value * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
465     // FRL marker not rotated - this line shifted below
466
467     if (div_units) {
468         char  TextLadder[8];
469         float label_length;
470         float label_height;
471         float left;
472         float right;
473         float bot;
474         float top;
475         float text_offset = 4.0f;
476         float zero_offset = 0.0;
477
478         if (climb_dive_ladder)
479             zero_offset = 50.0f; // horizon line is wider by this much (hard coded ??)
480         else
481             zero_offset = 10.0f;
482
483         fntFont *font      = HUDtext->getFont();
484         float    pointsize = HUDtext->getPointSize();
485         float    italic    = HUDtext->getSlant();
486
487         TextList.setFont( HUDtext );
488         TextList.erase();
489         LineList.erase();
490         StippleLineList.erase();
491
492         int last = FloatToInt(vmax)+1;
493         int i    = FloatToInt(vmin);
494
495         if ( !scr_hole ) {
496             x_end =  half_span;
497
498             for (; i<last; i++) {
499                 y = (((float)(i - pitch_value) * factor) + .5f);
500
501                 if ( !(i % div_units )) {           //  At integral multiple of div
502                     sprintf( TextLadder, "%d", i );
503                     font->getBBox ( TextLadder, pointsize, italic,
504                                     &left, &right, &bot, &top ) ;
505                     label_length  = right - left;
506                     label_length += text_offset;
507                     label_height  = (top - bot)/2.0f;
508
509                     x_ini = -half_span;
510
511                     if ( i >= 0 ) {
512                         // Make zero point wider on left
513                         if ( i == 0 )
514                             x_ini -= zero_offset;
515
516                         // Zero or above draw solid lines
517                         Line(x_ini, y, x_end, y);
518
519                         if (i == 90 && zenith == 1)
520                             drawZenith(x_ini, x_end,y);
521                     } else {
522                         // Below zero draw dashed lines.
523                         StippleLine(x_ini, y, x_end, y);
524
525                         if (i == -90 && nadir ==1)
526                             drawNadir(x_ini, x_end,y);
527                     }
528
529                     // Calculate the position of the left text and write it.
530                     Text( x_ini-label_length, y-label_height, TextLadder );
531                     Text( x_end+text_offset,  y-label_height, TextLadder );
532                 }
533             }
534
535         } else { // if (scr_hole )
536             // Draw ladder with space in the middle of the lines
537             float hole = (float)((scr_hole)/2.0f);
538
539             x_end = -half_span + hole;
540             x_ini2= half_span  - hole;
541
542             for (; i<last; i++) {
543                 if (hudladder_type=="Pitch Ladder")
544                     y = (((float)(i - pitch_value) * factor) + .5);
545                 else if (hudladder_type=="Climb/Dive Ladder")
546                     y = (((float)(i - actslope) * factor) + .5);
547
548                 if (!(i % div_units)) {  //  At integral multiple of div
549                     sprintf( TextLadder, "%d", i );
550                     font->getBBox ( TextLadder, pointsize, italic,
551                             &left, &right, &bot, &top ) ;
552                     label_length  = right - left;
553                     label_length += text_offset;
554                     label_height  = (top - bot)/2.0f;
555                     // printf("l %f r %f b %f t %f\n",left, right, bot, top );
556
557                     // Start by calculating the points and drawing the
558                     // left side lines.
559                     x_ini = -half_span;
560                     x_end2= half_span;
561
562                     if ( i >= 0 ) {
563                         // Make zero point wider on left
564                         if ( i == 0 ) {
565                             x_ini -= zero_offset;
566                             x_end2 +=zero_offset;
567                         }
568                         //draw climb bar vertical lines
569                         if (climb_dive_ladder) {
570                             // Zero or above draw solid lines
571                             Line(x_end, y-5.0, x_end, y);
572                             Line(x_ini2, y-5.0, x_ini2, y);
573                         }
574                         // draw pitch / climb bar
575                         Line(x_ini, y, x_end, y);
576                         Line(x_ini2, y, x_end2, y);
577
578                         if (i == 90 && zenith == 1)
579                             drawZenith(x_ini2, x_end,y);
580
581                     } else { // i < 0
582                         // draw dive bar vertical lines
583                         if (climb_dive_ladder) {
584                             Line(x_end, y+5.0, x_end, y);
585                             Line(x_ini2, y+5.0, x_ini2, y);
586                         }
587
588                         // draw pitch / dive bars
589                         StippleLine(x_ini, y, x_end, y);
590                         StippleLine(x_ini2, y, x_end2, y);
591
592                         if (i == -90 && nadir == 1)
593                             drawNadir(x_ini2, x_end,y);
594                     }
595
596                     // Now calculate the location of the left side label using
597                     Text( x_ini-label_length, y-label_height, TextLadder );
598                     Text(x_end2+text_offset, y-label_height, TextLadder );
599                 }
600             }
601
602             // OBJECT LADDER MARK
603             // TYPE LINE
604             // ATTRIB - ON CONDITION
605             // draw appraoch glide slope marker
606 #ifdef ENABLE_SP_FMDS
607             if (glide_slope_marker && ihook) {
608                 Line(-half_span+15, (glide_slope-actslope)*factor, -half_span + hole, (glide_slope-actslope)*factor);
609                 Line(half_span-15, (glide_slope-actslope)*factor, half_span - hole, (glide_slope-actslope)*factor);
610             } // if glide_slope_marker
611 #endif
612         }
613         TextList.draw();
614
615         glLineWidth(0.2);
616
617         LineList.draw();
618
619         glEnable(GL_LINE_STIPPLE);
620         glLineStipple( 1, 0x00FF );
621         StippleLineList.draw( );
622         glDisable(GL_LINE_STIPPLE);
623     }
624     glDisable(GL_CLIP_PLANE0);
625     glDisable(GL_CLIP_PLANE1);
626     glDisable(GL_CLIP_PLANE2);
627     //  glDisable(GL_SCISSOR_TEST);
628     glPopMatrix();
629     //*************************************************************
630
631     //*************************************************************
632 #ifdef ENABLE_SP_FMDS
633     if (waypoint_marker) {
634         //waypoint marker computation
635         float fromwp_lat,towp_lat,fromwp_lon,towp_lon,dist,delx,dely,hyp,theta,brg;
636
637         fromwp_lon = get_longitude()*SGD_DEGREES_TO_RADIANS;
638         fromwp_lat = get_latitude()*SGD_DEGREES_TO_RADIANS;
639         towp_lon = get_aux2()*SGD_DEGREES_TO_RADIANS;
640         towp_lat = get_aux1()*SGD_DEGREES_TO_RADIANS;
641
642         dist = acos(sin(fromwp_lat)*sin(towp_lat)+cos(fromwp_lat)*cos(towp_lat)*cos(fabs(fromwp_lon-towp_lon)));
643         delx= towp_lat - fromwp_lat;
644         dely = towp_lon - fromwp_lon;
645         hyp = sqrt(pow(delx,2)+pow(dely,2));
646
647         if (hyp != 0)
648             theta = asin(dely/hyp);
649         else
650             theta = 0.0;
651
652         brg = theta*SGD_RADIANS_TO_DEGREES;
653         if (brg > 360.0)
654             brg = 0.0;
655         if (delx < 0)
656             brg = 180 - brg;
657
658         // {Brg  = asin(cos(towp_lat)*sin(fabs(fromwp_lon-towp_lon))/ sin(dist));
659         // Brg = Brg * SGD_RADIANS_TO_DEGREES; }
660
661         dist = dist*SGD_RADIANS_TO_DEGREES * 60.0*1852.0; //rad->deg->nm->m
662         // end waypoint marker computation
663
664         //*********************************************************
665         // OBJECT MOVING RETICLE
666         // TYPE ARROW
667         // waypoint marker
668         if (fabs(brg-psi) > 10.0) {
669             glPushMatrix();
670             glTranslatef( centroid.x, centroid.y, 0);
671             glTranslatef( vel_x, vel_y, 0);
672             glRotatef(brg - psi,0.0,0.0,-1.0);
673             glBegin(GL_LINE_LOOP);
674             glVertex2f(-2.5,20.0);
675             glVertex2f(-2.5,30.0);
676             glVertex2f(-5.0,30.0);
677             glVertex2f(0.0,35.0);
678             glVertex2f(5.0,30.0);
679             glVertex2f(2.5,30.0);
680             glVertex2f(2.5,20.0);
681             glEnd();
682             glPopMatrix();
683         }
684
685         // waypoint marker on heading scale
686         if (fabs(brg-psi) < 12.0) {
687             if (hat == 0) {
688                 glBegin(GL_LINE_LOOP);
689                 glVertex2f(((brg-psi)*60/25)+320,240.0);
690                 glVertex2f(((brg-psi)*60/25)+326,240.0-4);
691                 glVertex2f(((brg-psi)*60/25)+323,240.0-4);
692                 glVertex2f(((brg-psi)*60/25)+323,240.0-8);
693                 glVertex2f(((brg-psi)*60/25)+317,240.0-8);
694                 glVertex2f(((brg-psi)*60/25)+317,240.0-4);
695                 glVertex2f(((brg-psi)*60/25)+314,240.0-4);
696                 glEnd();
697
698             } else { //if hat=0
699                 float x = (brg-psi)*60/25 + 320, y = 240.0, r = 5.0;
700                 float x1,y1;
701
702                 glEnable(GL_POINT_SMOOTH);
703                 glBegin(GL_POINTS);
704
705                 for (int count = 0; count <= 200; count++) {
706                     float temp = count * 3.142 * 3 / (200.0*2.0);
707                     float temp1 = temp-(45.0*SGD_DEGREES_TO_RADIANS);
708                     x1 = x + r * cos(temp1);
709                     y1 = y + r * sin(temp1);
710                     glVertex2f(x1, y1);
711                 }
712
713                 glEnd();
714                 glDisable(GL_POINT_SMOOTH);
715             } //hat=0
716
717          } //brg<12
718      } // if waypoint_marker
719 #endif
720 }//draw
721
722
723 /******************************************************************/
724 //  draws the zenith symbol  for highest possible climb angle (i,e 90 degree climb angle)
725 //
726 void HudLadder::drawZenith(float xfirst,float xlast,float yvalue)
727 {
728     float xcentre = (xfirst + xlast)/2.0;
729     float ycentre = yvalue;
730
731     Line(xcentre-9.0, ycentre, xcentre-3.0, ycentre+1.3);
732     Line(xcentre-9.0, ycentre, xcentre-3.0, ycentre-1.3);
733
734     Line(xcentre+9.0, ycentre, xcentre+3.0, ycentre+1.3);
735     Line(xcentre+9.0, ycentre, xcentre+3.0, ycentre-1.3);
736
737     Line(xcentre, ycentre+9.0, xcentre-1.3, ycentre+3.0);
738     Line(xcentre, ycentre+9.0, xcentre+1.3, ycentre+3.0);
739
740     Line(xcentre-3.9, ycentre+3.9, xcentre-3.0, ycentre+1.3);
741     Line(xcentre-3.9, ycentre+3.9, xcentre-1.3, ycentre+3.0);
742
743     Line(xcentre+3.9, ycentre+3.9, xcentre+1.3, ycentre+3.0);
744     Line(xcentre+3.9, ycentre+3.9, xcentre+3.0, ycentre+1.3);
745
746     Line(xcentre-3.9, ycentre-3.9, xcentre-3.0, ycentre-1.3);
747     Line(xcentre-3.9, ycentre-3.9, xcentre-1.3, ycentre-2.6);
748
749     Line(xcentre+3.9, ycentre-3.9, xcentre+3.0, ycentre-1.3);
750     Line(xcentre+3.9, ycentre-3.9, xcentre+1.3, ycentre-2.6);
751
752     Line(xcentre-1.3, ycentre-2.6, xcentre, ycentre-27.0);
753     Line(xcentre+1.3, ycentre-2.6, xcentre, ycentre-27.0);
754 }
755
756
757 //  draws the nadir symbol  for lowest possible dive angle (i,e 90 degree dive angle)
758 //
759 void HudLadder::drawNadir(float xfirst, float xlast, float yvalue)
760 {
761     float xcentre = (xfirst + xlast)/2.0;
762     float ycentre = yvalue;
763
764     float r = 7.5;
765     float x1,y1,x2,y2;
766
767     // to draw a circle
768     float xcent1, xcent2, ycent1, ycent2;
769     xcent1 = xcentre + r * cos(0.0);
770     ycent1 = ycentre + r * sin(0.0);
771
772     for (int count=1; count<=400; count++) {
773         float temp = count * 2 * 3.142 / 400.0;
774         xcent2 = xcentre + r * cos(temp);
775         ycent2 = ycentre + r * sin(temp);
776
777         Line(xcent1, ycent1, xcent2, ycent2);
778
779         xcent1 = xcent2;
780         ycent1 = ycent2;
781     }
782
783     xcent2 = xcentre + r * cos(0.0);
784     ycent2 = ycentre + r * sin(0.0);
785
786     drawOneLine(xcent1, ycent1, xcent2, ycent2); //to connect last point to first point
787     //end circle
788
789     Line(xcentre, ycentre+7.5, xcentre, ycentre+22.5); //to draw a line above the circle
790
791     Line(xcentre-7.5, ycentre, xcentre+7.5,ycentre); //line in the middle of circle
792
793     float theta = asin (2.5/7.5);
794     float theta1 = asin(5.0/7.5);
795
796     x1 = xcentre + r * cos(theta);
797     y1 = ycentre + 2.5;
798     x2 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) - theta);
799     y2 = ycentre + 2.5;
800     Line(x1,y1,x2,y2);
801
802     x1 = xcentre + r * cos(theta1);
803     y1 = ycentre + 5.0;
804     x2 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS)-theta1);
805     y2 = ycentre + 5.0;
806     Line(x1,y1,x2,y2);
807
808     x1 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) +theta);
809     y1 = ycentre - 2.5;
810     x2 = xcentre + r * cos((360.0* SGD_DEGREES_TO_RADIANS)-theta);
811     y2 = ycentre - 2.5;
812     Line(x1,y1,x2,y2);
813
814     x1 = xcentre + r * cos((180.0* SGD_DEGREES_TO_RADIANS) +theta1);
815     y1 = ycentre - 5.0;
816     x2 = xcentre + r * cos((360.0* SGD_DEGREES_TO_RADIANS)-theta1);
817     y2 = ycentre - 5.0;
818     Line(x1,y1,x2,y2);
819 }
820
821