Engauge Digitizer  2
Public Member Functions | List of all members
GridLineFactory Class Reference

Factory class for generating the points, composed of QGraphicsItem objects, along a GridLine. More...

#include <GridLineFactory.h>

Collaboration diagram for GridLineFactory:
Collaboration graph

Public Member Functions

 GridLineFactory (QGraphicsScene &scene, const DocumentModelCoords &modelCoords)
 Simple constructor for general use (i.e. not by Checker) More...
 
 GridLineFactory (QGraphicsScene &scene, int pointRadius, const QList< Point > &pointsToIsolate, const DocumentModelCoords &modelCoords)
 Constructor for use by Checker, which has points that are isolated. More...
 
GridLinecreateGridLine (double xFrom, double yFrom, double xTo, double yTo, const Transformation &transformation)
 Create grid line, either along constant X/theta or constant Y/radius side. More...
 
void createGridLinesForEvenlySpacedGrid (const DocumentModelGridDisplay &modelGridDisplay, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, GridLines &gridLines)
 Create a rectangular (cartesian) or annular (polar) grid of evenly spaced grid lines. More...
 

Detailed Description

Factory class for generating the points, composed of QGraphicsItem objects, along a GridLine.

For polar coordinates, the grid lines will appear as an annular segments.

For the Checker class, a set of Points can be specified which will be isolated by having grid lines stop at a specified distance (or radius) from each point

Definition at line 29 of file GridLineFactory.h.

Constructor & Destructor Documentation

◆ GridLineFactory() [1/2]

GridLineFactory::GridLineFactory ( QGraphicsScene &  scene,
const DocumentModelCoords modelCoords 
)

Simple constructor for general use (i.e. not by Checker)

Definition at line 35 of file GridLineFactory.cpp.

36  :
37  m_scene (scene),
38  m_pointRadius (0.0),
39  m_modelCoords (modelCoords),
40  m_isChecker (false)
41 {
42  LOG4CPP_DEBUG_S ((*mainCat)) << "GridLineFactory::GridLineFactory";
43 }
log4cpp::Category * mainCat
Definition: Logger.cpp:14
#define LOG4CPP_DEBUG_S(logger)
Definition: convenience.h:20

◆ GridLineFactory() [2/2]

GridLineFactory::GridLineFactory ( QGraphicsScene &  scene,
int  pointRadius,
const QList< Point > &  pointsToIsolate,
const DocumentModelCoords modelCoords 
)

Constructor for use by Checker, which has points that are isolated.

Definition at line 45 of file GridLineFactory.cpp.

48  :
49  m_scene (scene),
50  m_pointRadius (pointRadius),
51  m_pointsToIsolate (pointsToIsolate),
52  m_modelCoords (modelCoords),
53  m_isChecker (true)
54 {
55  LOG4CPP_DEBUG_S ((*mainCat)) << "GridLineFactory::GridLineFactory"
56  << " pointRadius=" << pointRadius
57  << " pointsToIsolate=" << pointsToIsolate.count();
58 }
log4cpp::Category * mainCat
Definition: Logger.cpp:14
#define LOG4CPP_DEBUG_S(logger)
Definition: convenience.h:20

Member Function Documentation

◆ createGridLine()

GridLine * GridLineFactory::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.

Line goes from pointFromGraph to pointToGraph. If the coordinates are polar, we go clockwise from pointFromGraph to pointToGraph (as set up by adjustPolarAngleRange).

Definition at line 73 of file GridLineFactory.cpp.

78 {
79  LOG4CPP_DEBUG_S ((*mainCat)) << "GridLineFactory::createGridLine"
80  << " xFrom=" << xFrom
81  << " yFrom=" << yFrom
82  << " xTo=" << xTo
83  << " yTo=" << yTo;
84 
85  GridLine *gridLine = new GridLine ();
86 
87  // Originally a complicated algorithm tried to intercept a straight line from (xFrom,yFrom) to (xTo,yTo). That did not work well since:
88  // 1) Calculations for mostly orthogonal cartesian coordinates worked less well with non-orthogonal polar coordinates
89  // 2) Ambiguity in polar coordinates between the shorter and longer paths between (theta0,radius) and (theta1,radius)
90  //
91  // Current algorithm breaks up the interval between (xMin,yMin) and (xMax,yMax) into many smaller pieces and stitches the
92  // desired pieces together. For straight lines in linear graphs this algorithm is very much overkill, but there is no significant
93  // penalty and this approach works in every situation
94 
95  // Should give single-pixel resolution on most images, and 'good enough' resolution on extremely large images
96  const int NUM_STEPS = 1000;
97 
98  bool stateSegmentIsActive = false;
99  QPointF posStartScreen (0, 0);
100 
101  // Loop through steps. Final step i=NUM_STEPS does final processing if a segment is active
102  for (int i = 0; i <= NUM_STEPS; i++) {
103 
104  double s = double (i) / double (NUM_STEPS);
105 
106  // Interpolate coordinates assuming normal linear scaling
107  double xGraph = (1.0 - s) * xFrom + s * xTo;
108  double yGraph = (1.0 - s) * yFrom + s * yTo;
109 
110  // Replace interpolated coordinates using log scaling if appropriate, preserving the same ranges
111  if (m_modelCoords.coordScaleXTheta() == COORD_SCALE_LOG) {
112  xGraph = qExp ((1.0 - s) * qLn (xFrom) + s * qLn (xTo));
113  }
114  if (m_modelCoords.coordScaleYRadius() == COORD_SCALE_LOG) {
115  yGraph = qExp ((1.0 - s) * qLn (yFrom) + s * qLn (yTo));
116  }
117 
118  QPointF pointScreen;
119  transformation.transformRawGraphToScreen (QPointF (xGraph, yGraph),
120  pointScreen);
121 
122  double distanceToNearestPoint = minScreenDistanceFromPoints (pointScreen);
123  if ((distanceToNearestPoint < m_pointRadius) ||
124  (i == NUM_STEPS)) {
125 
126  // Too close to point, so point is not included in side. Or this is the final iteration of the loop
127  if (stateSegmentIsActive) {
128 
129  // State transition
130  finishActiveGridLine (posStartScreen,
131  pointScreen,
132  yFrom,
133  yTo,
134  transformation,
135  *gridLine);
136  stateSegmentIsActive = false;
137 
138  }
139  } else {
140 
141  // Outside point, so include point in side
142  if (!stateSegmentIsActive) {
143 
144  // State transition
145  stateSegmentIsActive = true;
146  posStartScreen = pointScreen;
147 
148  }
149  }
150  }
151 
152  return gridLine;
153 }
void transformRawGraphToScreen(const QPointF &pointRaw, QPointF &pointScreen) const
Transform from raw graph coordinates to linear cartesian graph coordinates, then to screen coordinate...
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
log4cpp::Category * mainCat
Definition: Logger.cpp:14
Single grid line drawn a straight or curved line.
Definition: GridLine.h:20
#define LOG4CPP_DEBUG_S(logger)
Definition: convenience.h:20

