Engauge Digitizer  2
 All Classes Files Functions Variables Enumerations Enumerator Friends Pages
ExportFileFunctions.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 "CallbackGatherXThetaValuesFunctions.h"
8 #include "CurveConnectAs.h"
9 #include "Document.h"
10 #include "DocumentModelGeneral.h"
11 #include "EngaugeAssert.h"
12 #include "ExportFileFunctions.h"
13 #include "ExportLayoutFunctions.h"
14 #include "ExportOrdinalsSmooth.h"
15 #include "ExportXThetaValuesMergedFunctions.h"
16 #include "FormatCoordsUnits.h"
17 #include "LinearToLog.h"
18 #include "Logger.h"
19 #include <QTextStream>
20 #include <QVector>
21 #include "Spline.h"
22 #include "SplinePair.h"
23 #include "Transformation.h"
24 #include <vector>
25 
26 using namespace std;
27 
29 {
30 }
31 
32 void ExportFileFunctions::exportAllPerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
33  const Document &document,
34  const MainWindowModel &modelMainWindow,
35  const QStringList &curvesIncluded,
36  const ExportValuesXOrY &xThetaValues,
37  const QString &delimiter,
38  const Transformation &transformation,
39  bool isLogXTheta,
40  bool isLogYRadius,
41  QTextStream &str) const
42 {
43  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::exportAllPerLineXThetaValuesMerged";
44 
45  int curveCount = curvesIncluded.count();
46  int xThetaCount = xThetaValues.count();
47  QVector<QVector<QString*> > yRadiusValues (curveCount, QVector<QString*> (xThetaCount));
48  initializeYRadiusValues (curvesIncluded,
49  xThetaValues,
50  yRadiusValues);
51  loadYRadiusValues (modelExportOverride,
52  document,
53  modelMainWindow,
54  curvesIncluded,
55  transformation,
56  isLogXTheta,
57  isLogYRadius,
58  xThetaValues,
59  yRadiusValues);
60 
61  outputXThetaYRadiusValues (modelExportOverride,
62  document.modelCoords(),
63  document.modelGeneral(),
64  modelMainWindow,
65  curvesIncluded,
66  xThetaValues,
67  transformation,
68  yRadiusValues,
69  delimiter,
70  str);
71  destroy2DArray (yRadiusValues);
72 }
73 
74 void ExportFileFunctions::exportOnePerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
75  const Document &document,
76  const MainWindowModel &modelMainWindow,
77  const QStringList &curvesIncluded,
78  const ExportValuesXOrY &xThetaValues,
79  const QString &delimiter,
80  const Transformation &transformation,
81  bool isLogXTheta,
82  bool isLogYRadius,
83  QTextStream &str) const
84 {
85  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::exportOnePerLineXThetaValuesMerged";
86 
87  bool isFirst = true;
88 
89  QStringList::const_iterator itr;
90  for (itr = curvesIncluded.begin(); itr != curvesIncluded.end(); itr++) {
91 
92  insertLineSeparator (isFirst,
93  modelExportOverride.header(),
94  str);
95 
96  // This curve
97  const int CURVE_COUNT = 1;
98  QString curveIncluded = *itr;
99  QStringList curvesIncluded (curveIncluded);
100 
101  int xThetaCount = xThetaValues.count();
102  QVector<QVector<QString*> > yRadiusValues (CURVE_COUNT, QVector<QString*> (xThetaCount));
103  initializeYRadiusValues (curvesIncluded,
104  xThetaValues,
105  yRadiusValues);
106  loadYRadiusValues (modelExportOverride,
107  document,
108  modelMainWindow,
109  curvesIncluded,
110  transformation,
111  isLogXTheta,
112  isLogYRadius,
113  xThetaValues,
114  yRadiusValues);
115  outputXThetaYRadiusValues (modelExportOverride,
116  document.modelCoords(),
117  document.modelGeneral(),
118  modelMainWindow,
119  curvesIncluded,
120  xThetaValues,
121  transformation,
122  yRadiusValues,
123  delimiter,
124  str);
125  destroy2DArray (yRadiusValues);
126  }
127 }
128 
130  const Document &document,
131  const MainWindowModel &modelMainWindow,
132  const Transformation &transformation,
133  QTextStream &str) const
134 {
135  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::exportToFile";
136 
137  // Log coordinates must be temporarily transformed to linear coordinates
138  bool isLogXTheta = (document.modelCoords().coordScaleXTheta() == COORD_SCALE_LOG);
139  bool isLogYRadius = (document.modelCoords().coordScaleYRadius() == COORD_SCALE_LOG);
140 
141  // Identify curves to be included
142  QStringList curvesIncluded = curvesToInclude (modelExportOverride,
143  document,
144  document.curvesGraphsNames(),
145  CONNECT_AS_FUNCTION_SMOOTH,
146  CONNECT_AS_FUNCTION_STRAIGHT);
147 
148  // Delimiter
149  const QString delimiter = exportDelimiterToText (modelExportOverride.delimiter(),
150  modelExportOverride.header() == EXPORT_HEADER_GNUPLOT);
151 
152  // Get x/theta values to be used
153  CallbackGatherXThetaValuesFunctions ftor (modelExportOverride,
154  curvesIncluded,
155  transformation);
156  Functor2wRet<const QString &, const Point &, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
158  document.iterateThroughCurvesPointsGraphs(ftorWithCallback);
159 
160  ExportXThetaValuesMergedFunctions exportXTheta (modelExportOverride,
161  ftor.xThetaValuesRaw(),
162  transformation);
163  ExportValuesXOrY xThetaValuesMerged = exportXTheta.xThetaValues ();
164 
165  // Skip if every curve was a relation
166  if (xThetaValuesMerged.count() > 0) {
167 
168  // Export in one of two layouts
169  if (modelExportOverride.layoutFunctions() == EXPORT_LAYOUT_ALL_PER_LINE) {
170  exportAllPerLineXThetaValuesMerged (modelExportOverride,
171  document,
172  modelMainWindow,
173  curvesIncluded,
174  xThetaValuesMerged,
175  delimiter,
176  transformation,
177  isLogXTheta,
178  isLogYRadius,
179  str);
180  } else {
181  exportOnePerLineXThetaValuesMerged (modelExportOverride,
182  document,
183  modelMainWindow,
184  curvesIncluded,
185  xThetaValuesMerged,
186  delimiter,
187  transformation,
188  isLogXTheta,
189  isLogYRadius,
190  str);
191  }
192  }
193 }
194 
195 void ExportFileFunctions::initializeYRadiusValues (const QStringList &curvesIncluded,
196  const ExportValuesXOrY &xThetaValuesMerged,
197  QVector<QVector<QString*> > &yRadiusValues) const
198 {
199  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::initializeYRadiusValues";
200 
201  // Initialize every entry with empty string
202  int curveCount = curvesIncluded.count();
203  int xThetaCount = xThetaValuesMerged.count();
204  for (int row = 0; row < xThetaCount; row++) {
205  for (int col = 0; col < curveCount; col++) {
206  yRadiusValues [col] [row] = new QString;
207  }
208  }
209 }
210 
211 double ExportFileFunctions::linearlyInterpolate (const Points &points,
212  double xThetaValue,
213  const Transformation &transformation) const
214 {
215  // LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::linearlyInterpolate";
216 
217  // If point is within the range of the function points then interpolation will be used, otherwise
218  // extrapolation will be used
219  double yRadius = 0;
220  QPointF posGraphBefore; // Not set until ip=1
221  bool foundIt = false;
222  for (int ip = 0; !foundIt && (ip < points.count()); ip++) {
223 
224  const Point &point = points.at (ip);
225  QPointF posGraph;
226  transformation.transformScreenToRawGraph (point.posScreen(),
227  posGraph);
228 
229  // Cases where we have found it at this point in the code
230  // (1) interpolation case where (xBefore < xThetaValue < xAfter)
231  // (2) extrapolation case where (xThetaValue < xBefore < xAfter and ip=0) for which we delay finding it until ip=1 so we have
232  // two points for extrapolating. This case is why we have the subtle test for ip>0 in the next line
233  if (xThetaValue <= posGraph.x() && (ip > 0)) {
234 
235  foundIt = true;
236 
237  // Case 1 comments: xThetaValue is between posGraphBefore and posGraph. Note that if posGraph.x()=posGraphBefore.x() then
238  // previous iteration of loop would have been used for interpolation, and then the loop was exited. Range of s is 0<s<1
239  // Case 2 comments: Range of s is s<0
240  double s = (xThetaValue - posGraphBefore.x()) / (posGraph.x() - posGraphBefore.x());
241  yRadius = (1.0 -s) * posGraphBefore.y() + s * posGraph.y();
242 
243  break;
244  }
245 
246  posGraphBefore = posGraph;
247  }
248 
249  if (!foundIt) {
250 
251  if (points.count() > 1) {
252 
253  // Extrapolation will be used since point is out of the range of the function points. Specifically, it is greater than the
254  // last x value in the function. Range of s is 1<s
255  int N = points.count();
256  const Point &pointLast = points.at (N - 1);
257  const Point &pointBefore = points.at (N - 2);
258  QPointF posGraphLast;
259  transformation.transformScreenToRawGraph (pointLast.posScreen(),
260  posGraphLast);
261  transformation.transformScreenToRawGraph (pointBefore.posScreen(),
262  posGraphBefore);
263  double s = (xThetaValue - posGraphBefore.x()) / (posGraphLast.x() - posGraphBefore.x());
264  yRadius = (1.0 - s) * posGraphBefore.y() + s * posGraphLast.y();
265 
266  } else if (points.count() == 1) {
267 
268  // Just use the single point
269  yRadius = posGraphBefore.y();
270 
271  } else {
272 
273  ENGAUGE_ASSERT (false);
274 
275  }
276  }
277 
278  return yRadius;
279 }
280 
281 void ExportFileFunctions::loadYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
282  const Document &document,
283  const MainWindowModel &modelMainWindow,
284  const QStringList &curvesIncluded,
285  const Transformation &transformation,
286  bool isLogXTheta,
287  bool isLogYRadius,
288  const ExportValuesXOrY &xThetaValues,
289  QVector<QVector<QString*> > &yRadiusValues) const
290 {
291  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValues";
292 
293  // Loop through curves
294  int curveCount = curvesIncluded.count();
295  for (int col = 0; col < curveCount; col++) {
296 
297  const QString curveName = curvesIncluded.at (col);
298 
299  const Curve *curve = document.curveForCurveName (curveName);
300  Points points = curve->points (); // These points will be linearized below if either coordinate is log
301 
302  if (modelExportOverride.pointsSelectionFunctions() == EXPORT_POINTS_SELECTION_FUNCTIONS_RAW) {
303 
304  // No interpolation. Raw points
305  loadYRadiusValuesForCurveRaw (document.modelCoords(),
306  document.modelGeneral(),
307  modelMainWindow,
308  points,
309  xThetaValues,
310  transformation,
311  yRadiusValues [col]);
312  } else {
313 
314  // Interpolation
315  if (curve->curveStyle().lineStyle().curveConnectAs() == CONNECT_AS_FUNCTION_SMOOTH) {
316 
317  loadYRadiusValuesForCurveInterpolatedSmooth (document.modelCoords(),
318  document.modelGeneral(),
319  modelMainWindow,
320  points,
321  xThetaValues,
322  transformation,
323  isLogXTheta,
324  isLogYRadius,
325  yRadiusValues [col]);
326 
327  } else {
328 
329  loadYRadiusValuesForCurveInterpolatedStraight (document.modelCoords(),
330  document.modelGeneral(),
331  modelMainWindow,
332  points,
333  xThetaValues,
334  transformation,
335  yRadiusValues [col]);
336  }
337  }
338  }
339 }
340 
341 void ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedSmooth (const DocumentModelCoords &modelCoords,
342  const DocumentModelGeneral &modelGeneral,
343  const MainWindowModel &modelMainWindow,
344  const Points &points,
345  const ExportValuesXOrY &xThetaValues,
346  const Transformation &transformation,
347  bool isLogXTheta,
348  bool isLogYRadius,
349  QVector<QString*> &yRadiusValues) const
350 {
351  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedSmooth";
352 
353  // Convert screen coordinates to graph coordinates, in vectors suitable for spline fitting
354  vector<double> t;
355  vector<SplinePair> xy;
356  ExportOrdinalsSmooth ordinalsSmooth;
357 
358  ordinalsSmooth.loadSplinePairsWithTransformation (points,
359  transformation,
360  isLogXTheta,
361  isLogYRadius,
362  t,
363  xy);
364 
365  // Formatting
366  FormatCoordsUnits format;
367  QString dummyXThetaOut;
368 
369  if (points.count() == 0) {
370 
371  // Since there are no values, leave the field empty
372  for (int row = 0; row < xThetaValues.count(); row++) {
373  *(yRadiusValues [row]) = "";
374  }
375 
376  } else if (points.count() == 1 ||
377  points.count() == 2) {
378 
379  // Apply the single value everywhere (N=1) or do linear interpolation (N=2)
380  for (int row = 0; row < xThetaValues.count(); row++) {
381 
382  double xTheta = xThetaValues.at (row);
383  double yRadius;
384  if (points.count() == 1) {
385  yRadius = xy.at (0).y ();
386  } else {
387  double x0 = xy.at (0).x ();
388  double x1 = xy.at (1).x ();
389  double y0 = xy.at (0).y ();
390  double y1 = xy.at (1).y ();
391  if (x0 == x1) {
392  // Cannot do linear interpolation using two points at the same x value
393  yRadius = xy.at (0).y ();
394  } else {
395  double s = (xTheta - x0) / (x1 - x0);
396  yRadius = (1.0 - s) * y0 + s * y1;
397  }
398  }
399  format.unformattedToFormatted (xTheta,
400  yRadius,
401  modelCoords,
402  modelGeneral,
403  modelMainWindow,
404  dummyXThetaOut,
405  *(yRadiusValues [row]),
406  transformation);
407  }
408 
409  } else {
410 
411  // Iteration accuracy versus number of iterations 8->256, 10->1024, 12->4096. Single pixel accuracy out of
412  // typical image size of 1024x1024 means around 10 iterations gives decent accuracy for numbers much bigger
413  // than 1. A value of 12 gave some differences in the least significant figures of numbers like 10^-3 in
414  // the regression tests. Toggling between 30 and 32 made no difference in the regression tests.
415  const int MAX_ITERATIONS = 32;
416 
417  // Spline class requires at least one point
418  if (xy.size() > 0) {
419 
420  // Fit a spline
421  Spline spline (t,
422  xy);
423 
424  // Get value at desired points
425  for (int row = 0; row < xThetaValues.count(); row++) {
426 
427  double xTheta = xThetaValues.at (row);
428 
429  LinearToLog linearToLog;
430 
431  SplinePair splinePairFound = spline.findSplinePairForFunctionX (linearToLog.linearize (xTheta, isLogXTheta),
432  MAX_ITERATIONS);
433  double yRadius = linearToLog.delinearize (splinePairFound.y (),
434  isLogYRadius);
435 
436  // Save y/radius value for this row into yRadiusValues, after appropriate formatting
437  QString dummyXThetaOut;
438  format.unformattedToFormatted (xTheta,
439  yRadius,
440  modelCoords,
441  modelGeneral,
442  modelMainWindow,
443  dummyXThetaOut,
444  *(yRadiusValues [row]),
445  transformation);
446  }
447  }
448  }
449 }
450 
451 void ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedStraight (const DocumentModelCoords &modelCoords,
452  const DocumentModelGeneral &modelGeneral,
453  const MainWindowModel &modelMainWindow,
454  const Points &points,
455  const ExportValuesXOrY &xThetaValues,
456  const Transformation &transformation,
457  QVector<QString*> &yRadiusValues) const
458 {
459  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedStraight";
460 
461  FormatCoordsUnits format;
462 
463  // Get value at desired points
464  for (int row = 0; row < xThetaValues.count(); row++) {
465 
466  double xThetaValue = xThetaValues.at (row);
467 
468  double yRadius = linearlyInterpolate (points,
469  xThetaValue,
470  transformation);
471 
472  // Save y/radius value for this row into yRadiusValues, after appropriate formatting
473  QString dummyXThetaOut;
474  format.unformattedToFormatted (xThetaValue,
475  yRadius,
476  modelCoords,
477  modelGeneral,
478  modelMainWindow,
479  dummyXThetaOut,
480  *(yRadiusValues [row]),
481  transformation);
482  }
483 }
484 
485 void ExportFileFunctions::loadYRadiusValuesForCurveRaw (const DocumentModelCoords &modelCoords,
486  const DocumentModelGeneral &modelGeneral,
487  const MainWindowModel &modelMainWindow,
488  const Points &points,
489  const ExportValuesXOrY &xThetaValues,
490  const Transformation &transformation,
491  QVector<QString*> &yRadiusValues) const
492 {
493  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValuesForCurveRaw";
494 
495  FormatCoordsUnits format;
496 
497  // Since the curve points may be a subset of xThetaValues (in which case the non-applicable xThetaValues will have
498  // blanks for the yRadiusValues), we iterate over the smaller set
499  for (int pt = 0; pt < points.count(); pt++) {
500 
501  const Point &point = points.at (pt);
502 
503  QPointF posGraph;
504  transformation.transformScreenToRawGraph (point.posScreen(),
505  posGraph);
506 
507  // Find the closest point in xThetaValues. This is probably an N-squared algorithm, which is less than optimial,
508  // but the delay should be insignificant with normal-sized export files
509  double closestSeparation = 0.0;
510  int rowClosest = 0;
511  for (int row = 0; row < xThetaValues.count(); row++) {
512 
513  double xThetaValue = xThetaValues.at (row);
514 
515  double separation = qAbs (posGraph.x() - xThetaValue);
516 
517  if ((row == 0) ||
518  (separation < closestSeparation)) {
519 
520  closestSeparation = separation;
521  rowClosest = row;
522 
523  }
524  }
525 
526  // Save y/radius value for this row into yRadiusValues, after appropriate formatting
527  QString dummyXThetaOut;
528  format.unformattedToFormatted (posGraph.x(),
529  posGraph.y(),
530  modelCoords,
531  modelGeneral,
532  modelMainWindow,
533  dummyXThetaOut,
534  *(yRadiusValues [rowClosest]),
535  transformation);
536  }
537 }
538 
539 void ExportFileFunctions::outputXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
540  const DocumentModelCoords &modelCoords,
541  const DocumentModelGeneral &modelGeneral,
542  const MainWindowModel &modelMainWindow,
543  const QStringList &curvesIncluded,
544  const ExportValuesXOrY &xThetaValuesMerged,
545  const Transformation &transformation,
546  QVector<QVector<QString*> > &yRadiusValues,
547  const QString &delimiter,
548  QTextStream &str) const
549 {
550  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::outputXThetaYRadiusValues";
551 
552  // Header
553  if (modelExportOverride.header() != EXPORT_HEADER_NONE) {
554  if (modelExportOverride.header() == EXPORT_HEADER_GNUPLOT) {
555  str << curveSeparator (str.string());
556  str << gnuplotComment();
557  }
558  str << modelExportOverride.xLabel();
559  QStringList::const_iterator itrHeader;
560  for (itrHeader = curvesIncluded.begin(); itrHeader != curvesIncluded.end(); itrHeader++) {
561  QString curveName = *itrHeader;
562  str << delimiter << curveName;
563  }
564  str << "\n";
565  }
566 
567  FormatCoordsUnits format;
568  const double DUMMY_Y_RADIUS = 1.0;
569 
570  for (int row = 0; row < xThetaValuesMerged.count(); row++) {
571 
572  if (rowHasAtLeastOneYRadiusEntry (yRadiusValues,
573  row)) {
574 
575  double xTheta = xThetaValuesMerged.at (row);
576 
577  // Output x/theta value for this row
578  QString xThetaString, yRadiusString;
579  format.unformattedToFormatted (xTheta,
580  DUMMY_Y_RADIUS,
581  modelCoords,
582  modelGeneral,
583  modelMainWindow,
584  xThetaString,
585  yRadiusString,
586  transformation);
587  str << xThetaString;
588 
589  for (int col = 0; col < yRadiusValues.count(); col++) {
590 
591  str << delimiter << *(yRadiusValues [col] [row]);
592  }
593 
594  str << "\n";
595  }
596  }
597 }
598 
599 bool ExportFileFunctions::rowHasAtLeastOneYRadiusEntry (const QVector<QVector<QString*> > &yRadiusValues,
600  int row) const
601 {
602  bool hasEntry = false;
603 
604  for (int col = 0; col < yRadiusValues.count(); col++) {
605 
606  QString entry = *(yRadiusValues [col] [row]);
607  if (!entry.isEmpty()) {
608 
609  hasEntry = true;
610  break;
611 
612  }
613  }
614 
615  return hasEntry;
616 }
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
Model for DlgSettingsGeneral and CmdSettingsGeneral.
ExportPointsSelectionFunctions pointsSelectionFunctions() const
Get method for point selection for functions.
Creates the set of merged x/theta values for exporting functions, using interpolation.
ExportLayoutFunctions layoutFunctions() const
Get method for functions layout.
Cubic interpolation given independent and dependent value vectors.
Definition: Spline.h:21
const Points points() const
Return a shallow copy of the Points.
Definition: Curve.cpp:444
Model for DlgSettingsExportFormat and CmdSettingsExportFormat.
ExportValuesXOrY xThetaValues() const
Resulting x/theta values for all included functions.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
double delinearize(double value, bool isLog) const
Convert linear coordinates to log. This is a noop if the output is supposed to be linear...
Definition: LinearToLog.cpp:8
LineStyle lineStyle() const
Get method for LineStyle.
Definition: CurveStyle.cpp:26
ExportFileFunctions()
Single constructor.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition: Document.cpp:665
double y() const
Get method for y.
Definition: SplinePair.cpp:71
void loadSplinePairsWithTransformation(const Points &points, const Transformation &transformation, bool isLogXTheta, bool isLogYRadius, std::vector< double > &t, std::vector< SplinePair > &xy) const
Load t (=ordinal) and xy (=screen position) spline pairs, converting screen coordinates to graph coor...
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
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
void unformattedToFormatted(double xThetaUnformatted, double yRadiusUnformatted, const DocumentModelCoords &modelCoords, const DocumentModelGeneral &modelGeneral, const MainWindowModel &mainWindowModel, QString &xThetaFormatted, QString &yRadiusFormatted, const Transformation &transformation) const
Convert unformatted numeric value to formatted string. Transformation is used to determine best resol...
ExportHeader header() const
Get method for header.
Affine transformation between screen and graph coordinates, based on digitized axis points...
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
QString xLabel() const
Get method for x label.
Model for DlgSettingsMainWindow.
Utility class to interpolate points spaced evenly along a piecewise defined curve with fitted spline...
ExportDelimiter delimiter() const
Get method for delimiter.
double linearize(double value, bool isLog) const
Convert log coordinates to linear. This is a noop if the input is already linear. ...
Definition: LinearToLog.cpp:19
Model for DlgSettingsCoords and CmdSettingsCoords.
Storage of one imported image and the data attached to that image.
Definition: Document.h:41
Container for one set of digitized Points.
Definition: Curve.h:32
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition: Document.cpp:319
Highest-level wrapper around other Formats classes.
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
Definition: Document.cpp:305
CurveStyle curveStyle() const
Return the curve style.
Definition: Curve.cpp:141
void iterateThroughCurvesPointsGraphs(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for all the graphs curves.
Definition: Document.cpp:439
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
Callback for collecting X/Theta independent variables, for functions, in preparation for exporting...
Warps log coordinates to make them linear before passing them to code that accepts only linear coordi...
Definition: LinearToLog.h:7
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition: SplinePair.h:11
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition: Document.cpp:693
void exportToFile(const DocumentModelExportFormat &modelExportOverride, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str) const
Export Document points according to the settings.