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