7 #include "CallbackUpdateTransform.h"
9 #include "EngaugeAssert.h"
10 #include "FormatCoordsUnits.h"
15 #include "QtToString.h"
16 #include "Transformation.h"
22 const int PRECISION_DIGITS = 4;
24 const double PI = 3.1415926535;
25 const double ZERO_OFFSET_AFTER_LOG = 1;
28 m_transformIsDefined (false)
33 m_transformIsDefined (other.transformIsDefined()),
34 m_transform (other.transformMatrix())
57 const QPointF &posFrom1,
58 const QPointF &posFrom2,
59 const QPointF &posTo0,
60 const QPointF &posTo1,
61 const QPointF &posTo2)
63 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::calculateTransformFromLinearCartesianPoints";
66 from.setMatrix (posFrom0.x(), posFrom1.x(), posFrom2.x(),
67 posFrom0.y(), posFrom1.y(), posFrom2.y(),
70 to.setMatrix (posTo0.x(), posTo1.x(), posTo2.x(),
71 posTo0.y(), posTo1.y(), posTo2.y(),
73 QTransform fromInv = from.inverted ();
79 const QPointF &posGraphIn)
82 QPointF posGraphCartesian = posGraphIn;
84 if (modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
87 double angleRadians = 0;
90 case COORD_UNITS_POLAR_THETA_DEGREES:
91 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
92 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
93 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
94 angleRadians = posGraphIn.x () * PI / 180.0;
97 case COORD_UNITS_POLAR_THETA_GRADIANS:
98 angleRadians = posGraphIn.x () * PI / 200.0;
101 case COORD_UNITS_POLAR_THETA_RADIANS:
102 angleRadians = posGraphIn.x ();
105 case COORD_UNITS_POLAR_THETA_TURNS:
106 angleRadians = posGraphIn.x () * 2.0 * PI;
110 ENGAUGE_ASSERT (
false);
113 double radius = posGraphIn.y ();
114 posGraphCartesian.setX (radius * cos (angleRadians));
115 posGraphCartesian.setY (radius * sin (angleRadians));
118 return posGraphCartesian;
122 const QPointF &posGraphIn)
125 QPointF posGraphCartesianOrPolar = posGraphIn;
127 if (modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
130 double angleRadians = qAtan2 (posGraphIn.y (),
134 case COORD_UNITS_POLAR_THETA_DEGREES:
135 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
136 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
137 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
138 posGraphCartesianOrPolar.setX (angleRadians * 180.0 / PI);
141 case COORD_UNITS_POLAR_THETA_GRADIANS:
142 posGraphCartesianOrPolar.setX (angleRadians * 200.0 / PI);
145 case COORD_UNITS_POLAR_THETA_RADIANS:
146 posGraphCartesianOrPolar.setX (angleRadians);
149 case COORD_UNITS_POLAR_THETA_TURNS:
150 posGraphCartesianOrPolar.setX (angleRadians / 2.0 / PI);
154 ENGAUGE_ASSERT (
false);
157 double radius = qSqrt (posGraphIn.x () * posGraphIn.x () + posGraphIn.y () * posGraphIn.y ());
158 posGraphCartesianOrPolar.setY (radius);
161 return posGraphCartesianOrPolar;
165 QString &coordsScreen,
166 QString &coordsGraph,
167 QString &resolutionsGraph)
169 const int UNCONSTRAINED_FIELD_WIDTH = 0;
170 const double X_DELTA_PIXELS = 1.0, Y_DELTA_PIXELS = 1.0;
171 const char FORMAT =
'g';
173 if (cursorScreen.x() < 0 ||
174 cursorScreen.y() < 0) {
179 resolutionsGraph =
"";
183 coordsScreen = QString(
"(%1, %2)")
184 .arg (cursorScreen.x ())
185 .arg (cursorScreen.y ());
187 if (m_transformIsDefined) {
190 QPointF cursorScreenDelta (cursorScreen.x () + X_DELTA_PIXELS,
191 cursorScreen.y () + Y_DELTA_PIXELS);
194 QPointF pointGraph, pointGraphDelta;
201 double resolutionXGraph = qAbs ((pointGraphDelta.x () - pointGraph.x ()) / X_DELTA_PIXELS);
202 double resolutionYGraph = qAbs ((pointGraphDelta.y () - pointGraph.y ()) / Y_DELTA_PIXELS);
206 QString xThetaFormatted, yRadiusFormatted;
215 coordsGraph = QString (
"(%1, %2)")
216 .arg (xThetaFormatted)
217 .arg (yRadiusFormatted);
219 resolutionsGraph = QString (
"(%1, %2)")
220 .arg (resolutionXGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS)
221 .arg (resolutionYGraph, UNCONSTRAINED_FIELD_WIDTH, FORMAT, PRECISION_DIGITS);
225 coordsGraph =
"<font color=\"red\">Need more axis points</font>";
226 resolutionsGraph = coordsGraph;
235 m_transformIsDefined =
true;
249 return qLn (r) - qLn (rCenter);
254 return m_modelCoords;
259 return m_modelMainWindow;
262 ostringstream &operator<<(ostringstream &strOuter,
266 QTextStream strInner (&text);
269 strOuter << text.toLatin1().data ();
275 QTextStream &str)
const
277 str <<
"Transformation\n";
279 indentation += INDENTATION_DELTA;
281 if (m_transformIsDefined) {
283 str << indentation <<
"affine=" << (m_transform.isAffine() ?
"yes" :
"no") <<
" matrix=("
284 << m_transform.m11() <<
", " << m_transform.m12() <<
", " << m_transform.m13() <<
", "
285 << m_transform.m21() <<
", " << m_transform.m22() <<
", " << m_transform.m23() <<
", "
286 << m_transform.m31() <<
", " << m_transform.m32() <<
", " << m_transform.m33() <<
")";
290 str << indentation <<
"undefined";
297 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::resetOnLoad";
299 m_transformIsDefined =
false;
302 double Transformation::roundOffSmallValues (
double value,
double range)
304 if (qAbs (value) < range / qPow (10.0, PRECISION_DIGITS)) {
320 return m_transformIsDefined;
324 QPointF &pointRawGraph)
const
329 pointRawGraph = pointLinearCartesianGraph;
332 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
338 if ((m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) &&
340 pointRawGraph.setY (pointRawGraph.y() + m_modelCoords.
originRadius());
345 pointRawGraph.setX (qExp (pointRawGraph.x()));
350 if (m_modelCoords.
coordsType() == COORDS_TYPE_CARTESIAN) {
352 offset = ZERO_OFFSET_AFTER_LOG;
358 pointRawGraph.setY (qExp (pointRawGraph.y() + qLn (offset)));
363 QPointF &coordScreen)
const
365 ENGAUGE_ASSERT (m_transformIsDefined);
367 coordScreen = m_transform.inverted ().transposed ().map (coordGraph);
376 QPointF &pointLinearCartesian)
const
381 double x = pointRaw.x();
382 double y = pointRaw.y();
385 if ((m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) &&
396 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
401 ZERO_OFFSET_AFTER_LOG);
406 if (m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
413 pointLinearCartesian.setX (x);
414 pointLinearCartesian.setY (y);
418 QPointF &pointScreen)
const
420 QPointF pointLinearCartesianGraph;
423 pointLinearCartesianGraph);
429 QPointF &coordGraph)
const
431 ENGAUGE_ASSERT (m_transformIsDefined);
433 coordGraph = m_transform.transposed ().map (coordScreen);
437 QPointF &coordGraph)
const
439 QPointF pointLinearCartesianGraph;
441 pointLinearCartesianGraph);
450 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Transformation::update";
454 m_transformIsDefined =
false;
464 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
468 if (ftor.transformIsDefined ()) {
470 updateTransformFromMatrices (ftor.matrixScreen(),
474 m_transformIsDefined =
false;
480 void Transformation::updateTransformFromMatrices (
const QTransform &matrixScreen,
481 const QTransform &matrixGraph)
485 m_transformIsDefined =
true;
488 QPointF pointGraphRaw0 (matrixGraph.m11(),
490 QPointF pointGraphRaw1 (matrixGraph.m12(),
492 QPointF pointGraphRaw2 (matrixGraph.m13(),
495 QPointF pointGraphLinearCart0, pointGraphLinearCart1, pointGraphLinearCart2;
497 pointGraphLinearCart0);
499 pointGraphLinearCart1);
501 pointGraphLinearCart2);
505 QPointF (matrixScreen.m12(), matrixScreen.m22()),
506 QPointF (matrixScreen.m13(), matrixScreen.m23()),
507 QPointF (pointGraphLinearCart0.x(), pointGraphLinearCart0.y()),
508 QPointF (pointGraphLinearCart1.x(), pointGraphLinearCart1.y()),
509 QPointF (pointGraphLinearCart2.x(), pointGraphLinearCart2.y()));
512 QTransform matrixGraphLinear (pointGraphLinearCart0.x(),
513 pointGraphLinearCart1.x(),
514 pointGraphLinearCart2.x(),
515 pointGraphLinearCart0.y(),
516 pointGraphLinearCart1.y(),
517 pointGraphLinearCart2.y(),
521 QPointF pointScreenRoundTrip0, pointScreenRoundTrip1, pointScreenRoundTrip2;
523 pointScreenRoundTrip0);
525 pointScreenRoundTrip1);
527 pointScreenRoundTrip2);
529 QPointF pointScreen0 (matrixScreen.m11(),
531 QPointF pointScreen1 (matrixScreen.m12(),
533 QPointF pointScreen2 (matrixScreen.m13(),
536 LOG4CPP_INFO_S ((*mainCat)) <<
"Transformation::updateTransformFromMatrices"
537 <<
" matrixScreen=\n" << QTransformToString (matrixScreen).toLatin1().data () <<
" "
538 <<
" matrixGraphRaw=\n" << QTransformToString (matrixGraph).toLatin1().data() <<
" "
539 <<
" matrixGraphLinear=\n" << QTransformToString (matrixGraphLinear).toLatin1().data() <<
"\n"
540 <<
" originalScreen0=" << QPointFToString (pointScreen0).toLatin1().data() <<
"\n"
541 <<
" originalScreen1=" << QPointFToString (pointScreen1).toLatin1().data() <<
"\n"
542 <<
" originalScreen2=" << QPointFToString (pointScreen2).toLatin1().data() <<
"\n"
543 <<
" roundTripScreen0=" << QPointFToString (pointScreenRoundTrip0).toLatin1().data() <<
"\n"
544 <<
" roundTripScreen1=" << QPointFToString (pointScreenRoundTrip1).toLatin1().data() <<
"\n"
545 <<
" roundTripScreen2=" << QPointFToString (pointScreenRoundTrip2).toLatin1().data() <<
"\n";
DocumentAxesPointsRequired documentAxesPointsRequired() const
Get method for DocumentAxesPointsRequired.
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.
Model for DlgSettingsMainWindow.
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.