diff options
Diffstat (limited to 'chart2/source/view/charttypes/Splines.cxx')
-rw-r--r-- | chart2/source/view/charttypes/Splines.cxx | 89 |
1 files changed, 27 insertions, 62 deletions
diff --git a/chart2/source/view/charttypes/Splines.cxx b/chart2/source/view/charttypes/Splines.cxx index bd54b266345a..15980b638bc8 100644 --- a/chart2/source/view/charttypes/Splines.cxx +++ b/chart2/source/view/charttypes/Splines.cxx @@ -19,12 +19,11 @@ #include "Splines.hxx" #include <osl/diagnose.h> -#include <com/sun/star/drawing/PolyPolygonShape3D.hpp> #include <com/sun/star/drawing/Position3D.hpp> #include <vector> #include <algorithm> -#include <memory> +#include <optional> #include <cmath> #include <limits> @@ -121,7 +120,7 @@ lcl_SplineCalculation::lcl_SplineCalculation( m_fYp1( fY1FirstDerivation ), m_fYpN( fYnFirstDerivation ), m_nKLow( 0 ), - m_nKHigh( rSortedPoints.size() - 1 ), + m_nKHigh( m_aPoints.size() - 1 ), m_fLastInterpolatedValue(std::numeric_limits<double>::infinity()) { Calculate(); @@ -133,7 +132,7 @@ lcl_SplineCalculation::lcl_SplineCalculation( m_fYp1( 0.0 ), /*dummy*/ m_fYpN( 0.0 ), /*dummy*/ m_nKLow( 0 ), - m_nKHigh( rSortedPoints.size() - 1 ), + m_nKHigh( m_aPoints.size() - 1 ), m_fLastInterpolatedValue(std::numeric_limits<double>::infinity()) { CalculatePeriodic(); @@ -411,26 +410,19 @@ bool createParameterT(const tPointVecType& rUniquePoints, double* t) bool bIsSuccessful = true; const lcl_tSizeType n = rUniquePoints.size() - 1; t[0]=0.0; - double dx = 0.0; - double dy = 0.0; - double fDiffMax = 1.0; //dummy values double fDenominator = 0.0; // initialized for summing up for (lcl_tSizeType i=1; i<=n ; ++i) { // 4th root(dx^2+dy^2) - dx = rUniquePoints[i].first - rUniquePoints[i-1].first; - dy = rUniquePoints[i].second - rUniquePoints[i-1].second; - // scaling to avoid underflow or overflow - fDiffMax = std::max(fabs(dx), fabs(dy)); - if (fDiffMax == 0.0) + double dx = rUniquePoints[i].first - rUniquePoints[i-1].first; + double dy = rUniquePoints[i].second - rUniquePoints[i-1].second; + if (dx == 0 && dy == 0) { bIsSuccessful = false; break; } else { - dx /= fDiffMax; - dy /= fDiffMax; - fDenominator += sqrt(sqrt(dx * dx + dy * dy)) * sqrt(fDiffMax); + fDenominator += sqrt(std::hypot(dx, dy)); } } if (fDenominator == 0.0) @@ -444,13 +436,9 @@ bool createParameterT(const tPointVecType& rUniquePoints, double* t) double fNumerator = 0.0; for (lcl_tSizeType i=1; i<=j ; ++i) { - dx = rUniquePoints[i].first - rUniquePoints[i-1].first; - dy = rUniquePoints[i].second - rUniquePoints[i-1].second; - fDiffMax = std::max(fabs(dx), fabs(dy)); - // same as above, so should not be zero - dx /= fDiffMax; - dy /= fDiffMax; - fNumerator += sqrt(sqrt(dx * dx + dy * dy)) * sqrt(fDiffMax); + double dx = rUniquePoints[i].first - rUniquePoints[i-1].first; + double dy = rUniquePoints[i].second - rUniquePoints[i-1].second; + fNumerator += sqrt(std::hypot(dx, dy)); } t[j] = fNumerator / fDenominator; @@ -581,8 +569,8 @@ void SplineCalculater::CalculateCubicSplines( // generate a spline for each coordinate. It holds the complete // information to calculate each point of the curve - std::unique_ptr<lcl_SplineCalculation> aSplineX; - std::unique_ptr<lcl_SplineCalculation> aSplineY; + std::optional<lcl_SplineCalculation> aSplineX; + std::optional<lcl_SplineCalculation> aSplineY; // lcl_SplineCalculation* aSplineZ; the z-coordinates of all points in // a data series are equal. No spline calculation needed, but copy // coordinate to output @@ -592,16 +580,15 @@ void SplineCalculater::CalculateCubicSplines( pOld[ 0 ].PositionZ == pOld[nMaxIndexPoints].PositionZ && nMaxIndexPoints >=2 ) { // periodic spline - aSplineX.reset(new lcl_SplineCalculation( std::move(aInputX))); - aSplineY.reset(new lcl_SplineCalculation( std::move(aInputY))); - // aSplineZ = new lcl_SplineCalculation( aInputZ) ; + aSplineX.emplace(std::move(aInputX)); + aSplineY.emplace(std::move(aInputY)); } else // generate the kind "natural spline" { double fXDerivation = std::numeric_limits<double>::infinity(); double fYDerivation = std::numeric_limits<double>::infinity(); - aSplineX.reset(new lcl_SplineCalculation( std::move(aInputX), fXDerivation, fXDerivation )); - aSplineY.reset(new lcl_SplineCalculation( std::move(aInputY), fYDerivation, fYDerivation )); + aSplineX.emplace(std::move(aInputX), fXDerivation, fXDerivation); + aSplineY.emplace(std::move(aInputY), fYDerivation, fYDerivation); } // fill result polygon with calculated values @@ -690,29 +677,23 @@ void SplineCalculater::CalculateBSplines( continue; // need at least 2 points, degree p needs at least n+1 points // next piece of series - std::unique_ptr<double[]> t(new double [n+1]); - if (!createParameterT(aPointsIn, t.get())) + std::vector<double> t(n + 1); + if (!createParameterT(aPointsIn, t.data())) { continue; // next piece of series } lcl_tSizeType m = n + p + 1; - std::unique_ptr<double[]> u(new double [m+1]); - createKnotVector(n, p, t.get(), u.get()); + std::vector<double> u(m + 1); + createKnotVector(n, p, t.data(), u.data()); // The matrix N contains the B-spline basis functions applied to parameters. // In each row only p+1 adjacent elements are non-zero. The starting // column in a higher row is equal or greater than in the lower row. // To store this matrix the non-zero elements are shifted to column 0 // and the amount of shifting is remembered in an array. - std::unique_ptr<double*[]> aMatN(new double*[n+1]); - for (lcl_tSizeType row = 0; row <=n; ++row) - { - aMatN[row] = new double[p+1]; - for (sal_uInt32 col = 0; col <= p; ++col) - aMatN[row][col] = 0.0; - } - std::unique_ptr<lcl_tSizeType[]> aShift(new lcl_tSizeType[n+1]); + std::vector<std::vector<double>> aMatN(n + 1, std::vector<double>(p + 1)); + std::vector<lcl_tSizeType> aShift(n + 1); aMatN[0][0] = 1.0; //all others are zero aShift[0] = 0; aMatN[n][0] = 1.0; @@ -732,7 +713,7 @@ void SplineCalculater::CalculateBSplines( // index in reduced matrix aMatN = (index in full matrix N) - (i-p) aShift[k] = i - p; - applyNtoParameterT(i, t[k], p, u.get(), aMatN[k]); + applyNtoParameterT(i, t[k], p, u.data(), aMatN[k].data()); } // next row k // Get matrix C of control points from the matrix equation aMatN * C = aPointsIn @@ -742,9 +723,6 @@ void SplineCalculater::CalculateBSplines( lcl_tSizeType c = 0; // true column index double fDivisor = 1.0; // used for diagonal element double fEliminate = 1.0; // used for the element, that will become zero - double fHelp; - tPointType aHelp; - lcl_tSizeType nHelp; // used in triangle change bool bIsSuccessful = true; for (c = 0 ; c <= n && bIsSuccessful; ++c) { @@ -764,18 +742,9 @@ void SplineCalculater::CalculateBSplines( // exchange total row r with total row c if necessary if (r != c) { - for ( sal_uInt32 i = 0; i <= p ; ++i) - { - fHelp = aMatN[r][i]; - aMatN[r][i] = aMatN[c][i]; - aMatN[c][i] = fHelp; - } - aHelp = aPointsIn[r]; - aPointsIn[r] = aPointsIn[c]; - aPointsIn[c] = aHelp; - nHelp = aShift[r]; - aShift[r] = aShift[c]; - aShift[c] = nHelp; + std::swap( aMatN[r], aMatN[c] ); + std::swap( aPointsIn[r], aPointsIn[c] ); + std::swap( aShift[r], aShift[c] ); } // divide row c, so that element(c,c) becomes 1 @@ -843,7 +812,7 @@ void SplineCalculater::CalculateBSplines( pNew[nNewSize -1 ].PositionX = aPointsIn[n].first; pNew[nNewSize -1 ].PositionY = aPointsIn[n].second; pNew[nNewSize -1 ].PositionZ = fZCoordinate; - std::unique_ptr<double[]> aP(new double[m+1]); + std::vector<double> aP(m + 1); lcl_tSizeType nLow = 0; for ( lcl_tSizeType nTIndex = 0; nTIndex <= n-1; ++nTIndex) { @@ -895,10 +864,6 @@ void SplineCalculater::CalculateBSplines( } } } - for (lcl_tSizeType row = 0; row <=n; ++row) - { - delete[] aMatN[row]; - } } // next piece of the series } |