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 <Include/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 FG_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 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
234 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
235 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
236 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
238 for (wind_iterator WindIt = p.Wind.begin();
239 WindIt != p.Wind.end();
241 if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second) //when it's not inserted => it's already existing
242 Wind[WindIt->first] -= WindIt->second; //=> substract the value
244 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
245 TurbulenceIt != p.Turbulence.end();
247 if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second)
248 Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
250 for (scalar_iterator TemperatureIt = p.Temperature.begin();
251 TemperatureIt != p.Temperature.end();
253 if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)
254 Temperature[TemperatureIt->first] -= TemperatureIt->second;
256 AirPressure -= p.AirPressure.getValue();
258 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
259 VaporPressureIt != p.VaporPressure.end();
261 if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)
262 VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
268 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
270 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
272 vector_iterator it = Wind.lower_bound(a);
273 vector_iterator it2 = it;
276 //now I've got it->alt < a < it2->alt so I can interpolate
277 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
278 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
279 sgAddVec3(ret, *it2->second.getValue());
282 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
284 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
286 vector_iterator it = Turbulence.lower_bound(a);
287 vector_iterator it2 = it;
290 //now I've got it->alt < a < it2->alt so I can interpolate
291 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
292 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
293 sgAddVec3(ret, *it2->second.getValue());
296 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
298 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
300 scalar_iterator it = Temperature.lower_bound(a);
301 scalar_iterator it2 = it;
304 //now I've got it->alt < a < it2->alt so I can interpolate
305 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
308 //inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision x) const
309 //moved to FGPhysicalProperties.cpp as it got too complex to inline
311 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
313 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
315 scalar_iterator it = VaporPressure.lower_bound(a);
316 scalar_iterator it2 = it;
319 //now I've got it->alt < a < it2->alt so I can interpolate
320 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
324 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
329 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
334 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
339 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
344 /****************************************************************************/
345 #endif /*FGPhysicalProperties_H*/