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 );
126 //for easy binding to the property system
127 WeatherPrecision getWind_x( int number ) const;
128 WeatherPrecision getWind_y( int number ) const;
129 WeatherPrecision getWind_z( int number ) const;
130 WeatherPrecision getWind_a( int number ) const;
131 void setWind_x( int number, WeatherPrecision x);
132 void setWind_y( int number, WeatherPrecision y);
133 void setWind_z( int number, WeatherPrecision z);
134 void setWind_a( int number, WeatherPrecision a);
135 WeatherPrecision getTurbulence_x( int number ) const;
136 WeatherPrecision getTurbulence_y( int number ) const;
137 WeatherPrecision getTurbulence_z( int number ) const;
138 WeatherPrecision getTurbulence_a( int number ) const;
139 void setTurbulence_x( int number, WeatherPrecision x);
140 void setTurbulence_y( int number, WeatherPrecision y);
141 void setTurbulence_z( int number, WeatherPrecision z);
142 void setTurbulence_a( int number, WeatherPrecision a);
143 WeatherPrecision getTemperature_x( int number ) const;
144 WeatherPrecision getTemperature_a( int number ) const;
145 void setTemperature_x( int number, WeatherPrecision x);
146 void setTemperature_a( int number, WeatherPrecision a);
147 WeatherPrecision getVaporPressure_x( int number ) const;
148 WeatherPrecision getVaporPressure_a( int number ) const;
149 void setVaporPressure_x( int number, WeatherPrecision x);
150 void setVaporPressure_a( int number, WeatherPrecision a);
153 class FGPhysicalProperties2D : public FGPhysicalProperties
156 sgVec2 p; //position of the property (lat/lon)
157 friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
159 FGPhysicalProperties2D() {}
161 FGPhysicalProperties2D(const FGPhysicalProperties& prop, const sgVec2& pos)
164 Turbulence = prop.Turbulence;
165 Temperature = prop.Temperature;
166 AirPressure = prop.AirPressure;
167 VaporPressure = prop.VaporPressure;
172 typedef vector<FGPhysicalProperties> FGPhysicalPropertiesVector;
173 typedef FGPhysicalPropertiesVector::iterator FGPhysicalPropertiesVectorIt;
174 typedef FGPhysicalPropertiesVector::const_iterator FGPhysicalPropertiesVectorConstIt;
176 typedef vector<FGPhysicalProperties2D> FGPhysicalProperties2DVector;
177 typedef FGPhysicalProperties2DVector::iterator FGPhysicalProperties2DVectorIt;
178 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
182 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
185 Turbulence = p.Turbulence;
186 Temperature = p.Temperature;
187 AirPressure = p.AirPressure;
188 VaporPressure = p.VaporPressure;
192 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecision d )
194 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::iterator wind_iterator;
195 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::iterator turbulence_iterator;
196 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::iterator scalar_iterator;
198 for (wind_iterator WindIt = Wind.begin();
199 WindIt != Wind.end();
203 for (turbulence_iterator TurbulenceIt = Turbulence.begin();
204 TurbulenceIt != Turbulence.end();
206 TurbulenceIt->second *= d;
208 for (scalar_iterator TemperatureIt = Temperature.begin();
209 TemperatureIt != Temperature.end();
211 TemperatureIt->second *= d;
215 for (scalar_iterator VaporPressureIt = VaporPressure.begin();
216 VaporPressureIt != VaporPressure.end();
218 VaporPressureIt->second *= d;
223 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
225 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
226 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
227 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
229 for (wind_iterator WindIt = p.Wind.begin();
230 WindIt != p.Wind.end();
232 if (!Wind.insert(*WindIt).second) //when it's not inserted => it's already existing
233 Wind[WindIt->first] += WindIt->second; //=> add the value
235 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
236 TurbulenceIt != p.Turbulence.end();
238 if (!Turbulence.insert(*TurbulenceIt).second)
239 Turbulence[TurbulenceIt->first] += TurbulenceIt->second;
241 for (scalar_iterator TemperatureIt = p.Temperature.begin();
242 TemperatureIt != p.Temperature.end();
244 if (!Temperature.insert(*TemperatureIt).second)
245 Temperature[TemperatureIt->first] += TemperatureIt->second;
247 AirPressure += p.AirPressure.getValue();
249 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
250 VaporPressureIt != p.VaporPressure.end();
252 if (!VaporPressure.insert(*VaporPressureIt).second)
253 VaporPressure[VaporPressureIt->first] += VaporPressureIt->second;
258 // slightly modified version that also makes the Mac happy
259 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
261 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator wind_iterator;
262 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
263 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
265 // types to replace make_pair
266 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::value_type wind_type;
267 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::value_type turb_type;
268 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::value_type weather_type;
270 for (wind_iterator WindIt = p.Wind.begin();
271 WindIt != p.Wind.end();
273 if (!Wind.insert( wind_type(WindIt->first, -WindIt->second) ).second)
274 // when it's not inserted => it's already existing
275 Wind[WindIt->first] -= WindIt->second; //=> substract the value
277 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
278 TurbulenceIt != p.Turbulence.end();
280 if (!Turbulence.insert( turb_type(TurbulenceIt->first, -TurbulenceIt->second) ).second)
281 Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
283 for (scalar_iterator TemperatureIt = p.Temperature.begin();
284 TemperatureIt != p.Temperature.end();
286 if (!Temperature.insert( weather_type(TemperatureIt->first, -TemperatureIt->second) ).second)
287 Temperature[TemperatureIt->first] -= TemperatureIt->second;
289 AirPressure -= p.AirPressure.getValue();
291 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
292 VaporPressureIt != p.VaporPressure.end();
294 if (!VaporPressure.insert( weather_type(VaporPressureIt->first, -VaporPressureIt->second) ).second)
295 VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
301 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
303 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
304 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
305 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
307 for (wind_iterator WindIt = p.Wind.begin();
308 WindIt != p.Wind.end();
310 if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second) //when it's not inserted => it's already existing
311 Wind[WindIt->first] -= WindIt->second; //=> substract the value
313 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
314 TurbulenceIt != p.Turbulence.end();
316 if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second)
317 Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
319 for (scalar_iterator TemperatureIt = p.Temperature.begin();
320 TemperatureIt != p.Temperature.end();
322 if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)
323 Temperature[TemperatureIt->first] -= TemperatureIt->second;
325 AirPressure -= p.AirPressure.getValue();
327 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
328 VaporPressureIt != p.VaporPressure.end();
330 if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)
331 VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
338 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
340 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
342 vector_iterator it = Wind.lower_bound(a);
343 vector_iterator it2 = it;
346 //now I've got it->alt < a < it2->alt so I can interpolate
347 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
348 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
349 sgAddVec3(ret, *it2->second.getValue());
352 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
354 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
356 vector_iterator it = Turbulence.lower_bound(a);
357 vector_iterator it2 = it;
360 //now I've got it->alt < a < it2->alt so I can interpolate
361 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
362 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
363 sgAddVec3(ret, *it2->second.getValue());
366 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
368 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
370 scalar_iterator it = Temperature.lower_bound(a);
371 scalar_iterator it2 = it;
374 //now I've got it->alt < a < it2->alt so I can interpolate
375 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
378 //inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision x) const
379 //moved to FGPhysicalProperties.cpp as it got too complex to inline
381 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
383 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
385 scalar_iterator it = VaporPressure.lower_bound(a);
386 scalar_iterator it2 = it;
389 //now I've got it->alt < a < it2->alt so I can interpolate
390 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
394 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
399 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
404 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
409 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
414 /****************************************************************************/
415 #endif /*FGPhysicalProperties_H*/