764 lines
27 KiB
C
764 lines
27 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 "gui.h"
|
|
#include "sharp95.h"
|
|
|
|
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;
|
|
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Temperature Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if((sndgp->sndg[i].pres == pres) && ( qc(sndgp->sndg[i].temp)))
|
|
{
|
|
/* if pressure level exists, and temp exists, no need to interpolate */
|
|
return sndgp->sndg[i].temp;
|
|
}
|
|
if((sndgp->sndg[i].pres < pres) && ( qc(sndgp->sndg[i].temp) ) )
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Temperature Immediately Below level ----- */
|
|
ok = 0;
|
|
for (i = sndgp->numlev - 1; i > -1; i--)
|
|
{
|
|
if((sndgp->sndg[i].pres >= pres) && (sndgp->sndg[i].temp != -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 sndgp->sndg[above].temp;
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the temperature ----- */
|
|
|
|
nm1 = sndgp->sndg[above].temp - sndgp->sndg[below].temp;
|
|
nm2 = log( sndgp->sndg[below].pres / sndgp->sndg[above].pres );
|
|
nm4 = log( sndgp->sndg[below].pres / pres );
|
|
return (float)(sndgp->sndg[below].temp + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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;
|
|
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Dew Point Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if((sndgp->sndg[i].pres == pres) && (sndgp->sndg[i].dwpt != -999) && (sndgp->sndg[i].pres != -999))
|
|
{
|
|
/* no need to interpolate if we have the level and dewpoint exists */
|
|
return sndgp->sndg[i].dwpt;
|
|
}
|
|
if((sndgp->sndg[i].pres < pres) && (sndgp->sndg[i].dwpt != -999.0F))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Dew Point Immediately Below level ----- */
|
|
ok=0;
|
|
for (i = sndgp->numlev - 1; i > -1; i--)
|
|
{
|
|
if((sndgp->sndg[i].pres >= pres) && (sndgp->sndg[i].dwpt != -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 sndgp->sndg[above].dwpt;
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the dew point ----- */
|
|
nm1 = sndgp->sndg[above].dwpt - sndgp->sndg[below].dwpt;
|
|
nm2 = log( sndgp->sndg[below].pres / sndgp->sndg[above].pres );
|
|
nm4 = log( sndgp->sndg[below].pres / pres );
|
|
return (float)(sndgp->sndg[below].dwpt + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*===========================================================================*/
|
|
|
|
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;
|
|
double nm1, nm2, nm4;
|
|
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find Height Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if((sndgp->sndg[i].pres == pres) && (sndgp->sndg[i].hght != -999) && (sndgp->sndg[i].pres != -999))
|
|
{
|
|
/* no need to interpolate if we have the level!!! */
|
|
return sndgp->sndg[i].hght;
|
|
}
|
|
if((sndgp->sndg[i].pres < pres) && (sndgp->sndg[i].hght != -999) && (sndgp->sndg[i].pres != -999))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Height Immediately Below level ----- */
|
|
ok=0;
|
|
for (i = sndgp->numlev - 1; i > -1; i--)
|
|
{
|
|
if((sndgp->sndg[i].pres >= pres) && (sndgp->sndg[i].hght != -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 sndgp->sndg[above].hght;
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the height ----- */
|
|
nm1 = sndgp->sndg[above].hght - sndgp->sndg[below].hght;
|
|
nm2 = log( sndgp->sndg[below].pres / sndgp->sndg[above].pres );
|
|
nm4 = log( sndgp->sndg[below].pres / pres );
|
|
return (float)(sndgp->sndg[below].hght + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*==========================================================================*/
|
|
|
|
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;
|
|
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
below = 0;
|
|
above = 0;
|
|
|
|
/* ----- Find Pressure Immediately Above level ----- */
|
|
ok = 0;
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
/* if we have the level, no need to interpolate pressure */
|
|
if((sndgp->sndg[i].hght == hght) && (sndgp->sndg[i].pres != -999.0F))
|
|
return(sndgp->sndg[i].pres);
|
|
if((sndgp->sndg[i].hght > hght) && (sndgp->sndg[i].pres != -999.0F))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Pressure Below level ----- */
|
|
ok = 0;
|
|
for (i = sndgp->numlev - 1; i > -1; i--)
|
|
{
|
|
if((sndgp->sndg[i].hght <= hght) && (sndgp->sndg[i].pres != -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 sndgp->sndg[above].pres;
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the Pressure ----- */
|
|
nm1 = hght - sndgp->sndg[below].hght;
|
|
nm2 = sndgp->sndg[above].hght - sndgp->sndg[below].hght;
|
|
nm3 = log( sndgp->sndg[above].pres / sndgp->sndg[below].pres );
|
|
return (float)(sndgp->sndg[below].pres * exp(( nm1 / nm2) * nm3));
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
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);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
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);
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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 );
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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)));
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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;
|
|
|
|
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 ucomp( 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 ucomp( sndgp->sndg[above].drct, sndgp->sndg[above].sped );
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the Wind ----- */
|
|
nm1 = sndgp->sndg[below].pres - pres;
|
|
ubot = ucomp( sndgp->sndg[below].drct, sndgp->sndg[below].sped );
|
|
utop = ucomp( sndgp->sndg[above].drct, sndgp->sndg[above].sped );
|
|
return ubot - (nm1 / (sndgp->sndg[below].pres - sndgp->sndg[above].pres))
|
|
* (ubot - utop);
|
|
}
|
|
|
|
/*========================================================================*/
|
|
|
|
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));
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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;
|
|
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
below=0;
|
|
above=0;
|
|
|
|
/* ----- Find UVV Immediately Above level ----- */
|
|
ok=0;
|
|
for (i = 0; i < sndgp->numlev; i++)
|
|
{
|
|
if((sndgp->sndg[i].pres <= pres) && (qc(sndgp->sndg[i].omega)))
|
|
{
|
|
above = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- Find Temperature Immediately Below level ----- */
|
|
ok = 0;
|
|
for (i = sndgp->numlev-1; i > -1; i--)
|
|
{
|
|
if((sndgp->sndg[i].pres >= pres) && (qc(sndgp->sndg[i].omega)))
|
|
{
|
|
below = i; ok=1; break;
|
|
}
|
|
}
|
|
if( ok == 0 ) return -999.0F;
|
|
|
|
/* ----- If both levels are the same, return them ---- */
|
|
if( above == below)
|
|
{
|
|
return sndgp->sndg[above].omega;
|
|
}
|
|
|
|
/* ----- Now we need to interpolate to get the temperature ----- */
|
|
|
|
nm1 = sndgp->sndg[above].omega - sndgp->sndg[below].omega;
|
|
nm2 = log( sndgp->sndg[below].pres / sndgp->sndg[above].pres );
|
|
nm4 = log( sndgp->sndg[below].pres / pres );
|
|
return (float)(sndgp->sndg[below].omega + (( nm4 / nm2) * nm1));
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
short sfc ( void )
|
|
/*************************************************************/
|
|
/* SFC */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Returns the array pointer to the Surface Level. */
|
|
/*************************************************************/
|
|
{
|
|
short i;
|
|
|
|
if ( sndgp == NULL ) return ( 0 );
|
|
|
|
for( i = 0; i < sndgp->numlev; i++)
|
|
if( qc( sndgp->sndg[i].temp )) return i;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
float top_pres ( void )
|
|
/*************************************************************/
|
|
/* TOP_PRES */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Returns the pressure(mb) of highest level in sounding. */
|
|
/*************************************************************/
|
|
{
|
|
short i;
|
|
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
for( i=sndgp->numlev-1; i>0; i--)
|
|
{
|
|
if( qc(sndgp->sndg[i].pres)) { return sndgp->sndg[i].pres; }
|
|
}
|
|
return -999;
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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;
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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; }
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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); }
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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; }
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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; }
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
float agl ( float height )
|
|
/*************************************************************/
|
|
/* AGL */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts height (meters) MSL to AGL. */
|
|
/*************************************************************/
|
|
{
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
if( height <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return height - sndgp->sndg[sfc()].hght; }
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
float msl ( float height )
|
|
/*************************************************************/
|
|
/* MSL */
|
|
/* John Hart NSSFC KCMO */
|
|
/* */
|
|
/* Converts height (meters) AGL to MSL. */
|
|
/*************************************************************/
|
|
{
|
|
if ( sndgp == NULL ) return ( -999.0F );
|
|
|
|
if( height <= -998.0F )
|
|
{ return -999; }
|
|
else
|
|
{ return sndgp->sndg[sfc()].hght + height; }
|
|
}
|
|
|
|
/*=============================================================================*/
|
|
|
|
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; }
|
|
}
|
|
|