]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGPhysicalProperties.h
0795d4d51b3a86a85e9163d3eb62023f65f34d7d
[flightgear.git] / src / WeatherCM / FGPhysicalProperties.h
1 /*******-*- Mode: C++ -*-************************************************************
2
3  Header:       FGPhysicalProperties.h   
4  Author:       Christian Mayer
5  Date started: 28.05.99
6
7  ---------- Copyright (C) 1999  Christian Mayer (vader@t-online.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 *****************************************************************************/
38
39 /****************************************************************************/
40 /* SENTRY                                                                   */
41 /****************************************************************************/
42 #ifndef FGPhysicalProperties_H
43 #define FGPhysicalProperties_H
44
45 /****************************************************************************/
46 /* INCLUDES                                                                 */
47 /****************************************************************************/
48 #include <Include/compiler.h>
49 #include <vector>
50 #include <set>
51
52 FG_USING_STD(vector);
53 FG_USING_STD(set);
54 FG_USING_NAMESPACE(std);
55
56 #include <Math/point3d.hxx>
57 #include <Voronoi/point2d.h>
58 #include "FGWeatherDefs.h"
59
60 #include "FGWindItem.h"
61 #include "FGTurbulenceItem.h"
62 #include "FGTemperatureItem.h"
63 #include "FGAirPressureItem.h"
64 #include "FGVaporPressureItem.h"
65
66 #include "FGCloudItem.h"
67 #include "FGSnowRain.h"
68
69 class FGPhysicalProperties
70 {
71 public:
72     set<FGWindItem> Wind;                   //all Wind vectors
73     set<FGTurbulenceItem> Turbulence;       //all Turbulence vectors
74     set<FGTemperatureItem> Temperature;     //in deg. Kelvin (I *only* accept SI!)
75     FGAirPressureItem AirPressure;          //in Pascal (I *only* accept SI!)
76     set<FGVaporPressureItem> VaporPressure; //in Pascal (I *only* accept SI!)
77
78     set<FGCloudItem> Clouds;                //amount of covering and type
79     WeatherPrecition SnowRainIntensity;     //this also stands for hail, snow,...
80     SnowRainType     snowRainType;          
81     WeatherPrecition LightningProbability;
82
83     FGPhysicalProperties();   //consructor to fill it with FG standart weather
84
85     //return values at specified altitudes
86     Point3D WindAt(const WeatherPrecition& a) const;
87     Point3D TurbulenceAt(const WeatherPrecition& a) const;
88     WeatherPrecition TemperatureAt(const WeatherPrecition& a) const;
89     WeatherPrecition AirPressureAt(const WeatherPrecition& a) const;
90     WeatherPrecition VaporPressureAt(const WeatherPrecition& a) const;
91     
92     FGPhysicalProperties& operator = ( const FGPhysicalProperties& p ); 
93     FGPhysicalProperties& operator *= ( const WeatherPrecition& d ); 
94     FGPhysicalProperties& operator += ( const FGPhysicalProperties& p); 
95     FGPhysicalProperties& operator -= ( const FGPhysicalProperties& p); 
96 };
97
98 typedef vector<FGPhysicalProperties> FGPhysicalPropertiesVector;
99 typedef FGPhysicalPropertiesVector::iterator FGPhysicalPropertiesVectorIt;
100 typedef FGPhysicalPropertiesVector::const_iterator FGPhysicalPropertiesVectorConstIt;
101
102 class FGPhysicalProperties2D;
103 ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
104
105 class FGPhysicalProperties2D : public FGPhysicalProperties
106 {
107 public:
108     Point2D p;      //position of the property (lat/lon)
109     friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
110
111     FGPhysicalProperties2D() {}
112
113     FGPhysicalProperties2D(const FGPhysicalProperties& prop, const Point2D& pos) 
114     {
115         Wind = prop.Wind; Turbulence = prop.Turbulence; Temperature = prop.Temperature;
116         AirPressure = prop.AirPressure; VaporPressure = prop.VaporPressure; p = pos;
117     }
118 };
119
120 typedef vector<FGPhysicalProperties2D> FGPhysicalProperties2DVector;
121 typedef FGPhysicalProperties2DVector::iterator FGPhysicalProperties2DVectorIt;
122 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
123
124 inline ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p )
125 {
126     out << "Position: " << p.p << "\nStored Wind: ";
127     for (set<FGWindItem>::const_iterator WindIt = p.Wind.begin(); WindIt != p.Wind.end(); WindIt++)
128         out << "(" << WindIt->getValue() << ") at " << WindIt->getAlt() << "m; ";
129
130     out << "\nStored Turbulence: ";
131     for (set<FGTurbulenceItem>::const_iterator TurbulenceIt = p.Turbulence.begin(); 
132                                                TurbulenceIt != p.Turbulence.end(); 
133                                                TurbulenceIt++)
134         out << "(" << TurbulenceIt->getValue() << ") at " << TurbulenceIt->getAlt() << "m; ";
135
136     out << "\nStored Temperature: ";
137     for (set<FGTemperatureItem>::const_iterator TemperatureIt = p.Temperature.begin(); 
138                                                 TemperatureIt != p.Temperature.end(); 
139                                                 TemperatureIt++)
140         out << TemperatureIt->getValue() << " at " << TemperatureIt->getAlt() << "m; ";
141
142     out << "\nStored AirPressure: ";
143     out << p.AirPressure.getValue(0) << " at " << 0 << "m; ";
144
145     out << "\nStored VaporPressure: ";
146     for (set<FGVaporPressureItem>::const_iterator VaporPressureIt = p.VaporPressure.begin(); 
147                                                   VaporPressureIt != p.VaporPressure.end(); 
148                                                   VaporPressureIt++)
149         out << VaporPressureIt->getValue() << " at " << VaporPressureIt->getAlt() << "m; ";
150
151     return out << "\n";
152 }
153
154
155 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
156 {
157     Wind          = p.Wind; 
158     Turbulence    = p.Turbulence; 
159     Temperature   = p.Temperature;
160     AirPressure   = p.AirPressure; 
161     VaporPressure = p.VaporPressure; 
162     return *this;
163 }
164
165 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecition& d )
166 {
167
168     for (set<FGWindItem>::iterator WindIt = Wind.begin(); 
169                                    WindIt != Wind.end(); 
170                                    WindIt++)
171         *WindIt *= d;
172
173     for (set<FGTurbulenceItem>::iterator TurbulenceIt = Turbulence.begin(); 
174                                          TurbulenceIt != Turbulence.end(); 
175                                          TurbulenceIt++)
176         *TurbulenceIt  *= d;
177
178     for (set<FGTemperatureItem>::iterator TemperatureIt = Temperature.begin(); 
179                                           TemperatureIt != Temperature.end(); 
180                                           TemperatureIt++)
181         *TemperatureIt *= d;
182
183     AirPressure *= d;
184
185     for (set<FGVaporPressureItem>::iterator VaporPressureIt = VaporPressure.begin(); 
186                                             VaporPressureIt != VaporPressure.end(); 
187                                             VaporPressureIt++)
188         *VaporPressureIt *= d;
189
190     return *this;
191 }
192
193 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
194 {
195     for (set<FGWindItem>::const_iterator WindIt = p.Wind.begin(); 
196                                          WindIt != p.Wind.end(); 
197                                          WindIt++ )
198         if (WindIt != Wind.upper_bound( FGWindItem(WindIt->getAlt(), Point3D(0)) ))
199             Wind.insert(*WindIt);
200         else
201             *(Wind.upper_bound( FGWindItem(WindIt->getAlt(), Point3D(0))) ) += WindIt->getValue();
202             
203     for (set<FGTurbulenceItem>::const_iterator TurbulenceIt = p.Turbulence.begin(); 
204                                                TurbulenceIt != p.Turbulence.end(); 
205                                                TurbulenceIt++)
206         if (TurbulenceIt != Turbulence.upper_bound( FGTurbulenceItem(TurbulenceIt->getAlt(), Point3D(0)) ))
207             Turbulence.insert(*TurbulenceIt);
208         else
209             *(Turbulence.upper_bound( FGTurbulenceItem(TurbulenceIt->getAlt(), Point3D(0)) )) += TurbulenceIt->getValue();
210             
211     for (set<FGTemperatureItem>::const_iterator TemperatureIt = p.Temperature.begin(); 
212                                                 TemperatureIt != p.Temperature.end(); 
213                                                 TemperatureIt++)
214         if (TemperatureIt != Temperature.upper_bound( FGTemperatureItem(TemperatureIt->getAlt(), 0.0) ))
215             Temperature.insert(*TemperatureIt);
216         else
217             *(Temperature.upper_bound( FGTemperatureItem(TemperatureIt->getAlt(), 0.0) )) += TemperatureIt->getValue();
218             
219     AirPressure += p.AirPressure.getValue(0.0);
220             
221     for (set<FGVaporPressureItem>::const_iterator VaporPressureIt = p.VaporPressure.begin(); 
222                                                   VaporPressureIt != p.VaporPressure.end(); 
223                                                   VaporPressureIt++)
224         if (VaporPressureIt != VaporPressure.upper_bound( FGVaporPressureItem(VaporPressureIt->getAlt(), 0.0) ))
225             VaporPressure.insert(*VaporPressureIt);
226         else
227             *(VaporPressure.upper_bound( FGVaporPressureItem(VaporPressureIt->getAlt(), 0.0) )) += VaporPressureIt->getValue();
228
229     return *this;
230 }
231
232 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
233 {
234
235     for (set<FGWindItem>::const_iterator WindIt = p.Wind.begin(); 
236                                          WindIt != p.Wind.end(); 
237                                          WindIt++)
238         if (WindIt != Wind.upper_bound( FGWindItem(WindIt->getAlt(), Point3D(0)) ))
239             Wind.insert(-(*WindIt));
240         else
241             *(Wind.upper_bound( FGWindItem(WindIt->getAlt(), Point3D(0)) ))  -= WindIt->getValue();
242             
243     for (set<FGTurbulenceItem>::const_iterator TurbulenceIt = p.Turbulence.begin(); 
244                                                TurbulenceIt != p.Turbulence.end(); 
245                                                TurbulenceIt++)
246         if (TurbulenceIt != Turbulence.upper_bound( FGTurbulenceItem(TurbulenceIt->getAlt(), Point3D(0)) ))
247             Turbulence.insert(-(*TurbulenceIt));
248         else
249             *(Turbulence.upper_bound( FGTurbulenceItem(TurbulenceIt->getAlt(), Point3D(0)) )) -= TurbulenceIt->getValue();
250             
251     for (set<FGTemperatureItem>::const_iterator TemperatureIt = p.Temperature.begin(); 
252                                                 TemperatureIt != p.Temperature.end(); 
253                                                 TemperatureIt++)
254         if (TemperatureIt != Temperature.upper_bound( FGTemperatureItem(TemperatureIt->getAlt(), 0.0) ))
255             Temperature.insert(-(*TemperatureIt));
256         else
257             *(Temperature.upper_bound( FGTemperatureItem(TemperatureIt->getAlt(), 0.0) )) -= TemperatureIt->getValue();
258             
259     AirPressure -= p.AirPressure.getValue(0.0);
260             
261     for (set<FGVaporPressureItem>::const_iterator VaporPressureIt = p.VaporPressure.begin(); 
262                                                   VaporPressureIt != p.VaporPressure.end(); 
263                                                   VaporPressureIt++)
264         if (VaporPressureIt != VaporPressure.upper_bound( FGVaporPressureItem(VaporPressureIt->getAlt(), 0.0) ))
265             VaporPressure.insert(-(*VaporPressureIt));
266         else
267             *(VaporPressure.upper_bound( FGVaporPressureItem(VaporPressureIt->getAlt(), 0.0) )) -= VaporPressureIt->getValue();
268
269     return *this;
270 }
271
272
273 inline Point3D FGPhysicalProperties::WindAt(const WeatherPrecition& a) const
274 {
275     set<FGWindItem>::const_iterator it = Wind.lower_bound(FGWindItem(a, Point3D(0)));
276     set<FGWindItem>::const_iterator it2 = it;
277     it--;
278
279     //now I've got it->alt < a < it2->alt so I can interpolate
280     return ( (it2->getValue() - it->getValue())/(it2->getAlt() - it->getAlt()) )*
281              (a - it2->getAlt()) + 
282               it2->getValue(); 
283 }
284
285 inline Point3D FGPhysicalProperties::TurbulenceAt(const WeatherPrecition& a) const
286 {
287     set<FGTurbulenceItem>::const_iterator it = Turbulence.lower_bound(FGTurbulenceItem(a, Point3D(0)));
288     set<FGTurbulenceItem>::const_iterator it2 = it;
289     it--;
290
291     //now I've got it->alt < a < it2->alt so I can interpolate
292     return ( (it2->getValue() - it->getValue() )/(it2->getAlt() - it->getAlt()) )*
293            (a - it2->getAlt())+ it2->getValue(); 
294 }
295
296 inline WeatherPrecition FGPhysicalProperties::TemperatureAt(const WeatherPrecition& a) const
297 {
298     set<FGTemperatureItem>::const_iterator it = Temperature.lower_bound(FGTemperatureItem(a, 0));
299     set<FGTemperatureItem>::const_iterator it2 = it;
300     it--;
301
302     //now I've got it->alt < a < it2->alt so I can interpolate
303     return ( (it2->getValue() - it->getValue()) / (it2->getAlt() - it->getAlt()) )* 
304            (a - it2->getAlt() )+ it2->getValue(); 
305 }
306
307 inline WeatherPrecition FGPhysicalProperties::AirPressureAt(const WeatherPrecition& a) const
308 {
309     return AirPressure.getValue(a);
310 }
311
312 inline WeatherPrecition FGPhysicalProperties::VaporPressureAt(const WeatherPrecition& a) const
313 {
314     set<FGVaporPressureItem>::const_iterator it = VaporPressure.lower_bound(FGVaporPressureItem(a, 0));
315     set<FGVaporPressureItem>::const_iterator it2 = it;
316     it--;
317
318     //now I've got it->alt < a < it2->alt so I can interpolate
319     return ( (it2->getValue() - it->getValue() ) / (it2->getAlt() - it->getAlt() ) ) *
320            (a - it2->getAlt() )+ it2->getValue(); 
321 }
322
323
324 inline FGPhysicalProperties operator * (const FGPhysicalProperties& a, const WeatherPrecition& b)
325 {
326     return FGPhysicalProperties(a) *= b;
327 }
328
329 inline FGPhysicalProperties operator * (const WeatherPrecition& b, const FGPhysicalProperties& a)
330 {
331     return FGPhysicalProperties(a) *= b;
332 }
333
334 inline FGPhysicalProperties operator + (const FGPhysicalProperties& a, const FGPhysicalProperties& b)
335 {
336     return FGPhysicalProperties(a) += (FGPhysicalProperties)b;
337 }
338
339 inline FGPhysicalProperties operator - (const FGPhysicalProperties& a, const FGPhysicalProperties& b)
340 {
341     return FGPhysicalProperties(a) -= (FGPhysicalProperties)b;
342 }
343
344 /****************************************************************************/
345 #endif /*FGPhysicalProperties_H*/
346