7 #include "DocumentModelCoords.h"
8 #include "DocumentModelGridDisplay.h"
9 #include "EngaugeAssert.h"
10 #include "EnumsToQt.h"
11 #include "GraphicsArcItem.h"
12 #include "GridLineFactory.h"
13 #include "GridLineLimiter.h"
14 #include "GridLines.h"
15 #include "GridLineStyle.h"
17 #include "MainWindowModel.h"
18 #include <QGraphicsScene>
20 #include <QTextStream>
21 #include "QtToString.h"
22 #include "Transformation.h"
24 const int Z_VALUE_IN_FRONT = 100;
27 const double CHECKER_OPACITY = 0.6;
29 const double PI = 3.1415926535;
30 const double TWO_PI = 2.0 * PI;
31 const double DEGREES_TO_RADIANS = PI / 180.0;
32 const double RADIANS_TO_TICS = 5760 / TWO_PI;
38 m_modelCoords (modelCoords),
41 LOG4CPP_DEBUG_S ((*mainCat)) <<
"GridLineFactory::GridLineFactory";
46 const QList<Point> &pointsToIsolate,
49 m_pointRadius (pointRadius),
50 m_pointsToIsolate (pointsToIsolate),
51 m_modelCoords (modelCoords),
54 LOG4CPP_DEBUG_S ((*mainCat)) <<
"GridLineFactory::GridLineFactory"
55 <<
" pointRadius=" << pointRadius
56 <<
" pointsToIsolate=" << pointsToIsolate.count();
59 void GridLineFactory::bindItemToScene(QGraphicsItem *item)
const
61 LOG4CPP_DEBUG_S ((*mainCat)) <<
"GridLineFactory::bindItemToScene";
63 item->setOpacity (CHECKER_OPACITY);
64 item->setZValue (Z_VALUE_IN_FRONT);
66 item->setToolTip (QObject::tr (
"Axes checker. If this does not align with the axes, then the axes points should be checked"));
69 m_scene.addItem (item);
78 LOG4CPP_DEBUG_S ((*mainCat)) <<
"GridLineFactory::createGridLine"
95 const int NUM_STEPS = 1000;
97 bool stateSegmentIsActive =
false;
98 QPointF posStartScreen (0, 0);
101 for (
int i = 0; i <= NUM_STEPS; i++) {
103 double s = (double) i / (
double) NUM_STEPS;
106 double xGraph = (1.0 - s) * xFrom + s * xTo;
107 double yGraph = (1.0 - s) * yFrom + s * yTo;
111 xGraph = qExp ((1.0 - s) * qLn (xFrom) + s * qLn (xTo));
114 yGraph = qExp ((1.0 - s) * qLn (yFrom) + s * qLn (yTo));
121 double distanceToNearestPoint = minScreenDistanceFromPoints (pointScreen);
122 if ((distanceToNearestPoint < m_pointRadius) ||
126 if (stateSegmentIsActive) {
129 finishActiveGridLine (posStartScreen,
135 stateSegmentIsActive =
false;
141 if (!stateSegmentIsActive) {
144 stateSegmentIsActive =
true;
145 posStartScreen = pointScreen;
163 modelGridDisplay.
stable()) {
165 double startX = modelGridDisplay.
startX ();
166 double startY = modelGridDisplay.
startY ();
167 double stepX = modelGridDisplay.
stepX ();
168 double stepY = modelGridDisplay.
stepY ();
169 double stopX = modelGridDisplay.
stopX ();
170 double stopY = modelGridDisplay.
stopY ();
185 QColor color (ColorPaletteToQColor (modelGridDisplay.
paletteColor()));
186 QPen pen (QPen (color,
191 for (
double x = startX; x <= stopX; (isLinearX ? x += stepX : x *= stepX)) {
195 gridLines.
add (gridLine);
199 for (
double y = startY; y <= stopY; (isLinearY ? y += stepY : y *= stepY)) {
203 gridLines.
add (gridLine);
209 void GridLineFactory::createTransformAlign (
const Transformation &transformation,
210 double radiusLinearCartesian,
211 const QPointF &posOriginScreen,
212 QTransform &transformAlign,
213 double &ellipseXAxis,
214 double &ellipseYAxis)
const
227 QPointF posXRadiusY0Graph (radiusLinearCartesian, 0), posX0YRadiusGraph (0, radiusLinearCartesian);
228 QPointF posXRadiusY0Screen, posX0YRadiusScreen;
235 QPointF deltaXRadiusY0 = posXRadiusY0Screen - posOriginScreen;
236 QPointF deltaX0YRadius = posX0YRadiusScreen - posOriginScreen;
237 ellipseXAxis = qSqrt (deltaXRadiusY0.x () * deltaXRadiusY0.x () +
238 deltaXRadiusY0.y () * deltaXRadiusY0.y ());
239 ellipseYAxis = qSqrt (deltaX0YRadius.x () * deltaX0YRadius.x () +
240 deltaX0YRadius.y () * deltaX0YRadius.y ());
243 QPointF posXRadiusY0AlignedScreen (posOriginScreen.x() + ellipseXAxis, posOriginScreen.y());
244 QPointF posX0YRadiusAlignedScreen (posOriginScreen.x(), posOriginScreen.y() - ellipseYAxis);
250 posXRadiusY0AlignedScreen,
251 posX0YRadiusAlignedScreen);
253 LOG4CPP_INFO_S ((*mainCat)) <<
"GridLineFactory::createTransformAlign"
254 <<
" transformation=" << QTransformToString (transformation.
transformMatrix()).toLatin1().data() << endl
255 <<
" radiusLinearCartesian=" << radiusLinearCartesian
256 <<
" posXRadiusY0Screen=" << QPointFToString (posXRadiusY0Screen).toLatin1().data()
257 <<
" posX0YRadiusScreen=" << QPointFToString (posX0YRadiusScreen).toLatin1().data()
258 <<
" ellipseXAxis=" << ellipseXAxis
259 <<
" ellipseYAxis=" << ellipseYAxis
260 <<
" posXRadiusY0AlignedScreen=" << QPointFToString (posXRadiusY0AlignedScreen).toLatin1().data()
261 <<
" posX0YRadiusAlignedScreen=" << QPointFToString (posX0YRadiusAlignedScreen).toLatin1().data()
262 <<
" transformAlign=" << QTransformToString (transformAlign).toLatin1().data();
265 QGraphicsItem *GridLineFactory::ellipseItem (
const Transformation &transformation,
266 double radiusLinearCartesian,
267 const QPointF &posStartScreen,
268 const QPointF &posEndScreen)
const
272 QPointF posStartGraph, posEndGraph;
280 double angleStart = posStartGraph.x() * DEGREES_TO_RADIANS;
281 double angleEnd = posEndGraph.x() * DEGREES_TO_RADIANS;
282 if (angleEnd < angleStart) {
285 double angleSpan = angleEnd - angleStart;
288 QPointF posOriginGraph (0, 0), posOriginScreen;
292 LOG4CPP_INFO_S ((*mainCat)) <<
"GridLineFactory::ellipseItem"
293 <<
" radiusLinearCartesian=" << radiusLinearCartesian
294 <<
" posStartScreen=" << QPointFToString (posStartScreen).toLatin1().data()
295 <<
" posEndScreen=" << QPointFToString (posEndScreen).toLatin1().data()
296 <<
" posOriginScreen=" << QPointFToString (posOriginScreen).toLatin1().data()
297 <<
" angleStart=" << angleStart / DEGREES_TO_RADIANS
298 <<
" angleEnd=" << angleEnd / DEGREES_TO_RADIANS
299 <<
" transformation=" << transformation;
304 double ellipseXAxis, ellipseYAxis;
305 QTransform transformAlign;
306 createTransformAlign (transformation,
307 radiusLinearCartesian,
314 QRectF boundingRect (-1.0 * ellipseXAxis + posOriginScreen.x(),
315 -1.0 * ellipseYAxis + posOriginScreen.y(),
319 item->setStartAngle (angleStart * RADIANS_TO_TICS);
320 item->setSpanAngle (angleSpan * RADIANS_TO_TICS);
322 item->setTransform (transformAlign.transposed ().inverted ());
327 void GridLineFactory::finishActiveGridLine (
const QPointF &posStartScreen,
328 const QPointF &posEndScreen,
334 LOG4CPP_DEBUG_S ((*mainCat)) <<
"GridLineFactory::finishActiveGridLine"
335 <<
" posStartScreen=" << QPointFToString (posStartScreen).toLatin1().data()
336 <<
" posEndScreen=" << QPointFToString (posEndScreen).toLatin1().data()
337 <<
" yFrom=" << yFrom
341 if ((m_modelCoords.
coordsType() == COORDS_TYPE_POLAR) &&
345 double radiusLinearCartesian = yFrom;
354 item = ellipseItem (transformation,
355 radiusLinearCartesian,
362 item = lineItem (posStartScreen,
367 bindItemToScene (item);
370 QGraphicsItem *GridLineFactory::lineItem (
const QPointF &posStartScreen,
371 const QPointF &posEndScreen)
const
373 LOG4CPP_DEBUG_S ((*mainCat)) <<
"GridLineFactory::lineItem"
374 <<
" posStartScreen=" << QPointFToString (posStartScreen).toLatin1().data()
375 <<
" posEndScreen=" << QPointFToString (posEndScreen).toLatin1().data();
377 return new QGraphicsLineItem (QLineF (posStartScreen,
381 double GridLineFactory::minScreenDistanceFromPoints (
const QPointF &posScreen)
383 double minDistance = 0;
384 for (
int i = 0; i < m_pointsToIsolate.count (); i++) {
385 const Point &pointCenter = m_pointsToIsolate.at (i);
387 double dx = posScreen.x() - pointCenter.
posScreen().x();
388 double dy = posScreen.y() - pointCenter.
posScreen().y();
390 double distance = qSqrt (dx * dx + dy * dy);
391 if (i == 0 || distance < minDistance) {
392 minDistance = distance;
double stopX() const
Get method for x grid line upper bound (inclusive).
double stepX() const
Get method for x grid line increment.
Model for DlgSettingsGridDisplay and CmdSettingsGridDisplay.
void createGridLinesForEvenlySpacedGrid(const DocumentModelGridDisplay &modelGridDisplay, const MainWindowModel &modelMainWindow, const Transformation &transformation, GridLines &gridLines)
Create a rectangular (cartesian) or annular (polar) grid of evenly spaced grid lines.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
double originRadius() const
Get method for origin radius in polar mode.
Draw an arc as an ellipse but without lines from the center to the start and end points.
double startX() const
Get method for x grid line lower bound (inclusive).
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
QPointF posScreen() const
Accessor for screen position.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
Model for DlgSettingsMainWindow.
Container class for GridLine objects.
double limitedStepYRange(const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid) const
Limit step value for y/range coordinate. This is a noop if the maximum grid line limit in MainWindowM...
CoordsType coordsType() const
Get method for coordinates type.
Model for DlgSettingsCoords and CmdSettingsCoords.
ColorPalette paletteColor() const
Get method for color.
double stopY() const
Get method for y grid line upper bound (inclusive).
double startY() const
Get method for y grid line lower bound (inclusive).
double stepY() const
Get method for y grid line increment.
GridLineFactory(QGraphicsScene &scene, const DocumentModelCoords &modelCoords)
Simple constructor for general use (i.e. not by Checker)
void add(GridLine *gridLine)
Add specified grid line. Ownership of all allocated QGraphicsItems is passed to new GridLine...
bool stable() const
Get method for stable flag.
void setPen(const QPen &pen)
Set the pen style.
Single grid line drawn a straight or curved line.
Limit the number of grid lines so a bad combination of start/step/stop value will not lead to extreme...
double limitedStepXTheta(const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid) const
Limit step value for x/theta coordinate. This is a noop if the maximum grid line limit in MainWindowM...
GridLine * createGridLine(double xFrom, double yFrom, double xTo, double yTo, const Transformation &transformation)
Create grid line, either along constant X/theta or constant Y/radius side.
void add(QGraphicsItem *item)
Add graphics item which represents one segment of the line.