Salome HOME
debug of tests for DTM
[modules/hydro.git] / src / HYDROData / HYDROData_LinearInterpolator.cxx
index af2eb24c24f8fc290d1290189028f4e3c12f725d..aea863d188b14afb8b845cee2a97b1018660e788 100644 (file)
@@ -1,8 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015  EDF-R&D
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
@@ -21,7 +17,8 @@
 //
 
 #include "HYDROData_LinearInterpolator.h"
-
+#include <cstdlib>
+#include <cmath>
 
 HYDROData_LinearInterpolator::HYDROData_LinearInterpolator()
 {
@@ -31,14 +28,80 @@ HYDROData_LinearInterpolator::~HYDROData_LinearInterpolator()
 {
 }
 
-std::string HYDROData_LinearInterpolator::GetDescription() const
+TCollection_AsciiString HYDROData_LinearInterpolator::GetDescription() const
 {
-  std::string aDescription( "Simple linear interpolator" );
+  TCollection_AsciiString aDescription( "Simple linear interpolator" );
 
   return aDescription;
 }
 
-InterpolationError HYDROData_LinearInterpolator::Calculate()
+void HYDROData_LinearInterpolator::Calculate()
 {
-  return OK;
-}
\ No newline at end of file
+  // Reset result data
+  ClearResults();
+
+  // Check input data
+  std::vector<double> aProfile1 = GetFirstProfileCoords();
+  std::vector<double> aProfile2 = GetSecondProfileCoords();
+  int aNbProfilesToCompute = GetNbProfilesToCompute();
+
+  int aSize1 = aProfile1.size();
+  int aSize2 = aProfile2.size();
+
+  div_t aDiv1 = std::div( aSize1, 3 );
+  div_t aDiv2 = std::div( aSize2, 3 );
+  
+  if ( aNbProfilesToCompute < 1 ||
+       aSize1 < 2 || aDiv1.rem != 0 ||
+       aSize2 < 2 || aDiv2.rem != 0 ) {
+    SetErrorCode( InvalidParametersError );
+    return;
+  }
+
+  bool isSame = false;
+  if ( aSize1 < aSize2 ) {
+    isSame = std::equal( aProfile1.begin(), aProfile1.end(), aProfile2.begin() );
+  } else {
+    isSame = std::equal( aProfile2.begin(), aProfile2.end(), aProfile1.begin() );
+  }
+
+  if ( isSame ) {
+    SetErrorCode( InvalidParametersError );
+    return;
+  }
+
+  // Linear interpolation
+  InterpolationError aStatus = OK;
+
+  // the first profile should have the equal or less number of points than the second profile
+  int aNbPoints1 = aDiv1.quot;
+  int aNbPoints2 = aDiv2.quot;
+  if ( aNbPoints1 > aNbPoints2 ) {
+    aProfile1.swap( aProfile2 );
+    std::swap( aNbPoints1, aNbPoints2 );
+  }
+
+  for ( int k = 0; k <= aNbProfilesToCompute - 1; k++ ) {
+    std::vector<double> aResultProfile; ///< the k-th computed profile
+
+    double aRelParam = (double)( k + 1 ) / ( aNbProfilesToCompute + 1 );
+    for ( int i = 0; i <= aNbPoints1 - 1; i++ ) {
+      double aRel = ( aNbPoints2 - 1 ) / ( aNbPoints1 - 1 );
+      int aPointIndex = (int) std::floor( aRel * i ); ///< point index in the second profile
+      int anXindex1 = i * 3;
+      int anXindex2 = aPointIndex * 3;
+
+      double anXi = ( aProfile1[anXindex1] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2] * aRelParam );
+      double anYi = ( aProfile1[anXindex1 + 1] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2 + 1] * aRelParam );
+      double aZi = ( aProfile1[anXindex1 + 2] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2 + 2] * aRelParam );
+
+      aResultProfile.push_back( anXi );
+      aResultProfile.push_back( anYi );
+      aResultProfile.push_back( aZi );
+    }
+   
+    InsertResultProfile( aResultProfile );
+  }
+
+  SetErrorCode( aStatus );
+}