Engauge Digitizer  2
ExportFileRelations.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 "CurveConnectAs.h"
8 #include "Document.h"
9 #include "DocumentModelGeneral.h"
10 #include "EngaugeAssert.h"
11 #include "ExportFileRelations.h"
12 #include "ExportLayoutFunctions.h"
13 #include "ExportOrdinalsSmooth.h"
14 #include "ExportOrdinalsStraight.h"
15 #include "FormatCoordsUnits.h"
16 #include "Logger.h"
17 #include <qdebug.h>
18 #include <qmath.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 
28 const int COLUMNS_PER_CURVE = 2;
29 
31 {
32 }
33 
34 void ExportFileRelations::exportAllPerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
35  const Document &document,
36  const MainWindowModel &modelMainWindow,
37  const QStringList &curvesIncluded,
38  const QString &delimiter,
39  const Transformation &transformation,
40  bool isLogXTheta,
41  bool isLogYRadius,
42  QTextStream &str) const
43 {
44  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportAllPerLineXThetaValuesMerged";
45 
46  int maxColumnSize = maxColumnSizeAllocation (modelExportOverride,
47  document,
48  transformation,
49  isLogXTheta,
50  isLogYRadius,
51  curvesIncluded);
52 
53  // Skip if every curve was a function
54  if (maxColumnSize > 0) {
55 
56  if (modelExportOverride.pointsSelectionRelations() == EXPORT_POINTS_SELECTION_RELATIONS_INTERPOLATE) {
57 
58  exportAllPerLineXThetaValuesMergedMultiplePass (maxColumnSize,
59  modelExportOverride,
60  document,
61  modelMainWindow,
62  curvesIncluded,
63  delimiter,
64  transformation,
65  isLogXTheta,
66  isLogYRadius,
67  str);
68 
69  } else {
70 
71  exportAllPerLineXThetaValuesMergedOnePass (maxColumnSize,
72  modelExportOverride,
73  document,
74  modelMainWindow,
75  curvesIncluded,
76  delimiter,
77  transformation,
78  isLogXTheta,
79  isLogYRadius,
80  str);
81  }
82  }
83 }
84 
85 void ExportFileRelations::exportAllPerLineXThetaValuesMergedMultiplePass (int maxColumnSize,
86  const DocumentModelExportFormat &modelExportOverride,
87  const Document &document,
88  const MainWindowModel &modelMainWindow,
89  const QStringList &curvesIncluded,
90  const QString &delimiter,
91  const Transformation &transformation,
92  bool isLogXTheta,
93  bool isLogYRadius,
94  QTextStream &str) const
95 {
96  // For interpolation of relations in general a single set of x/theta values cannot be created that work for every
97  // relation curve, since one curve may have M y/radius values for a specific x/radius while another curve has
98  // N y/radius values for that same x/radius value. So we export each curve into memory separately and then merge
99  // the results. Why? Since the methods called from this method all assume a single set of x/theta values can be
100  // used for all curves
101 
102  const int CURVE_COUNT_PER_PASS = 1;
103 
104  int curveCount = curvesIncluded.count ();
105 
106  QVector<QVector<QString*> > xThetaYRadiusValuesAll (COLUMNS_PER_CURVE * curveCount, QVector<QString*> (maxColumnSize));
107 
108  initializeXThetaYRadiusValues (curvesIncluded,
109  xThetaYRadiusValuesAll);
110 
111  // One pass per curve
112  int colX = 0, colY = colX + 1;
113  for (int c = 0; c < curvesIncluded.count (); c++) {
114  QString curve = curvesIncluded [c];
115 
116  QStringList curvesIncludedInPass;
117  curvesIncludedInPass << curve;
118  ENGAUGE_ASSERT (curvesIncludedInPass.count () == CURVE_COUNT_PER_PASS);
119 
120  QVector<QVector<QString*> > xThetaYRadiusValuesOne (COLUMNS_PER_CURVE * CURVE_COUNT_PER_PASS, QVector<QString*> (maxColumnSize));
121 
122  initializeXThetaYRadiusValues (curvesIncludedInPass,
123  xThetaYRadiusValuesOne);
124  loadXThetaYRadiusValues (modelExportOverride,
125  document,
126  modelMainWindow,
127  curvesIncludedInPass,
128  transformation,
129  isLogXTheta,
130  isLogYRadius,
131  xThetaYRadiusValuesOne);
132 
133  // Merge one curve array into all curves array
134  for (int row = 0; row < maxColumnSize; row++) {
135  *(xThetaYRadiusValuesAll [colX] [row]) = *(xThetaYRadiusValuesOne [0] [row]);
136  *(xThetaYRadiusValuesAll [colY] [row]) = *(xThetaYRadiusValuesOne [1] [row]);
137  }
138 
139  destroy2DArray (xThetaYRadiusValuesOne);
140 
141  colX += 2;
142  colY += 2;
143  }
144 
145  outputXThetaYRadiusValues (modelExportOverride,
146  curvesIncluded,
147  xThetaYRadiusValuesAll,
148  delimiter,
149  str);
150  destroy2DArray (xThetaYRadiusValuesAll);
151 }
152 
153 void ExportFileRelations::exportAllPerLineXThetaValuesMergedOnePass (int maxColumnSize,
154  const DocumentModelExportFormat &modelExportOverride,
155  const Document &document,
156  const MainWindowModel &modelMainWindow,
157  const QStringList &curvesIncluded,
158  const QString &delimiter,
159  const Transformation &transformation,
160  bool isLogXTheta,
161  bool isLogYRadius,
162  QTextStream &str) const
163 {
164  int curveCount = curvesIncluded.count ();
165 
166  QVector<QVector<QString*> > xThetaYRadiusValues (COLUMNS_PER_CURVE * curveCount, QVector<QString*> (maxColumnSize));
167  initializeXThetaYRadiusValues (curvesIncluded,
168  xThetaYRadiusValues);
169  loadXThetaYRadiusValues (modelExportOverride,
170  document,
171  modelMainWindow,
172  curvesIncluded,
173  transformation,
174  isLogXTheta,
175  isLogYRadius,
176  xThetaYRadiusValues);
177  outputXThetaYRadiusValues (modelExportOverride,
178  curvesIncluded,
179  xThetaYRadiusValues,
180  delimiter,
181  str);
182  destroy2DArray (xThetaYRadiusValues);
183 }
184 
185 void ExportFileRelations::exportOnePerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
186  const Document &document,
187  const MainWindowModel &modelMainWindow,
188  const QStringList &curvesIncluded,
189  const QString &delimiter,
190  const Transformation &transformation,
191  bool isLogXTheta,
192  bool isLogYRadius,
193  QTextStream &str) const
194 {
195  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportOnePerLineXThetaValuesMerged";
196 
197  QStringList::const_iterator itr;
198  for (itr = curvesIncluded.begin(); itr != curvesIncluded.end(); itr++) {
199 
200  QString curveIncluded = *itr;
201 
202  exportAllPerLineXThetaValuesMerged (modelExportOverride,
203  document,
204  modelMainWindow,
205  QStringList (curveIncluded),
206  delimiter,
207  transformation,
208  isLogXTheta,
209  isLogYRadius,
210  str);
211  }
212 }
213 
215  const Document &document,
216  const MainWindowModel &modelMainWindow,
217  const Transformation &transformation,
218  QTextStream &str) const
219 {
220  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportToFile";
221 
222  // Log coordinates must be temporarily transformed to linear coordinates
223  bool isLogXTheta = (document.modelCoords().coordScaleXTheta() == COORD_SCALE_LOG);
224  bool isLogYRadius = (document.modelCoords().coordScaleYRadius() == COORD_SCALE_LOG);
225 
226  // Identify curves to be included
227  QStringList curvesIncluded = curvesToInclude (modelExportOverride,
228  document,
229  document.curvesGraphsNames(),
230  CONNECT_AS_RELATION_SMOOTH,
231  CONNECT_AS_RELATION_STRAIGHT);
232 
233  // Delimiter
234  const QString delimiter = exportDelimiterToText (modelExportOverride.delimiter(),
235  modelExportOverride.header() == EXPORT_HEADER_GNUPLOT);
236 
237  // Export in one of two layouts
238  if (modelExportOverride.layoutFunctions() == EXPORT_LAYOUT_ALL_PER_LINE) {
239  exportAllPerLineXThetaValuesMerged (modelExportOverride,
240  document,
241  modelMainWindow,
242  curvesIncluded,
243  delimiter,
244  transformation,
245  isLogXTheta,
246  isLogYRadius,
247  str);
248  } else {
249  exportOnePerLineXThetaValuesMerged (modelExportOverride,
250  document,
251  modelMainWindow,
252  curvesIncluded,
253  delimiter,
254  transformation,
255  isLogXTheta,
256  isLogYRadius,
257  str);
258  }
259 }
260 
261 void ExportFileRelations::initializeXThetaYRadiusValues (const QStringList &curvesIncluded,
262  QVector<QVector<QString*> > &xThetaYRadiusValues) const
263 {
264  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::initializeXThetaYRadiusValues";
265 
266  // Initialize every entry with empty string
267  int curveCount = curvesIncluded.count();
268  int xThetaCount = xThetaYRadiusValues [0].count();
269  for (int row = 0; row < xThetaCount; row++) {
270  for (int col = 0; col < COLUMNS_PER_CURVE * curveCount; col++) {
271  xThetaYRadiusValues [col] [row] = new QString;
272  }
273  }
274 }
275 
276 QPointF ExportFileRelations::linearlyInterpolate (const Points &points,
277  double ordinal,
278  const Transformation &transformation) const
279 {
280  // LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::linearlyInterpolate";
281 
282  double xTheta = 0, yRadius = 0;
283  double ordinalBefore = 0; // Not set until ip=1
284  QPointF posGraphBefore; // Not set until ip=1
285  bool foundIt = false;
286  for (int ip = 0; ip < points.count(); ip++) {
287 
288  const Point &point = points.at (ip);
289  QPointF posGraph;
290  transformation.transformScreenToRawGraph (point.posScreen(),
291  posGraph);
292 
293  if (ordinal <= point.ordinal()) {
294 
295  foundIt = true;
296  if (ip == 0) {
297 
298  // Use first point
299  xTheta = posGraph.x();
300  yRadius = posGraph.y();
301 
302  } else {
303 
304  // Between posGraphBefore and posGraph. Note that if posGraph.x()=posGraphBefore.x() then
305  // previous iteration of loop would have been used for interpolation, and then the loop was exited
306  double s = (ordinal - ordinalBefore) / (point.ordinal() - ordinalBefore);
307  xTheta = (1.0 - s) * posGraphBefore.x() + s * posGraph.x();
308  yRadius = (1.0 - s) * posGraphBefore.y() + s * posGraph.y();
309  }
310 
311  break;
312  }
313 
314  ordinalBefore = point.ordinal();
315  posGraphBefore = posGraph;
316  }
317 
318  if (!foundIt) {
319 
320  // Use last point
321  xTheta = posGraphBefore.x();
322  yRadius = posGraphBefore.y();
323 
324  }
325 
326  return QPointF (xTheta,
327  yRadius);
328 }
329 
330 void ExportFileRelations::loadXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
331  const Document &document,
332  const MainWindowModel &modelMainWindow,
333  const QStringList &curvesIncluded,
334  const Transformation &transformation,
335  bool isLogXTheta,
336  bool isLogYRadius,
337  QVector<QVector<QString*> > &xThetaYRadiusValues) const
338 {
339  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValues";
340 
341  // The curve processing logic here is mirrored in maxColumnSizeAllocation so the array allocations are in sync
342  for (int ic = 0; ic < curvesIncluded.count(); ic++) {
343 
344  int colXTheta = 2 * ic;
345  int colYRadius = 2 * ic + 1;
346 
347  const QString curveName = curvesIncluded.at (ic);
348 
349  const Curve *curve = document.curveForCurveName (curveName);
350  const Points points = curve->points ();
351 
352  if (modelExportOverride.pointsSelectionRelations() == EXPORT_POINTS_SELECTION_RELATIONS_RAW) {
353 
354  // No interpolation. Raw points
355  loadXThetaYRadiusValuesForCurveRaw (document.modelCoords(),
356  document.modelGeneral(),
357  modelMainWindow,
358  points,
359  xThetaYRadiusValues [colXTheta],
360  xThetaYRadiusValues [colYRadius],
361  transformation);
362  } else {
363 
364  const LineStyle &lineStyle = document.modelCurveStyles().lineStyle(curveName);
365 
366  // Interpolation. Points are taken approximately every every modelExport.pointsIntervalRelations
367  ExportValuesOrdinal ordinals = ordinalsAtIntervals (modelExportOverride.pointsIntervalRelations(),
368  modelExportOverride.pointsIntervalUnitsRelations(),
369  lineStyle.curveConnectAs(),
370  transformation,
371  isLogXTheta,
372  isLogYRadius,
373  points);
374 
375  if (curve->curveStyle().lineStyle().curveConnectAs() == CONNECT_AS_RELATION_SMOOTH) {
376 
377  loadXThetaYRadiusValuesForCurveInterpolatedSmooth (document.modelCoords(),
378  document.modelGeneral(),
379  modelMainWindow,
380  points,
381  ordinals,
382  xThetaYRadiusValues [colXTheta],
383  xThetaYRadiusValues [colYRadius],
384  transformation,
385  isLogXTheta,
386  isLogYRadius);
387 
388  } else {
389 
390  loadXThetaYRadiusValuesForCurveInterpolatedStraight (document.modelCoords(),
391  document.modelGeneral(),
392  modelMainWindow,
393  points,
394  ordinals,
395  xThetaYRadiusValues [colXTheta],
396  xThetaYRadiusValues [colYRadius],
397  transformation);
398  }
399  }
400  }
401 }
402 
403 void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth (const DocumentModelCoords &modelCoords,
404  const DocumentModelGeneral &modelGeneral,
405  const MainWindowModel &modelMainWindow,
406  const Points &points,
407  const ExportValuesOrdinal &ordinals,
408  QVector<QString*> &xThetaValues,
409  QVector<QString*> &yRadiusValues,
410  const Transformation &transformation,
411  bool isLogXTheta,
412  bool isLogYRadius) const
413 {
414  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth";
415 
416  vector<double> t;
417  vector<SplinePair> xy;
418  ExportOrdinalsSmooth ordinalsSmooth;
419 
420  ordinalsSmooth.loadSplinePairsWithTransformation (points,
421  transformation,
422  isLogXTheta,
423  isLogYRadius,
424  t,
425  xy);
426 
427  // Spline class requires at least one point
428  if (xy.size() > 0) {
429 
430  // Fit a spline
431  Spline spline (t,
432  xy);
433 
434  FormatCoordsUnits format;
435 
436  // Extract the points
437  for (int row = 0; row < ordinals.count(); row++) {
438 
439  double ordinal = ordinals.at (row);
440  SplinePair splinePairFound = spline.interpolateCoeff(ordinal);
441  double xTheta = splinePairFound.x ();
442  double yRadius = splinePairFound.y ();
443 
444  // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
445  format.unformattedToFormatted (xTheta,
446  yRadius,
447  modelCoords,
448  modelGeneral,
449  modelMainWindow,
450  *(xThetaValues [row]),
451  *(yRadiusValues [row]),
452  transformation);
453  }
454  }
455 }
456 
457 void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight (const DocumentModelCoords &modelCoords,
458  const DocumentModelGeneral &modelGeneral,
459  const MainWindowModel &modelMainWindow,
460  const Points &points,
461  const ExportValuesOrdinal &ordinals,
462  QVector<QString*> &xThetaValues,
463  QVector<QString*> &yRadiusValues,
464  const Transformation &transformation) const
465 {
466  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight";
467 
468  FormatCoordsUnits format;
469 
470  // Get value at desired points
471  for (int row = 0; row < ordinals.count(); row++) {
472 
473  double ordinal = ordinals.at (row);
474 
475  QPointF pointInterpolated = linearlyInterpolate (points,
476  ordinal,
477  transformation);
478 
479  // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
480  format.unformattedToFormatted (pointInterpolated.x(),
481  pointInterpolated.y(),
482  modelCoords,
483  modelGeneral,
484  modelMainWindow,
485  *(xThetaValues [row]),
486  *(yRadiusValues [row]),
487  transformation);
488  }
489 }
490 
491 void ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw (const DocumentModelCoords &modelCoords,
492  const DocumentModelGeneral &modelGeneral,
493  const MainWindowModel &modelMainWindow,
494  const Points &points,
495  QVector<QString*> &xThetaValues,
496  QVector<QString*> &yRadiusValues,
497  const Transformation &transformation) const
498 {
499  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw";
500 
501  FormatCoordsUnits format;
502 
503  for (int pt = 0; pt < points.count(); pt++) {
504 
505  const Point &point = points.at (pt);
506 
507  QPointF posGraph;
508  transformation.transformScreenToRawGraph (point.posScreen(),
509  posGraph);
510 
511  // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
512  format.unformattedToFormatted (posGraph.x(),
513  posGraph.y(),
514  modelCoords,
515  modelGeneral,
516  modelMainWindow,
517  *(xThetaValues [pt]),
518  *(yRadiusValues [pt]),
519  transformation);
520  }
521 }
522 
523 int ExportFileRelations::maxColumnSizeAllocation (const DocumentModelExportFormat &modelExport,
524  const Document &document,
525  const Transformation &transformation,
526  bool isLogXTheta,
527  bool isLogYRadius,
528  const QStringList &curvesIncluded) const
529 {
530  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::maxColumnSizeAllocation";
531 
532  int maxColumnSize = 0;
533 
534  // The curve processing logic here is mirrored in loadXThetaYRadiusValues so the array allocations are in sync
535  for (int ic = 0; ic < curvesIncluded.count(); ic++) {
536 
537  const QString curveName = curvesIncluded.at (ic);
538 
539  const Curve *curve = document.curveForCurveName (curveName);
540  const Points points = curve->points ();
541 
542  if (modelExport.pointsSelectionRelations() == EXPORT_POINTS_SELECTION_RELATIONS_RAW) {
543 
544  // No interpolation. Raw points
545  maxColumnSize = qMax (maxColumnSize,
546  points.count());
547 
548  } else {
549 
550  const LineStyle &lineStyle = document.modelCurveStyles().lineStyle(curveName);
551 
552 
553  // Interpolation. Points are taken approximately every every modelExport.pointsIntervalRelations
554  ExportValuesOrdinal ordinals = ordinalsAtIntervals (modelExport.pointsIntervalRelations(),
555  modelExport.pointsIntervalUnitsRelations(),
556  lineStyle.curveConnectAs(),
557  transformation,
558  isLogXTheta,
559  isLogYRadius,
560  points);
561 
562  maxColumnSize = qMax (maxColumnSize,
563  ordinals.count());
564  }
565  }
566 
567  return maxColumnSize;
568 }
569 
570 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervals (double pointsIntervalRelations,
571  ExportPointsIntervalUnits pointsIntervalUnits,
572  CurveConnectAs curveConnectAs,
573  const Transformation &transformation,
574  bool isLogXTheta,
575  bool isLogYRadius,
576  const Points &points) const
577 {
578  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervals";
579 
580  if (pointsIntervalUnits == EXPORT_POINTS_INTERVAL_UNITS_GRAPH) {
581  if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH) {
582 
583  return ordinalsAtIntervalsSmoothGraph (pointsIntervalRelations,
584  transformation,
585  isLogXTheta,
586  isLogYRadius,
587  points);
588 
589  } else {
590 
591  return ordinalsAtIntervalsStraightGraph (pointsIntervalRelations,
592  transformation,
593  points);
594 
595  }
596  } else {
597 
598  if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH) {
599 
600  return ordinalsAtIntervalsSmoothScreen (pointsIntervalRelations,
601  points);
602 
603  } else {
604 
605  return ordinalsAtIntervalsStraightScreen (pointsIntervalRelations,
606  points);
607 
608  }
609  }
610 }
611 
612 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsSmoothGraph (double pointsIntervalRelations,
613  const Transformation &transformation,
614  bool isLogXTheta,
615  bool isLogYRadius,
616  const Points &points) const
617 {
618  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsSmoothGraph";
619 
620  ExportValuesOrdinal ordinals;
621 
622  // Prevent infinite loop when there are no points or will be too many points
623  if ((pointsIntervalRelations > 0) &&
624  (points.count() > 0)) {
625 
626  vector<double> t;
627  vector<SplinePair> xy;
628  ExportOrdinalsSmooth ordinalsSmooth;
629 
630  ordinalsSmooth.loadSplinePairsWithTransformation (points,
631  transformation,
632  isLogXTheta,
633  isLogYRadius,
634  t,
635  xy);
636 
637  ordinals = ordinalsSmooth.ordinalsAtIntervalsGraph (t,
638  xy,
639  pointsIntervalRelations);
640  }
641 
642  return ordinals;
643 }
644 
645 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsSmoothScreen (double pointsIntervalRelations,
646  const Points &points) const
647 {
648  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsSmoothScreen"
649  << " pointCount=" << points.count();
650 
651  // Results
652  ExportValuesOrdinal ordinals;
653 
654  // Prevent infinite loop when there are no points or will be too many points
655  if ((pointsIntervalRelations > 0) &&
656  (points.count() > 0)) {
657 
658  vector<double> t;
659  vector<SplinePair> xy;
660  ExportOrdinalsSmooth ordinalsSmooth;
661 
662  ordinalsSmooth.loadSplinePairsWithoutTransformation (points,
663  t,
664  xy);
665 
666  ordinals = ordinalsSmooth.ordinalsAtIntervalsGraph (t,
667  xy,
668  pointsIntervalRelations);
669  }
670 
671  return ordinals;
672 }
673 
674 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsStraightGraph (double pointsIntervalRelations,
675  const Transformation &transformation,
676  const Points &points) const
677 {
678  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsStraightGraph";
679 
680  ExportValuesOrdinal ordinals;
681 
682  // Prevent infinite loop when there are no points or will be too many points
683  if ((pointsIntervalRelations > 0) &&
684  (points.count() > 0)) {
685 
686  ExportOrdinalsStraight ordinalsStraight;
687 
688  ordinals = ordinalsStraight.ordinalsAtIntervalsGraphWithTransformation (points,
689  transformation,
690  pointsIntervalRelations);
691  }
692 
693  return ordinals;
694 }
695 
696 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsStraightScreen (double pointsIntervalRelations,
697  const Points &points) const
698 {
699  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsStraightScreen"
700  << " pointCount=" << points.count();
701 
702  // Results
703  ExportValuesOrdinal ordinals;
704 
705  // Prevent infinite loop when there are no points or will be too many points
706  if ((pointsIntervalRelations > 0) &&
707  (points.count() > 0)) {
708 
709  ExportOrdinalsStraight ordinalsStraight;
710 
711  ordinals = ordinalsStraight.ordinalsAtIntervalsGraphWithoutTransformation (points,
712  pointsIntervalRelations);
713  }
714 
715  return ordinals;
716 }
717 
718 void ExportFileRelations::outputXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
719  const QStringList &curvesIncluded,
720  QVector<QVector<QString*> > &xThetaYRadiusValues,
721  const QString &delimiter,
722  QTextStream &str) const
723 {
724  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::outputXThetaYRadiusValues";
725 
726  // Header
727  if (modelExportOverride.header() != EXPORT_HEADER_NONE) {
728  if (modelExportOverride.header() == EXPORT_HEADER_GNUPLOT) {
729  str << curveSeparator(str.string());
730  str << gnuplotComment();
731  }
732  QString delimiterForRow;
733  QStringList::const_iterator itr;
734  for (itr = curvesIncluded.begin(); itr != curvesIncluded.end(); itr++) {
735  QString curveName = *itr;
736  str << delimiterForRow << modelExportOverride.xLabel();
737  delimiterForRow = delimiter;
738  str << delimiterForRow << curveName;
739  }
740  str << "\n";
741  }
742 
743  for (int row = 0; row < xThetaYRadiusValues [0].count(); row++) {
744 
745  QString delimiterForRow;
746  for (int col = 0; col < xThetaYRadiusValues.count(); col++) {
747 
748  str << delimiterForRow << *(xThetaYRadiusValues [col] [row]);
749  delimiterForRow = delimiter;
750  }
751 
752  str << "\n";
753  }
754 }
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:166
Model for DlgSettingsGeneral and CmdSettingsGeneral.
ExportLayoutFunctions layoutFunctions() const
Get method for functions layout.
Cubic interpolation given independent and dependent value vectors.
Definition: Spline.h:21
ExportPointsIntervalUnits pointsIntervalUnitsRelations() const
Get method for points interval units for relations.
const Points points() const
Return a shallow copy of the Points.
Definition: Curve.cpp:451
Model for DlgSettingsExportFormat and CmdSettingsExportFormat.
void exportToFile(const DocumentModelExportFormat &modelExportOverride, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str) const
Export Document points according to the settings.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
LineStyle lineStyle() const
Get method for LineStyle.
Definition: CurveStyle.cpp:26
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition: Document.cpp:693
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
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.
const LineStyle lineStyle(const QString &curveName) const
Get method for copying one line style in one step.
Definition: CurveStyles.cpp:97
Affine transformation between screen and graph coordinates, based on digitized axis points...
ExportValuesOrdinal ordinalsAtIntervalsGraphWithoutTransformation(const Points &points, double pointsInterval) const
Compute ordinals, without any conversion to graph coordinates.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
QString xLabel() const
Get method for x label.
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition: Document.cpp:700
Model for DlgSettingsMainWindow.
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...
Utility class to interpolate points spaced evenly along a piecewise defined curve with fitted spline...
ExportDelimiter delimiter() const
Get method for delimiter.
Model for DlgSettingsCoords and CmdSettingsCoords.
double pointsIntervalRelations() const
Get method for relations interval for relations.
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:33
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.
Details for a specific Line.
Definition: LineStyle.h:19
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition: Document.cpp:347
Highest-level wrapper around other Formats classes.
Utility class to interpolate points spaced evenly along a piecewise defined curve with line segments ...
double x() const
Get method for x.
Definition: SplinePair.cpp:66
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
Definition: Document.cpp:333
CurveStyle curveStyle() const
Return the curve style.
Definition: Curve.cpp:148
double ordinal(ApplyHasCheck applyHasCheck=KEEP_HAS_CHECK) const
Get method for ordinal. Skip check if copying one instance to another.
Definition: Point.cpp:374
ExportFileRelations()
Single constructor.
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
ExportValuesOrdinal ordinalsAtIntervalsGraphWithTransformation(const Points &points, const Transformation &transformation, double pointsInterval) const
Compute ordinals, converting screen coordinates to graph coordinates.
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:721
ExportPointsSelectionRelations pointsSelectionRelations() const
Get method for point selection for relations.