1 #include "CallbackUpdateTransform.h"
3 #include "EngaugeAssert.h"
4 #include "FormatCoordsUnits.h"
9 #include "QtToString.h"
10 #include "Transformation.h"
16 const int PRECISION_DIGITS = 4;
18 const double PI = 3.1415926535;
19 const double ZERO_OFFSET_AFTER_LOG = 1;
22 m_transformIsDefined (false)
41 const QPointF &posFrom1,
42 const QPointF &posFrom2,
43 const QPointF &posTo0,
44 const QPointF &posTo1,
45 const QPointF &posTo2)
47 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::calculateTransformFromLinearCartesianPoints";
50 from.setMatrix (posFrom0.x(), posFrom1.x(), posFrom2.x(),
51 posFrom0.y(), posFrom1.y(), posFrom2.y(),
54 to.setMatrix (posTo0.x(), posTo1.x(), posTo2.x(),
55 posTo0.y(), posTo1.y(), posTo2.y(),
57 QTransform fromInv = from.inverted ();
63 const QPointF &posGraphIn)
66 QPointF posGraphCartesian = posGraphIn;
68 if (modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
71 double angleRadians = 0;
74 case COORD_UNITS_POLAR_THETA_DEGREES:
75 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
76 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
77 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
78 angleRadians = posGraphIn.x () * PI / 180.0;
81 case COORD_UNITS_POLAR_THETA_GRADIANS:
82 angleRadians = posGraphIn.x () * PI / 200.0;
85 case COORD_UNITS_POLAR_THETA_RADIANS:
86 angleRadians = posGraphIn.x ();
89 case COORD_UNITS_POLAR_THETA_TURNS:
90 angleRadians = posGraphIn.x () * 2.0 * PI;
94 ENGAUGE_ASSERT (
false);
97 double radius = posGraphIn.y ();
98 posGraphCartesian.setX (radius * cos (angleRadians));
99 posGraphCartesian.setY (radius * sin (angleRadians));
102 return posGraphCartesian;
106 const QPointF &posGraphIn)
109 QPointF posGraphCartesianOrPolar = posGraphIn;
111 if (modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
114 double angleRadians = qAtan2 (posGraphIn.y (),
118 case COORD_UNITS_POLAR_THETA_DEGREES:
119 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
120 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
121 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
122 posGraphCartesianOrPolar.setX (angleRadians * 180.0 / PI);
125 case COORD_UNITS_POLAR_THETA_GRADIANS:
126 posGraphCartesianOrPolar.setX (angleRadians * 200.0 / PI);
129 case COORD_UNITS_POLAR_THETA_RADIANS:
130 posGraphCartesianOrPolar.setX (angleRadians);
133 case COORD_UNITS_POLAR_THETA_TURNS:
134 posGraphCartesianOrPolar.setX (angleRadians / 2.0 / PI);
138 ENGAUGE_ASSERT (
false);
141 double radius = qSqrt (posGraphIn.x () * posGraphIn.x () + posGraphIn.y () * posGraphIn.y ());
142 posGraphCartesianOrPolar.setY (radius);
145 return posGraphCartesianOrPolar;
149 QString &coordsScreen,
150 QString &coordsGraph,
151 QString &resolutionsGraph)
153 const int UNCONSTRAINED_FIELD_WIDTH = 0;
154 const double X_DELTA_PIXELS = 1.0, Y_DELTA_PIXELS = 1.0;
155 const char FORMAT =
'g';
157 if (cursorScreen.x() < 0 ||
158 cursorScreen.y() < 0) {
163 resolutionsGraph =
"";
167 coordsScreen = QString(
"(%1, %2)")
168 .arg (cursorScreen.x ())
169 .arg (cursorScreen.y ());
171 if (m_transformIsDefined) {
174 QPointF cursorScreenDelta (cursorScreen.x () + X_DELTA_PIXELS,
175 cursorScreen.y () + Y_DELTA_PIXELS);
178 QPointF pointGraph, pointGraphDelta;
185 double resolutionXGraph = qAbs ((pointGraphDelta.x () - pointGraph.x ()) / X_DELTA_PIXELS);
186 double resolutionYGraph = qAbs ((pointGraphDelta.y () - pointGraph.y ()) / Y_DELTA_PIXELS);
190 QString xThetaFormatted, yRadiusFormatted;
198 coordsGraph = QString (
"(%1, %2)")
199 .arg (xThetaFormatted)
200 .arg (yRadiusFormatted);
202 resolutionsGraph = QString (
"(%1, %2)")
203 .arg (resolutionXGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS)
204 .arg (resolutionYGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS);
208 coordsGraph =
"<font color=\"red\">Need more axis points</font>";
209 resolutionsGraph = coordsGraph;
218 m_transformIsDefined =
true;
232 return qLn (r) - qLn (rCenter);
237 return m_modelCoords;
244 QTextStream strInner (&text);
247 strOuter << text.toLatin1().data ();
249 return transformation;
253 QTextStream &str)
const
255 str <<
"Transformation\n";
257 indentation += INDENTATION_DELTA;
259 if (m_transformIsDefined) {
261 str << indentation <<
"affine=" << (m_transform.isAffine() ?
"yes" :
"no") <<
" matrix=("
262 << m_transform.m11() <<
", " << m_transform.m12() <<
", " << m_transform.m13() <<
", "
263 << m_transform.m21() <<
", " << m_transform.m22() <<
", " << m_transform.m23() <<
", "
264 << m_transform.m31() <<
", " << m_transform.m32() <<
", " << m_transform.m33() <<
")";
268 str << indentation <<
"undefined";
275 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::resetOnLoad";
277 m_transformIsDefined =
false;
280 double Transformation::roundOffSmallValues (
double value,
double range)
282 if (qAbs (value) < range / qPow (10.0, PRECISION_DIGITS)) {
295 QPointF &pointRawGraph)
const
300 pointRawGraph = pointLinearCartesianGraph;
303 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
309 if ((m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) &&
311 pointRawGraph.setY (pointRawGraph.y() + m_modelCoords.
originRadius());
316 pointRawGraph.setX (qExp (pointRawGraph.x()));
321 if (m_modelCoords.
coordsType() == COORDS_TYPE_CARTESIAN) {
323 offset = ZERO_OFFSET_AFTER_LOG;
329 pointRawGraph.setY (qExp (pointRawGraph.y() + qLn (offset)));
334 QPointF &coordScreen)
const
336 ENGAUGE_ASSERT (m_transformIsDefined);
338 coordScreen = m_transform.inverted ().transposed ().map (coordGraph);
347 QPointF &pointLinearCartesian)
const
352 double x = pointRaw.x();
353 double y = pointRaw.y();
356 if ((m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) &&
367 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
372 ZERO_OFFSET_AFTER_LOG);
377 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
384 pointLinearCartesian.setX (x);
385 pointLinearCartesian.setY (y);
389 QPointF &pointScreen)
const
391 QPointF pointLinearCartesianGraph;
394 pointLinearCartesianGraph);
400 QPointF &coordGraph)
const
402 ENGAUGE_ASSERT (m_transformIsDefined);
404 coordGraph = m_transform.transposed ().map (coordScreen);
408 QPointF &coordGraph)
const
410 QPointF pointLinearCartesianGraph;
412 pointLinearCartesianGraph);
420 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Transformation::update";
424 m_transformIsDefined =
false;
432 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
436 if (ftor.transformIsDefined ()) {
438 updateTransformFromMatrices (ftor.matrixScreen(),
442 m_transformIsDefined =
false;
448 void Transformation::updateTransformFromMatrices (
const QTransform &matrixScreen,
449 const QTransform &matrixGraph)
453 m_transformIsDefined =
true;
456 QPointF pointGraphRaw0 (matrixGraph.m11(),
458 QPointF pointGraphRaw1 (matrixGraph.m12(),
460 QPointF pointGraphRaw2 (matrixGraph.m13(),
463 QPointF pointGraphLinearCart0, pointGraphLinearCart1, pointGraphLinearCart2;
465 pointGraphLinearCart0);
467 pointGraphLinearCart1);
469 pointGraphLinearCart2);
473 QPointF (matrixScreen.m12(), matrixScreen.m22()),
474 QPointF (matrixScreen.m13(), matrixScreen.m23()),
475 QPointF (pointGraphLinearCart0.x(), pointGraphLinearCart0.y()),
476 QPointF (pointGraphLinearCart1.x(), pointGraphLinearCart1.y()),
477 QPointF (pointGraphLinearCart2.x(), pointGraphLinearCart2.y()));
480 QTransform matrixGraphLinear (pointGraphLinearCart0.x(),
481 pointGraphLinearCart1.x(),
482 pointGraphLinearCart2.x(),
483 pointGraphLinearCart0.y(),
484 pointGraphLinearCart1.y(),
485 pointGraphLinearCart2.y(),
489 QPointF pointScreenRoundTrip0, pointScreenRoundTrip1, pointScreenRoundTrip2;
491 pointScreenRoundTrip0);
493 pointScreenRoundTrip1);
495 pointScreenRoundTrip2);
497 QPointF pointScreen0 (matrixScreen.m11(),
499 QPointF pointScreen1 (matrixScreen.m12(),
501 QPointF pointScreen2 (matrixScreen.m13(),
504 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::updateTransformFromMatrices"
505 <<
" matrixScreen=\n" << QTransformToString (matrixScreen).toLatin1().data () <<
" "
506 <<
" matrixGraphRaw=\n" << QTransformToString (matrixGraph).toLatin1().data() <<
" "
507 <<
" matrixGraphLinear=\n" << QTransformToString (matrixGraphLinear).toLatin1().data() <<
"\n"
508 <<
" originalScreen0=" << QPointFToString (pointScreen0).toLatin1().data() <<
"\n"
509 <<
" originalScreen1=" << QPointFToString (pointScreen1).toLatin1().data() <<
"\n"
510 <<
" originalScreen2=" << QPointFToString (pointScreen2).toLatin1().data() <<
"\n"
511 <<
" roundTripScreen0=" << QPointFToString (pointScreenRoundTrip0).toLatin1().data() <<
"\n"
512 <<
" roundTripScreen1=" << QPointFToString (pointScreenRoundTrip1).toLatin1().data() <<
"\n"
513 <<
" roundTripScreen2=" << QPointFToString (pointScreenRoundTrip2).toLatin1().data() <<
"\n";
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
double originRadius() const
Get method for origin radius in polar mode.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
CoordsType coordsType() const
Get method for coordinates type.
Model for DlgSettingsCoords and CmdSettingsCoords.
CoordUnitsPolarTheta coordUnitsTheta() const
Get method for theta unit.
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.