Example #1
0
void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight (const DocumentModelCoords &modelCoords,
                                                                               const DocumentModelGeneral &modelGeneral,
                                                                               const MainWindowModel &modelMainWindow,
                                                                               const Points &points,
                                                                               const ExportValuesOrdinal &ordinals,
                                                                               QVector<QString*> &xThetaValues,
                                                                               QVector<QString*> &yRadiusValues,
                                                                               const Transformation &transformation) const
{
  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight";

  FormatCoordsUnits format;

  // Get value at desired points
  for (int row = 0; row < ordinals.count(); row++) {

    double ordinal = ordinals.at (row);

    QPointF pointInterpolated = linearlyInterpolate (points,
                                                     ordinal,
                                                     transformation);

    // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
    format.unformattedToFormatted (pointInterpolated.x(),
                                   pointInterpolated.y(),
                                   modelCoords,
                                   modelGeneral,
                                   modelMainWindow,
                                   *(xThetaValues [row]),
                                   *(yRadiusValues [row]),
                                   transformation);
  }
}
Example #2
0
void ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw (const DocumentModelCoords &modelCoords,
                                                              const DocumentModelGeneral &modelGeneral,
                                                              const MainWindowModel &modelMainWindow,
                                                              const Points &points,
                                                              QVector<QString*> &xThetaValues,
                                                              QVector<QString*> &yRadiusValues,
                                                              const Transformation &transformation) const
{
  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw";

  FormatCoordsUnits format;

  for (int pt = 0; pt < points.count(); pt++) {

    const Point &point = points.at (pt);

    QPointF posGraph;
    transformation.transformScreenToRawGraph (point.posScreen(),
                                              posGraph);

    // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
    format.unformattedToFormatted (posGraph.x(),
                                   posGraph.y(),
                                   modelCoords,
                                   modelGeneral,
                                   modelMainWindow,
                                   *(xThetaValues [pt]),
                                   *(yRadiusValues [pt]),
                                   transformation);
  }
}
void ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedStraight (const DocumentModelCoords &modelCoords,
                                                                         const MainWindowModel &modelMainWindow,
                                                                         const Points &points,
                                                                         const ExportValuesXOrY &xThetaValues,
                                                                         const Transformation &transformation,
                                                                         QVector<QString*> &yRadiusValues) const
{
  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedStraight";

  FormatCoordsUnits format;

  // Get value at desired points
  for (int row = 0; row < xThetaValues.count(); row++) {

    double xThetaValue = xThetaValues.at (row);

    double yRadius = linearlyInterpolate (points,
                                          xThetaValue,
                                          transformation);

    // Save y/radius value for this row into yRadiusValues, after appropriate formatting
    QString dummyXThetaOut;
    format.unformattedToFormatted (xThetaValue,
                                   yRadius,
                                   modelCoords,
                                   modelMainWindow,
                                   dummyXThetaOut,
                                   *(yRadiusValues [row]),
                                   transformation);
  }
}
void ExportFileFunctions::outputXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
                                                     const DocumentModelCoords &modelCoords,
                                                     const MainWindowModel &modelMainWindow,
                                                     const QStringList &curvesIncluded,
                                                     const ExportValuesXOrY &xThetaValuesMerged,
                                                     const Transformation &transformation,
                                                     QVector<QVector<QString*> > &yRadiusValues,
                                                     const QString &delimiter,
                                                     QTextStream &str) const
{
  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::outputXThetaYRadiusValues";

  // Header
  if (modelExportOverride.header() != EXPORT_HEADER_NONE) {
    if (modelExportOverride.header() == EXPORT_HEADER_GNUPLOT) {
      str << curveSeparator (str.string());
      str << gnuplotComment();
    }
    str << modelExportOverride.xLabel();
    QStringList::const_iterator itrHeader;
    for (itrHeader = curvesIncluded.begin(); itrHeader != curvesIncluded.end(); itrHeader++) {
      QString curveName = *itrHeader;
      str << delimiter << curveName;
    }
    str << "\n";
  }

  FormatCoordsUnits format;
  const double DUMMY_Y_RADIUS = 1.0;

  for (int row = 0; row < xThetaValuesMerged.count(); row++) {

    if (rowHasAtLeastOneYRadiusEntry (yRadiusValues,
                                      row)) {

      double xTheta = xThetaValuesMerged.at (row);

      // Output x/theta value for this row
      QString xThetaString, yRadiusString;
      format.unformattedToFormatted (xTheta,
                                     DUMMY_Y_RADIUS,
                                     modelCoords,
                                     modelMainWindow,
                                     xThetaString,
                                     yRadiusString,
                                     transformation);
      str << xThetaString;

      for (int col = 0; col < yRadiusValues.count(); col++) {

        str << delimiter << *(yRadiusValues [col] [row]);
      }

      str << "\n";
    }
  }
}
void ExportFileFunctions::loadYRadiusValuesForCurveRaw (const DocumentModelCoords &modelCoords,
                                                        const MainWindowModel &modelMainWindow,
                                                        const Points &points,
                                                        const ExportValuesXOrY &xThetaValues,
                                                        const Transformation &transformation,
                                                        QVector<QString*> &yRadiusValues) const
{
  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValuesForCurveRaw";

  FormatCoordsUnits format;

  // Since the curve points may be a subset of xThetaValues (in which case the non-applicable xThetaValues will have
  // blanks for the yRadiusValues), we iterate over the smaller set
  for (int pt = 0; pt < points.count(); pt++) {

    const Point &point = points.at (pt);

    QPointF posGraph;
    transformation.transformScreenToRawGraph (point.posScreen(),
                                              posGraph);

    // Find the closest point in xThetaValues. This is probably an N-squared algorithm, which is less than optimial,
    // but the delay should be insignificant with normal-sized export files
    double closestSeparation = 0.0;
    int rowClosest = 0;
    for (int row = 0; row < xThetaValues.count(); row++) {

      double xThetaValue = xThetaValues.at (row);

      double separation = qAbs (posGraph.x() - xThetaValue);

      if ((row == 0) ||
          (separation < closestSeparation)) {

        closestSeparation = separation;
        rowClosest = row;

      }
    }

    // Save y/radius value for this row into yRadiusValues, after appropriate formatting
    QString dummyXThetaOut;
    format.unformattedToFormatted (posGraph.x(),
                                   posGraph.y(),
                                   modelCoords,
                                   modelMainWindow,
                                   dummyXThetaOut,
                                   *(yRadiusValues [rowClosest]),
                                   transformation);
  }
}
Example #6
0
void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth (const DocumentModelCoords &modelCoords,
                                                                             const DocumentModelGeneral &modelGeneral,
                                                                             const MainWindowModel &modelMainWindow,
                                                                             const Points &points,
                                                                             const ExportValuesOrdinal &ordinals,
                                                                             QVector<QString*> &xThetaValues,
                                                                             QVector<QString*> &yRadiusValues,
                                                                             const Transformation &transformation) const
{
  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth";

  vector<double> t;
  vector<SplinePair> xy;
  ExportOrdinalsSmooth ordinalsSmooth;

  ordinalsSmooth.loadSplinePairsWithTransformation (points,
                                                    transformation,
                                                    t,
                                                    xy);

  // Spline class requires at least one point
  if (xy.size() > 0) {

    // Fit a spline
    Spline spline (t,
                   xy);

    FormatCoordsUnits format;

    // Extract the points
    for (int row = 0; row < ordinals.count(); row++) {

      double ordinal = ordinals.at (row);
      SplinePair splinePairFound = spline.interpolateCoeff(ordinal);
      double xTheta = splinePairFound.x ();
      double yRadius = splinePairFound.y ();

      // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
      format.unformattedToFormatted (xTheta,
                                     yRadius,
                                     modelCoords,
                                     modelGeneral,
                                     modelMainWindow,
                                     *(xThetaValues [row]),
                                     *(yRadiusValues [row]),
                                     transformation);
    }
  }
}
double DlgEditScale::scaleLength () const
{
  double xTheta, yRadius;
  const QString DUMMY_Y ("0");

  FormatCoordsUnits format;

  // Format conversion is done using x coordinate. Y coordinate is given a dummy value and the result is ignored
  format.formattedToUnformatted (m_editScaleLength->text(),
                                 DUMMY_Y,
                                 m_modelCoords,
                                 m_modelMainWindow,
                                 xTheta,
                                 yRadius);

  return xTheta;
}
Example #8
0
void DlgEditPointGraph::posGraph (bool &isX,
                                  double &x,
                                  bool &isY,
                                  double &y) const
{
  FormatCoordsUnits format;

  // Use zero for any empty coordinate
  QString xTextNotEmpty = QString ("%1").arg (m_editGraphX->text().isEmpty () ? "0" : m_editGraphX->text());
  QString yTextNotEmpty = QString ("%1").arg (m_editGraphY->text().isEmpty () ? "0" : m_editGraphY->text());

  format.formattedToUnformatted (xTextNotEmpty,
                                 yTextNotEmpty,
                                 m_modelCoords,
                                 m_modelMainWindow,
                                 x,
                                 y);

  isX = !m_editGraphX->text().isEmpty();
  isY = !m_editGraphY->text().isEmpty();
}
Example #9
0
void DlgEditPointGraph::initializeGraphCoordinates (const double *xInitialValue,
                                                    const double *yInitialValue,
                                                    const Transformation &transformation)
{
  LOG4CPP_INFO_S ((*mainCat)) << "DlgEditPointGraph::initializeGraphCoordinates";

  QString xTheta, yRadius;
  if ((xInitialValue != 0) &&
      (yInitialValue != 0)) {

    FormatCoordsUnits format;
    format.unformattedToFormatted (*xInitialValue,
                                   *yInitialValue,
                                   m_modelCoords,
                                   m_modelGeneral,
                                   m_modelMainWindow,
                                   xTheta,
                                   yRadius,
                                   transformation);
  }

  m_editGraphX->setText (xTheta);
  m_editGraphY->setText (yRadius);
}
void ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedSmooth (const DocumentModelCoords &modelCoords,
                                                                       const MainWindowModel &modelMainWindow,
                                                                       const Points &points,
                                                                       const ExportValuesXOrY &xThetaValues,
                                                                       const Transformation &transformation,
                                                                       QVector<QString*> &yRadiusValues) const
{
  LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedSmooth";

  // Convert screen coordinates to graph coordinates, in vectors suitable for spline fitting
  vector<double> t;
  vector<SplinePair> xy;
  ExportOrdinalsSmooth ordinalsSmooth;

  ordinalsSmooth.loadSplinePairsWithTransformation (points,
                                                    transformation,
                                                    t,
                                                    xy);

  // Formatting
  FormatCoordsUnits format;
  QString dummyXThetaOut;

  if (points.count() == 0) {

    // Since there are no values, leave the field empty
    for (int row = 0; row < xThetaValues.count(); row++) {
      *(yRadiusValues [row]) = "";
    }

  } else if (points.count() == 1 ||
             points.count() == 2) {

    // Apply the single value everywhere (N=1) or do linear interpolation (N=2)
    for (int row = 0; row < xThetaValues.count(); row++) {

      double xTheta = xThetaValues.at (row);
      double yRadius;
      if (points.count() == 1) {
        yRadius = xy.at (0).y ();
      } else {
        double x0 = xy.at (0).x ();
        double x1 = xy.at (1).x ();
        double y0 = xy.at (0).y ();
        double y1 = xy.at (1).y ();
        if (x0 == x1) {
          // Cannot do linear interpolation using two points at the same x value
          yRadius = xy.at (0).y ();
        } else {
          double s = (xTheta - x0) / (x1 - x0);
          yRadius = (1.0 - s) * y0 + s * y1;
        }
      }
      format.unformattedToFormatted (xTheta,
                                     yRadius,
                                     modelCoords,
                                     modelMainWindow,
                                     dummyXThetaOut,
                                     *(yRadiusValues [row]),
                                     transformation);
    }

  } else {

    // Iteration accuracy versus number of iterations 8->256, 10->1024, 12->4096. Single pixel accuracy out of
    // typical image size of 1024x1024 means around 10 iterations gives decent accuracy for numbers much bigger
    // than 1. A value of 12 gave some differences in the least significant figures of numbers like 10^-3 in
    // the regression tests. Toggling between 30 and 32 made no difference in the regression tests.
    const int MAX_ITERATIONS = 32;

    // Spline class requires at least one point
    if (xy.size() > 0) {

      // Fit a spline
      Spline spline (t,
                     xy);

      // Get value at desired points
      for (int row = 0; row < xThetaValues.count(); row++) {

        double xTheta = xThetaValues.at (row);
        SplinePair splinePairFound = spline.findSplinePairForFunctionX (xTheta,
                                                                        MAX_ITERATIONS);
        double yRadius = splinePairFound.y ();

        // Save y/radius value for this row into yRadiusValues, after appropriate formatting
        QString dummyXThetaOut;
        format.unformattedToFormatted (xTheta,
                                       yRadius,
                                       modelCoords,
                                       modelMainWindow,
                                       dummyXThetaOut,
                                       *(yRadiusValues [row]),
                                       transformation);
      }
    }
  }
}
void Transformation::coordTextForStatusBar (QPointF cursorScreen,
                                            QString &coordsScreen,
                                            QString &coordsGraph,
                                            QString &resolutionsGraph)
{
  const int UNCONSTRAINED_FIELD_WIDTH = 0;
  const double X_DELTA_PIXELS = 1.0, Y_DELTA_PIXELS = 1.0;
  const char FORMAT = 'g';

  if (cursorScreen.x() < 0 ||
      cursorScreen.y() < 0) {

    // Out of bounds, so return empty text
    coordsScreen = "";
    coordsGraph = "";
    resolutionsGraph = "";

  } else {

    coordsScreen = QString("(%1, %2)")
                   .arg (cursorScreen.x ())
                   .arg (cursorScreen.y ());

    if (m_transformIsDefined) {

      // For resolution we compute graph coords for cursorScreen, and then for cursorScreen plus a delta
      QPointF cursorScreenDelta (cursorScreen.x () + X_DELTA_PIXELS,
                                 cursorScreen.y () + Y_DELTA_PIXELS);

      // Convert to graph coordinates
      QPointF pointGraph, pointGraphDelta;
      transformScreenToRawGraph (cursorScreen,
                                 pointGraph);
      transformScreenToRawGraph (cursorScreenDelta,
                                 pointGraphDelta);

      // Compute graph resolutions at cursor
      double resolutionXGraph = qAbs ((pointGraphDelta.x () - pointGraph.x ()) / X_DELTA_PIXELS);
      double resolutionYGraph = qAbs ((pointGraphDelta.y () - pointGraph.y ()) / Y_DELTA_PIXELS);

      // Formatting for date/time and degrees/minutes/seconds is only done on coordinates, and not on resolution
      FormatCoordsUnits format;
      QString xThetaFormatted, yRadiusFormatted;
      format.unformattedToFormatted (pointGraph.x(),
                                     pointGraph.y(),
                                     m_modelCoords,
                                     m_modelMainWindow,
                                     xThetaFormatted,
                                     yRadiusFormatted,
                                     *this);

      coordsGraph = QString ("(%1, %2)")
                    .arg (xThetaFormatted)
                    .arg (yRadiusFormatted);

      resolutionsGraph = QString ("(%1, %2)")
                         .arg (resolutionXGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS)
                         .arg (resolutionYGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS);

    } else {

      coordsGraph = "<font color=\"red\">Need more axis points</font>";
      resolutionsGraph = coordsGraph;

    }
  }
}