Former-commit-id:7fa9dbd5fb
[formerly4bfbdad17d
] [formerly9f8cb727a5
] [formerly8485b90ff8
[formerly9f8cb727a5
[formerly bf53d06834caa780226121334ac1bcf0534c3f16]]] Former-commit-id:8485b90ff8
Former-commit-id: 73930fb29d0c1e91204e76e6ebfdbe757414f319 [formerlya28d70b5c5
] Former-commit-id:33a67cdd82
1216 lines
37 KiB
C
1216 lines
37 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 */
|
|
/* 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 */
|
|
/* */
|
|
/***************************************************************/
|
|
/* OPC MODIFICATION - J. Morgan 5/12/05 */
|
|
/* header - Added isobar_nolabel */
|
|
/* draw_skewt() - Added drawing of OPC diagnostic layers */
|
|
/* ISOBAR_NOLABEL - New function */
|
|
/***************************************************************/
|
|
#define GLOBAL
|
|
#define VIDEO
|
|
#include "gui.h"
|
|
#include "sharp95.h"
|
|
|
|
/*
|
|
* Private functions
|
|
*/
|
|
void dry_adiabat (float thta);
|
|
void hodo_to_pix (float dir, float mag, short *x, short *y);
|
|
void isobar (float pres, short flag);
|
|
void isotherm (float temp);
|
|
void plot_barbs (void);
|
|
void trace_hodo (short width);
|
|
void trace_temp (struct sndg_struct *sp, short width);
|
|
void trace_temp2 (short width);
|
|
void trace_vtmp (short width);
|
|
void trace_wetbulb (short width);
|
|
void trace_dwpt (struct sndg_struct *sp, short width);
|
|
void trace_dwpt2 (short width);
|
|
void vvel_profile (void);
|
|
void wind_barb (float wdir, float wspd, short x, short y, short siz);
|
|
void isobar_nolabel (float pres);
|
|
|
|
|
|
/*===============================================================================*/
|
|
|
|
void
|
|
make_screen (void)
|
|
/*************************************************************/
|
|
/* MAKE_SCREEN */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws basic SHARP graphic template on screen, including */
|
|
/* areas, buttons, and tables. */
|
|
/* */
|
|
/*************************************************************/
|
|
{
|
|
/* char st[80]; */
|
|
|
|
pagenum = 1;
|
|
|
|
X_Init ();
|
|
|
|
/* ----- RAOB Title Line ----- */
|
|
setcolor (1, draw_reg, gc);
|
|
set_font (1);
|
|
|
|
/* ----- Parameter Area ----- */
|
|
setcolor (4, draw_reg, gc);
|
|
rectangle (1, (short) (skv.brx + 20), skv.tly, (short) (xwdth - 5),
|
|
(short) (xhght - 5));
|
|
setcolor (1, draw_reg, gc);
|
|
rectangle (0, (short) (skv.brx + 20), skv.tly, (short) (xwdth - 5),
|
|
(short) (xhght - 5));
|
|
|
|
/* ----- Cursor Data Area ----- *-
|
|
setcolor(3, draw_reg, gc);
|
|
strcpy( st, "CURSOR DATA" );
|
|
outgtext ( st,
|
|
(((skv.brx + 20 + xwdth) / 2) - (getgtextextent( st ) / 2)),
|
|
skv.tly + 5 );
|
|
setcolor(0, draw_reg, gc);
|
|
rectangle( 1, (short)(skv.brx+30), (short)(skv.tly+22), (short)(xwdth-15), 100);
|
|
setcolor(1, draw_reg, gc);
|
|
rectangle( 0, (short)(skv.brx+30), (short)(skv.tly+22), (short)(xwdth-15), 100); */
|
|
|
|
mode = 1;
|
|
pagenum = 1;
|
|
|
|
/* ----- Begin Main Processing Loop ----- */
|
|
StartLoop ();
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
void draw_skewt (void)
|
|
/*************************************************************/
|
|
/* DRAW_SKEWT */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws a standard Skew-T/LogP diagram. */
|
|
/*************************************************************/
|
|
{
|
|
short i;
|
|
float thta;
|
|
float ix1, ix2, ix3, ix4, ix5, ix6, ix7;
|
|
float lvl[] =
|
|
{ 1050.0F, 1000.0F, 850.0F, 700.0F, 500.0F, 300.0F, 200.0F, 100.0F };
|
|
char rtitle[200];
|
|
|
|
setcliprgn (1, 1, xwdth, xhght, draw_reg, gc);
|
|
setcolor (0, draw_reg, gc);
|
|
rectangle (1, 1, 1, skv.brx + 14, skv.bry + skv.tly + 14);
|
|
setcolor (1, draw_reg, gc);
|
|
set_font (2);
|
|
setcliprgn (skv.tlx, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
rectangle (0, skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
|
|
/* ----- Draw Skewed Temperature Lines ----- */
|
|
setcolor (24, draw_reg, gc);
|
|
setlinestyle (2, 1);
|
|
for (i = (-160); i <= 50; i = i + 10)
|
|
{
|
|
isotherm ((float) i);
|
|
}
|
|
|
|
/* ----- Draw Dry Adiabats ----- */
|
|
setcolor (24, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
for (thta = (-70.0F); thta <= 350.0F; thta = thta + 20.0F)
|
|
{
|
|
dry_adiabat (thta);
|
|
};
|
|
|
|
/* ----- Draw Horizontal Pressure Lines ----- */
|
|
setcolor (1, draw_reg, gc);
|
|
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);
|
|
}
|
|
|
|
/* ----- Draw OPC Horizontal Stability Lines ----- *
|
|
************************************************************************
|
|
* OPC MODIFICATION - J. Morgan 5/12/05 *
|
|
* Draws: *
|
|
* Lowest Inversion Height *
|
|
* Layer Based Mixing Height *
|
|
* Surface Based Mixing Height *
|
|
* Calls: *
|
|
* xwvid.c: void isobar_nolabel () *
|
|
* skparams.c: void low_inv () *
|
|
* skparams.c: void mix_height () *
|
|
***********************************************************************/
|
|
|
|
low_inv( &ix1, &ix2 );
|
|
setcolor (5, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
isobar_nolabel (ix1);
|
|
|
|
mix_height( &ix1, &ix2, &ix3, &ix4, &ix5, &ix6, &ix7, 1);
|
|
setcolor (6, draw_reg, gc);
|
|
setlinestyle (2, 1);
|
|
isobar_nolabel (ix1);
|
|
|
|
mix_height( &ix1, &ix2, &ix3, &ix4, &ix5, &ix6, &ix7, 0);
|
|
setcolor (7, draw_reg, gc);
|
|
setlinestyle (4, 1);
|
|
isobar_nolabel (ix1);
|
|
|
|
/* Draw frame boarder */
|
|
setcolor (1, draw_reg, gc);
|
|
rectangle (0, skv.tlx, skv.tly, skv.brx, skv.bry);
|
|
|
|
if (sndgp != NULL)
|
|
{
|
|
|
|
/* ----- Plot old sounding if exists ----- */
|
|
setcolor (28, draw_reg, gc);
|
|
if ((overlay_previous == 1) && (sndgp->ovrlev > 0))
|
|
{
|
|
trace_temp2 (3);
|
|
trace_dwpt2 (3);
|
|
}
|
|
|
|
if (sndgp->numlev > 0)
|
|
{
|
|
/* ----- Plot Environmental Temperature Data ----- */
|
|
setcolor (2, draw_reg, gc);
|
|
trace_temp (sndgp, 3);
|
|
|
|
/* ----- Plot Environmental Dew Point Data ----- */
|
|
setcolor (3, draw_reg, gc);
|
|
trace_dwpt (sndgp, 3);
|
|
|
|
/* ----- Plot Environmental Virtual Temperature Data ----- */
|
|
setcolor (2, draw_reg, gc);
|
|
trace_vtmp (1);
|
|
|
|
/* ----- Plot Environmental Wetbulb Temperature Data ----- */
|
|
setcolor (6, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
trace_wetbulb (1);
|
|
|
|
/* ----- Plot Wind Barbs ----- */
|
|
setcolor (5, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
plot_barbs ();
|
|
|
|
/* ----- If Available, plot VVEL profile ----- */
|
|
vvel_profile ();
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----- Display Skew-T Inset ----- */
|
|
draw_skinset ();
|
|
|
|
setcliprgn (1, 1, xwdth, xhght, draw_reg, gc);
|
|
setcolor (1, draw_reg, gc);
|
|
set_font (1);
|
|
|
|
sprintf (rtitle, "%s (%s)", sndgp->title, raob_type);
|
|
outgtext (rtitle, skv.tlx, 1);
|
|
|
|
update_text_values ();
|
|
}
|
|
|
|
XCopyArea (XtDisplay (draw_reg), canvas, XtWindow (draw_reg),
|
|
gc, 0, 0, xwdth, xhght, 0, 0);
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
void
|
|
draw_hodo (void)
|
|
/*************************************************************/
|
|
/* DRAW_HODO */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws a standard Hodograph display. */
|
|
/*************************************************************/
|
|
{
|
|
short x1, y1, x2, y2, i, y3;
|
|
float wdir, wspd, mnu, mnv, ix1, ix2, ix3, ix4;
|
|
char st[10];
|
|
|
|
setcolor (0, draw_reg, gc);
|
|
rectangle (1, 1, 1, hov.brx + 14, hov.bry + 14);
|
|
setcolor (1, draw_reg, gc);
|
|
set_font (2);
|
|
setcliprgn (hov.tlx, hov.tly, hov.brx, hov.bry, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
rectangle (0, hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
|
|
/* ----- Plot crosshairs ----- */
|
|
setcolor (31, draw_reg, gc);
|
|
hodo_to_pix (180.0F, 60.0F, &x1, &y1);
|
|
moveto (x1, hov.tly);
|
|
lineto (x1, hov.bry);
|
|
|
|
setcolor (31, draw_reg, gc);
|
|
hodo_to_pix (270.0F, 60.0F, &x1, &y1);
|
|
moveto (hov.tlx, y1);
|
|
lineto (hov.brx, y1);
|
|
|
|
/* ----- Plot Radius circles ----- */
|
|
setcolor (24, draw_reg, gc);
|
|
setlinestyle (2, 1);
|
|
hodo_to_pix (0.0F, 0.0F, &x1, &y1);
|
|
x2 = x1;
|
|
y2 = y1;
|
|
for (i = hov.scale; i <= hov.hodomag; i = i + hov.scale)
|
|
{
|
|
hodo_to_pix (0.0F, (float) i, &x1, &y1);
|
|
y3 = (y1 - y2);
|
|
ellipse (0, x2 - y3, y2 - y3, x2 + y3, y2 + y3);
|
|
}
|
|
|
|
setcolor (1, draw_reg, gc);
|
|
/* ----- Plot X-Coord hash marks ----- */
|
|
for (i = hov.scale; i <= hov.hodomag; i = i + hov.scale)
|
|
{
|
|
hodo_to_pix (180.0F, (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.0F, (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, draw_reg, gc);
|
|
for (i = hov.scale; i <= hov.hodomag; i = i + hov.scale)
|
|
{
|
|
hodo_to_pix (90.0F, (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.0F, (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, draw_reg, gc);
|
|
setlinestyle (1, 2);
|
|
|
|
if ((sndgp != NULL) && (sndgp->numlev > 0))
|
|
{
|
|
trace_hodo (3);
|
|
|
|
/* ----- Plot Mean Wind Vector ----- yellow square */
|
|
setcolor (5, draw_reg, gc);
|
|
mean_wind (-1.0F, -1.0F, &mnu, &mnv, &wdir, &wspd);
|
|
hodo_to_pix (wdir, wspd, &x1, &y1);
|
|
moveto (x1, y1);
|
|
rectangle (0, (short) (x1 - 4), (short) (y1 - 4), (short) (x1 + 4),
|
|
(short) (y1 + 4));
|
|
|
|
|
|
/* ----- Plot 30/75 Storm Motion Vector -----small light pink circle */
|
|
mean_wind (sndgp->sndg[sfc ()].pres, i_pres (msl (6000.0F)), &ix1, &ix2,
|
|
&ix3, &ix4);
|
|
setcolor (11, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
ix4 *= .75F;
|
|
ix3 += 30.0F;
|
|
if (ix3 > 360.0F)
|
|
ix3 -= 360.0F;
|
|
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 15/85 Storm Motion Vector ----- small light brick color circle*/
|
|
mean_wind (sndgp->sndg[sfc ()].pres, i_pres (msl (6000.0F)), &ix1, &ix2,
|
|
&ix3, &ix4);
|
|
setcolor (12, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
ix4 *= .85F;
|
|
ix3 += 15.0F;
|
|
if (ix3 > 360.0F)
|
|
ix3 -= 360.0F;
|
|
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 ----bigger-white circle , initially at same location as 30/75 stomr */
|
|
setcolor (31, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
hodo_to_pix (sndgp->st_dir, sndgp->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);
|
|
|
|
/* ----- Display Hodograph Inset ----- */
|
|
draw_hoinset ();
|
|
|
|
setcolor (1, draw_reg, gc);
|
|
set_font (1);
|
|
outgtext (sndgp->title, skv.tlx, 1);
|
|
}
|
|
|
|
|
|
/* ----- Draw final outline of hodograph ----- */
|
|
setcolor (1, draw_reg, gc);
|
|
setlinestyle (1, 1);
|
|
rectangle (0, hov.tlx, hov.tly, hov.brx, hov.bry);
|
|
|
|
/* reset clip region */
|
|
setcliprgn (1, 1, xwdth, xhght, draw_reg, gc);
|
|
|
|
XCopyArea (XtDisplay (draw_reg), canvas, XtWindow (draw_reg),
|
|
gc, 0, 0, xwdth, xhght, 0, 0);
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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;
|
|
float scle;
|
|
|
|
scle = (float) ((hov.brx - hov.tlx) / hov.hodomag);
|
|
midx = hov.tlx + ((hov.brx - hov.tlx) / 2) + (hov.xshift * scle);
|
|
midy = hov.tly + ((hov.bry - hov.tly) / 2) - (hov.yshift * scle);
|
|
|
|
*x = (short) (midx - (ucomp (dir, mag) * scle));
|
|
*y = (short) (midy + (vcomp (dir, mag) * scle));
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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;
|
|
|
|
scle = (hov.brx - hov.tlx) / hov.hodomag; /* pixels/knot */
|
|
midx = hov.tlx + ((hov.brx - hov.tlx) / 2) + (hov.xshift * scle);
|
|
midy = hov.tly + ((hov.bry - hov.tly) / 2) - (hov.yshift * scle);
|
|
|
|
u = (midx - x) / scle;
|
|
v = (y - midy) / scle;
|
|
|
|
*dir = angle (u, v);
|
|
*mag = (float) (sqrt ((u * u) + (v * v)));
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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;
|
|
|
|
if (sndgp == NULL)
|
|
return;
|
|
|
|
setlinestyle (1, width);
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if (qc (sndgp->sndg[i].drct) && qc (sndgp->sndg[i].sped))
|
|
{
|
|
|
|
if (sndgp->sndg[i].hght <= msl (3000.0F))
|
|
setcolor (2, draw_reg, gc);
|
|
else if (sndgp->sndg[i].hght > msl (3000.0F)
|
|
&& sndgp->sndg[i].hght <= msl (6000.0F))
|
|
setcolor (3, draw_reg, gc);
|
|
else if (sndgp->sndg[i].hght > msl (6000.0F)
|
|
&& sndgp->sndg[i].hght <= msl (9000.0F))
|
|
setcolor (5, draw_reg, gc);
|
|
else if (sndgp->sndg[i].hght > msl (9000.0F)
|
|
&& sndgp->sndg[i].hght <= msl (12000.0F))
|
|
setcolor (6, draw_reg, gc);
|
|
else if (sndgp->sndg[i].hght > msl (12000.0F))
|
|
setcolor (28, draw_reg, gc);
|
|
|
|
xold = x;
|
|
yold = y;
|
|
hodo_to_pix (sndgp->sndg[i].drct, sndgp->sndg[i].sped, &x, &y);
|
|
if (ok == 0)
|
|
{
|
|
moveto (x, y);
|
|
ok = 1;
|
|
}
|
|
else
|
|
{
|
|
moveto (xold, yold);
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
for (pres = 1050; pres >= 100; pres = pres - 50)
|
|
{
|
|
temp = (float) ((((double) thta + 273.15) / pow (1000.0 /
|
|
(double) pres,
|
|
ROCP)) - 273.15);
|
|
|
|
x = temp_to_pix (temp, pres);
|
|
y = pres_to_pix (pres);
|
|
|
|
/*
|
|
if( pres <= 200) { printf( "%f %f %d\n", pres, temp, x);}
|
|
*/
|
|
|
|
if (pres == 1050)
|
|
{
|
|
moveto (x, y);
|
|
}
|
|
else
|
|
{
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
void
|
|
isotherm (float temp)
|
|
/*************************************************************/
|
|
/* ISOTHERM */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Draws temperature lines (temp, c) on SkewT graphic. */
|
|
/*************************************************************/
|
|
{
|
|
short x, y;
|
|
char st[10];
|
|
|
|
setcolor (24, draw_reg, gc);
|
|
x = temp_to_pix (temp, 1050);
|
|
y = skv.bry;
|
|
if ((temp >= -30) && (temp <= 50))
|
|
{
|
|
setcliprgn (1, 1, xwdth, xhght, draw_reg, gc);
|
|
itoa ((short) temp, st, 10);
|
|
setcolor (1, draw_reg, gc);
|
|
outgtext (st, x - (getgtextextent (st) / 2), y);
|
|
setcolor (24, draw_reg, gc);
|
|
}
|
|
setcliprgn (skv.tlx, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
moveto (x, y);
|
|
x = temp_to_pix (temp, 100);
|
|
y = skv.tly;
|
|
lineto (x, y);
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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, draw_reg, gc);
|
|
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, skv.bry, draw_reg, gc);
|
|
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
|
|
trace_temp (struct sndg_struct *sp, short width)
|
|
/*************************************************************/
|
|
/* TRACE_TEMP */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental temperature trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, xold, yold, ok = 0;
|
|
|
|
setcliprgn (skv.tlx, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
setlinestyle (1, width);
|
|
for (i = 0; i < sp->numlev; i++)
|
|
{
|
|
if (sp->sndg[i].temp > -200)
|
|
{
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix (sndgp->sndg[i].temp, sndgp->sndg[i].pres);
|
|
y = pres_to_pix (sndgp->sndg[i].pres);
|
|
if (ok == 0)
|
|
{
|
|
moveto (x, y);
|
|
ok = 1;
|
|
}
|
|
else
|
|
{
|
|
moveto (xold, yold);
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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, numlvl2;
|
|
|
|
numlvl2 = sndgp->ovrlev;
|
|
setcliprgn (skv.tlx, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
setlinestyle (1, width);
|
|
for (i = 0; i < numlvl2; i++)
|
|
{
|
|
if (sndgp->ovrl[i].temp > -200)
|
|
{
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix (sndgp->ovrl[i].temp, sndgp->ovrl[i].pres);
|
|
y = pres_to_pix (sndgp->ovrl[i].pres);
|
|
if (ok == 0)
|
|
{
|
|
moveto (x, y);
|
|
ok = 1;
|
|
}
|
|
else
|
|
{
|
|
moveto (xold, yold);
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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;
|
|
|
|
setlinestyle (3, width);
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if (qc (sndgp->sndg[i].temp) && qc (sndgp->sndg[i].dwpt))
|
|
{
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix (i_vtmp (sndgp->sndg[i].pres), sndgp->sndg[i].pres);
|
|
y = pres_to_pix (sndgp->sndg[i].pres);
|
|
if (ok == 0)
|
|
{
|
|
moveto (x, y);
|
|
ok = 1;
|
|
}
|
|
else
|
|
{
|
|
moveto (xold, yold);
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
void
|
|
trace_dwpt (struct sndg_struct *sp, short width)
|
|
/*************************************************************/
|
|
/* TRACE_DWPT */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots environmental Dew Point trace on SkewT. */
|
|
/*************************************************************/
|
|
{
|
|
short i, x, y, xold, yold, ok = 0;
|
|
|
|
setcliprgn (skv.tlx, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
setlinestyle (1, width);
|
|
for (i = 0; i < sp->numlev; i++)
|
|
{
|
|
if (sp->sndg[i].dwpt > -200)
|
|
{
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix (sp->sndg[i].dwpt, sp->sndg[i].pres);
|
|
y = pres_to_pix (sp->sndg[i].pres);
|
|
if (ok == 0)
|
|
{
|
|
moveto (x, y);
|
|
ok = 1;
|
|
}
|
|
else
|
|
{
|
|
moveto (xold, yold);
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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, numlvl2;
|
|
|
|
numlvl2 = sndgp->ovrlev;
|
|
setcliprgn (skv.tlx, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
setlinestyle (1, width);
|
|
for (i = 0; i < numlvl2; i++)
|
|
{
|
|
if (sndgp->ovrl[i].dwpt > -200)
|
|
{
|
|
xold = x;
|
|
yold = y;
|
|
x = temp_to_pix (sndgp->ovrl[i].dwpt, sndgp->ovrl[i].pres);
|
|
y = pres_to_pix (sndgp->ovrl[i].pres);
|
|
if (ok == 0)
|
|
{
|
|
moveto (x, y);
|
|
ok = 1;
|
|
}
|
|
else
|
|
{
|
|
moveto (xold, yold);
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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;
|
|
|
|
setlinestyle (1, width);
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if (sndgp->sndg[i].dwpt > -200)
|
|
{
|
|
xold = x;
|
|
yold = y;
|
|
|
|
t1 =
|
|
wetbulb (sndgp->sndg[i].pres, sndgp->sndg[i].temp,
|
|
sndgp->sndg[i].dwpt);
|
|
|
|
x = temp_to_pix (t1, sndgp->sndg[i].pres);
|
|
y = pres_to_pix (sndgp->sndg[i].pres);
|
|
if (ok == 0)
|
|
{
|
|
moveto (x, y);
|
|
ok = 1;
|
|
}
|
|
else
|
|
{
|
|
moveto (xold, yold);
|
|
lineto (x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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 ((double) pres);
|
|
return (skv.bry - (short) ((scl2 / scl1) * (skv.bry - skv.tly)));
|
|
}
|
|
|
|
/*==============================================================================*/
|
|
|
|
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 = (double) (skv.bry - pix);
|
|
scl3 = (double) (skv.bry - skv.tly + 1);
|
|
return (float) (1050.0 / 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 = (float) 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*/ 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;
|
|
|
|
if (!qc (pres) || !qc (temp) || !qc (dwpt))
|
|
return;
|
|
|
|
setcolor (31, draw_reg, gc);
|
|
setlinestyle (4, 1);
|
|
|
|
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);
|
|
}
|
|
|
|
/*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, maxsiz = 3;
|
|
float dx, dy, spcx, spcy, wid, hgt;
|
|
|
|
dx = (ucomp (wdir, 10) * (float) siz) / 1.5F;
|
|
dy = (vcomp (wdir, 10) * (float) siz) / 1.5F;
|
|
|
|
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) ----- */
|
|
while (sped > 47)
|
|
{
|
|
x1 = x1 - (short) spcx;
|
|
y1 = y1 + (short) spcy;
|
|
|
|
hgt = .5F; /* Heigth 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; /* Heigth 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; /* Heigth 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 ii, xx, yy;
|
|
float lastpres;
|
|
|
|
setcliprgn (1, 1, xwdth, xhght, draw_reg, gc);
|
|
lastpres = 1100;
|
|
for (ii = 0; ii < sndgp->numlev; ii++)
|
|
{
|
|
if (qc (sndgp->sndg[ii].drct))
|
|
{
|
|
yy = pres_to_pix (sndgp->sndg[ii].pres);
|
|
xx = skv.brx - 40;
|
|
|
|
if ((sndgp->sndg[ii].hght - i_hght (lastpres)) > 400)
|
|
{
|
|
wind_barb (sndgp->sndg[ii].drct, sndgp->sndg[ii].sped, xx, yy,
|
|
4);
|
|
lastpres = sndgp->sndg[ii].pres;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*==============================================================================*/
|
|
|
|
void
|
|
vvel_profile (void)
|
|
/*************************************************************/
|
|
/* VVEL_PROFILE */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Plots vertical velocity profile */
|
|
/*************************************************************/
|
|
{
|
|
short i, x1, x2, y, avail, leng;
|
|
|
|
avail = 0;
|
|
setcliprgn (1, 1, xwdth, xhght, draw_reg, gc);
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if (qc (sndgp->sndg[i].omega) && (sndgp->sndg[i].omega < 1))
|
|
{
|
|
avail++;
|
|
y = pres_to_pix (sndgp->sndg[i].pres);
|
|
x1 = skv.tlx + 40;
|
|
leng = (sndgp->sndg[i].omega * 1000); /* Convert to Mbs/sec */
|
|
x2 = x1 - (leng * 2); /* Determine screen scale */
|
|
setcolor (25, draw_reg, gc);
|
|
if (sndgp->sndg[i].omega < 0)
|
|
setcolor (12, draw_reg, gc);
|
|
moveto (x1, y);
|
|
lineto (x2, y);
|
|
}
|
|
}
|
|
|
|
/* ----- Draw Scales ----- */
|
|
if (avail > 5)
|
|
{
|
|
setcolor (7, draw_reg, gc);
|
|
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);
|
|
}
|
|
}
|
|
|
|
void isobar_nolabel (float pres)
|
|
/*************************************************************/
|
|
/* OPC MODIFICATION - J. Morgan 5/12/05 */
|
|
/* ISOBAR_NOLABEL - New function */
|
|
/* */
|
|
/* ISOBAR_NOLABEL */
|
|
/* J. Morgan OPC */
|
|
/* */
|
|
/* Modification of void isobar() to draw pressure (pres) */
|
|
/* without a label on SkewT graphic */
|
|
/* */
|
|
/* Called by xwvid1.c: draw_skewt() */
|
|
/*************************************************************/
|
|
{
|
|
short y;
|
|
|
|
setcliprgn (1, 1, xwdth, xhght, draw_reg, gc);
|
|
y = pres_to_pix (pres);
|
|
moveto (skv.tlx, y);
|
|
setcliprgn (skv.tlx, skv.tly, skv.brx, skv.bry, draw_reg, gc);
|
|
moveto (skv.tlx, y);
|
|
lineto (skv.brx, y);
|
|
}
|