1 /*****************************************************************************
3 Header: FGPhysicalProperties.h
4 Author: Christian Mayer
7 -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA.
23 Further information about the GNU General Public License can also be found on
24 the world wide web at http://www.gnu.org.
26 FUNCTIONAL DESCRIPTION
27 ------------------------------------------------------------------------------
28 Define the simulated physical properties of the weather
31 ------------------------------------------------------------------------------
32 28.05.1999 Christian Mayer Created
33 16.06.1999 Durk Talsma Portability for Linux
34 20.06.1999 Christian Mayer Changed struct to class
35 20.06.1999 Christian Mayer added lots of consts
36 30.06.1999 Christian Mayer STL portability
37 11.10.1999 Christian Mayer changed set<> to map<> on Bernie Bright's
39 19.10.1999 Christian Mayer change to use PLIB's sg instead of Point[2/3]D
40 and lots of wee code cleaning
41 15.12.1999 Christian Mayer changed the air pressure calculation to a much
42 more realistic formula. But as I need for that
43 the temperature I moved the code to
45 *****************************************************************************/
47 /****************************************************************************/
49 /****************************************************************************/
50 #ifndef FGPhysicalProperties_H
51 #define FGPhysicalProperties_H
53 /****************************************************************************/
55 /****************************************************************************/
60 #include <simgear/compiler.h>
72 #include "FGWeatherDefs.h"
74 #include "FGAirPressureItem.h"
75 #include "FGWindItem.h"
76 #include "FGTurbulenceItem.h"
78 #include "FGCloudItem.h"
79 #include "FGSnowRain.h"
83 SG_USING_NAMESPACE(std);
85 /****************************************************************************/
86 /* FOREWARD DEFINITIONS */
87 /****************************************************************************/
88 class FGPhysicalProperties2D;
89 ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
91 class FGPhysicalProperties
94 typedef WeatherPrecision Altitude;
96 map<Altitude,FGWindItem> Wind; //all Wind vectors
97 map<Altitude,FGTurbulenceItem> Turbulence; //all Turbulence vectors
98 map<Altitude,WeatherPrecision> Temperature; //in deg. Kelvin (I *only* accept SI!)
99 FGAirPressureItem AirPressure; //in Pascal (I *only* accept SI!)
100 map<Altitude,WeatherPrecision> VaporPressure; //in Pascal (I *only* accept SI!)
102 map<Altitude,FGCloudItem> Clouds; //amount of covering and type
104 WeatherPrecision SnowRainIntensity; //this also stands for hail, snow,...
105 SnowRainType snowRainType;
106 WeatherPrecision LightningProbability; //in lightnings per second
108 FGPhysicalProperties(); //consructor to fill it with FG standart weather
110 //return values at specified altitudes
111 void WindAt (sgVec3 ret, const WeatherPrecision a) const;
112 void TurbulenceAt (sgVec3 ret, const WeatherPrecision a) const;
113 WeatherPrecision TemperatureAt (const WeatherPrecision a) const;
114 WeatherPrecision AirPressureAt (const WeatherPrecision x) const; //x is used here instead of a on purpose
115 WeatherPrecision VaporPressureAt(const WeatherPrecision a) const;
117 //for easier access to the cloud stuff:
118 unsigned int getNumberOfCloudLayers(void) const;
119 FGCloudItem getCloudLayer(unsigned int nr) const;
121 FGPhysicalProperties& operator = ( const FGPhysicalProperties& p );
122 FGPhysicalProperties& operator *= ( const WeatherPrecision d );
123 FGPhysicalProperties& operator += ( const FGPhysicalProperties& p );
124 FGPhysicalProperties& operator -= ( const FGPhysicalProperties& p );
127 class FGPhysicalProperties2D : public FGPhysicalProperties
130 sgVec2 p; //position of the property (lat/lon)
131 friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
133 FGPhysicalProperties2D() {}
135 FGPhysicalProperties2D(const FGPhysicalProperties& prop, const sgVec2& pos)
138 Turbulence = prop.Turbulence;
139 Temperature = prop.Temperature;
140 AirPressure = prop.AirPressure;
141 VaporPressure = prop.VaporPressure;
146 typedef vector<FGPhysicalProperties> FGPhysicalPropertiesVector;
147 typedef FGPhysicalPropertiesVector::iterator FGPhysicalPropertiesVectorIt;
148 typedef FGPhysicalPropertiesVector::const_iterator FGPhysicalPropertiesVectorConstIt;
150 typedef vector<FGPhysicalProperties2D> FGPhysicalProperties2DVector;
151 typedef FGPhysicalProperties2DVector::iterator FGPhysicalProperties2DVectorIt;
152 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
156 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
159 Turbulence = p.Turbulence;
160 Temperature = p.Temperature;
161 AirPressure = p.AirPressure;
162 VaporPressure = p.VaporPressure;
166 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecision d )
168 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::iterator wind_iterator;
169 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::iterator turbulence_iterator;
170 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::iterator scalar_iterator;
172 for (wind_iterator WindIt = Wind.begin();
173 WindIt != Wind.end();
177 for (turbulence_iterator TurbulenceIt = Turbulence.begin();
178 TurbulenceIt != Turbulence.end();
180 TurbulenceIt->second *= d;
182 for (scalar_iterator TemperatureIt = Temperature.begin();
183 TemperatureIt != Temperature.end();
185 TemperatureIt->second *= d;
189 for (scalar_iterator VaporPressureIt = VaporPressure.begin();
190 VaporPressureIt != VaporPressure.end();
192 VaporPressureIt->second *= d;
197 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
199 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
200 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
201 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
203 for (wind_iterator WindIt = p.Wind.begin();
204 WindIt != p.Wind.end();
206 if (!Wind.insert(*WindIt).second) //when it's not inserted => it's already existing
207 Wind[WindIt->first] += WindIt->second; //=> add the value
209 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
210 TurbulenceIt != p.Turbulence.end();
212 if (!Turbulence.insert(*TurbulenceIt).second)
213 Turbulence[TurbulenceIt->first] += TurbulenceIt->second;
215 for (scalar_iterator TemperatureIt = p.Temperature.begin();
216 TemperatureIt != p.Temperature.end();
218 if (!Temperature.insert(*TemperatureIt).second)
219 Temperature[TemperatureIt->first] += TemperatureIt->second;
221 AirPressure += p.AirPressure.getValue();
223 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
224 VaporPressureIt != p.VaporPressure.end();
226 if (!VaporPressure.insert(*VaporPressureIt).second)
227 VaporPressure[VaporPressureIt->first] += VaporPressureIt->second;
232 // slightly modified version that also makes the Mac happy
233 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
235 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator wind_iterator;
236 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
237 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
239 // types to replace make_pair
240 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::value_type wind_type;
241 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::value_type turb_type;
242 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::value_type weather_type;
244 for (wind_iterator WindIt = p.Wind.begin();
245 WindIt != p.Wind.end();
247 if (!Wind.insert( wind_type(WindIt->first, -WindIt->second) ).second)
248 // when it's not inserted => it's already existing
249 Wind[WindIt->first] -= WindIt->second; //=> substract the value
251 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
252 TurbulenceIt != p.Turbulence.end();
254 if (!Turbulence.insert( turb_type(TurbulenceIt->first, -TurbulenceIt->second) ).second)
255 Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
257 for (scalar_iterator TemperatureIt = p.Temperature.begin();
258 TemperatureIt != p.Temperature.end();
260 if (!Temperature.insert( weather_type(TemperatureIt->first, -TemperatureIt->second) ).second)
261 Temperature[TemperatureIt->first] -= TemperatureIt->second;
263 AirPressure -= p.AirPressure.getValue();
265 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
266 VaporPressureIt != p.VaporPressure.end();
268 if (!VaporPressure.insert( weather_type(VaporPressureIt->first, -VaporPressureIt->second) ).second)
269 VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
275 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
277 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
278 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
279 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
281 for (wind_iterator WindIt = p.Wind.begin();
282 WindIt != p.Wind.end();
284 if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second) //when it's not inserted => it's already existing
285 Wind[WindIt->first] -= WindIt->second; //=> substract the value
287 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
288 TurbulenceIt != p.Turbulence.end();
290 if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second)
291 Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
293 for (scalar_iterator TemperatureIt = p.Temperature.begin();
294 TemperatureIt != p.Temperature.end();
296 if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)
297 Temperature[TemperatureIt->first] -= TemperatureIt->second;
299 AirPressure -= p.AirPressure.getValue();
301 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
302 VaporPressureIt != p.VaporPressure.end();
304 if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)
305 VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
312 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
314 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
316 vector_iterator it = Wind.lower_bound(a);
317 vector_iterator it2 = it;
320 //now I've got it->alt < a < it2->alt so I can interpolate
321 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
322 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
323 sgAddVec3(ret, *it2->second.getValue());
326 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
328 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
330 vector_iterator it = Turbulence.lower_bound(a);
331 vector_iterator it2 = it;
334 //now I've got it->alt < a < it2->alt so I can interpolate
335 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
336 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
337 sgAddVec3(ret, *it2->second.getValue());
340 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
342 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
344 scalar_iterator it = Temperature.lower_bound(a);
345 scalar_iterator it2 = it;
348 //now I've got it->alt < a < it2->alt so I can interpolate
349 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
352 //inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision x) const
353 //moved to FGPhysicalProperties.cpp as it got too complex to inline
355 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
357 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
359 scalar_iterator it = VaporPressure.lower_bound(a);
360 scalar_iterator it2 = it;
363 //now I've got it->alt < a < it2->alt so I can interpolate
364 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
368 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
373 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
378 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
383 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
388 /****************************************************************************/
389 #endif /*FGPhysicalProperties_H*/