◆ createGridLinesForEvenlySpacedGrid()

void GridLineFactory::createGridLinesForEvenlySpacedGrid ( const DocumentModelGridDisplay modelGridDisplay,
const Document document,
const MainWindowModel modelMainWindow,
const Transformation transformation,
GridLines gridLines 
)

Create a rectangular (cartesian) or annular (polar) grid of evenly spaced grid lines.

Definition at line 155 of file GridLineFactory.cpp.

160 {
161  // At a minimum the transformation must be defined. Also, there is a brief interval between the definition of
162  // the transformation and the initialization of modelGridDisplay (at which point this method gets called again) and
163  // we do not want to create grid lines during that brief interval
164  if (transformation.transformIsDefined() &&
165  modelGridDisplay.stable()) {
166 
167  double startX = modelGridDisplay.startX ();
168  double startY = modelGridDisplay.startY ();
169  double stepX = modelGridDisplay.stepX ();
170  double stepY = modelGridDisplay.stepY ();
171  double stopX = modelGridDisplay.stopX ();
172  double stopY = modelGridDisplay.stopY ();
173 
174  // Limit the number of grid lines. This is a noop if the limit is not exceeded
175  GridLineLimiter gridLineLimiter;
176  gridLineLimiter.limitForXTheta (document,
177  transformation,
178  m_modelCoords,
179  modelMainWindow,
180  modelGridDisplay,
181  startX,
182  stepX,
183  stopX);
184  gridLineLimiter.limitForYRadius (document,
185  transformation,
186  m_modelCoords,
187  modelMainWindow,
188  modelGridDisplay,
189  startY,
190  stepY,
191  stopY);
192 
193  // Apply if possible
194  bool isLinearX = (m_modelCoords.coordScaleXTheta() == COORD_SCALE_LINEAR);
195  bool isLinearY = (m_modelCoords.coordScaleYRadius() == COORD_SCALE_LINEAR);
196  if (stepX > (isLinearX ? 0 : 1) &&
197  stepY > (isLinearY ? 0 : 1) &&
198  (isLinearX || (startX > 0)) &&
199  (isLinearY || (startY > 0))) {
200 
201  QColor color (ColorPaletteToQColor (modelGridDisplay.paletteColor()));
202  QPen pen (QPen (color,
204  GRID_LINE_STYLE));
205 
206  for (double x = startX; x <= stopX; (isLinearX ? x += stepX : x *= stepX)) {
207 
208  GridLine *gridLine = createGridLine (x, startY, x, stopY, transformation);
209  gridLine->setPen (pen);
210  gridLines.add (gridLine);
211  }
212 
213  for (double y = startY; y <= stopY; (isLinearY ? y += stepY : y *= stepY)) {
214 
215  GridLine *gridLine = createGridLine (startX, y, stopX, y, transformation);
216  gridLine->setPen (pen);
217  gridLines.add (gridLine);
218  }
219  }
220  }
221 }
void limitForXTheta(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid, double &startX, double &stepX, double &stopX) const
Limit step value for x/theta coordinate. This is a noop if the maximum grid line limit in MainWindowM...
bool stable() const
Get method for stable flag.
QColor ColorPaletteToQColor(ColorPalette color)
Definition: EnumsToQt.cpp:15
void limitForYRadius(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid, double &startY, double &stepY, double &stopY) const
Limit step value for y/range coordinate. This is a noop if the maximum grid line limit in MainWindowM...
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
double stopY() const
Get method for y grid line upper bound (inclusive).
double stopX() const
Get method for x grid line upper bound (inclusive).
ColorPalette paletteColor() const
Get method for color.
double startY() const
Get method for y grid line lower bound (inclusive).
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
void add(GridLine *gridLine)
Add specified grid line. Ownership of all allocated QGraphicsItems is passed to new GridLine.
Definition: GridLines.cpp:19
double stepY() const
Get method for y grid line increment.
const int GRID_LINE_WIDTH
Definition: GridLineStyle.h:6
double startX() const
Get method for x grid line lower bound (inclusive).
void setPen(const QPen &pen)
Set the pen style.
Definition: GridLine.cpp:47
Single grid line drawn a straight or curved line.
Definition: GridLine.h:20
const Qt::PenStyle GRID_LINE_STYLE
Definition: GridLineStyle.h:7
Limit the number of grid lines so a bad combination of start/step/stop value will not lead to extreme...
double stepX() const
Get method for x grid line increment.
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.

The documentation for this class was generated from the following files: