Engauge Digitizer  2
 All Classes Files Functions Variables Enumerations Enumerator Friends Pages
ExportOrdinalsSmooth.cpp
1 /******************************************************************************************************
2  * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3  * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4  * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5  ******************************************************************************************************/
6 
7 #include "ExportOrdinalsSmooth.h"
8 #include "Logger.h"
9 #include <qdebug.h>
10 #include <qmath.h>
11 #include <QPointF>
12 #include "Spline.h"
13 #include "Transformation.h"
14 
15 using namespace std;
16 
18 {
19 }
20 
22  vector<double> &t,
23  vector<SplinePair> &xy) const
24 {
25  LOG4CPP_INFO_S ((*mainCat)) << "ExportOrdinalsSmooth::loadSplinePairsWithoutTransformation";
26 
27  Points::const_iterator itrP;
28  for (itrP = points.begin(); itrP != points.end(); itrP++) {
29  const Point &point = *itrP;
30  QPointF posScreen = point.posScreen();
31 
32  t.push_back (point.ordinal ());
33  xy.push_back (SplinePair (posScreen.x(),
34  posScreen.y()));
35  }
36 }
37 
39  const Transformation &transformation,
40  vector<double> &t,
41  vector<SplinePair> &xy) const
42 {
43  LOG4CPP_INFO_S ((*mainCat)) << "ExportOrdinalsSmooth::loadSplinePairsWithTransformation";
44 
45  Points::const_iterator itrP;
46  for (itrP = points.begin(); itrP != points.end(); itrP++) {
47  const Point &point = *itrP;
48  QPointF posScreen = point.posScreen();
49  QPointF posGraph;
50  transformation.transformScreenToRawGraph (posScreen,
51  posGraph);
52 
53  t.push_back (point.ordinal ());
54  xy.push_back (SplinePair (posGraph.x(),
55  posGraph.y()));
56  }
57 }
58 
59 ExportValuesOrdinal ExportOrdinalsSmooth::ordinalsAtIntervalsGraph (const vector<double> &t,
60  const vector<SplinePair> &xy,
61  double pointsInterval) const
62 {
63  LOG4CPP_INFO_S ((*mainCat)) << "ExportOrdinalsSmooth::ordinalsAtIntervalsGraph";
64 
65  const double NUM_SMALLER_INTERVALS = 1000;
66 
67  // Results. Initially empty, but at the end it will have tMin, ..., tMax
68  ExportValuesOrdinal ordinals;
69 
70  // Spline class requires at least one point
71  if (xy.size() > 0) {
72 
73  // Fit a spline
74  Spline spline (t,
75  xy);
76 
77  // Integrate the distances for the subintervals
78  double integratedSeparation = 0;
79  QPointF posLast (xy [0].x(),
80  xy [0].y());
81 
82  // Simplest method to find the intervals is to break up the curve into many smaller intervals, and then aggregate them
83  // into intervals that, as much as possible, have the desired length. Simplicity wins out over accuracy in this
84  // approach - accuracy is sacrificed to achieve simplicity
85  double tMin = t.front();
86  double tMax = t.back();
87 
88  double tLast = 0.0;
89  int iTLastInterval = 0;
90  for (int iT = 0; iT < NUM_SMALLER_INTERVALS; iT++) {
91 
92  double t = tMin + ((tMax - tMin) * iT) / (NUM_SMALLER_INTERVALS - 1.0);
93 
94  SplinePair pairNew = spline.interpolateCoeff(t);
95 
96  QPointF posNew = QPointF (pairNew.x(),
97  pairNew.y());
98 
99  QPointF posDelta = posNew - posLast;
100  double integratedSeparationDelta = qSqrt (posDelta.x() * posDelta.x() + posDelta.y() * posDelta.y());
101  integratedSeparation += integratedSeparationDelta;
102 
103  while (integratedSeparation >= pointsInterval) {
104 
105  // End of current interval, and start of next interval. For better accuracy without having to crank up
106  // the number of points by orders of magnitude, we use linear interpolation
107  double sInterp;
108  if (iT == 0) {
109  sInterp = 0.0;
110  } else {
111  sInterp = (double) pointsInterval / (double) integratedSeparation;
112  }
113  double tInterp = (1.0 - sInterp) * tLast + sInterp * t;
114 
115  integratedSeparation -= pointsInterval; // Part of delta that was not used gets applied to next interval
116 
117  tLast = tInterp;
118  ordinals.push_back (tInterp);
119  iTLastInterval = iT;
120  }
121 
122  tLast = t;
123  posLast = posNew;
124  }
125 
126  if (iTLastInterval < NUM_SMALLER_INTERVALS - 1) {
127 
128  // Add last point so we end up at tMax
129  ordinals.push_back (tMax);
130 
131  }
132  }
133 
134  return ordinals;
135 }
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
SplinePair interpolateCoeff(double t) const
Return interpolated y for specified x.
Definition: Spline.cpp:139
Cubic interpolation given independent and dependent value vectors.
Definition: Spline.h:21
double y() const
Get method for y.
Definition: SplinePair.cpp:71
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:23
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:392
Affine transformation between screen and graph coordinates, based on digitized axis points...
void loadSplinePairsWithTransformation(const Points &points, const Transformation &transformation, std::vector< double > &t, std::vector< SplinePair > &xy) const
Load t (=ordinal) and xy (=screen position) spline pairs, converting screen coordinates to graph coor...
void loadSplinePairsWithoutTransformation(const Points &points, std::vector< double > &t, std::vector< SplinePair > &xy) const
Load t (=ordinal) and xy (=screen position) spline pairs, without any conversion to graph coordinates...
ExportValuesOrdinal ordinalsAtIntervalsGraph(const std::vector< double > &t, const std::vector< SplinePair > &xy, double pointsInterval) const
Perform the interpolation on the arrays loaded by the other methods.
double x() const
Get method for x.
Definition: SplinePair.cpp:66
double ordinal(ApplyHasCheck applyHasCheck=KEEP_HAS_CHECK) const
Get method for ordinal. Skip check if copying one instance to another.
Definition: Point.cpp:374
ExportOrdinalsSmooth()
Single constructor.
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition: SplinePair.h:11