Salome HOME
Corrections of examples path after install with scbi
[modules/hydro.git] / src / HYDROData / HYDROData_LinearInterpolator.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROData_LinearInterpolator.h"
20 #include <cstdlib>
21 #include <cmath>
22
23 HYDROData_LinearInterpolator::HYDROData_LinearInterpolator()
24 {
25 }
26
27 HYDROData_LinearInterpolator::~HYDROData_LinearInterpolator()
28 {
29 }
30
31 TCollection_AsciiString HYDROData_LinearInterpolator::GetDescription() const
32 {
33   TCollection_AsciiString aDescription( "Simple linear interpolator" );
34
35   return aDescription;
36 }
37
38 void HYDROData_LinearInterpolator::Calculate()
39 {
40   // Reset result data
41   ClearResults();
42
43   // Check input data
44   std::vector<double> aProfile1 = GetFirstProfileCoords();
45   std::vector<double> aProfile2 = GetSecondProfileCoords();
46   int aNbProfilesToCompute = GetNbProfilesToCompute();
47
48   int aSize1 = aProfile1.size();
49   int aSize2 = aProfile2.size();
50
51   div_t aDiv1 = std::div( aSize1, 3 );
52   div_t aDiv2 = std::div( aSize2, 3 );
53   
54   if ( aNbProfilesToCompute < 1 ||
55        aSize1 < 2 || aDiv1.rem != 0 ||
56        aSize2 < 2 || aDiv2.rem != 0 ) {
57     SetErrorCode( InvalidParametersError );
58     return;
59   }
60
61   bool isSame = false;
62   if ( aSize1 < aSize2 ) {
63     isSame = std::equal( aProfile1.begin(), aProfile1.end(), aProfile2.begin() );
64   } else {
65     isSame = std::equal( aProfile2.begin(), aProfile2.end(), aProfile1.begin() );
66   }
67
68   if ( isSame ) {
69     SetErrorCode( InvalidParametersError );
70     return;
71   }
72
73   // Linear interpolation
74   InterpolationError aStatus = OK;
75
76   // the first profile should have the equal or less number of points than the second profile
77   int aNbPoints1 = aDiv1.quot;
78   int aNbPoints2 = aDiv2.quot;
79   if ( aNbPoints1 > aNbPoints2 ) {
80     aProfile1.swap( aProfile2 );
81     std::swap( aNbPoints1, aNbPoints2 );
82   }
83
84   for ( int k = 0; k <= aNbProfilesToCompute - 1; k++ ) {
85     std::vector<double> aResultProfile; ///< the k-th computed profile
86
87     double aRelParam = (double)( k + 1 ) / ( aNbProfilesToCompute + 1 );
88     for ( int i = 0; i <= aNbPoints1 - 1; i++ ) {
89       double aRel = ( aNbPoints2 - 1 ) / ( aNbPoints1 - 1 );
90       int aPointIndex = (int) std::floor( aRel * i ); ///< point index in the second profile
91       int anXindex1 = i * 3;
92       int anXindex2 = aPointIndex * 3;
93
94       double anXi = ( aProfile1[anXindex1] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2] * aRelParam );
95       double anYi = ( aProfile1[anXindex1 + 1] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2 + 1] * aRelParam );
96       double aZi = ( aProfile1[anXindex1 + 2] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2 + 2] * aRelParam );
97
98       aResultProfile.push_back( anXi );
99       aResultProfile.push_back( anYi );
100       aResultProfile.push_back( aZi );
101     }
102    
103     InsertResultProfile( aResultProfile );
104   }
105
106   SetErrorCode( aStatus );
107 }