Former-commit-id:fd2abfb6f1
[formerly 99fb675cc2e1b94825ccda1fe09b1be0c3c25b3f] Former-commit-id:cd49ef3eda
735 lines
24 KiB
C
735 lines
24 KiB
C
/***************************************************************/
|
|
/* SHARP-95 */
|
|
/* Advanced Interactive Sounding Analysis Program */
|
|
/* */
|
|
/* Basic Interpolation and Conversion Routines */
|
|
/* */
|
|
/* John A. Hart */
|
|
/* National Severe Storms Forecast Center */
|
|
/* Kansas City, Missouri */
|
|
/* -------------------------------------------------- */
|
|
/* List of Routines in this module: */
|
|
/* */
|
|
/* I_TEMP */
|
|
/* I_DWPT */
|
|
/* I_PRES */
|
|
/* I_HGHT */
|
|
/* I_VTMP */
|
|
/* I_WDIR */
|
|
/* I_WSPD */
|
|
/* I_WNDU */
|
|
/* I_WNDV */
|
|
/* I_OMEG */
|
|
/* VIRTEMP */
|
|
/* SFC */
|
|
/* TOP_PRES */
|
|
/* QC */
|
|
/* QC2 */
|
|
/* MTOF */
|
|
/* FTOM */
|
|
/* FTOC */
|
|
/* CTOF */
|
|
/* AGL */
|
|
/* MSL */
|
|
/* KT_TO_MPS */
|
|
/***************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sharp95.h>
|
|
|
|
/*NP*/
|
|
float i_temp( float pres )
|
|
/*************************************************************/
|
|
/* I_TEMP */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a temperature. */
|
|
/* at pressure level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a temperature */
|
|
/*************************************************************/
|
|
{
|
|
short below, above, i, ok;
|
|
double nm1, nm2, nm4;
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Temperature Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < numlvl; i++)
|
|
{
|
|
if((sndg[i][1] == pres) && ( qc(sndg[i][3]) ) )
|
|
{
|
|
/* if pressure level exists, and temp exists, no need to interpolate */
|
|
return sndg[i][3];
|
|
}
|
|
if((sndg[i][1] < pres) && ( qc(sndg[i][3]) ) )
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Temperature Immediately Below level ----- */
|
|
ok = 0;
|
|
for (i = numlvl-1; i > -1; i--)
|
|
{
|
|
if((sndg[i][1] >= pres) && (sndg[i][3] != -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 sndg[above][3];
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the temperature ----- */
|
|
|
|
nm1 = sndg[above][3] - sndg[below][3];
|
|
nm2 = log( sndg[below][1] / sndg[above][1] );
|
|
nm4 = log( sndg[below][1] / pres );
|
|
return (float)(sndg[below][3] + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*NP*/
|
|
float i_dwpt( float pres )
|
|
/*************************************************************/
|
|
/* I_DWPT */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a dew point */
|
|
/* at pressure level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a Dew Point */
|
|
/*************************************************************/
|
|
{
|
|
short below, above, i, ok;
|
|
double nm1, nm2, nm4;
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Dew Point Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < numlvl; i++)
|
|
{
|
|
if((sndg[i][1] == pres) && (sndg[i][4] != -999) && (sndg[i][1] != -999))
|
|
{
|
|
/* no need to interpolate if we have the level and dewpoint exists */
|
|
return sndg[i][4];
|
|
}
|
|
if((sndg[i][1] < pres) && (sndg[i][4] != -999.0F))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Dew Point Immediately Below level ----- */
|
|
ok=0;
|
|
for (i = numlvl - 1; i > -1; i--)
|
|
{
|
|
if((sndg[i][1] >= pres) && (sndg[i][4] != -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 sndg[above][4];
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the dew point ----- */
|
|
nm1 = sndg[above][4] - sndg[below][4];
|
|
nm2 = log( sndg[below][1] / sndg[above][1] );
|
|
nm4 = log( sndg[below][1] / pres );
|
|
return (float)(sndg[below][4] + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*NP*/
|
|
float i_hght( float pres )
|
|
/*************************************************************/
|
|
/* I_HGHT */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a height */
|
|
/* at pressure level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a Height */
|
|
/*************************************************************/
|
|
{
|
|
short below, above, i, ok, itophght;
|
|
double nm1, nm2, nm3, nm4;
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Height Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < numlvl; i++)
|
|
{
|
|
if((sndg[i][1] == pres) && (sndg[i][2] != -999) && (sndg[i][1] != -999))
|
|
{
|
|
/* no need to interpolate if we have the level!!! */
|
|
return sndg[i][2];
|
|
}
|
|
if((sndg[i][1] < pres) && (sndg[i][2] != -999) && (sndg[i][1] != -999))
|
|
{
|
|
itophght = i;
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Height Immediately Below level ----- */
|
|
ok=0;
|
|
for (i = numlvl - 1; i > -1; i--)
|
|
{
|
|
if((sndg[i][1] >= pres) && (sndg[i][2] != -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 sndg[above][2];
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the height ----- */
|
|
nm1 = sndg[above][2] - sndg[below][2];
|
|
nm2 = log( sndg[below][1] / sndg[above][1] );
|
|
nm4 = log( sndg[below][1] / pres );
|
|
return (float)(sndg[below][2] + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*NP*/
|
|
float i_pres( float hght )
|
|
/*************************************************************/
|
|
/* I_PRES */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a pressure(mb) */
|
|
/* at height (hght). */
|
|
/* */
|
|
/* hght - Height(m) of level */
|
|
/*************************************************************/
|
|
{
|
|
short below, above, i, ok;
|
|
double nm1, nm2, nm3, nm4;
|
|
|
|
below = 0;
|
|
above = 0;
|
|
|
|
/* ----- Find Pressure Immediately Above level ----- */
|
|
ok = 0;
|
|
for (i = 0; i < numlvl; i++)
|
|
{
|
|
/* if we have the level, no need to interpolate pressure */
|
|
if((sndg[i][2] == hght) && (sndg[i][1] != -999.0F))
|
|
return(sndg[i][1]);
|
|
if((sndg[i][2] > hght) && (sndg[i][1] != -999.0F))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Pressure Below level ----- */
|
|
ok = 0;
|
|
for (i = numlvl - 1; i > -1; i--)
|
|
{
|
|
if((sndg[i][2] <= hght) && (sndg[i][1] != -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 sndg[above][1];
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the Pressure ----- */
|
|
nm1 = hght - sndg[below][2];
|
|
nm2 = sndg[above][2] - sndg[below][2];
|
|
nm3 = log( sndg[above][1] / sndg[below][1] );
|
|
return (float)(sndg[below][1] * exp(( nm1 / nm2) * nm3));
|
|
}
|
|
|
|
/*NP*/
|
|
float i_vtmp( float pres )
|
|
/*************************************************************/
|
|
/* I_VTMP */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Calculates the virtual temperature (C) at pressure */
|
|
/* level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a virtual temp. */
|
|
/*************************************************************/
|
|
{
|
|
double cta, eps, tk, w;
|
|
|
|
if( !qc(i_dwpt( pres )))
|
|
{
|
|
if( !qc( i_temp( pres ))) { return -999.0F; }
|
|
return i_temp( pres );
|
|
}
|
|
|
|
cta = 273.15;
|
|
eps = .62197;
|
|
|
|
tk = (double)i_temp(pres) + cta;
|
|
w = .001 * (double) mixratio( pres, i_dwpt(pres));
|
|
return (float)(tk * (1 + w / eps) / (1 + w) - cta);
|
|
}
|
|
|
|
/*NP*/
|
|
float virtemp( float pres, float temp, float dwpt )
|
|
/*************************************************************/
|
|
/* VIRTEMP */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Calculates the virtual temperature (C) of parcel */
|
|
/* (pres, temp, dwpt). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a virtual temp. */
|
|
/* temp - Temperature(c). */
|
|
/* dwpt - Dew point(c). */
|
|
/*************************************************************/
|
|
{
|
|
double cta, eps, tk, w;
|
|
|
|
if( !qc(dwpt) ) { return temp; }
|
|
|
|
cta = 273.15;
|
|
eps = .62197;
|
|
|
|
tk = temp + cta;
|
|
w = .001 * mixratio( pres, dwpt);
|
|
return (float)(tk * (1 + w / eps) / (1 + w) - cta);
|
|
}
|
|
|
|
/*NP*/
|
|
float i_wdir( float pres )
|
|
/*************************************************************/
|
|
/* I_WDIR */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a wind */
|
|
/* direction (deg) at pressure level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a Wind */
|
|
/*************************************************************/
|
|
{
|
|
float u, v;
|
|
|
|
if( !qc(i_wndu( pres )) || !qc(i_wndv( pres ))) { return -999.0F; }
|
|
|
|
u = i_wndu( pres );
|
|
v = i_wndv( pres );
|
|
return angle( u, v );
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
float i_wspd( float pres )
|
|
/*************************************************************/
|
|
/* I_WSPD */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a wind */
|
|
/* magnitude (kt) at pressure level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a Wind */
|
|
/*************************************************************/
|
|
{
|
|
float u, v;
|
|
|
|
if( !qc(i_wndu( pres )) || !qc(i_wndv( pres ))) { return -999.0F; }
|
|
|
|
u = i_wndu( pres );
|
|
v = i_wndv( pres );
|
|
return (float)(sqrt((u * u) + (v * v)));
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
float i_wndu( float pres )
|
|
/*************************************************************/
|
|
/* I_WNDU */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a */
|
|
/* u-component to the wind at pressure level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a U-Component */
|
|
/*************************************************************/
|
|
{
|
|
short below, above, i, ok;
|
|
float utop, ubot, nm1;
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Wind Immediately Above level ----- */
|
|
ok = 0;
|
|
for (i = 0;i < numlvl; i++)
|
|
{
|
|
if((sndg[i][1] == pres) && (sndg[i][5] != -999.0F) &&
|
|
(sndg[i][6] != -999.0F))
|
|
return ucomp( sndg[i][5], sndg[i][6] );
|
|
if((sndg[i][1] < pres) && (sndg[i][5] != -999.0F))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Wind Immediately Below level ----- */
|
|
ok = 0;
|
|
for (i = numlvl - 1; i > -1; i--)
|
|
{
|
|
if((sndg[i][1] >= pres) && (sndg[i][5] != -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 ucomp( sndg[above][5], sndg[above][6] );
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the Wind ----- */
|
|
nm1 = sndg[below][1] - pres;
|
|
ubot = ucomp( sndg[below][5], sndg[below][6] );
|
|
utop = ucomp( sndg[above][5], sndg[above][6] );
|
|
return ubot - (nm1 / (sndg[below][1] - sndg[above][1]))
|
|
* (ubot - utop);
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
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;
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Wind Immediately Above level ----- */
|
|
ok = 0;
|
|
for (i = 0; i < numlvl; i++)
|
|
{
|
|
if((sndg[i][1] == pres) && (sndg[i][5] != -999.0F) &&
|
|
(sndg[i][6] != -999.0F))
|
|
return vcomp( sndg[i][5], sndg[i][6] );
|
|
if((sndg[i][1] < pres) && (sndg[i][5] != -999.0F))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Wind Immediately Below level ----- */
|
|
ok = 0;
|
|
for (i = numlvl - 1; i > -1; i--)
|
|
{
|
|
if((sndg[i][1] >= pres) && (sndg[i][5] != -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( sndg[above][5], sndg[above][6] );
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the Wind ----- */
|
|
nm1 = sndg[below][1] - pres;
|
|
vbot = vcomp( sndg[below][5], sndg[below][6] );
|
|
vtop = vcomp( sndg[above][5], sndg[above][6] );
|
|
return vbot - ((nm1 / (sndg[below][1] - sndg[above][1]))
|
|
* (vbot - vtop));
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
float i_omeg( float pres )
|
|
/*************************************************************/
|
|
/* I_OMEG */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Interpolates the given data to calculate a vert motion */
|
|
/* at pressure level (pres). */
|
|
/* */
|
|
/* pres - Level(mb) to compute a UVV */
|
|
/*************************************************************/
|
|
{
|
|
short below, above, i, ok;
|
|
double nm1, nm2, nm4;
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find UVV Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < numlvl; i++)
|
|
{
|
|
if((sndg[i][1] <= pres) && (qc(sndg[i][0])))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Temperature Immediately Below level ----- */
|
|
ok = 0;
|
|
for (i = numlvl-1; i > -1; i--)
|
|
{
|
|
if((sndg[i][1] >= pres) && (qc(sndg[i][0])))
|
|
{
|
|
below = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- If both levels are the same, return them ---- */
|
|
if( above == below)
|
|
{
|
|
return sndg[above][0];
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the temperature ----- */
|
|
|
|
nm1 = sndg[above][0] - sndg[below][0];
|
|
nm2 = log( sndg[below][1] / sndg[above][1] );
|
|
nm4 = log( sndg[below][1] / pres );
|
|
return (float)(sndg[below][0] + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*NP*/
|
|
short sfc( void )
|
|
/*************************************************************/
|
|
/* SFC */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Returns the array pointer to the Surface Level. */
|
|
/*************************************************************/
|
|
{
|
|
short i;
|
|
for( i = 0; i < numlvl; i++)
|
|
{ if( qc( sndg[i][3] )) { return i; } }
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
float top_pres( void )
|
|
/*************************************************************/
|
|
/* TOP_PRES */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Returns the pressure(mb) of highest level in sounding. */
|
|
/*************************************************************/
|
|
{
|
|
short i;
|
|
|
|
for( i=numlvl-1; i>0; i--)
|
|
{
|
|
if( qc(sndg[i][1])) { return sndg[i][1]; }
|
|
}
|
|
return -999;
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
short qc( float value )
|
|
/*************************************************************/
|
|
/* QC */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Quality control of sndg data. Searches for missing */
|
|
/* data (-999) and returns (1 = OK), (0 = missing) */
|
|
/*************************************************************/
|
|
{
|
|
if( value < -998.0F ) { return 0; }
|
|
if( value > 2.0E+05F ) { return 0; }
|
|
return 1;
|
|
}
|
|
|
|
/*NP*/
|
|
char *qc2( float value, char *label, short prec )
|
|
/*************************************************************/
|
|
/* QC2 */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Quality control of sndg data. Searches for missing */
|
|
/* data (-999) and returns (char = OK), (M = missing) */
|
|
/* Returns real numbers with (prec) decimal points. */
|
|
/*************************************************************/
|
|
{
|
|
char fmt[10], st2[10];
|
|
static char st1[40];
|
|
|
|
|
|
if( !qc(value) )
|
|
{
|
|
return "M";
|
|
}
|
|
else
|
|
{
|
|
itoa( prec, st2, 10 );
|
|
strcpy( fmt, "%." );
|
|
strcat( fmt, st2 );
|
|
strcat( fmt, "f%s" );
|
|
sprintf( st1, fmt, value, label);
|
|
return st1;
|
|
}
|
|
}
|
|
|
|
/*NP*/
|
|
float ctof( float value )
|
|
/*************************************************************/
|
|
/* CTOF */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given temperature (c) to (f). */
|
|
/*************************************************************/
|
|
{
|
|
if( value <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return ( 1.8F * value) + 32; }
|
|
}
|
|
|
|
/*NP*/
|
|
float ftoc( float value )
|
|
/*************************************************************/
|
|
/* FTOC */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given temperature (f) to (c). */
|
|
/*************************************************************/
|
|
{
|
|
if( value <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return (float)(5/9) * (value - 32); }
|
|
}
|
|
|
|
/*NP*/
|
|
float mtof( float value )
|
|
/*************************************************************/
|
|
/* MTOF */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given distance (m) to (ft). */
|
|
/* */
|
|
/* T. Lee 7/2012 Changed .3049 to .3048 */
|
|
/*************************************************************/
|
|
{
|
|
if( value <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return value / .3048F; }
|
|
}
|
|
|
|
/*NP*/
|
|
float ftom( float value )
|
|
/*************************************************************/
|
|
/* FTOM */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts given distance (ft) to (m). */
|
|
/* */
|
|
/* T. Lee 7/2012 Changed .3049 to .3048 */
|
|
/*************************************************************/
|
|
{
|
|
if( value <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return value * .3048F; }
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
float agl( float height )
|
|
/*************************************************************/
|
|
/* AGL */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts height (meters) MSL to AGL. */
|
|
/*************************************************************/
|
|
{
|
|
if( height <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return height - sndg[sfc()][2]; }
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
float msl( float height )
|
|
/*************************************************************/
|
|
/* MSL */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts height (meters) AGL to MSL. */
|
|
/*************************************************************/
|
|
{
|
|
if( height <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return sndg[sfc()][2] + height; }
|
|
}
|
|
|
|
|
|
/*NP*/
|
|
float kt_to_mps( float spd )
|
|
/*************************************************************/
|
|
/* KT_TO_MPS */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts speed (knots) to meters per second. */
|
|
/*************************************************************/
|
|
{
|
|
if( spd <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return spd * .51479F; }
|
|
}
|
|
|
|
|