7#include "CallbackUpdateTransform.h"
9#include "EngaugeAssert.h"
10#include "FormatCoordsUnits.h"
15#include "QtToString.h"
16#include "Transformation.h"
22const int PRECISION_DIGITS = 4;
24const double PI = 3.1415926535;
25const double ZERO_OFFSET_AFTER_LOG = 1;
28 m_transformIsDefined (false)
47 const QPointF &posFrom1,
48 const QPointF &posFrom2,
49 const QPointF &posTo0,
50 const QPointF &posTo1,
51 const QPointF &posTo2)
53 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::calculateTransformFromLinearCartesianPoints";
56 from.setMatrix (posFrom0.x(), posFrom1.x(), posFrom2.x(),
57 posFrom0.y(), posFrom1.y(), posFrom2.y(),
60 to.setMatrix (posTo0.x(), posTo1.x(), posTo2.x(),
61 posTo0.y(), posTo1.y(), posTo2.y(),
63 QTransform fromInv = from.inverted ();
69 const QPointF &posGraphIn)
72 QPointF posGraphCartesian = posGraphIn;
77 double angleRadians = 0;
80 case COORD_UNITS_POLAR_THETA_DEGREES:
81 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
82 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
83 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
84 angleRadians = posGraphIn.x () * PI / 180.0;
87 case COORD_UNITS_POLAR_THETA_GRADIANS:
88 angleRadians = posGraphIn.x () * PI / 200.0;
91 case COORD_UNITS_POLAR_THETA_RADIANS:
92 angleRadians = posGraphIn.x ();
95 case COORD_UNITS_POLAR_THETA_TURNS:
96 angleRadians = posGraphIn.x () * 2.0 * PI;
100 ENGAUGE_ASSERT (
false);
103 double radius = posGraphIn.y ();
104 posGraphCartesian.setX (radius * cos (angleRadians));
105 posGraphCartesian.setY (radius * sin (angleRadians));
108 return posGraphCartesian;
112 const QPointF &posGraphIn)
115 QPointF posGraphCartesianOrPolar = posGraphIn;
120 double angleRadians = qAtan2 (posGraphIn.y (),
124 case COORD_UNITS_POLAR_THETA_DEGREES:
125 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
126 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
127 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
128 posGraphCartesianOrPolar.setX (angleRadians * 180.0 / PI);
131 case COORD_UNITS_POLAR_THETA_GRADIANS:
132 posGraphCartesianOrPolar.setX (angleRadians * 200.0 / PI);
135 case COORD_UNITS_POLAR_THETA_RADIANS:
136 posGraphCartesianOrPolar.setX (angleRadians);
139 case COORD_UNITS_POLAR_THETA_TURNS:
140 posGraphCartesianOrPolar.setX (angleRadians / 2.0 / PI);
144 ENGAUGE_ASSERT (
false);
147 double radius = qSqrt (posGraphIn.x () * posGraphIn.x () + posGraphIn.y () * posGraphIn.y ());
148 posGraphCartesianOrPolar.setY (radius);
151 return posGraphCartesianOrPolar;
155 QString &coordsScreen,
156 QString &coordsGraph,
157 QString &resolutionsGraph)
159 const int UNCONSTRAINED_FIELD_WIDTH = 0;
160 const double X_DELTA_PIXELS = 1.0, Y_DELTA_PIXELS = 1.0;
161 const char FORMAT =
'g';
163 if (cursorScreen.x() < 0 ||
164 cursorScreen.y() < 0) {
169 resolutionsGraph =
"";
173 coordsScreen = QString(
"(%1, %2)")
174 .arg (cursorScreen.x ())
175 .arg (cursorScreen.y ());
177 if (m_transformIsDefined) {
180 QPointF cursorScreenDelta (cursorScreen.x () + X_DELTA_PIXELS,
181 cursorScreen.y () + Y_DELTA_PIXELS);
184 QPointF pointGraph, pointGraphDelta;
191 double resolutionXGraph = qAbs ((pointGraphDelta.x () - pointGraph.x ()) / X_DELTA_PIXELS);
192 double resolutionYGraph = qAbs ((pointGraphDelta.y () - pointGraph.y ()) / Y_DELTA_PIXELS);
196 QString xThetaFormatted, yRadiusFormatted;
205 coordsGraph = QString (
"(%1, %2)")
206 .arg (xThetaFormatted)
207 .arg (yRadiusFormatted);
209 resolutionsGraph = QString (
"(%1, %2)")
210 .arg (resolutionXGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS)
211 .arg (resolutionYGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS);
215 coordsGraph =
"<font color=\"red\">Need more axis points</font>";
216 resolutionsGraph = coordsGraph;
225 m_transformIsDefined =
true;
239 return qLn (r) - qLn (rCenter);
244 return m_modelCoords;
251 QTextStream strInner (&text);
254 strOuter << text.toLatin1().data ();
256 return transformation;
260 QTextStream &str)
const
262 str <<
"Transformation\n";
264 indentation += INDENTATION_DELTA;
266 if (m_transformIsDefined) {
268 str << indentation <<
"affine=" << (m_transform.isAffine() ?
"yes" :
"no") <<
" matrix=("
269 << m_transform.m11() <<
", " << m_transform.m12() <<
", " << m_transform.m13() <<
", "
270 << m_transform.m21() <<
", " << m_transform.m22() <<
", " << m_transform.m23() <<
", "
271 << m_transform.m31() <<
", " << m_transform.m32() <<
", " << m_transform.m33() <<
")";
275 str << indentation <<
"undefined";
282 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::resetOnLoad";
284 m_transformIsDefined =
false;
287double Transformation::roundOffSmallValues (
double value,
double range)
289 if (qAbs (value) < range / qPow (10.0, PRECISION_DIGITS)) {
300 m_modelMainWindow = modelMainWindow;
305 return m_transformIsDefined;
309 QPointF &pointRawGraph)
const
314 pointRawGraph = pointLinearCartesianGraph;
317 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
323 if ((m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) &&
325 pointRawGraph.setY (pointRawGraph.y() + m_modelCoords.
originRadius());
330 pointRawGraph.setX (qExp (pointRawGraph.x()));
335 if (m_modelCoords.
coordsType() == COORDS_TYPE_CARTESIAN) {
337 offset = ZERO_OFFSET_AFTER_LOG;
343 pointRawGraph.setY (qExp (pointRawGraph.y() + qLn (offset)));
348 QPointF &coordScreen)
const
350 ENGAUGE_ASSERT (m_transformIsDefined);
352 coordScreen = m_transform.inverted ().transposed ().map (coordGraph);
361 QPointF &pointLinearCartesian)
const
366 double x = pointRaw.x();
367 double y = pointRaw.y();
370 if ((m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) &&
381 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
386 ZERO_OFFSET_AFTER_LOG);
391 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
398 pointLinearCartesian.setX (x);
399 pointLinearCartesian.setY (y);
403 QPointF &pointScreen)
const
405 QPointF pointLinearCartesianGraph;
408 pointLinearCartesianGraph);
414 QPointF &coordGraph)
const
416 ENGAUGE_ASSERT (m_transformIsDefined);
418 coordGraph = m_transform.transposed ().map (coordScreen);
422 QPointF &coordGraph)
const
424 QPointF pointLinearCartesianGraph;
426 pointLinearCartesianGraph);
435 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Transformation::update";
439 m_transformIsDefined =
false;
449 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
459 m_transformIsDefined =
false;
465void Transformation::updateTransformFromMatrices (
const QTransform &matrixScreen,
466 const QTransform &matrixGraph)
470 m_transformIsDefined =
true;
473 QPointF pointGraphRaw0 (matrixGraph.m11(),
475 QPointF pointGraphRaw1 (matrixGraph.m12(),
477 QPointF pointGraphRaw2 (matrixGraph.m13(),
480 QPointF pointGraphLinearCart0, pointGraphLinearCart1, pointGraphLinearCart2;
482 pointGraphLinearCart0);
484 pointGraphLinearCart1);
486 pointGraphLinearCart2);
490 QPointF (matrixScreen.m12(), matrixScreen.m22()),
491 QPointF (matrixScreen.m13(), matrixScreen.m23()),
492 QPointF (pointGraphLinearCart0.x(), pointGraphLinearCart0.y()),
493 QPointF (pointGraphLinearCart1.x(), pointGraphLinearCart1.y()),
494 QPointF (pointGraphLinearCart2.x(), pointGraphLinearCart2.y()));
497 QTransform matrixGraphLinear (pointGraphLinearCart0.x(),
498 pointGraphLinearCart1.x(),
499 pointGraphLinearCart2.x(),
500 pointGraphLinearCart0.y(),
501 pointGraphLinearCart1.y(),
502 pointGraphLinearCart2.y(),
506 QPointF pointScreenRoundTrip0, pointScreenRoundTrip1, pointScreenRoundTrip2;
508 pointScreenRoundTrip0);
510 pointScreenRoundTrip1);
512 pointScreenRoundTrip2);
514 QPointF pointScreen0 (matrixScreen.m11(),
516 QPointF pointScreen1 (matrixScreen.m12(),
518 QPointF pointScreen2 (matrixScreen.m13(),
521 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::updateTransformFromMatrices"
522 <<
" matrixScreen=\n" << QTransformToString (matrixScreen).toLatin1().data () <<
" "
523 <<
" matrixGraphRaw=\n" << QTransformToString (matrixGraph).toLatin1().data() <<
" "
524 <<
" matrixGraphLinear=\n" << QTransformToString (matrixGraphLinear).toLatin1().data() <<
"\n"
525 <<
" originalScreen0=" << QPointFToString (pointScreen0).toLatin1().data() <<
"\n"
526 <<
" originalScreen1=" << QPointFToString (pointScreen1).toLatin1().data() <<
"\n"
527 <<
" originalScreen2=" << QPointFToString (pointScreen2).toLatin1().data() <<
"\n"
528 <<
" roundTripScreen0=" << QPointFToString (pointScreenRoundTrip0).toLatin1().data() <<
"\n"
529 <<
" roundTripScreen1=" << QPointFToString (pointScreenRoundTrip1).toLatin1().data() <<
"\n"
530 <<
" roundTripScreen2=" << QPointFToString (pointScreenRoundTrip2).toLatin1().data() <<
"\n";
QTransform matrixGraph() const
Returns graph coordinates matrix after transformIsDefined has already indicated success.
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
QTransform matrixScreen() const
Returns screen coordinates matrix after transformIsDefined has already indicated success.
Model for DlgSettingsCoords and CmdSettingsCoords.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
CoordUnitsPolarTheta coordUnitsTheta() const
Get method for theta unit.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
CoordsType coordsType() const
Get method for coordinates type.
double originRadius() const
Get method for origin radius in polar mode.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
DocumentAxesPointsRequired documentAxesPointsRequired() const
Get method for DocumentAxesPointsRequired.
Model for DlgSettingsMainWindow.