Former-commit-id:4bfbdad17d
[formerly9f8cb727a5
] [formerly4bfbdad17d
[formerly9f8cb727a5
] [formerly8485b90ff8
[formerly bf53d06834caa780226121334ac1bcf0534c3f16]]] Former-commit-id:8485b90ff8
Former-commit-id:33a67cdd82
[formerlya28d70b5c5
] Former-commit-id:e5543a0e86
2557 lines
80 KiB
C
2557 lines
80 KiB
C
/***************************************************************/
|
|
/* SHARP-95 */
|
|
/* Advanced Interactive Sounding Analysis Program */
|
|
/* */
|
|
/* XW Video Graphics Routines (Part #1) */
|
|
/* These are the routines that pertain specifically to */
|
|
/* representing the Skew/t and Hodograph on the screen. */
|
|
/* */
|
|
/* John A. Hart */
|
|
/* National Severe Storms Forecast Center */
|
|
/* Kansas City, Missouri */
|
|
/* -------------------------------------------------- */
|
|
/* List of Routines in this module: */
|
|
/* */
|
|
/* MAKE_SCREEN */
|
|
/* DRAW_SKEWT */
|
|
/* DRAW_HODO */
|
|
/* HODO_TO_PIX */
|
|
/* PIX_TO_HODO */
|
|
/* TRACE_HODO */
|
|
/* DRY_ADIABAT */
|
|
/* ISOTHERM */
|
|
/* HIGHLIGHT_MINUS20 */
|
|
/* ISOBAR */
|
|
/* TRACE_TEMP */
|
|
/* TRACE_VTMP */
|
|
/* TRACE_DWPT */
|
|
/* TRACE_WETBULB */
|
|
/* PRES_TO_PIX */
|
|
/* PIX_TO_PRES */
|
|
/* TEMP_TO_PIX */
|
|
/* PIX_TO_TEMP */
|
|
/* TRACE_PARCEL */
|
|
/* WIND_BARB */
|
|
/* PLOT_BARBS */
|
|
/* */
|
|
/***************************************************************/
|
|
#define GLOBAL
|
|
#define VIDEO
|
|
//#include "xwcmn.h"
|
|
#include "sharp95.h"
|
|
|
|
/*
|
|
* Global vars
|
|
*
|
|
* These are all of the global XW related vars from globals_xw.h
|
|
*/
|
|
|
|
short drawing_mode;
|
|
short display_mode_left;
|
|
short display_mode_right;
|
|
short inset_mode;
|
|
short hodo_mode;
|
|
short auto_mode;
|
|
|
|
int xwdth, xhght, xdpth;
|
|
int raob_mod;
|
|
|
|
#ifndef _WIN32
|
|
Pixel pixels[40]; /* for colors */
|
|
GC gc;
|
|
Widget draw_reg;
|
|
Pixmap canvas;
|
|
XtAppContext app;
|
|
#endif
|
|
|
|
short pagenum = 1;
|
|
short overlay_previous;
|
|
short inset_previous;
|
|
|
|
struct _skewt skv = { 40, 25, 500, 500, 100, 70, 60, 1};
|
|
/*struct _hodog hov = { 40, 675, 350, 1025, -20, -20, 100, 10}; */
|
|
struct _hodog hov = { 40, 675, 350, 1025, 0, 0, 120, 10};
|
|
struct _stpinset stv = { 720, 520, 1080, 790, 0};
|
|
struct _startup autostart;
|
|
#ifndef _WIN32
|
|
typedef struct { /* for drawing moving crosshairs or zoom boxes */
|
|
int start_x, start_y,
|
|
last_x, last_y;
|
|
GC gc;
|
|
XPoint points[4];
|
|
int itype; /* 0 = temp 1 = dwpt */
|
|
int ilev; /* 0 = bottom 1 = top 2 = inbetween */
|
|
short yy, i;
|
|
} rubber_band_data;
|
|
|
|
rubber_band_data rbdata;
|
|
#endif
|
|
|
|
/* mkay added functions */
|
|
void mixratline(float val);
|
|
int GetWindSpeedColor(float speed);
|
|
void display_levels(short colr);
|
|
void display_effective_layer(short colr);
|
|
|
|
/*NP*/
|
|
#ifndef _WIN32
|
|
void make_screen(int argc, char *argv[])
|
|
/*************************************************************/
|
|
/* MAKE_SCREEN */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws basic SHARP graphic template on screen, including */
|
|
/* areas, buttons, and tables. */
|
|
/* */
|
|
/*************************************************************/
|
|
{
|
|
char st[80];
|
|
|
|
/* in xwvid6.c */
|
|
X_Init(argc, argv);
|
|
|
|
/* ----- Parameter Area ----- */
|
|
setlinestyle(1, 2);
|
|
setcolor(24);
|
|
rectangle(1, skv.tlx, skv.bry + 25, hov.brx, xhght - 10);
|
|
setcolor(1);
|
|
rectangle(0, skv.tlx, skv.bry + 25, hov.brx, xhght - 10);
|
|
|
|
/* ----- Begin Main Processing Loop ----- */
|
|
set_font(2);
|
|
XtAppMainLoop(app);
|
|
}
|
|
|
|
void draw_skewt(void)
|
|
/*************************************************************/
|
|
/* DRAW_SKEWT */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws a standard Skew-T/LogP diagram. */
|
|
/*************************************************************/
|
|
{
|
|
FILE *fp1;
|
|
short i, pIndex, dIndex, tIndex;
|
|
/* short x, y1, y2; */
|
|
float a, thta, ix1, ix2, ix3, ix4;
|
|
float lvl[] = {1050,1000,850,700,500,300,200,100};
|
|
float sfcpres, sfctemp, sfcdwpt;
|
|
char rtitle[80], st[80];
|
|
HistElmt *he;
|
|
Sounding *cursndg=NULL, *prevsndg=NULL;
|
|
Parcel pcl;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tIndex = getParmIndex("TEMP");
|
|
dIndex = getParmIndex("DWPT");
|
|
|
|
printf("Current Parcel: %d\n", lplvals.flag);
|
|
|
|
/* commented out 10/25/06 by RLT */
|
|
/*if (numlvl>5)
|
|
{*/
|
|
/* Here are a few parameters that are listed in the text screen
|
|
for various people in the SPC */
|
|
/*uncapped_cape(&ix1, &ix2, -50);
|
|
sfctemp = lplvals.temp;
|
|
sfcdwpt = lplvals.dwpt;
|
|
sfcpres = lplvals.pres;
|
|
ix1 = parcel( -1, -1, sfcpres, sfctemp, sfcdwpt, &pcl);
|
|
|
|
fp1 = fopen("/tmp/GLDJPR.txt","wt");
|
|
fprintf( fp1, "-------------------------------------\n");
|
|
fprintf( fp1, "%s (%s)\n", raobtitle, raob_type);
|
|
fprintf( fp1, "-------------------------------------\n");
|
|
printf( "-------------------------------------\n");
|
|
ix2 = mean_relhum(&ix1, sndg[sfc()][pIndex], 850);
|
|
fprintf( fp1, "1. Sfc-850mb RH: %3.0f %\n", ix2);
|
|
printf( "1. Sfc-850mb RH: %3.0f %\n", ix2);
|
|
ix2 = mean_relhum(&ix1, 850, 700);
|
|
fprintf( fp1, "2. 850-700mb RH: %3.0f %\n", ix2);
|
|
printf( "2. 850-700mb RH: %3.0f %\n", ix2);
|
|
ix2 = mean_relhum(&ix1, 700, 500);
|
|
fprintf( fp1, "3. 700-500mb RH: %3.0f %\n", ix2);
|
|
printf( "3. 700-500mb RH: %3.0f %\n", ix2);
|
|
strcpy( st, qc2( lapse_rate( &ix1, sndg[sfc()][pIndex], 850 ), " C/km", 1 ));
|
|
fprintf( fp1, "4. Sfc-850mb Lapse Rate: %s\n", st);
|
|
printf( "4. Sfc-850mb Lapse Rate: %s\n", st);
|
|
wind_shear(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "5. Sfc-6km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "5. Sfc-6km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
wind_shear(i_pres(msl(2000)), i_pres(msl(8000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "6. 2km-8km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "6. 2km-8km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
wind_shear(sndg[sfc()][pIndex], i_pres(msl(2000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "7. Sfc-2km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "7. Sfc-2km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
wind_shear(i_pres(msl(1500)), i_pres(msl(8000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "8. 1.5km-8km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "8. 1.5km-8km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
ix4 = helicity(0, msl(2000), st_dir, st_spd, &ix1, &ix2);
|
|
fprintf( fp1, "9. Sfc-2km AGL SR Helicity: %3.0f m2/s2\n", ix4);
|
|
printf( "9. Sfc-2km AGL SR Helicity: %3.0f m2/s2\n", ix4);
|
|
mean_wind( sndg[sfc()][pIndex], i_pres(msl(2000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "10. Sfc-2km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "10. Sfc-2km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
mean_wind( i_pres(msl(2000)), i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "11. 2km-6km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "11. 2km-6km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
mean_wind( i_pres(msl(9000)), i_pres(msl(11000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "12. 9km-11km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "12. 9km-11km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
wind_shear(i_pres(msl(2000)), i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "13. 2km-6km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "13. 2km-6km AGL Shear Vector: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
mean_wind( i_pres(msl(2000)), i_pres(msl(8000)), &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "14. 2km-8km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "14. 2km-8km AGL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
mean_wind( pcl.lfcpres, pcl.elpres, &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "15. LFC-EL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "15. LFC-EL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
mean_wind( pcl.lclpres, pcl.elpres, &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "16. LCL-EL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "16. LCL-EL Mean Wind: %3.0f/ %.0f kt\n", ix3, ix4);
|
|
wind_shear( pcl.lfcpres, pcl.elpres, &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "17. LFC-EL Shear Vector %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "17. LFC-EL Shear Vector %3.0f/ %.0f kt\n", ix3, ix4);
|
|
wind_shear( pcl.lclpres, pcl.elpres, &ix1, &ix2, &ix3, &ix4);
|
|
fprintf( fp1, "18. LCL-EL Shear Vector %3.0f/ %.0f kt\n", ix3, ix4);
|
|
printf( "18. LCL-EL Shear Vector %3.0f/ %.0f kt\n", ix3, ix4);
|
|
fprintf( fp1, "-------------------------------------\n");
|
|
printf( "-------------------------------------\n");
|
|
fclose(fp1);*/
|
|
/* sfctemp = lplvals.temp;
|
|
sfcdwpt = lplvals.dwpt;
|
|
sfcpres = lplvals.pres; */
|
|
|
|
/* ----- Calculate Parcel Data ----- */
|
|
/*ix1 = parcel( -1, -1, sfcpres, sfctemp, sfcdwpt, &pcl);
|
|
hailgrowth(&ix4); */
|
|
/* printf( "1. PM Hail Aloft: %.1f cm\n", ix4);
|
|
printf( "2. SBCAPE (J/kg): %.0f J/kg\n", pcl.bplus);
|
|
printf( "3. SBCINH (J/kg): %.0f J/kg\n", pcl.bminus);
|
|
wind_shear(850, 500, &ix1, &ix2, &ix3, &ix4);
|
|
printf( "4. 850-500mb Shear: %.1f m/s\n", kt_to_mps(ix4));
|
|
wind_shear(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
printf( "5. Sfc-6km Shear: %.1f m/s\n", kt_to_mps(ix4));
|
|
wind_shear(-1, i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
printf( "6. Low-6km Shear: %.1f m/s\n", kt_to_mps(ix4));
|
|
mean_wind(sndg[sfc()][pIndex], i_pres(msl(1000)), &ix1, &ix2, &ix3, &ix4);
|
|
printf( "7. Sfc-1km Mean Wind: %.1f m/s\n", kt_to_mps(ix4));
|
|
sr_wind(sndg[sfc()][pIndex], i_pres(msl(1000)), st_dir, st_spd, &ix1, &ix2, &ix3, &ix4);
|
|
printf( "8. Sfc-1km SR Wind: %.1f m/s\n", kt_to_mps(ix4));
|
|
sr_wind(sndg[sfc()][pIndex], i_pres(msl(2000)), st_dir, st_spd, &ix1, &ix2, &ix3, &ix4);
|
|
printf( "9. Sfc-2km SR Wind: %.1f m/s\n", kt_to_mps(ix4));
|
|
ix4 = helicity(0, msl(3000), st_dir, st_spd, &ix1, &ix2);
|
|
printf( "10. Sfc-3km SR Helicity: %.0f m2/s2\n", ix4);
|
|
strcpy( st, qc2( ehi(pcl.bplus, ix4), "" , 1));
|
|
printf( "11. EHI: %s\n", st);
|
|
strcpy( st, qc2( scp(st_dir, st_spd), "", 1 ));
|
|
printf( "12. SCP: %s\n", st);
|
|
ix4 = sndg[sfc()][dIndex] - i_temp(500, I_PRES);
|
|
printf( "13. sfc Td - 500 T: %.1f c\n", ix4);
|
|
strcpy( st, qc2( agl(i_hght(temp_lvl( 0, &ix1 ), I_PRES)), "m", 0 ));
|
|
printf( "14. Freezing Level: %s\n", st);
|
|
strcpy( st, qc2( agl(i_hght(wb_lvl( 0, &ix1 ), I_PRES)), "m", 0 ));
|
|
printf( "15. Wet Bulb Zero: %s\n", st);
|
|
strcpy( st, qc2( lapse_rate( &ix1, 700, 500 ), " C/km", 1 ));
|
|
printf( "16. 700-500mb Lapse Rate: %s\n", st);
|
|
printf( "17. 300mb Temp : %.1f C\n", i_temp(300, I_PRES));
|
|
strcpy( st, qc2( lapse_rate( &ix1, 500, 300 ), " C/km", 1 ));
|
|
printf( "18. 500-300mb Lapse Rate: %s\n", st);
|
|
printf( "-------------------------------------\n\n\n\n");
|
|
*/
|
|
/* }*/
|
|
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
setcolor(0);
|
|
rectangle(1, 1, 1, skv.brx, skv.bry+15);
|
|
setcolor(1);
|
|
set_font(3);
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
setlinestyle(1, 1);
|
|
rectangle(0, skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
|
|
/* ----- Draw Skewed Temperature Lines ----- */
|
|
setlinestyle(2, 1);
|
|
for( i=-160; i<=50; i=i+10 ) { isotherm(i, 24); }
|
|
isotherm(0, 26);
|
|
|
|
/* ----- Draw Dry Adiabats ----- */
|
|
setcolor(24);
|
|
setlinestyle(1, 1);
|
|
for (thta=-70; thta<=350; thta=thta+20)
|
|
dry_adiabat(thta);
|
|
|
|
/* ----- Draw Mixing Ratio Lines ----- */
|
|
setcolor(23);
|
|
setlinestyle(3, 1);
|
|
/* First draw from 0.2 g/kg to 1.0 g/kg */
|
|
/*for (a=0.2;a<=1.0;a+=0.2)
|
|
mixratline(a); */
|
|
/* Next draw from 2 g/kg to 30.0(!) g/kg */
|
|
for (a=1.0;a<=30.0;a+=4.0)
|
|
mixratline(a);
|
|
|
|
/* ----- Draw Horizontal Pressure Lines ----- */
|
|
setcolor(1);
|
|
setlinestyle(1, 1);
|
|
for(i=1; i<8; i++)
|
|
isobar(lvl[i], 0);
|
|
for(i=100; i<=1050; i=i+50)
|
|
isobar((float)i, 1);
|
|
|
|
#define HISTORY
|
|
#ifdef HISTORY
|
|
/* ----- Plot old sounding if exists ----- */
|
|
if (overlay_previous == 1) {
|
|
cursndg = getGlobalSounding();
|
|
he = history_first(&hist);
|
|
if (he)
|
|
he = history_next(he);
|
|
if (he) {
|
|
prevsndg = (Sounding *)history_data(he);
|
|
if (prevsndg) {
|
|
changeGlobalSounding(prevsndg);
|
|
if (sndg && (numlvl > 0)) {
|
|
/* setcolor(28); */
|
|
trace_temp(3, 28);
|
|
/* setcolor(28); */
|
|
trace_dwpt(3, 28);
|
|
setcolor(28);
|
|
plot_barbs2();
|
|
display_effective_layer(28);
|
|
}
|
|
}
|
|
}
|
|
/* Reset sounding */
|
|
changeGlobalSounding(cursndg);
|
|
}
|
|
#endif
|
|
|
|
/* ----- Plot Environmental Temperature Data ----- */
|
|
setcolor(2);
|
|
if (numlvl > 2)
|
|
trace_temp(3, 2);
|
|
|
|
if (numlvl > 2)
|
|
highlight_temp(-20, 26);
|
|
|
|
/* ----- Plot Environmental Dew Point Data ----- */
|
|
/* setcolor(3); */
|
|
if (numlvl > 2)
|
|
trace_dwpt(3, 3);
|
|
|
|
/* ----- Plot Environmental Virtual Temperature Data ----- */
|
|
setcolor(2);
|
|
if (numlvl > 2)
|
|
trace_vtmp(2);
|
|
|
|
/* ----- Plot Environmental Wetbulb Temperature Data ----- */
|
|
setcolor(6);
|
|
setlinestyle(1, 1);
|
|
if (numlvl > 2)
|
|
trace_wetbulb(1);
|
|
|
|
/* ----- Plot Wind Barbs ----- */
|
|
/* setcolor(0);
|
|
rectangle(1, skv.brx-52, skv.tly+1, skv.brx-1, skv.bry);
|
|
*/ setcolor(31);
|
|
setlinestyle(1, 1);
|
|
if (numlvl > 2)
|
|
plot_barbs();
|
|
|
|
/* ----- If Available, plot VVEL profile ----- */
|
|
if (numlvl > 2)
|
|
vvel_profile();
|
|
|
|
/* ----- Display Skew-T Inset ----- */
|
|
draw_skinset();
|
|
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
setcolor(1);
|
|
set_font(1);
|
|
if (*raobtitle)
|
|
sprintf(rtitle, "%s (%s)", raobtitle, raob_type);
|
|
else
|
|
strcpy(rtitle, " ");
|
|
outgtext(rtitle, skv.tlx, 1);
|
|
|
|
/* Add title for previous sounding */
|
|
if (overlay_previous == 1) {
|
|
setcolor(28);
|
|
if (*raobtitle2)
|
|
sprintf(rtitle, "%s (%s)", raobtitle2, raob_type2);
|
|
else
|
|
strcpy(rtitle, " ");
|
|
outgtext(rtitle, skv.brx - getgtextextent(rtitle), 1);
|
|
}
|
|
|
|
copytodisplay();
|
|
}
|
|
|
|
/*NP*/
|
|
void draw_hodo(void)
|
|
/*************************************************************/
|
|
/* DRAW_HODO */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws a standard Hodograph display. */
|
|
/*************************************************************/
|
|
{
|
|
short x1, y1, x2, y2, i, y3;
|
|
short pIndex;
|
|
float wdir, wspd, mnu, mnv, ix1, ix2, ix3, ix4, ix5, ix6, ix7, ix8;
|
|
float uref, vref, dd, ss;
|
|
char st[20], rtitle[80];
|
|
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
|
|
setcolor(0);
|
|
rectangle( 1, hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
|
|
setcolor(1);
|
|
setlinestyle(1, 1);
|
|
rectangle(0, hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
|
|
setcliprgn(hov.tlx+2, hov.tly+1, hov.brx-3, hov.bry-3);
|
|
/*setcliprgn(hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
setcolor(1);
|
|
setlinestyle(1, 1);
|
|
rectangle(0, hov.tlx, hov.tly, hov.brx, hov.bry);*/
|
|
|
|
/* ----- Plot crosshairs ----- */
|
|
setcolor(31);
|
|
hodo_to_pix(180, 60, &x1, &y1);
|
|
moveto(x1, hov.tly);
|
|
lineto(x1, hov.bry);
|
|
|
|
setcolor(31);
|
|
hodo_to_pix(270, 60, &x1, &y1);
|
|
moveto(hov.tlx, y1);
|
|
lineto(hov.brx, y1);
|
|
|
|
/* ----- Plot Radius circles ----- */
|
|
setcolor(24);
|
|
setlinestyle(2, 1);
|
|
hodo_to_pix(0, 0, &x1, &y1);
|
|
x2 = x1;
|
|
y2 = y1;
|
|
for(i = hov.scale; i <= hov.hodomag; i = i + hov.scale) {
|
|
hodo_to_pix(0, (float)i, &x1, &y1);
|
|
y3 = (y1 - y2);
|
|
ellipse(0, x2-y3, y2-y3, x2+y3, y2+y3);
|
|
}
|
|
|
|
setcolor(1);
|
|
set_font(3);
|
|
|
|
/* ----- Plot X-Coord hash marks ----- */
|
|
for(i = hov.scale; i <= hov.hodomag; i = i + hov.scale) {
|
|
hodo_to_pix(180, (float)i, &x1, &y1);
|
|
moveto(x1-3, y1);
|
|
lineto(x1+3, y1);
|
|
itoa(i, st, 10);
|
|
outgtext(st, x1 - getgtextextent(st) - 4, y1 - 5);
|
|
|
|
hodo_to_pix(360, (float)i, &x1, &y1);
|
|
moveto(x1-3, y1);
|
|
lineto(x1+3, y1);
|
|
itoa(i, st, 10);
|
|
outgtext(st, x1 - getgtextextent(st) - 4, y1 - 5);
|
|
}
|
|
|
|
/* ----- Plot Y-Coord hash marks ----- */
|
|
setcolor(1);
|
|
for (i = hov.scale; i <= hov.hodomag; i = i + hov.scale) {
|
|
hodo_to_pix(90, (float)i, &x1, &y1);
|
|
moveto(x1, y1-3);
|
|
lineto(x1, y1+3);
|
|
itoa(i, st, 10);
|
|
outgtext(st, x1 - (getgtextextent(st) / 2), y1 + 5);
|
|
|
|
hodo_to_pix(270, (float)i, &x1, &y1);
|
|
moveto(x1, y1-3);
|
|
lineto(x1, y1+3);
|
|
itoa(i, st, 10);
|
|
outgtext(st, x1 - (getgtextextent(st) / 2), y1 + 5);
|
|
}
|
|
|
|
/* ----- Plot Hodograph (Shear Vectors) ----- */
|
|
setcolor(2);
|
|
setlinestyle(1,2);
|
|
if (numlvl > 0) {
|
|
trace_hodo(3);
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
|
|
if ((hodo_mode == HODO_NORMAL) || (hodo_mode == HODO_MEANWIND) || (hodo_mode == HODO_BNDRY)) {
|
|
/* ----- Plot Mean Wind Vector ----- */
|
|
setcolor(5);
|
|
set_font(3);
|
|
mean_wind( -1, -1, &mnu, &mnv, &wdir, &wspd);
|
|
hodo_to_pix( wdir, wspd, &x1, &y1);
|
|
moveto(x1, y1);
|
|
rectangle(0, x1-4, y1-4, x1+4, y1+4);
|
|
sprintf( st, "%.0f/%.0f MW", wdir, wspd);
|
|
outgtext(st, x1-2, y1+7);
|
|
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
/* printf("draw_hodo: pIndex = %d\n", pIndex);
|
|
|
|
if (sndg && pIndex != -1) {
|
|
*/ mean_wind(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
/* ----- Plot 30/75 Storm Motion Vector ----- */
|
|
if (hodo_mode == HODO_STORMRELATIVE) {
|
|
uref = ix1 - ucomp(st_dir, st_spd);
|
|
vref = ix2 - vcomp(st_dir, st_spd);
|
|
dd = angle(uref,vref);
|
|
ss = speed(uref,vref); }
|
|
else {
|
|
dd = ix3;
|
|
ss = ix4; }
|
|
|
|
/* printf("mean wind is from %.1f at %.1f kt\n", dd, ss);
|
|
*/ setcolor(11);
|
|
setlinestyle(1, 1);
|
|
ss *= .75;
|
|
dd += 30;
|
|
if(dd>360) dd -= 360;
|
|
hodo_to_pix(dd, ss, &x1, &y1);
|
|
moveto(x1-3, y1); lineto(x1+3, y1);
|
|
moveto(x1, y1-3); lineto(x1, y1+3);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
|
|
|
|
mean_wind(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2,
|
|
&ix3, &ix4);
|
|
setcolor(12);
|
|
setlinestyle(1, 1);
|
|
ix4 *= .85;
|
|
ix3 += 15;
|
|
if(ix3>360) ix3 -= 360;
|
|
hodo_to_pix( ix3, ix4, &x1, &y1);
|
|
moveto(x1-3, y1); lineto(x1+3, y1);
|
|
moveto(x1, y1-3); lineto(x1, y1+3);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
/* }
|
|
*/
|
|
|
|
|
|
/* ----- Plot Current Storm Motion Vector ----- */
|
|
setcolor(31);
|
|
setlinestyle(1, 1);
|
|
set_font(5);
|
|
hodo_to_pix(st_dir, st_spd, &x1, &y1);
|
|
moveto(x1-6, y1); lineto(x1+6, y1);
|
|
moveto(x1, y1-6); lineto(x1, y1+6);
|
|
ellipse(0, x1-6, y1-6, x1+6, y1+6);
|
|
sprintf( st, "%.0f/%.0f", st_dir, st_spd);
|
|
outgtext(st, x1-2, y1+7);
|
|
|
|
/* ----- Plot Bunkers RIGHT Storm Motion Vector ----- */
|
|
bunkers_storm_motion(&ix1, &ix2, &ix3, &ix4);
|
|
/* printf("\n pre plot dir = %0f\n", ix3);
|
|
printf("\n pre plot spd = %0f\n", ix4);
|
|
*/ setcolor(15);
|
|
setlinestyle(1, 1);
|
|
set_font(5);
|
|
hodo_to_pix(ix3, ix4, &x1, &y1);
|
|
moveto(x1-5, y1); lineto(x1+5, y1);
|
|
moveto(x1, y1-5); lineto(x1, y1+5);
|
|
ellipse(0, x1-5, y1-5, x1+5, y1+5);
|
|
sprintf( st, "%.0f/%.0f RM", ix3, ix4);
|
|
outgtext(st, x1-2, y1+7);
|
|
|
|
/* ----- Plot Bunkers LEFT Storm Motion Vector ----- */
|
|
bunkers_left_motion(&ix1, &ix2, &ix3, &ix4);
|
|
setcolor(26);
|
|
setlinestyle(1, 1);
|
|
set_font(5);
|
|
hodo_to_pix(ix3, ix4, &x1, &y1);
|
|
moveto(x1-5, y1); lineto(x1+5, y1);
|
|
moveto(x1, y1-5); lineto(x1, y1+5);
|
|
ellipse(0, x1-5, y1-5, x1+5, y1+5);
|
|
sprintf( st, "%.0f/%.0f LM", ix3, ix4);
|
|
outgtext(st, x1-2, y1+7);
|
|
}
|
|
|
|
|
|
/* ----- Plot Corfidi Vectors ----- */
|
|
/* corfidi_MCS_motion(&ix1, &ix2, &ix3, &ix4, &ix5, &ix6, &ix7, &ix8);
|
|
setcolor(25);
|
|
set_font(5);
|
|
hodo_to_pix(ix3, ix4, &x1, &y1);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
sprintf( st, "DP=%.0f/%.0f", ix3, ix4);
|
|
outgtext(st, x1-2, y1+7);
|
|
|
|
hodo_to_pix(ix7, ix8, &x1, &y1);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
sprintf( st, "UP=%.0f/%.0f", ix7, ix8);
|
|
outgtext(st, x1-2, y1+7);
|
|
*/
|
|
|
|
/* ----- Draw final outline of hodograph ----- */
|
|
setcolor(1);
|
|
setlinestyle(1, 1);
|
|
rectangle(0, hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
setcolor(1);
|
|
set_font(1);
|
|
outgtext(raobtitle, skv.tlx, 1);
|
|
|
|
/* Add title for previous sounding */
|
|
if (overlay_previous == 1) {
|
|
setcolor(28);
|
|
if (*raobtitle2)
|
|
sprintf(rtitle, "%s (%s)", raobtitle2, raob_type2);
|
|
else
|
|
strcpy(rtitle, " ");
|
|
outgtext(rtitle, skv.brx - getgtextextent(rtitle), 1);
|
|
}
|
|
|
|
if (hodo_mode == HODO_BNDRY) { trace_bndry(bd_dir, bd_spd); }
|
|
trace_esrh();
|
|
|
|
/* Draw mode buttons on hodograph */
|
|
set_font(4);
|
|
x1 = hov.tlx;
|
|
y1 = hov.tly;
|
|
sprintf( st, "NORMAL");
|
|
setcolor(26);
|
|
if (hodo_mode == HODO_NORMAL) setcolor(1);
|
|
outgtext( st, x1+4, y1+4);
|
|
rectangle(0, x1, y1, x1+68, y1+18);
|
|
|
|
sprintf( st, "STORMREL");
|
|
setcolor(26);
|
|
if (hodo_mode == HODO_STORMRELATIVE) setcolor(1);
|
|
outgtext( st, x1+4, y1+22);
|
|
rectangle(0, x1, y1+19, x1+68, y1+37);
|
|
|
|
/*sprintf( st, "EFFECTIVE");
|
|
setcolor(24);
|
|
if (hodo_mode == HODO_EFFECTIVE) setcolor(1);
|
|
outgtext( st, x1, y1+22);
|
|
rectangle(0, x1-1, y1+21, x1+50, y1+30);*/
|
|
|
|
/* 4jan07 */
|
|
sprintf( st, "MEAN WIND");
|
|
setcolor(26);
|
|
if (hodo_mode == HODO_MEANWIND) setcolor(1);
|
|
outgtext( st, x1+4, y1+40);
|
|
rectangle(0, x1, y1+37, x1+68, y1+55);
|
|
/*outgtext( st, x1, y1+33);
|
|
rectangle(0, x1-1, y1+32, x1+50, y1+41);*/
|
|
|
|
copytodisplay();
|
|
|
|
/* do not plot motion vectors below if boundary motion entered by user */
|
|
if ((hodo_mode == HODO_BNDRY) || (hodo_mode == HODO_STORMRELATIVE)) {
|
|
return; }
|
|
else {
|
|
|
|
/* ----- Plot Corfidi Vectors ----- */
|
|
corfidi_MCS_motion(&ix1, &ix2, &ix3, &ix4, &ix5, &ix6, &ix7, &ix8);
|
|
setcolor(25);
|
|
set_font(5);
|
|
hodo_to_pix(ix3, ix4, &x1, &y1);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
sprintf( st, "DP=%.0f/%.0f", ix3, ix4);
|
|
outgtext(st, x1-32, y1+7);
|
|
|
|
hodo_to_pix(ix7, ix8, &x1, &y1);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
sprintf( st, "UP=%.0f/%.0f", ix7, ix8);
|
|
outgtext(st, x1-2, y1+7);
|
|
|
|
/* ----- Plot 30R75 Storm Motion Vector ----- */
|
|
/* printf("mean_wind1: pIndex = %d\n", pIndex);
|
|
if (sndg && pIndex != -1) {
|
|
*/ mean_wind(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
setcolor(11);
|
|
setlinestyle(1, 1);
|
|
ix4 *= .75;
|
|
ix3 += 30;
|
|
if(dd>360) dd -= 360;
|
|
hodo_to_pix(dd, ss, &x1, &y1);
|
|
moveto(x1-3, y1); lineto(x1+3, y1);
|
|
moveto(x1, y1-3); lineto(x1, y1+3);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
/* }
|
|
*/
|
|
/* ----- Plot 15R85 Storm Motion Vector ----- */
|
|
/* printf("mean_wind2: pIndex = %d\n", pIndex);
|
|
if (sndg && pIndex != -1) {
|
|
*/ mean_wind(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2,&ix3, &ix4);
|
|
setcolor(12);
|
|
setlinestyle(1, 1);
|
|
ix4 *= .85;
|
|
ix3 += 15;
|
|
if(ix3>360) ix3 -= 360;
|
|
hodo_to_pix( ix3, ix4, &x1, &y1);
|
|
moveto(x1-3, y1); lineto(x1+3, y1);
|
|
moveto(x1, y1-3); lineto(x1, y1+3);
|
|
ellipse(0, x1-3, y1-3, x1+3, y1+3);
|
|
/* }
|
|
*/ }
|
|
|
|
}
|
|
#endif
|
|
/*NP*/
|
|
void hodo_to_pix(float dir, float mag, short *x, short *y)
|
|
/*************************************************************/
|
|
/* HODO_TO_PIX */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Calculates the screen location (x,y) in pixels of the */
|
|
/* wind vector (dir,mag). */
|
|
/*************************************************************/
|
|
{
|
|
float midx, midy, scle;
|
|
float uref, vref, ix1, ix2, ix3, ix4;
|
|
|
|
uref=0;
|
|
vref=0;
|
|
/*if (hodo_mode == HODO_STORMRELATIVE) {
|
|
uref = ucomp(st_dir, st_spd);
|
|
vref = vcomp(st_dir, st_spd);
|
|
}*/
|
|
/* 4jan07 */
|
|
if (hodo_mode == HODO_MEANWIND) {
|
|
mean_wind(i_pres(msl(1500)), i_pres(msl(8000)), &ix1, &ix2, &ix3, &ix4);
|
|
if (ix1 > 40.0) ix1 = 40.0;
|
|
if (ix2 > 40.0) ix2 = 40.0;
|
|
if (-998 < ix1 < -40) ix1 = -40.0;
|
|
if (ix1 <= -999) ix1 = 0.0;
|
|
if (-998 < ix2 < -40) ix2 = -40.0;
|
|
if (ix2 <= -999) ix2 = 0.0;
|
|
uref = ix1;
|
|
vref = ix2;
|
|
|
|
}
|
|
|
|
scle = (hov.brx - hov.tlx) / hov.hodomag;
|
|
midx = hov.tlx + ((hov.brx - hov.tlx) / 2.0) + (hov.xshift * scle);
|
|
midy = hov.tly + ((hov.bry - hov.tly) / 2.0) - (hov.yshift * scle);
|
|
|
|
*x = (short)(midx + ((ucomp(dir, mag) - uref) * scle));
|
|
*y = (short)(midy - ((vcomp(dir, mag) - vref) * scle));
|
|
}
|
|
|
|
/*NP*/
|
|
void pix_to_hodo(short x, short y, float *dir, float *mag)
|
|
/*************************************************************/
|
|
/* PIX_TO_HODO */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Calculates the wind vector (dir, mag) in knots of the */
|
|
/* screen location (x,y). */
|
|
/*************************************************************/
|
|
{
|
|
float midx, midy, scle, u, v;
|
|
float uref, vref, ix1, ix2, ix3, ix4;
|
|
|
|
uref=0;
|
|
vref=0;
|
|
/*if (hodo_mode == HODO_STORMRELATIVE) {
|
|
uref = ucomp(st_dir, st_spd);
|
|
vref = vcomp(st_dir, st_spd);
|
|
}*/
|
|
/* 4jan07 */
|
|
if (hodo_mode == HODO_MEANWIND) {
|
|
mean_wind(i_pres(msl(1500)), i_pres(msl(8000)), &ix1, &ix2, &ix3, &ix4);
|
|
if (ix1 > 40.0) ix1 = 40.0;
|
|
if (ix2 > 40.0) ix2 = 40.0;
|
|
if (-998 < ix1 < -40) ix1 = -40.0;
|
|
if (ix1 <= -999) ix1 = 0.0;
|
|
if (-998 < ix2 < -40) ix2 = -40.0;
|
|
if (ix2 <= -999) ix2 = 0.0;
|
|
/*if (ix1 < -150) ix1 = 0.0;
|
|
if (ix2 < -150) ix2 = 0.0;*/
|
|
uref = ix1;
|
|
vref = ix2;
|
|
}
|
|
|
|
scle = (hov.brx - hov.tlx) / hov.hodomag; /* pixels/knot */
|
|
midx = hov.tlx + ((hov.brx - hov.tlx) / 2.0) + (hov.xshift * scle);
|
|
midy = hov.tly + ((hov.bry - hov.tly) / 2.0) - (hov.yshift * scle);
|
|
|
|
u = ((x - midx) / scle) + uref;
|
|
v = ((midy - y) / scle) + vref;
|
|
|
|
*dir = angle(u, v) ;
|
|
*mag = speed(u, v);
|
|
}
|
|
|
|
#ifndef _WIN32
|
|
/*NP*/
|
|
void trace_hodo(short width)
|
|
/*************************************************************/
|
|
/* TRACE_HODO */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental wind shear vectors on Hodograph. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, xold, yold, ok = 0;
|
|
short zIndex, dIndex, sIndex, pIndex;
|
|
float lvl, u, v, dd, ss, uref, vref;
|
|
char st[20];
|
|
Sounding *cursndg=NULL, *prevsndg=NULL;
|
|
HistElmt *he;
|
|
|
|
if (!sndg || numlvl < 2)
|
|
return;
|
|
|
|
setlinestyle(1, width);
|
|
|
|
zIndex = getParmIndex("HGHT");
|
|
dIndex = getParmIndex("DRCT");
|
|
sIndex = getParmIndex("SPED");
|
|
|
|
if (zIndex == -1 || dIndex == -1 || sIndex == -1)
|
|
return;
|
|
|
|
|
|
setlinestyle(1,width);
|
|
if (hodo_mode == HODO_BNDRY) {
|
|
setlinestyle(1,1);
|
|
for( i=0; i < numlvl; i++) {
|
|
/* Don't plot data above 12km (~200mb) */
|
|
if (sndg[i][zIndex] > msl(12000)) break;
|
|
|
|
if (qc(sndg[i][dIndex]) && qc(sndg[i][sIndex])) {
|
|
if (sndg[i][zIndex] <= msl(12000))
|
|
setcolor(14);
|
|
/* else if (sndg[i][zIndex] > msl(3000) &&
|
|
sndg[i][zIndex] <= msl(6000))
|
|
setcolor(14);
|
|
else if (sndg[i][zIndex] > msl(6000) &&
|
|
sndg[i][zIndex] <= msl(9000))
|
|
setcolor(14);
|
|
else if (sndg[i][zIndex] > msl(9000) &&
|
|
sndg[i][zIndex] <= msl(12000))
|
|
setcolor(14);
|
|
else if (sndg[i][zIndex] > msl(12000))
|
|
setcolor(28);
|
|
*/
|
|
xold = x;
|
|
yold = y;
|
|
if (hodo_mode == HODO_STORMRELATIVE) {
|
|
uref = ucomp(sndg[i][dIndex], sndg[i][sIndex]) - ucomp(st_dir, st_spd);
|
|
vref = vcomp(sndg[i][dIndex], sndg[i][sIndex]) - vcomp(st_dir, st_spd);
|
|
dd = angle(uref,vref);
|
|
ss = speed(uref,vref);
|
|
hodo_to_pix(dd, ss, &x, &y); }
|
|
|
|
else {
|
|
hodo_to_pix(sndg[i][dIndex], sndg[i][sIndex], &x, &y); }
|
|
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/* Plot height labels on hodograph */
|
|
for( i=0; i < numlvl; i++)
|
|
{
|
|
if (sndg[i][zIndex] > msl(9000)) break;
|
|
|
|
lvl = (float)((int)(sndg[i][zIndex]/1000) * 1000);
|
|
dd = i_wdir(i_pres(msl(lvl)), I_PRES);
|
|
ss = i_wspd(i_pres(msl(lvl)), I_PRES);
|
|
hodo_to_pix(dd, ss, &x, &y);
|
|
setcolor(14);
|
|
set_font(4);
|
|
sprintf( st, "%.0f", lvl/1000);
|
|
outgtext(st, x, y);
|
|
}
|
|
}
|
|
|
|
|
|
else {
|
|
setlinestyle(1,width);
|
|
for( i=0; i < numlvl; i++) {
|
|
/* Don't plot data above 12km (~200mb) */
|
|
if (sndg[i][zIndex] > msl(12000)) break;
|
|
|
|
if (qc(sndg[i][dIndex]) && qc(sndg[i][sIndex])) {
|
|
if (sndg[i][zIndex] <= msl(3000))
|
|
setcolor(2);
|
|
else if (sndg[i][zIndex] > msl(3000) &&
|
|
sndg[i][zIndex] <= msl(6000))
|
|
setcolor(3);
|
|
else if (sndg[i][zIndex] > msl(6000) &&
|
|
sndg[i][zIndex] <= msl(9000))
|
|
setcolor(5);
|
|
else if (sndg[i][zIndex] > msl(9000) &&
|
|
sndg[i][zIndex] <= msl(12000))
|
|
setcolor(6);
|
|
/* else if (sndg[i][zIndex] > msl(12000))
|
|
setcolor(28);
|
|
*/
|
|
xold = x;
|
|
yold = y;
|
|
if (hodo_mode == HODO_STORMRELATIVE) {
|
|
uref = ucomp(sndg[i][dIndex], sndg[i][sIndex]) - ucomp(st_dir, st_spd);
|
|
vref = vcomp(sndg[i][dIndex], sndg[i][sIndex]) - vcomp(st_dir, st_spd);
|
|
dd = angle(uref,vref);
|
|
ss = speed(uref,vref);
|
|
hodo_to_pix(dd, ss, &x, &y); }
|
|
|
|
else {
|
|
hodo_to_pix(sndg[i][dIndex], sndg[i][sIndex], &x, &y); }
|
|
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
|
|
}
|
|
}
|
|
/* Plot height labels on hodograph */
|
|
if (hodo_mode == HODO_STORMRELATIVE) {
|
|
for( i=0; i < numlvl; i++)
|
|
{
|
|
if (sndg[i][zIndex] > msl(9000)) break;
|
|
|
|
lvl = (float)((int)(sndg[i][zIndex]/1000) * 1000);
|
|
|
|
dd = angle((i_wndu(i_pres(msl(lvl)), I_PRES) - ucomp(st_dir, st_spd)), i_wndv(i_pres(msl(lvl)), I_PRES) - vcomp(st_dir, st_spd));
|
|
ss = speed((i_wndu(i_pres(msl(lvl)), I_PRES) - ucomp(st_dir, st_spd)), i_wndv(i_pres(msl(lvl)), I_PRES) - vcomp(st_dir, st_spd));
|
|
/*printf("\ndd = %0.1f\n", dd);
|
|
printf("\nss = %0.1f\n", ss);*/
|
|
/*dd = i_wdir(i_pres(msl(lvl)), I_PRES);
|
|
ss = i_wspd(i_pres(msl(lvl)), I_PRES);*/
|
|
hodo_to_pix(dd, ss, &x, &y);
|
|
setcolor(1);
|
|
set_font(5);
|
|
sprintf( st, "%.0f", lvl/1000);
|
|
outgtext(st, x, y);
|
|
}
|
|
}
|
|
else {
|
|
/* Plot height labels on hodograph */
|
|
/*for( i=0; i < numlvl; i++)
|
|
{
|
|
if (sndg[i][zIndex] > msl(500)) break;
|
|
|
|
lvl = (float)((int)(sndg[i][zIndex]/500) * 500);*/
|
|
dd = i_wdir(i_pres(msl(500)), I_PRES);
|
|
ss = i_wspd(i_pres(msl(500)), I_PRES);
|
|
hodo_to_pix(dd, ss, &x, &y);
|
|
setcolor(7);
|
|
set_font(5);
|
|
ellipse(0, x-2, y-2, x+2, y+2);
|
|
/*sprintf( st, "%.1f", lvl/1000);
|
|
outgtext(st, x, y);*/
|
|
/* }*/
|
|
for( i=0; i < numlvl; i++)
|
|
{
|
|
if (sndg[i][zIndex] > msl(9000)) break;
|
|
|
|
lvl = (float)((int)(sndg[i][zIndex]/1000) * 1000);
|
|
dd = i_wdir(i_pres(msl(lvl)), I_PRES);
|
|
ss = i_wspd(i_pres(msl(lvl)), I_PRES);
|
|
hodo_to_pix(dd, ss, &x, &y);
|
|
setcolor(1);
|
|
set_font(5);
|
|
sprintf( st, "%.0f", lvl/1000);
|
|
outgtext(st, x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef HISTORY
|
|
if (overlay_previous != 1)
|
|
return;
|
|
|
|
cursndg = getGlobalSounding();
|
|
he = history_first(&hist);
|
|
if (he)
|
|
he = history_next(he);
|
|
if (!he) {
|
|
return;
|
|
}
|
|
|
|
prevsndg = (Sounding *)history_data(he);
|
|
if (!prevsndg) {
|
|
return;
|
|
}
|
|
|
|
changeGlobalSounding(prevsndg);
|
|
if (!sndg || numlvl < 2) {
|
|
changeGlobalSounding(cursndg);
|
|
return;
|
|
}
|
|
|
|
zIndex = getParmIndex("HGHT");
|
|
dIndex = getParmIndex("DRCT");
|
|
sIndex = getParmIndex("SPED");
|
|
|
|
if (zIndex == -1 || dIndex == -1 || sIndex == -1) {
|
|
changeGlobalSounding(cursndg);
|
|
return;
|
|
}
|
|
|
|
ok = 0;
|
|
|
|
for (i=0; i < numlvl; i++) {
|
|
/* Don't plot data above 12km (~200mb) */
|
|
if (sndg[i][zIndex] > msl(12000))
|
|
break;
|
|
|
|
if (qc(sndg[i][dIndex]) && qc(sndg[i][sIndex])) {
|
|
if (sndg[i][zIndex] <= msl(3000))
|
|
setcolor(14);
|
|
else if (sndg[i][zIndex] > msl(3000) &&
|
|
sndg[i][zIndex] <= msl(6000))
|
|
setcolor(23);
|
|
else if (sndg[i][zIndex] > msl(6000) &&
|
|
sndg[i][zIndex] <= msl(9000))
|
|
setcolor(19);
|
|
else if (sndg[i][zIndex] > msl(9000) &&
|
|
sndg[i][zIndex] <= msl(12000))
|
|
setcolor(25);
|
|
/* else if (sndg[i][zIndex] > msl(12000))
|
|
setcolor(30);
|
|
*/
|
|
xold = x;
|
|
yold = y;
|
|
hodo_to_pix(sndg[i][dIndex], sndg[i][sIndex], &x, &y);
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Reset our sounding again */
|
|
changeGlobalSounding(cursndg);
|
|
#endif
|
|
}
|
|
|
|
/*NP*/
|
|
void trace_esrh(void)
|
|
/*************************************************************/
|
|
/* TRACE_ESRH */
|
|
/* Rich Thompson SPC OUN */
|
|
/* */
|
|
/* Traces upper and lower bounds of effective SRH layer on */
|
|
/* hodograph, based on the effective Bunkers motion. */
|
|
/*************************************************************/
|
|
{
|
|
float pbot, ptop, bot_spd, bot_dir, top_spd, top_dir, ix1, ix2, ix3, ix4;
|
|
float u_bot, v_bot, u_top, v_top, ca, shr_dir, sr_dir;
|
|
short x, y, x2, y2, bx, by, pIndex;
|
|
char st[20];
|
|
|
|
if (hodo_mode == HODO_BNDRY) return;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
|
|
/* calculate pressure of effective layer top and bottom */
|
|
|
|
/* 24 Mar 2008 */
|
|
/* effective_inflow_layer(100,-250, &p_bot, &p_top);
|
|
|
|
printf("\ninflow base = %0.1f", agl(i_hght(p_bot, I_PRES)));
|
|
printf("\ninflow top = %0.1f\n", agl(i_hght(p_top, I_PRES)));
|
|
*/
|
|
if (p_bot < 1) return;
|
|
|
|
if ((hodo_mode == HODO_MEANWIND) || (hodo_mode == HODO_NORMAL)) {
|
|
/* interpolate wind direction and speed at top and bottom of effective layer */
|
|
bot_spd = i_wspd(p_bot, I_PRES);
|
|
bot_dir = i_wdir(p_bot, I_PRES);
|
|
top_spd = i_wspd(p_top, I_PRES);
|
|
top_dir = i_wdir(p_top, I_PRES);
|
|
|
|
/* convert effective layer top and bottom to pixel location on hodograph */
|
|
hodo_to_pix(bot_dir, bot_spd, &x, &y);
|
|
hodo_to_pix(top_dir, top_spd, &x2, &y2);
|
|
/* convert effective Bunkers motion to pixel location on hodograph */
|
|
/* bunkers_storm_motion(&ix1, &ix2, &st_dir, &st_spd);
|
|
*/ hodo_to_pix(st_dir, st_spd, &bx, &by);
|
|
|
|
/*draw lines from storm motion to top and bottom of effective layer */
|
|
setcliprgn(hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
setcolor(26);
|
|
setlinestyle(1,1);
|
|
moveto(bx, by);
|
|
lineto(x, y);
|
|
moveto(bx, by);
|
|
lineto(x2, y2);
|
|
|
|
if (agl(i_hght(p_bot, I_PRES)) > 1) return;
|
|
/* interpolate 500 m wind direction and speed */
|
|
bot_spd = i_wspd(p_bot, I_PRES);
|
|
bot_dir = i_wdir(p_bot, I_PRES);
|
|
top_spd = i_wspd(i_pres(msl(500)), I_PRES);
|
|
top_dir = i_wdir(i_pres(msl(500)), I_PRES);
|
|
hodo_to_pix(bot_dir, bot_spd, &x, &y);
|
|
hodo_to_pix(top_dir, top_spd, &x2, &y2);
|
|
|
|
/*draw 0-500 m shear vector */
|
|
setcolor(7);
|
|
setlinestyle(1,1);
|
|
moveto(x2, y2);
|
|
lineto(x, y);
|
|
}
|
|
|
|
|
|
/* critical angle from Guiliano and Esterheld (2007) */
|
|
sr_wind( p_bot, p_bot, st_dir, st_spd, &ix1, &ix2, &sr_dir, &ix4);
|
|
wind_shear( p_bot, i_pres(msl(500)), &ix1, &ix2, &shr_dir, &ix4);
|
|
if ((sr_dir <= 180) && (shr_dir <= 180)){ ca = (sr_dir + 180) - shr_dir;}
|
|
if ((sr_dir <= 180) && (shr_dir > 180)){ ca = (sr_dir + 180) - shr_dir;}
|
|
if ((sr_dir > 180) && (shr_dir <= 180)){ ca = (sr_dir - 180) - shr_dir;}
|
|
if ((sr_dir > 180) && (shr_dir > 180)){ ca = 180 - ((shr_dir - 180) - (sr_dir - 180));}
|
|
/*printf("\nsfc DIR = %0.1f \ sfc spd = %0.1f \ sfc u (ucomp) = %0.1f \ sfc v (vcomp) = %0.1f", bot_dir, bot_spd,
|
|
ucomp(bot_dir, bot_spd), vcomp(bot_dir, bot_spd));
|
|
printf("\n500m DIR = %0.1f \ 500m spd = %0.1f \ 500m u (ucomp) = %0.1f \ 500m v (vcomp) = %0.1f", top_dir, top_spd,
|
|
ucomp(top_dir, top_spd), vcomp(top_dir, top_spd));
|
|
printf("\nsfc SR dir = %0.1f", sr_dir);
|
|
printf("\n0-500m shr dir = %0.1f", shr_dir);
|
|
printf("\nCRITICAL ANGLE = %0.1f\n", ca);*/
|
|
setcolor(6);
|
|
set_font(4);
|
|
sprintf( st, "Critical Angle = %.0f", ca);
|
|
outgtext(st, hov.tlx + 10, hov.bry - 20);
|
|
|
|
if (hodo_mode == HODO_STORMRELATIVE) {
|
|
|
|
/* interpolate wind dir/spd for top and bottom of effective inflow layer, and adjust for storm motion */
|
|
u_bot = i_wndu(p_bot, I_PRES) - ucomp(st_dir, st_spd);
|
|
v_bot = i_wndv(p_bot, I_PRES) - vcomp(st_dir, st_spd);
|
|
u_top = i_wndu(p_top, I_PRES) - ucomp(st_dir, st_spd);
|
|
v_top = i_wndv(p_top, I_PRES) - vcomp(st_dir, st_spd);
|
|
|
|
bot_spd = speed(u_bot, v_bot);
|
|
bot_dir = angle(u_bot, v_bot);
|
|
top_spd = speed(u_top, v_top);
|
|
top_dir = angle(u_top, v_top);
|
|
|
|
/* convert effective layer top and bottom to pixel location on hodograph */
|
|
hodo_to_pix(bot_dir, bot_spd, &x, &y);
|
|
hodo_to_pix(top_dir, top_spd, &x2, &y2);
|
|
|
|
/* convert storm motion to origin of hodograph */
|
|
hodo_to_pix(0, 0, &bx, &by);
|
|
|
|
/*draw lines from storm motion to top and bottom of effective layer */
|
|
setcliprgn(hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
setcolor(26);
|
|
setlinestyle(1,1);
|
|
moveto(bx, by);
|
|
lineto(x, y);
|
|
moveto(bx, by);
|
|
lineto(x2, y2);
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
void trace_bndry(float dir, float spd)
|
|
/*************************************************************/
|
|
/* TRACE BOUNDARY MOTION AND ORIENTATION */
|
|
/* Rich Thompson SPC OUN */
|
|
/* */
|
|
/* Plots boundary orientation and motion on hodograph. */
|
|
/*************************************************************/
|
|
{
|
|
float d, u_bndry, v_bndry, u_right, v_right, u_left, v_left;
|
|
float ix1, ix2, ix3, ix4, u6, v6, u6rel, v6rel, u9, v9, u9rel, v9rel, rel_dir, rel_spd;
|
|
float dir_right, spd_right, dir_left, spd_left;
|
|
short x, y, xr, yr, xl, yl, x6, y6, x9, y9;
|
|
short pIndex;
|
|
char st[20];
|
|
|
|
/* make sure a boundary dir/spd is provided */
|
|
if ((dir < -999.0) || (spd < -999.0)){
|
|
return; }
|
|
else {
|
|
hodo_mode = HODO_BNDRY; }
|
|
|
|
/* d = length of boundary segments on hodograph (kt) */
|
|
d = 40.0;
|
|
|
|
u_bndry = ucomp(dir, spd);
|
|
v_bndry = vcomp(dir, spd);
|
|
|
|
/* compute left and right orthogonal vectors from boundary motion */
|
|
/* orthogonal right segment */
|
|
u_right = u_bndry + ((d / pow((u_bndry * u_bndry) + (v_bndry * v_bndry), 0.5)) * v_bndry);
|
|
v_right = v_bndry - ((d / pow((u_bndry * u_bndry) + (v_bndry * v_bndry), 0.5)) * u_bndry);
|
|
dir_right = angle(u_right, v_right);
|
|
spd_right = speed(u_right, v_right);
|
|
|
|
/* orthogonal left segment */
|
|
u_left = u_bndry - ((d / pow((u_bndry * u_bndry) + (v_bndry * v_bndry), 0.5)) * v_bndry);
|
|
v_left = v_bndry + ((d / pow((u_bndry * u_bndry) + (v_bndry * v_bndry), 0.5)) * u_bndry);
|
|
dir_left = angle(u_left, v_left);
|
|
spd_left = speed(u_left, v_left);
|
|
|
|
/* convert boundary motion and orientation segments to pixel location on hodograph */
|
|
hodo_to_pix(dir, spd, &x, &y);
|
|
hodo_to_pix(dir_right, spd_right, &xr, &yr);
|
|
hodo_to_pix(dir_left, spd_left, &xl, &yl);
|
|
|
|
/*draw lines from boundary motion orthogonal left and right (segment length of 25 kt) */
|
|
setcliprgn(hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
setcolor(18);
|
|
setlinestyle(1,2);
|
|
moveto(x, y);
|
|
lineto(xr, yr);
|
|
moveto(x, y);
|
|
lineto(xl, yl);
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
|
|
/* 0-6 km vector shear relative to boundary */
|
|
wind_shear(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
|
|
u6 = ix1;
|
|
v6 = ix2;
|
|
|
|
if ((u6 < -999.0) || (v6 < -999.0)){
|
|
return;
|
|
}
|
|
|
|
u6rel = u6 + u_bndry;
|
|
v6rel = v6 + v_bndry;
|
|
rel_dir = angle(u6rel, v6rel);
|
|
rel_spd = speed(u6rel, v6rel);
|
|
|
|
hodo_to_pix(rel_dir, rel_spd, &x6, &y6);
|
|
|
|
setcliprgn(hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
setcolor(26);
|
|
setlinestyle(1,2);
|
|
moveto(x, y);
|
|
lineto(x6, y6);
|
|
set_font(5);
|
|
/* sprintf( st, "%.0f/%.0f 0-6km shr", ((dir+90)-rel_dir), ix4);
|
|
*/
|
|
sprintf( st, "%.0f/%.0f 0-6km shr", rel_dir, ix4);
|
|
outgtext(st, x6-30, y6-8);
|
|
|
|
/* 9-11 km SR wind relative to boundary */
|
|
sr_wind(i_pres(msl(9000)), i_pres(msl(11000)), st_dir, st_spd, &ix1, &ix2, &ix3, &ix4);
|
|
u9 = ix1;
|
|
v9 = ix2;
|
|
|
|
if ((u9 < -999.0) || (v9 < -999.0)){
|
|
return;
|
|
}
|
|
|
|
u9rel = u9 + u_bndry;
|
|
v9rel = v9 + v_bndry;
|
|
rel_dir = angle(u9rel, v9rel);
|
|
rel_spd = speed(u9rel, v9rel);
|
|
|
|
hodo_to_pix(rel_dir, rel_spd, &x9, &y9);
|
|
|
|
setcliprgn(hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
setcolor(7);
|
|
setlinestyle(1,2);
|
|
moveto(x, y);
|
|
lineto(x9, y9);
|
|
set_font(5);
|
|
sprintf( st, "%.0f/%.0f 9-11km SR", rel_dir, ix4);
|
|
outgtext(st, x9-30, y9+8);
|
|
|
|
}
|
|
|
|
/*NP */
|
|
void dry_adiabat(float thta)
|
|
/*************************************************************/
|
|
/* DRY_ADIABAT */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws dry adiabat of theta (thta, c) on SkewT graphic. */
|
|
/*************************************************************/
|
|
{
|
|
float pres, temp;
|
|
short x, y;
|
|
|
|
setcliprgn(skv.tlx+2, skv.tly+2, skv.brx-55, skv.bry-2);
|
|
for( pres = 1050.0; pres >= 100.0; pres-=50.0 ) {
|
|
temp = ((thta + 273.15) / pow( 1000.0 / pres, ROCP )) - 273.15;
|
|
|
|
x = temp_to_pix(temp , pres);
|
|
y = pres_to_pix(pres);
|
|
|
|
if (pres == 1050.0)
|
|
moveto(x, y);
|
|
else
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
void isotherm(float temp, short colr)
|
|
/*************************************************************/
|
|
/* ISOTHERM */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws temperature lines (temp, c) on SkewT graphic. */
|
|
/* Color variable is for line, labels in white. */
|
|
/*************************************************************/
|
|
{
|
|
short x, y;
|
|
char st[10];
|
|
|
|
x = temp_to_pix(temp, 1045.0);
|
|
y = skv.bry;
|
|
if ((temp >= -30) && (temp <= 50)) {
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
itoa((short)temp, st, 10);
|
|
setcolor(1);
|
|
outgtext(st, x - (getgtextextent( st ) / 2), y+2);
|
|
}
|
|
setcliprgn(skv.tlx+3, skv.tly+3, skv.brx-55, skv.bry-5);
|
|
setcolor(colr);
|
|
moveto(x, y);
|
|
x = temp_to_pix(temp, 100.0);
|
|
y = skv.tly;
|
|
lineto(x, y);
|
|
}
|
|
|
|
/*NP*/
|
|
void highlight_temp(float temp, short colr)
|
|
/*************************************************************/
|
|
/* HIGHLIGHT_TEMP */
|
|
/* Rich Thompson SPC OUN */
|
|
/* */
|
|
/* Highlights portion of isotherm through chosen sounding */
|
|
/* temperature. Temp is temperature (C) and colr is the */
|
|
/* line color. */
|
|
/*************************************************************/
|
|
{
|
|
short x, y1, y2;
|
|
float pres;
|
|
|
|
y1 = temp_lvl(temp, &pres);
|
|
y2 = pres_to_pix(pres);
|
|
x = temp_to_pix(temp, pres);
|
|
|
|
setcolor(colr);
|
|
setlinestyle(1, 2);
|
|
ellipse(0, x-3, y2-3, x+3, y2+3);
|
|
|
|
setlinestyle(2, 1);
|
|
setcliprgn(x, skv.tly, skv.brx, y2);
|
|
moveto(x, y2);
|
|
x = temp_to_pix(temp, pres-150);
|
|
y2 = pres_to_pix(pres-150);
|
|
lineto(x, y2);
|
|
}
|
|
|
|
/*NP*/
|
|
void isobar(float pres, short flag)
|
|
/*************************************************************/
|
|
/* ISOBAR */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws pressure lines (pres, mb) on SkewT graphic. */
|
|
/* */
|
|
/* flag = 0 Draw complete horizontal line */
|
|
/* = 1 Draw small tick marks along sides of chart */
|
|
/*************************************************************/
|
|
{
|
|
short y;
|
|
char st[10];
|
|
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
y = pres_to_pix(pres);
|
|
if (flag == 0) {
|
|
moveto(skv.tlx, y);
|
|
itoa((short)pres, st, 10);
|
|
outgtext(st, skv.tlx - getgtextextent( st ) - 2, y - 5);
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx-55, skv.bry);
|
|
moveto(skv.tlx, y);
|
|
lineto(skv.brx, y);
|
|
}
|
|
else {
|
|
moveto(skv.tlx, y);
|
|
lineto(skv.tlx + 5, y);
|
|
moveto(skv.brx, y);
|
|
lineto(skv.brx - 5, y);
|
|
}
|
|
}
|
|
|
|
void mixratline(float val)
|
|
{
|
|
float top=600.0;
|
|
float bot=1045.0;
|
|
float temp;
|
|
short x0, y0, x1, y1;
|
|
|
|
/* bottom */
|
|
temp = temp_at_mixrat(val, bot);
|
|
x0 = temp_to_pix(temp, bot);
|
|
y0 = pres_to_pix(bot);
|
|
|
|
/* top */
|
|
temp = temp_at_mixrat(val, top);
|
|
x1 = temp_to_pix(temp, top);
|
|
y1 = pres_to_pix(top);
|
|
|
|
moveto(x0, y0);
|
|
lineto(x1, y1);
|
|
}
|
|
|
|
/*NP*/
|
|
void trace_temp(short width, short colr)
|
|
/*************************************************************/
|
|
/* TRACE_TEMP */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental temperature trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, x2, y2, x3, y3, xold, yold, ok = 0;
|
|
short pIndex, tIndex;
|
|
char st[20];
|
|
|
|
float minus20;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tIndex = getParmIndex("TEMP");
|
|
|
|
if (!sndg || pIndex == -1 || tIndex == -1)
|
|
return;
|
|
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry+8);
|
|
setlinestyle(1, width);
|
|
setcolor(colr);
|
|
for( i=0; i < numlvl; i++) {
|
|
if (sndg[i][tIndex] > -200.0) {
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix(sndg[i][tIndex], sndg[i][pIndex]);
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Plot Surface T along bottom */
|
|
set_font(4);
|
|
sprintf( st, "%.0f", ctof(sndg[sfc()][tIndex]));
|
|
x = temp_to_pix(sndg[sfc()][tIndex], sndg[sfc()][pIndex]);
|
|
y = pres_to_pix(sndg[sfc()][pIndex]);
|
|
x2 = x + getgtextextent(st)+2;
|
|
y2 = y + 12;
|
|
setcolor(0);
|
|
rectangle(1, x+1, y+3, x2, y+13);
|
|
setcolor(colr);
|
|
outgtext(st, x+2, y+2);
|
|
|
|
/* Highlight -20C isotherm near actual temp trace */
|
|
/* temp_lvl(-20, &minus20);
|
|
printf("\npres lvl of -20c (mb) = %.1f\n", minus20);
|
|
x3 = temp_to_pix(-20, minus20);
|
|
y3 = pres_to_pix(minus20);
|
|
setcolor(5);
|
|
setlinestyle(2, 4);
|
|
moveto(skv.tlx+x3, skv.tly+y3);
|
|
lineto(skv.tlx+x3+10, skv.tly+y3+10);
|
|
*/
|
|
|
|
if ((display_mode_left == DISPLAY_WINTER_LEFT) && (colr == 2)) display_dendritic_zone(width);
|
|
if (display_mode_left == DISPLAY_CONVECTION_LEFT) display_effective_layer(27);
|
|
|
|
/* added 25OCT06 by RLT */
|
|
if (display_mode_left == DISPLAY_SARS_LEFT) display_effective_layer(27);
|
|
if (display_mode_left == DISPLAY_HAIL_LEFT) display_effective_layer(27);
|
|
if (display_mode_left == DISPLAY_SHIP_LEFT) display_effective_layer(27);
|
|
if (display_mode_left == DISPLAY_STP_LEFT) display_effective_layer(27);
|
|
if (display_mode_left == DISPLAY_EBS_LEFT) display_effective_layer(27);
|
|
if (display_mode_left == DISPLAY_FIRE_LEFT) display_effective_layer(27);
|
|
|
|
display_levels(colr);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
This routine has same problems as trace_hodo
|
|
|
|
*/
|
|
|
|
/*NP*/
|
|
void trace_temp2(short width)
|
|
/*************************************************************/
|
|
/* TRACE_TEMP2 */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental temperature trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, xold, yold, ok = 0;
|
|
|
|
if (!sndg)
|
|
return;
|
|
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
setlinestyle(1, width);
|
|
for (i=0; i < numlvl; i++) {
|
|
if (sndg2[i][3] > -200.0) {
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix(sndg[i][3], sndg[i][1]);
|
|
y = pres_to_pix(sndg[i][1]);
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
void trace_vtmp(short width)
|
|
/*************************************************************/
|
|
/* TRACE_VTMP */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots virtual temperature trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, xold, yold, ok = 0;
|
|
short pIndex, tIndex, tdIndex;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tIndex = getParmIndex("TEMP");
|
|
tdIndex = getParmIndex("DWPT");
|
|
|
|
if (!sndg || pIndex == -1 || tIndex == -1 || tdIndex == -1)
|
|
return;
|
|
|
|
setlinestyle(10, width);
|
|
for (i = 0; i < numlvl; i++) {
|
|
if (qc(sndg[i][tIndex]) && qc(sndg[i][tdIndex])) {
|
|
xold = x;
|
|
yold = y;
|
|
/* x = temp_to_pix(i_vtmp(sndg[i][pIndex], I_PRES), sndg[i][pIndex]); */
|
|
x = temp_to_pix(virtemp(sndg[i][pIndex], sndg[i][tIndex], sndg[i][tdIndex]), sndg[i][pIndex]);
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
void trace_dwpt(short width, short colr)
|
|
/*************************************************************/
|
|
/* TRACE_DWPT */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental Dew Point trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, x2, y2, xold, yold, ok = 0;
|
|
short pIndex, tdIndex;
|
|
char st[20];
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tdIndex = getParmIndex("DWPT");
|
|
|
|
if (!sndg || pIndex == -1 || tdIndex == -1)
|
|
return;
|
|
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
setlinestyle(1, width);
|
|
setcolor(colr);
|
|
for (i=0; i < numlvl; i++) {
|
|
if (sndg[i][tdIndex] > -200.0) {
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix(sndg[i][tdIndex], sndg[i][pIndex]);
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* set_font(4);
|
|
sprintf( st, "%.0f", ctof(sndg[sfc()][tIndex]));
|
|
x = temp_to_pix(sndg[sfc()][tIndex], sndg[sfc()][pIndex]);
|
|
y = pres_to_pix(sndg[sfc()][pIndex]);
|
|
x2 = x + getgtextextent(st)+4;
|
|
y2 = y + 12;
|
|
setcolor(0);
|
|
rectangle(1, x, y+3, x2, y2+3);
|
|
setcolor(colr);
|
|
outgtext(st, x+2, y+3);
|
|
*/
|
|
|
|
/* Plot Surface Td along bottom */
|
|
set_font(4);
|
|
sprintf( st, "%.0f", ctof(sndg[sfc()][tdIndex]));
|
|
x = temp_to_pix(sndg[sfc()][tdIndex], sndg[sfc()][pIndex]);
|
|
y = pres_to_pix(sndg[sfc()][pIndex]);
|
|
x2 = x + getgtextextent(st)-12;
|
|
y2 = y + 12;
|
|
setcolor(0);
|
|
rectangle(1, x-13, y+3, x2, y+13);
|
|
setcolor(colr);
|
|
outgtext(st, x-12, y+2);
|
|
}
|
|
|
|
/*
|
|
|
|
This routine has same problems as trace_hodo
|
|
|
|
*/
|
|
|
|
/*NP*/
|
|
void trace_dwpt2(short width)
|
|
/*************************************************************/
|
|
/* TRACE_DWPT2 */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental Dew Point trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, xold, yold, ok = 0;
|
|
|
|
if (!sndg)
|
|
return;
|
|
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
setlinestyle(1, width);
|
|
for (i=0; i < numlvl; i++) {
|
|
if (sndg[i][4] > -200) {
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix(sndg[i][4], sndg[i][1]);
|
|
y = pres_to_pix(sndg[i][1]);
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
void trace_wetbulb(short width)
|
|
/*************************************************************/
|
|
/* TRACE_WETBULB */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental Wetbulb trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, xold, yold, ok = 0;
|
|
float t1;
|
|
short pIndex, tIndex, tdIndex;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tIndex = getParmIndex("TEMP");
|
|
tdIndex = getParmIndex("DWPT");
|
|
|
|
if (!sndg || pIndex == -1 || tIndex == -1 || tdIndex == -1)
|
|
return;
|
|
|
|
setlinestyle(1, width);
|
|
for (i=0; i < numlvl; i++) {
|
|
if (sndg[i][tdIndex] > -200.0) {
|
|
xold = x;
|
|
yold = y;
|
|
|
|
t1 = wetbulb(sndg[i][pIndex], sndg[i][tIndex], sndg[i][tdIndex]);
|
|
|
|
x = temp_to_pix(t1, sndg[i][pIndex]);
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
if (ok == 0) {
|
|
moveto(x, y);
|
|
ok = 1;
|
|
}
|
|
else {
|
|
moveto(xold, yold);
|
|
lineto(x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
/*NP*/
|
|
short pres_to_pix(float pres)
|
|
/*************************************************************/
|
|
/* PRES_TO_PIX */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given pressure (mb) to an Y coordinate on */
|
|
/* Skewt graphic. */
|
|
/*************************************************************/
|
|
{
|
|
double scl1, scl2;
|
|
scl1 = log(1050) - log(100);
|
|
scl2 = log(1050) - log(pres);
|
|
return (short)(skv.bry - (scl2 / scl1) * (skv.bry - skv.tly));
|
|
}
|
|
|
|
/*NP*/
|
|
float pix_to_pres(short pix)
|
|
/*************************************************************/
|
|
/* PIX_TO_PRES */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given Y coordinate on Skewt graphic to */
|
|
/* pressure(mb). */
|
|
/*************************************************************/
|
|
{
|
|
double scl1, scl2, scl3;
|
|
scl1 = log(1050) - log(100);
|
|
scl2 = skv.bry - (double)pix;
|
|
scl3 = skv.bry - skv.tly + 1;
|
|
return (float)(1050 / exp((scl2 / scl3) * scl1));
|
|
}
|
|
|
|
/*NP*/
|
|
short temp_to_pix(float temp, float pres)
|
|
/*************************************************************/
|
|
/* TEMP_TO_PIX */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given temperature (c) to an X coordinate on */
|
|
/* Thermodynamic diagram. */
|
|
/* */
|
|
/* Depending on (skv.type), relationship is for (1) Pseudo- */
|
|
/* Adiabatic or (2) Skew-T/Log P diagram. */
|
|
/* */
|
|
/* Skew: 90c spread across the bottom of chart. */
|
|
/* 120c spread up-and-down the chart. */
|
|
/* Temp at BR of chart = 50c */
|
|
/*************************************************************/
|
|
{
|
|
float scl1, scl2;
|
|
|
|
if (skv.type == 1) {
|
|
scl1 = (float)skv.brtemp - ((((float)skv.bry -
|
|
(float)pres_to_pix( pres )) / ((float)skv.bry - (float)skv.tly)) *
|
|
(float)skv.vspread);
|
|
}
|
|
else {
|
|
scl1 = skv.brtemp;
|
|
}
|
|
scl2 = skv.brx - (((scl1 - temp) / skv.hspread) * (skv.brx - skv.tlx));
|
|
return (short)scl2;
|
|
}
|
|
|
|
/*NP*/
|
|
float pix_to_temp(short x, short y)
|
|
/*************************************************************/
|
|
/* PIX_TO_TEMP */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given X/Y coordinates to temperature(c) on */
|
|
/* Thermodynamic diagram. */
|
|
/*************************************************************/
|
|
{
|
|
float scl1, scl2, scl3;
|
|
|
|
scl1 = 1 - (((float)x - (float)skv.tlx) /
|
|
((float)skv.brx - (float)skv.tlx));
|
|
scl2 = (float)skv.brtemp - (scl1 * skv.hspread);
|
|
scl1 = 1 - (((float)y - (float)skv.tly) / ((float)skv.bry -
|
|
(float)skv.tly));
|
|
scl3 = scl2 - (scl1 * (float)skv.vspread);
|
|
return scl3;
|
|
}
|
|
|
|
/*NP*/
|
|
#ifndef _WIN32
|
|
void trace_parcel(float pres, float temp, float dwpt)
|
|
/*************************************************************/
|
|
/* TRACE_PARCEL */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots parcel(pres, temp, dwpt) trajectory on SkewT */
|
|
/* graphic. */
|
|
/* */
|
|
/* pres - Pressure of initial parcel(mb) */
|
|
/* temp - Temperature of initial parcel (c) */
|
|
/* dwpt - Dew Point of initial parcel (c) */
|
|
/*************************************************************/
|
|
{
|
|
float i, p2, t2, t3;
|
|
short x, y;
|
|
|
|
setcolor(31);
|
|
setlinestyle(4, 2);
|
|
|
|
/* ----- Draw Virtual Temperature Profile ----- */
|
|
x = temp_to_pix(virtemp(pres, temp, dwpt), pres);
|
|
y = pres_to_pix(pres);
|
|
moveto(x, y);
|
|
|
|
drylift(pres, temp, dwpt, &p2, &t2);
|
|
x = temp_to_pix(virtemp(p2, t2, t2), p2);
|
|
y = pres_to_pix(p2);
|
|
lineto(x, y);
|
|
|
|
for (i = p2 - 50; i >= 100; i = i - 50) {
|
|
t3 = wetlift(p2, t2, i);
|
|
x = temp_to_pix(virtemp(i, t3, t3), i);
|
|
y = pres_to_pix(i);
|
|
lineto(x, y);
|
|
}
|
|
t3 = wetlift(p2, t2, 100);
|
|
x = temp_to_pix(virtemp(100, t3, t3), 100);
|
|
y = pres_to_pix(100);
|
|
lineto(x, y);
|
|
|
|
setcolor(18);
|
|
setlinestyle(4, 1);
|
|
|
|
/* ----- Draw Basic Parcel Ascent ----- */
|
|
x = temp_to_pix(temp, pres);
|
|
y = pres_to_pix(pres);
|
|
moveto(x, y);
|
|
|
|
drylift(pres, temp, dwpt, &p2, &t2);
|
|
x = temp_to_pix(t2, p2);
|
|
y = pres_to_pix(p2);
|
|
lineto( x, y );
|
|
|
|
for(i = p2 - 50; i >= 100; i = i - 50) {
|
|
t3 = wetlift(p2, t2, i);
|
|
x = temp_to_pix(t3, i);
|
|
y = pres_to_pix(i);
|
|
lineto(x, y);
|
|
}
|
|
t3 = wetlift(p2, t2, 100);
|
|
x = temp_to_pix(t3, 100);
|
|
y = pres_to_pix(100);
|
|
lineto(x, y);
|
|
}
|
|
|
|
/*NP*/
|
|
void wind_barb(float wdir, float wspd, short x, short y, short siz)
|
|
/*************************************************************/
|
|
/* WIND_BARB */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots wind barb at location (x,y) for given wind. */
|
|
/*************************************************************/
|
|
{
|
|
short x1, y1, x2, y2, x3, y3, sped, flag, maxsiz=3;
|
|
float dx, dy, spcx, spcy, wid, hgt;
|
|
|
|
dx = -ucomp(wdir, 10) * siz / 1.5;
|
|
dy = -vcomp(wdir, 10) * siz / 1.5;
|
|
|
|
x1 = x;
|
|
y1 = y;
|
|
x2 = x1 + (short)dx;
|
|
y2 = y1 - (short)dy;
|
|
|
|
/* ----- Draw backbone of wind barb, along with origin dot ----- */
|
|
if (siz > maxsiz)
|
|
setlinestyle(1, 2);
|
|
else
|
|
setlinestyle(1, 1);
|
|
|
|
rectangle(0, x1-1, y1-1, x1+1, y1+1);
|
|
moveto(x1, y1);
|
|
lineto(x2, y2);
|
|
|
|
sped = (short)wspd;
|
|
x1 = x2;
|
|
y1 = y2;
|
|
|
|
wid = 5; /* Number of flags that will fit */
|
|
spcx = dx / wid;
|
|
spcy = dy / wid;
|
|
x1 = x1 + (short)spcx;
|
|
y1 = y1 - (short)spcy;
|
|
|
|
/* ----- Draw wind flags (increments of 50kt) ----- */
|
|
flag = 0;
|
|
while (sped > 47) {
|
|
flag = 1;
|
|
x1 = x1 - (short)spcx;
|
|
y1 = y1 + (short)spcy;
|
|
|
|
hgt = .5F; /* Height of flags */
|
|
x2 = x1 + (short)(dy * hgt);
|
|
y2 = y1 + (short)(dx * hgt);
|
|
|
|
x3 = x1 - (short)spcx;
|
|
y3 = y1 + (short)spcy;
|
|
|
|
moveto(x1, y1);
|
|
lineto(x2, y2);
|
|
lineto(x3, y3);
|
|
|
|
x2 = (x1 + x2 + x3) / 3;
|
|
y2 = (y1 + y2 + y3) / 3;
|
|
|
|
sped -= 50;
|
|
x1 = x3;
|
|
y1 = y3;
|
|
}
|
|
|
|
/* ----- Draw wind barbs (increments of 5kt) ----- */
|
|
while (sped > 7) {
|
|
hgt = .5F; /* Height of flags */
|
|
x2 = x1 + (short)(dy * hgt);
|
|
y2 = y1 + (short)(dx * hgt);
|
|
|
|
x3 = x1 - (short)spcx;
|
|
y3 = y1 + (short)spcy;
|
|
|
|
moveto(x3, y3);
|
|
lineto(x2, y2);
|
|
|
|
sped -= 10;
|
|
x1 = x3;
|
|
y1 = y3;
|
|
}
|
|
|
|
/* ----- Draw short barb ----- */
|
|
if (sped > 3) {
|
|
hgt = .5F; /* Height of flags */
|
|
x2 = x1 + (short)(dy * hgt);
|
|
y2 = y1 + (short)(dx * hgt);
|
|
|
|
x3 = x1 - (short)spcx;
|
|
y3 = y1 + (short)spcy;
|
|
|
|
dx = (x3 - x2) / 2;
|
|
dy = (y3 - y2) / 2;
|
|
|
|
x2 = x3 - (short)dx;
|
|
y2 = y3 - (short)dy;
|
|
|
|
moveto(x3, y3);
|
|
lineto(x2, y2);
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
void plot_barbs(void)
|
|
/*************************************************************/
|
|
/* PLOT_BARBS */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots wind barbs along side of thermo diagram. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y;
|
|
short dIndex, sIndex, pIndex, zIndex;
|
|
float lastpres;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
zIndex = getParmIndex("HGHT");
|
|
dIndex = getParmIndex("DRCT");
|
|
sIndex = getParmIndex("SPED");
|
|
|
|
if (!sndg || pIndex == -1 || zIndex == -1 || dIndex == -1 ||
|
|
sIndex == -1)
|
|
return;
|
|
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
lastpres = 1100;
|
|
for (i = 0; i < numlvl; i++) {
|
|
/* Only plot barbs up to 100 mb */
|
|
if (sndg[i][pIndex] < 100.0) break;
|
|
|
|
if (qc(sndg[i][dIndex])) {
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
x = skv.brx - 28;
|
|
|
|
if ((sndg[i][zIndex]-i_hght(lastpres, I_PRES)) > 400) {
|
|
wind_barb(sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lastpres = sndg[i][pIndex];
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* short i, x, y;
|
|
float lasthght;
|
|
short pIndex, dIndex, sIndex, zIndex;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
zIndex = getParmIndex("HGHT");
|
|
dIndex = getParmIndex("DRCT");
|
|
sIndex = getParmIndex("SPED");
|
|
|
|
if (!sndg || dIndex == -1 || sIndex == -1 || zIndex == -1)
|
|
return;
|
|
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
lasthght = 0;
|
|
for (i = 0; i < numlvl; i++) {
|
|
|
|
if (sndg[i][pIndex] < 100.0 ) break;
|
|
|
|
if (qc(sndg[i][dIndex])) {
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
x = skv.brx - 28;
|
|
|
|
if ((sndg[i][zIndex]-lasthght) > 400.0)
|
|
{
|
|
wind_barb( sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lasthght = sndg[i][zIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
/* RLT attempt to color code wind barbs to match hodograph 2/25/05 */
|
|
/* if (((sndg[i][zIndex]-lasthght) > 400.0) && ((sndg[i][zIndex] >= 0) && (sndg[i][zIndex] < 3000)))
|
|
{
|
|
setcolor(2);
|
|
wind_barb( sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lasthght = sndg[i][zIndex];
|
|
}
|
|
if (((sndg[i][zIndex]-lasthght) > 400.0) && ((sndg[i][zIndex] >= 3000) && (sndg[i][zIndex] < 6000)))
|
|
{
|
|
setcolor(3);
|
|
wind_barb( sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lasthght = sndg[i][zIndex];
|
|
}
|
|
if (((sndg[i][zIndex]-lasthght) > 400.0) && ((sndg[i][zIndex] >= 6000) && (sndg[i][zIndex] < 9000)))
|
|
{
|
|
setcolor(5);
|
|
wind_barb( sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lasthght = sndg[i][zIndex];
|
|
}
|
|
if (((sndg[i][zIndex]-lasthght) > 400.0) && ((sndg[i][zIndex] >= 9000) && (sndg[i][zIndex] < 12000)))
|
|
{
|
|
setcolor(6);
|
|
wind_barb( sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lasthght = sndg[i][zIndex];
|
|
}
|
|
if (((sndg[i][zIndex]-lasthght) > 400.0) && (sndg[i][zIndex] >= 12000))
|
|
{
|
|
setcolor(29);
|
|
wind_barb( sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lasthght = sndg[i][zIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
This routine has problems like trace_hodo
|
|
|
|
*/
|
|
/*NP*/
|
|
void plot_barbs2(void)
|
|
/*************************************************************/
|
|
/* PLOT_BARBS */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots wind barbs along side of thermo diagram. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y;
|
|
short dIndex, sIndex, pIndex, zIndex;
|
|
float lastpres;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
zIndex = getParmIndex("HGHT");
|
|
dIndex = getParmIndex("DRCT");
|
|
sIndex = getParmIndex("SPED");
|
|
|
|
if (!sndg || pIndex == -1 || zIndex == -1 || dIndex == -1 ||
|
|
sIndex == -1)
|
|
return;
|
|
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
lastpres = 1100;
|
|
for (i = 0; i < numlvl; i++) {
|
|
/* Only plot barbs up to 100 mb */
|
|
if (sndg[i][pIndex] < 100.0) break;
|
|
|
|
if (qc(sndg[i][dIndex])) {
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
x = skv.brx - 80;
|
|
|
|
if ((sndg[i][zIndex]-i_hght(lastpres, I_PRES)) > 400) {
|
|
wind_barb(sndg[i][dIndex], sndg[i][sIndex], x, y, 3.5);
|
|
lastpres = sndg[i][pIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
void vvel_profile(void)
|
|
/*************************************************************/
|
|
/* VVEL_PROFILE */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots vertical velocity profile */
|
|
/*************************************************************/
|
|
{
|
|
short i, x1, x2, y, avail, leng;
|
|
short pIndex, oIndex;
|
|
float lastpres;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
oIndex = getParmIndex("OMEG");
|
|
|
|
if (!sndg || pIndex == -1 || oIndex == -1)
|
|
return;
|
|
|
|
avail=0;
|
|
setcliprgn(1, 1, xwdth, xhght);
|
|
lastpres = 1100;
|
|
|
|
for (i = 0; i < numlvl; i++) {
|
|
if (qc(sndg[i][oIndex]) && (sndg[i][oIndex] < 1)) {
|
|
avail++;
|
|
y = pres_to_pix(sndg[i][pIndex]);
|
|
x1 = skv.tlx + 40;
|
|
leng = (sndg[i][oIndex] * 1000); /* Convert to Mbs/sec */
|
|
x2 = x1 - (leng * 2); /* Determine screen scale */
|
|
setcolor(25);
|
|
if (sndg[i][oIndex] < 0)
|
|
setcolor(12);
|
|
moveto(x1, y);
|
|
lineto(x2, y);
|
|
}
|
|
}
|
|
|
|
/* ----- Draw Scales ----- */
|
|
if (avail > 5) {
|
|
setcolor(7);
|
|
x1 = skv.tlx + 40;
|
|
moveto(x1, skv.tly+40);
|
|
lineto(x1, skv.bry-10);
|
|
|
|
setlinestyle(3, 1);
|
|
x1 = skv.tlx + 20;
|
|
moveto(x1, skv.tly+40);
|
|
lineto(x1, skv.bry-10);
|
|
x1 = skv.tlx + 60;
|
|
moveto(x1, skv.tly+40);
|
|
lineto(x1, skv.bry-10);
|
|
|
|
set_font(2);
|
|
outgtext("OMEGA", skv.tlx+18, skv.tlx);
|
|
outgtext("+10", skv.tlx+3, skv.tlx+15);
|
|
outgtext("-10", skv.tlx+43, skv.tlx+15);
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
void trace_dcape(void)
|
|
/*************************************************************/
|
|
/* TRACE_DCAPE */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots downdraft parcel trajectory */
|
|
/*************************************************************/
|
|
{
|
|
float mine, minep, ix1, tp1, tp2, te1, te2, pe1, pe2, h1, h2;
|
|
float ent2, tote, lyre, upper, p5;
|
|
short i, uptr, x, y;
|
|
short pIndex, zIndex, tIndex, tdIndex;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
zIndex = getParmIndex("HGHT");
|
|
tIndex = getParmIndex("TEMP");
|
|
tdIndex = getParmIndex("DWPT");
|
|
|
|
if (!sndg || numlvl < 1 || pIndex == -1 || zIndex == -1 ||
|
|
tIndex == -1 || tdIndex == -1)
|
|
return;
|
|
|
|
setcolor(31);
|
|
setlinestyle(4, 1);
|
|
|
|
/* ----- Find highest observation in layer ----- */
|
|
i=numlvl-1;
|
|
while (sndg[i][pIndex] < sndg[sfc()][pIndex]-400) { i--;}
|
|
p5 = i;
|
|
if (sndg[i][pIndex] == sndg[sfc()][pIndex]-400 ) { p5--; }
|
|
|
|
/* ----- Find min ThetaE layer ----- */
|
|
mine=1000; minep=-999;
|
|
for (i=0;i<p5;i++) {
|
|
if (qc(sndg[i][tdIndex]) &&
|
|
(qc(i_temp(sndg[i][pIndex]+100, I_PRES)))) {
|
|
Mean_thetae(&ix1, sndg[i][pIndex], sndg[i][pIndex]-100);
|
|
if (qc(ix1) && (ix1 < mine)) {
|
|
mine=ix1; minep=sndg[i][pIndex]-50;
|
|
}
|
|
}
|
|
}
|
|
if (minep < 0)
|
|
return;
|
|
|
|
upper = minep;
|
|
|
|
/* ----- Find highest observation in layer ----- */
|
|
i=numlvl-1;
|
|
while (sndg[i][pIndex] < upper) { i--;}
|
|
uptr = i;
|
|
if (sndg[i][pIndex] == upper) { uptr--; }
|
|
|
|
/* ----- Define parcel starting point ----- */
|
|
tp1 = wetbulb(upper, i_temp(upper, I_PRES), i_dwpt(upper, I_PRES));
|
|
pe1 = upper;
|
|
te1 = i_temp(pe1, I_PRES);
|
|
h1 = i_hght(pe1, I_PRES);
|
|
tote = 0;
|
|
lyre = 0;
|
|
|
|
x = temp_to_pix(tp1 , pe1);
|
|
y = pres_to_pix(pe1);
|
|
moveto(x, y);
|
|
|
|
for (i=uptr;i>=sfc();i--) {
|
|
pe2 = sndg[i][pIndex];
|
|
te2 = sndg[i][tIndex];
|
|
h2 = sndg[i][zIndex];
|
|
tp2 = wetlift(pe1, tp1, pe2);
|
|
|
|
if (qc(te2) && qc(tp2)) {
|
|
/* Account for Entrainment */
|
|
ent2 = ENTRAIN_DEFAULT * ((h1 - h2) / 1000);
|
|
tp2 = tp2 + ((te2 - tp2) * ent2);
|
|
|
|
x = temp_to_pix( tp2 , pe2 );
|
|
y = pres_to_pix( pe2 );
|
|
lineto(x, y);
|
|
|
|
pe1 = pe2;
|
|
te1 = te2;
|
|
h1 = h2;
|
|
tp1 = tp2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void copytodisplay(void)
|
|
{
|
|
XCopyArea(XtDisplay(draw_reg), canvas, XtWindow(draw_reg),
|
|
gc, 0, 0, xwdth, xhght, 0, 0);
|
|
XFlush(XtDisplay(draw_reg));
|
|
}
|
|
|
|
void display_dendritic_zone(short width)
|
|
{
|
|
short i, x, y, xold, yold;
|
|
short pIndex, tIndex;
|
|
float p_top, p_bot, ix1, ix2, ix3, ix4;
|
|
float t1, p1;
|
|
char st[20];
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tIndex = getParmIndex("TEMP");
|
|
|
|
if (!sndg || pIndex == -1 || tIndex == -1) return;
|
|
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
setlinestyle(1, width + 1);
|
|
setcolor(19);
|
|
|
|
/* Determine height of -16 temp */
|
|
p_top = temp_lvl(-17, &ix1);
|
|
|
|
/* Determine height of -12 temp */
|
|
p_bot = temp_lvl(-12, &ix1);
|
|
|
|
/* Loop though each observation and draw lines */
|
|
x = temp_to_pix(-17, p_top);
|
|
y = pres_to_pix(p_top);
|
|
moveto(x,y);
|
|
for( i=p_top; i <= p_bot; i=i+5)
|
|
{
|
|
xold = x;
|
|
yold = y;
|
|
|
|
t1 = i_temp(i, I_PRES);
|
|
x = temp_to_pix(t1, i);
|
|
y = pres_to_pix(i);
|
|
|
|
lineto(x, y);
|
|
}
|
|
|
|
/* Draw lines to define top/bottom of layer */
|
|
setlinestyle(1, 1);
|
|
setcolor(19);
|
|
set_font(3);
|
|
|
|
y = pres_to_pix(p_top);
|
|
moveto(skv.brx - 80, y);
|
|
lineto(skv.brx - 120, y);
|
|
sprintf( st, "%.0f'", mtof(i_hght(p_top, I_PRES)));
|
|
disp_param( st, skv.brx-130, y-10);
|
|
|
|
y = pres_to_pix(p_bot);
|
|
moveto(skv.brx - 80, y);
|
|
lineto(skv.brx - 120, y);
|
|
sprintf( st, "%.0f'", mtof(i_hght(p_bot, I_PRES)));
|
|
disp_param( st, skv.brx-130, y-10);
|
|
|
|
/* Draw marker for freezing level */
|
|
setcolor(16);
|
|
p_top = temp_lvl(0, &ix1);
|
|
if (p_top < (sndg[sfc()][pIndex] - 1))
|
|
{
|
|
y = pres_to_pix(p_top);
|
|
moveto(skv.brx - 80, y);
|
|
lineto(skv.brx - 120, y);
|
|
sprintf( st, "FRZ = %.0f'", mtof(i_hght(p_top, I_PRES)));
|
|
disp_param( st, skv.brx-130, y-10);
|
|
}
|
|
|
|
/* Draw marker for WBZ level */
|
|
setcolor(21);
|
|
p_top = wb_lvl(0, &ix1);
|
|
if (p_top < (sndg[sfc()][pIndex] - 1))
|
|
{
|
|
y = pres_to_pix(p_top);
|
|
moveto(skv.brx - 80, y);
|
|
lineto(skv.brx - 120, y);
|
|
sprintf( st, "WBZ = %.0f'", mtof(i_hght(p_top, I_PRES)));
|
|
disp_param( st, skv.brx-130, y-10);
|
|
}
|
|
}
|
|
|
|
void display_levels(short colr)
|
|
{
|
|
short i, x, y, xold, yold;
|
|
short pIndex, tIndex;
|
|
float p_top, p_bot, ix1, ix2, ix3, ix4;
|
|
float h;
|
|
char st[20];
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tIndex = getParmIndex("TEMP");
|
|
|
|
if (!sndg || pIndex == -1 || tIndex == -1) return;
|
|
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
setlinestyle(1, 1);
|
|
setcolor(colr);
|
|
set_font(4);
|
|
|
|
/* Draw sfc level */
|
|
h = 0;
|
|
y = pres_to_pix(i_pres(msl(h)));
|
|
setcolor(0);
|
|
rectangle(1, skv.tlx + 18, y-7, skv.tlx + 100, y+7);
|
|
setcolor(colr);
|
|
moveto(skv.tlx + 20, y);
|
|
lineto(skv.tlx + 30, y);
|
|
sprintf( st, "SFC (%.0fm)", i_hght(sndg[sfc()][pIndex], I_PRES));
|
|
outgtext(st, skv.tlx+ 35, y-5);
|
|
|
|
/* Draw 1km level */
|
|
h = 1000;
|
|
y = pres_to_pix(i_pres(msl(h)));
|
|
setcolor(0);
|
|
rectangle(1, skv.tlx + 18, y-7, skv.tlx + 60, y+7);
|
|
setcolor(colr);
|
|
moveto(skv.tlx + 20, y);
|
|
lineto(skv.tlx + 30, y);
|
|
sprintf( st, "1 km");
|
|
outgtext(st, skv.tlx+ 35, y-5);
|
|
|
|
/* Draw 3km level */
|
|
h = 3000;
|
|
y = pres_to_pix(i_pres(msl(h)));
|
|
setcolor(0);
|
|
rectangle(1, skv.tlx + 18, y-7, skv.tlx + 60, y+7);
|
|
setcolor(colr);
|
|
moveto(skv.tlx + 20, y);
|
|
lineto(skv.tlx + 30, y);
|
|
sprintf( st, "3 km");
|
|
outgtext(st, skv.tlx+ 35, y-5);
|
|
|
|
/* Draw 6km level */
|
|
h = 6000;
|
|
y = pres_to_pix(i_pres(msl(h)));
|
|
setcolor(0);
|
|
rectangle(1, skv.tlx + 18, y-7, skv.tlx + 60, y+7);
|
|
setcolor(colr);
|
|
moveto(skv.tlx + 20, y);
|
|
lineto(skv.tlx + 30, y);
|
|
sprintf( st, "6 km");
|
|
outgtext(st, skv.tlx+ 35, y-5);
|
|
|
|
/* Draw 9km level */
|
|
h = 9000;
|
|
y = pres_to_pix(i_pres(msl(h)));
|
|
setcolor(0);
|
|
rectangle(1, skv.tlx + 18, y-7, skv.tlx + 60, y+7);
|
|
setcolor(colr);
|
|
moveto(skv.tlx + 20, y);
|
|
lineto(skv.tlx + 30, y);
|
|
sprintf( st, "9 km");
|
|
outgtext(st, skv.tlx+ 35, y-5);
|
|
|
|
/* Draw 12km level */
|
|
h = 12000;
|
|
y = pres_to_pix(i_pres(msl(h)));
|
|
setcolor(0);
|
|
rectangle(1, skv.tlx + 18, y-7, skv.tlx + 65, y+7);
|
|
setcolor(colr);
|
|
moveto(skv.tlx + 20, y);
|
|
lineto(skv.tlx + 30, y);
|
|
sprintf( st, "12 km");
|
|
outgtext(st, skv.tlx+ 35, y-5);
|
|
|
|
/* Draw 15km level */
|
|
h = 15000;
|
|
y = pres_to_pix(i_pres(msl(h)));
|
|
setcolor(0);
|
|
rectangle(1, skv.tlx + 18, y-7, skv.tlx + 65, y+7);
|
|
setcolor(colr);
|
|
moveto(skv.tlx + 20, y);
|
|
lineto(skv.tlx + 30, y);
|
|
sprintf( st, "15 km");
|
|
outgtext(st, skv.tlx+ 35, y-5);
|
|
}
|
|
|
|
void display_effective_layer(short colr)
|
|
{
|
|
short i, x, y, xold, yold;
|
|
short pIndex, tIndex, x1, x2, x3;
|
|
float ptop, pbot, ix1, ix2, ix3, ix4;
|
|
float h, y1, y2;
|
|
char st[20];
|
|
Parcel pcl;
|
|
|
|
/* x1 = 350;
|
|
x2 = x1 + 40;
|
|
x3 = (x1 + x2) / 2;
|
|
*/
|
|
|
|
x1 = (xwdth*.31);
|
|
x2 = x1 + 40;
|
|
x3 = (x1 + x2) / 2;
|
|
|
|
pIndex = getParmIndex("PRES");
|
|
tIndex = getParmIndex("TEMP");
|
|
|
|
if (!sndg || pIndex == -1 || tIndex == -1) return;
|
|
|
|
setcliprgn(skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
setlinestyle(1, 2);
|
|
setcolor(colr);
|
|
set_font(4);
|
|
|
|
/* Get Effective Layer Data */
|
|
/* printf( "Getting Effective Layer Data\n");
|
|
*/
|
|
|
|
/* 24 Mar 2008 */
|
|
effective_inflow_layer(100,-250, &p_bot, &p_top);
|
|
|
|
/* printf("\n display elayer pbot = %.1f\n", p_bot);
|
|
printf("\n display elayer pbot = %.1f\n", p_top);
|
|
*/
|
|
if (p_bot < 1) return;
|
|
|
|
/* Draw effective sfc level */
|
|
/* printf( "Drawing Effective Layer Data\n");
|
|
*/ y = pres_to_pix(p_bot);
|
|
y1 = y;
|
|
moveto(skv.brx - x1, y);
|
|
lineto(skv.brx - x2, y);
|
|
if (agl(i_hght(p_bot, I_PRES)) < 1)
|
|
{ sprintf( st, "SFC", agl(i_hght(p_bot, I_PRES))); }
|
|
else
|
|
{ sprintf( st, "%.0fm", agl(i_hght(p_bot, I_PRES))); }
|
|
setcolor(0);
|
|
rectangle(1, skv.brx - x2 - 42, y-3, skv.brx - x2 - 1, y+10);
|
|
setcolor(colr);
|
|
outgtext(st, skv.brx - x2 - 40, y-2);
|
|
|
|
/* Draw effective top level */
|
|
y = pres_to_pix(p_top);
|
|
y2 = y;
|
|
moveto(skv.brx - x1, y);
|
|
lineto(skv.brx - x2, y);
|
|
setcolor(0);
|
|
rectangle(1, skv.brx - x2 - 42, y-13, skv.brx - x2 - 1, y-1);
|
|
setcolor(colr);
|
|
sprintf( st, "%.0fm", agl(i_hght(p_top, I_PRES)));
|
|
outgtext(st, skv.brx - x2 - 40, y-12);
|
|
|
|
/* Draw connecting line */
|
|
moveto(skv.brx - x3, y1);
|
|
lineto(skv.brx - x3, y2);
|
|
|
|
/* Compute and display effective helicity */
|
|
ix4 = helicity(agl(i_hght(p_bot, I_PRES)), agl(i_hght(p_top, I_PRES)), st_dir, st_spd, &ix1, &ix2);
|
|
setcolor(0);
|
|
rectangle(1, skv.brx-x2 -8, y2-12, skv.brx-x2+50, y2-1);
|
|
setcolor(colr);
|
|
sprintf( st, "%4.0f m%cs%c", ix4, 178, 178 );
|
|
outgtext(st, skv.brx - x2, y2-13);
|
|
|
|
/* Mark effective layer on hodograph */
|
|
|
|
|
|
/* define_parcel(6, 100);
|
|
ix1 = parcel( -1, -1, lplvals.pres, lplvals.temp, lplvals.dwpt, &pcl);
|
|
sprintf( st, "%4.0f J/kg", pcl.bplus);
|
|
outgtext(st, skv.brx - x2, y1+5); */
|
|
}
|
|
#endif
|