float i_wndv ( float pres ) /*************************************************************/ /* I_WNDV */ /* John Hart NSSFC KCMO */ /* */ /* Interpolates the given data to calculate a */ /* v-component to the wind at pressure level (pres). */ /* */ /* pres - Level(mb) to compute a V-Component */ /*************************************************************/ { short below, above, i, ok; float vtop, vbot, nm1; if ( sndgp == NULL ) return ( -999.0F ); below=0; above=0; /* ----- Find Wind Immediately Above level ----- */ ok = 0; for (i = 0; i < sndgp->numlev; i++) { if((sndgp->sndg[i].pres == pres) && (sndgp->sndg[i].drct != -999.0F) && (sndgp->sndg[i].sped != -999.0F)) return vcomp( sndgp->sndg[i].drct, sndgp->sndg[i].sped ); if((sndgp->sndg[i].pres < pres) && (sndgp->sndg[i].drct != -999.0F)) { above = i; ok=1; break; } } if( ok == 0 ) return -999.0F; /* ----- Find Wind Immediately Below level ----- */ ok = 0; for (i = sndgp->numlev - 1; i > -1; i--) { if((sndgp->sndg[i].pres >= pres) && (sndgp->sndg[i].drct != -999.0F)) { below = i; ok=1; break; } } if( ok == 0 ) return -999.0F; /* ----- If both levels are the same, return them ---- */ if( above == below) { return vcomp( sndgp->sndg[above].drct, sndgp->sndg[above].sped ); } /* ----- Now we need to interpolate to get the Wind ----- */ nm1 = sndgp->sndg[below].pres - pres; vbot = vcomp( sndgp->sndg[below].drct, sndgp->sndg[below].sped ); vtop = vcomp( sndgp->sndg[above].drct, sndgp->sndg[above].sped ); return vbot - ((nm1 / (sndgp->sndg[below].pres - sndgp->sndg[above].pres)) * (vbot - vtop)); }
/*NP*/ void plot_vis(void) /*************************************************************/ /* PLOT_VIS */ /* John Hart NSSFC KCMO */ /* */ /* Plots the results of storm-relative parcel trajectory. */ /*************************************************************/ { float sfctemp, sfcdwpt, sfcpres, ix1; short x1, y1, x2, y2, ulx, uly, vwid; Parcel pcl; ulx = hov.tlx; uly = hov.bry; vwid = 120; setcliprgn( ulx, uly, ulx + vwid, uly + vwid - 1); setcolor(0); setlinestyle( 1, 1 ); rectangle( 1, ulx, uly, ulx + vwid, uly + vwid - 1); setcolor(1); rectangle( 0, ulx, uly, ulx + vwid, uly + vwid - 1); /* ----- Plot Crosshairs ----- */ setcolor(24); moveto(ulx, uly + (vwid/2)); lineto(ulx + vwid, uly + (vwid/2)); moveto(ulx + (vwid/2), uly); lineto(ulx + (vwid/2), uly + vwid); /* ----- Plot Label ----- */ setcolor(1); /* outgtext( "Storm", hov.brx-145, hov.tly + 125 ); */ outgtext( "Storm Slinky", ulx + 5, uly + vwid-13 ); /* ----- Calculate Parcel Data ----- */ sfctemp = lplvals.temp; sfcdwpt = lplvals.dwpt; sfcpres = lplvals.pres; ix1 = parcel( -1, -1, sfcpres, sfctemp, sfcdwpt, &pcl); /* ----- Plot storm motion ----- */ x1 = ulx + (vwid/2); y1 = uly + (vwid/2); x2 = x1 + (short)ucomp( st_dir, 30); y2 = y1 - (short)vcomp( st_dir, 30); setcolor(31); moveto( x1, y1); lineto( x2, y2); /* ----- Run Visualization Routine ----- */ ix1 = visual1( pcl.lfcpres, pcl.elpres, sfcpres, sfctemp, sfcdwpt, ulx, uly, vwid); setcliprgn(1, 1, xwdth, xhght); }
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)); }
/*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); } }