]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGPhysicalProperties.h
Hack in an /accelerations/pilot-g property, for testing a new panel
[flightgear.git] / src / WeatherCM / FGPhysicalProperties.h
1 /*****************************************************************************
2
3  Header:       FGPhysicalProperties.h   
4  Author:       Christian Mayer
5  Date started: 28.05.99
6
7  -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
8
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
12  version.
13
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
17  details.
18
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.
22
23  Further information about the GNU General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 FUNCTIONAL DESCRIPTION
27 ------------------------------------------------------------------------------
28 Define the simulated physical properties of the weather
29
30 HISTORY
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 
38                                 suggestion
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 
44                                 FGPhysicalProperties
45 *****************************************************************************/
46
47 /****************************************************************************/
48 /* SENTRY                                                                   */
49 /****************************************************************************/
50 #ifndef FGPhysicalProperties_H
51 #define FGPhysicalProperties_H
52
53 /****************************************************************************/
54 /* INCLUDES                                                                 */
55 /****************************************************************************/
56 #ifdef HAVE_CONFIG_H
57 #  include <config.h>
58 #endif
59
60 #include <simgear/compiler.h>
61
62 #ifdef HAVE_WINDOWS_H
63 #  include <windows.h>
64 #endif
65
66 #include STL_IOSTREAM
67 #include <vector>
68 #include <map>
69
70 #include <plib/sg.h>
71
72 #include "FGWeatherDefs.h"
73
74 #include "FGAirPressureItem.h"
75 #include "FGWindItem.h"
76 #include "FGTurbulenceItem.h"
77
78 #include "FGCloudItem.h"
79 #include "FGSnowRain.h"
80
81 SG_USING_STD(vector);
82 SG_USING_STD(map);
83 SG_USING_NAMESPACE(std);
84
85 /****************************************************************************/
86 /* FOREWARD DEFINITIONS                                                     */
87 /****************************************************************************/
88 class FGPhysicalProperties2D;
89 ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
90
91 class FGPhysicalProperties
92 {
93 public:
94     typedef WeatherPrecision Altitude;  
95
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!)
101
102     map<Altitude,FGCloudItem>      Clouds;          //amount of covering and type
103
104     WeatherPrecision               SnowRainIntensity;       //this also stands for hail, snow,...
105     SnowRainType                   snowRainType;            
106     WeatherPrecision               LightningProbability;    //in lightnings per second   
107
108     FGPhysicalProperties();   //consructor to fill it with FG standart weather
109
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;
116
117     //for easier access to the cloud stuff:
118     unsigned int getNumberOfCloudLayers(void) const;
119     FGCloudItem  getCloudLayer(unsigned int nr) const;
120     
121     FGPhysicalProperties& operator =  ( const FGPhysicalProperties& p ); 
122     FGPhysicalProperties& operator *= ( const WeatherPrecision      d ); 
123     FGPhysicalProperties& operator += ( const FGPhysicalProperties& p ); 
124     FGPhysicalProperties& operator -= ( const FGPhysicalProperties& p ); 
125
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);
151 };
152
153 class FGPhysicalProperties2D : public FGPhysicalProperties
154 {
155 public:
156     sgVec2 p;       //position of the property (lat/lon)
157     friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
158
159     FGPhysicalProperties2D() {}
160
161     FGPhysicalProperties2D(const FGPhysicalProperties& prop, const sgVec2& pos) 
162     {
163         Wind = prop.Wind; 
164         Turbulence = prop.Turbulence;
165         Temperature = prop.Temperature;
166         AirPressure = prop.AirPressure; 
167         VaporPressure = prop.VaporPressure; 
168         sgCopyVec2(p, pos);
169     }
170 };
171
172 typedef vector<FGPhysicalProperties>                 FGPhysicalPropertiesVector;
173 typedef FGPhysicalPropertiesVector::iterator         FGPhysicalPropertiesVectorIt;
174 typedef FGPhysicalPropertiesVector::const_iterator   FGPhysicalPropertiesVectorConstIt;
175
176 typedef vector<FGPhysicalProperties2D>               FGPhysicalProperties2DVector;
177 typedef FGPhysicalProperties2DVector::iterator       FGPhysicalProperties2DVectorIt;
178 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
179
180
181
182 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
183 {
184     Wind          = p.Wind; 
185     Turbulence    = p.Turbulence; 
186     Temperature   = p.Temperature;
187     AirPressure   = p.AirPressure; 
188     VaporPressure = p.VaporPressure; 
189     return *this;
190 }
191
192 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecision d )
193 {
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;
197
198     for (wind_iterator       WindIt = Wind.begin(); 
199                              WindIt != Wind.end(); 
200                              WindIt++)
201         WindIt->second*= d;
202
203     for (turbulence_iterator TurbulenceIt = Turbulence.begin(); 
204                              TurbulenceIt != Turbulence.end(); 
205                              TurbulenceIt++)
206         TurbulenceIt->second *= d;
207
208     for (scalar_iterator     TemperatureIt = Temperature.begin(); 
209                              TemperatureIt != Temperature.end(); 
210                              TemperatureIt++)
211         TemperatureIt->second *= d;
212
213     AirPressure *= d;
214
215     for (scalar_iterator     VaporPressureIt = VaporPressure.begin(); 
216                              VaporPressureIt != VaporPressure.end(); 
217                              VaporPressureIt++)
218         VaporPressureIt->second *= d;
219
220     return *this;
221 }
222
223 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
224 {
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;
228
229     for (wind_iterator       WindIt = p.Wind.begin(); 
230                              WindIt != p.Wind.end(); 
231                              WindIt++)
232         if (!Wind.insert(*WindIt).second)           //when it's not inserted => it's already existing
233             Wind[WindIt->first] += WindIt->second;  //=> add the value
234             
235     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
236                              TurbulenceIt != p.Turbulence.end(); 
237                              TurbulenceIt++)
238         if (!Turbulence.insert(*TurbulenceIt).second)   
239             Turbulence[TurbulenceIt->first] += TurbulenceIt->second;
240
241     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
242                              TemperatureIt != p.Temperature.end(); 
243                              TemperatureIt++)
244         if (!Temperature.insert(*TemperatureIt).second) 
245             Temperature[TemperatureIt->first] += TemperatureIt->second;
246             
247     AirPressure += p.AirPressure.getValue();
248             
249     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
250                              VaporPressureIt != p.VaporPressure.end(); 
251                              VaporPressureIt++)
252         if (!VaporPressure.insert(*VaporPressureIt).second)     
253             VaporPressure[VaporPressureIt->first] += VaporPressureIt->second;
254
255     return *this;
256 }
257
258 // slightly modified version that also makes the Mac happy
259 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
260 {
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;
264     
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;
269     
270     for (wind_iterator WindIt = p.Wind.begin();
271          WindIt != p.Wind.end();
272          WindIt++)
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
276
277     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
278          TurbulenceIt != p.Turbulence.end();
279          TurbulenceIt++)
280         if (!Turbulence.insert( turb_type(TurbulenceIt->first, -TurbulenceIt->second) ).second)
281             Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
282     
283     for (scalar_iterator TemperatureIt = p.Temperature.begin();
284          TemperatureIt != p.Temperature.end();
285          TemperatureIt++)
286         if (!Temperature.insert( weather_type(TemperatureIt->first, -TemperatureIt->second) ).second)
287             Temperature[TemperatureIt->first] -= TemperatureIt->second;
288     
289     AirPressure -= p.AirPressure.getValue();
290     
291     for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
292          VaporPressureIt != p.VaporPressure.end();
293          VaporPressureIt++)
294         if (!VaporPressure.insert( weather_type(VaporPressureIt->first, -VaporPressureIt->second) ).second)
295             VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
296
297     return *this;
298 }
299
300 #if 0 // old version
301 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
302 {
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;
306
307     for (wind_iterator       WindIt = p.Wind.begin(); 
308                              WindIt != p.Wind.end(); 
309                              WindIt++)
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
312             
313     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
314                              TurbulenceIt != p.Turbulence.end(); 
315                              TurbulenceIt++)
316         if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second) 
317             Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
318             
319     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
320                              TemperatureIt != p.Temperature.end(); 
321                              TemperatureIt++)
322         if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)      
323             Temperature[TemperatureIt->first] -= TemperatureIt->second;
324             
325     AirPressure -= p.AirPressure.getValue();
326             
327     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
328                              VaporPressureIt != p.VaporPressure.end(); 
329                              VaporPressureIt++)
330         if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)        
331             VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
332
333
334     return *this;
335 }
336 #endif
337
338 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
339 {
340     typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
341
342     vector_iterator it = Wind.lower_bound(a);
343     vector_iterator it2 = it;
344     it--;
345
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());
350 }
351
352 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
353 {
354     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
355
356     vector_iterator it = Turbulence.lower_bound(a);
357     vector_iterator it2 = it;
358     it--;
359
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());
364 }
365
366 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
367 {
368     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
369
370     scalar_iterator it = Temperature.lower_bound(a);
371     scalar_iterator it2 = it;
372     it--;
373
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; 
376 }
377
378 //inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision x) const
379 //moved to FGPhysicalProperties.cpp as it got too complex to inline
380
381 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
382 {
383     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
384
385     scalar_iterator it = VaporPressure.lower_bound(a);
386     scalar_iterator it2 = it;
387     it--;
388
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; 
391 }
392
393
394 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
395 {
396     return a *= b;
397 }
398
399 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
400 {
401     return a *= b;
402 }
403
404 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
405 {
406     return a += b;
407 }
408
409 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
410 {
411     return a -= b;
412 }
413
414 /****************************************************************************/
415 #endif /*FGPhysicalProperties_H*/
416