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)
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;
74 if (modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
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;
117 if (modelCoords.
coordsType() == COORDS_TYPE_POLAR) {
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;
287 double 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,
453 if (ftor.transformIsDefined ()) {
455 updateTransformFromMatrices (ftor.matrixScreen(),
459 m_transformIsDefined =
false;
465 void 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";
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.