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 *****************************************************************************/
43 /****************************************************************************/
45 /****************************************************************************/
46 #ifndef FGPhysicalProperties_H
47 #define FGPhysicalProperties_H
49 /****************************************************************************/
51 /****************************************************************************/
52 #include <Include/compiler.h>
60 #include "FGWeatherDefs.h"
62 #include "FGAirPressureItem.h"
63 #include "FGWindItem.h"
64 #include "FGTurbulenceItem.h"
66 #include "FGCloudItem.h"
67 #include "FGSnowRain.h"
71 FG_USING_NAMESPACE(std);
73 /****************************************************************************/
74 /* FOREWARD DEFINITIONS */
75 /****************************************************************************/
76 class FGPhysicalProperties2D;
77 ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
79 class FGPhysicalProperties
82 typedef WeatherPrecision Altitude;
84 map<Altitude,FGWindItem> Wind; //all Wind vectors
85 map<Altitude,FGTurbulenceItem> Turbulence; //all Turbulence vectors
86 map<Altitude,WeatherPrecision> Temperature; //in deg. Kelvin (I *only* accept SI!)
87 FGAirPressureItem AirPressure; //in Pascal (I *only* accept SI!)
88 map<Altitude,WeatherPrecision> VaporPressure; //in Pascal (I *only* accept SI!)
90 map<Altitude,FGCloudItem> Clouds; //amount of covering and type
92 WeatherPrecision SnowRainIntensity; //this also stands for hail, snow,...
93 SnowRainType snowRainType;
94 WeatherPrecision LightningProbability;
96 FGPhysicalProperties(); //consructor to fill it with FG standart weather
98 //return values at specified altitudes
99 void WindAt (sgVec3 ret, const WeatherPrecision a) const;
100 void TurbulenceAt (sgVec3 ret, const WeatherPrecision a) const;
101 WeatherPrecision TemperatureAt (const WeatherPrecision a) const;
102 WeatherPrecision AirPressureAt (const WeatherPrecision a) const;
103 WeatherPrecision VaporPressureAt(const WeatherPrecision a) const;
105 //for easier access to the cloud stuff:
106 unsigned int getNumberOfCloudLayers(void) const;
107 FGCloudItem getCloudLayer(unsigned int nr) const;
109 FGPhysicalProperties& operator = ( const FGPhysicalProperties& p );
110 FGPhysicalProperties& operator *= ( const WeatherPrecision d );
111 FGPhysicalProperties& operator += ( const FGPhysicalProperties& p );
112 FGPhysicalProperties& operator -= ( const FGPhysicalProperties& p );
115 class FGPhysicalProperties2D : public FGPhysicalProperties
118 sgVec2 p; //position of the property (lat/lon)
119 friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
121 FGPhysicalProperties2D() {}
123 FGPhysicalProperties2D(const FGPhysicalProperties& prop, const sgVec2& pos)
126 Turbulence = prop.Turbulence;
127 Temperature = prop.Temperature;
128 AirPressure = prop.AirPressure;
129 VaporPressure = prop.VaporPressure;
134 typedef vector<FGPhysicalProperties> FGPhysicalPropertiesVector;
135 typedef FGPhysicalPropertiesVector::iterator FGPhysicalPropertiesVectorIt;
136 typedef FGPhysicalPropertiesVector::const_iterator FGPhysicalPropertiesVectorConstIt;
138 typedef vector<FGPhysicalProperties2D> FGPhysicalProperties2DVector;
139 typedef FGPhysicalProperties2DVector::iterator FGPhysicalProperties2DVectorIt;
140 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
142 inline ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p )
144 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
145 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
146 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
148 out << "Position: (" << p.p[0] << ", " << p.p[1] << ", " << p.p[2] << ")\n";
150 out << "Stored Wind: ";
151 for (wind_iterator WindIt = p.Wind.begin();
152 WindIt != p.Wind.end();
154 out << "(" << WindIt->first << ") at (" << WindIt->second.x() << ", " << WindIt->second.y() << ", " << WindIt->second.z() << ") m; ";
157 out << "Stored Turbulence: ";
158 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
159 TurbulenceIt != p.Turbulence.end();
161 out << "(" << TurbulenceIt->first << ") at (" << TurbulenceIt->second.x() << ", " << TurbulenceIt->second.y() << ", " << TurbulenceIt->second.z() << ") m; ";
164 out << "Stored Temperature: ";
165 for (scalar_iterator TemperatureIt = p.Temperature.begin();
166 TemperatureIt != p.Temperature.end();
168 out << TemperatureIt->first << " at " << TemperatureIt->second << "m; ";
171 out << "Stored AirPressure: ";
172 out << p.AirPressure.getValue(0) << " at " << 0.0 << "m; ";
175 out << "Stored VaporPressure: ";
176 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
177 VaporPressureIt != p.VaporPressure.end();
179 out << VaporPressureIt->first << " at " << VaporPressureIt->second << "m; ";
186 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
189 Turbulence = p.Turbulence;
190 Temperature = p.Temperature;
191 AirPressure = p.AirPressure;
192 VaporPressure = p.VaporPressure;
196 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecision d )
198 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::iterator wind_iterator;
199 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::iterator turbulence_iterator;
200 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::iterator scalar_iterator;
202 for (wind_iterator WindIt = Wind.begin();
203 WindIt != Wind.end();
207 for (turbulence_iterator TurbulenceIt = Turbulence.begin();
208 TurbulenceIt != Turbulence.end();
210 TurbulenceIt->second *= d;
212 for (scalar_iterator TemperatureIt = Temperature.begin();
213 TemperatureIt != Temperature.end();
215 TemperatureIt->second *= d;
219 for (scalar_iterator VaporPressureIt = VaporPressure.begin();
220 VaporPressureIt != VaporPressure.end();
222 VaporPressureIt->second *= d;
227 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
229 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
230 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
231 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
233 for (wind_iterator WindIt = p.Wind.begin();
234 WindIt != p.Wind.end();
236 if (!Wind.insert(*WindIt).second) //when it's not inserted => it's already existing
237 Wind[WindIt->first] += WindIt->second; //=> add the value
239 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
240 TurbulenceIt != p.Turbulence.end();
242 if (!Turbulence.insert(*TurbulenceIt).second)
243 Turbulence[TurbulenceIt->first] += TurbulenceIt->second;
245 for (scalar_iterator TemperatureIt = p.Temperature.begin();
246 TemperatureIt != p.Temperature.end();
248 if (!Temperature.insert(*TemperatureIt).second)
249 Temperature[TemperatureIt->first] += TemperatureIt->second;
251 AirPressure += p.AirPressure.getValue(0.0);
253 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
254 VaporPressureIt != p.VaporPressure.end();
256 if (!VaporPressure.insert(*VaporPressureIt).second)
257 VaporPressure[VaporPressureIt->first] += VaporPressureIt->second;
262 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
264 typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
265 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
266 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
268 for (wind_iterator WindIt = p.Wind.begin();
269 WindIt != p.Wind.end();
271 if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second) //when it's not inserted => it's already existing
272 Wind[WindIt->first] -= WindIt->second; //=> substract the value
274 for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
275 TurbulenceIt != p.Turbulence.end();
277 if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second)
278 Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
280 for (scalar_iterator TemperatureIt = p.Temperature.begin();
281 TemperatureIt != p.Temperature.end();
283 if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)
284 Temperature[TemperatureIt->first] -= TemperatureIt->second;
286 AirPressure -= p.AirPressure.getValue(0.0);
288 for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
289 VaporPressureIt != p.VaporPressure.end();
291 if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)
292 VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
299 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
301 typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
303 vector_iterator it = Wind.lower_bound(a);
304 vector_iterator it2 = it;
307 //now I've got it->alt < a < it2->alt so I can interpolate
308 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
309 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
310 sgAddVec3(ret, *it2->second.getValue());
313 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
315 typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
317 vector_iterator it = Turbulence.lower_bound(a);
318 vector_iterator it2 = it;
321 //now I've got it->alt < a < it2->alt so I can interpolate
322 sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
323 sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
324 sgAddVec3(ret, *it2->second.getValue());
327 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
329 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
331 scalar_iterator it = Temperature.lower_bound(a);
332 scalar_iterator it2 = it;
335 //now I've got it->alt < a < it2->alt so I can interpolate
336 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
339 inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision a) const
341 return AirPressure.getValue(a);
344 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
346 typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
348 scalar_iterator it = VaporPressure.lower_bound(a);
349 scalar_iterator it2 = it;
352 //now I've got it->alt < a < it2->alt so I can interpolate
353 return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second;
357 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
362 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
367 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
372 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
377 /****************************************************************************/
378 #endif /*FGPhysicalProperties_H*/