Engauge Digitizer 2
Loading...
Searching...
No Matches
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)
 GridLineFactory (QGraphicsScene &scene, int pointRadius, const QList< Point > &pointsToIsolate, const DocumentModelCoords &modelCoords)
 Constructor for use by Checker, which has points that are isolated.
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.
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.

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 33 of file GridLineFactory.cpp.

34 :
35 m_scene (scene),
36 m_pointRadius (0.0),
37 m_modelCoords (modelCoords),
38 m_isChecker (false)
39{
40 LOG4CPP_DEBUG_S ((*mainCat)) << "GridLineFactory::GridLineFactory";
41}
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 43 of file GridLineFactory.cpp.

46 :
47 m_scene (scene),
48 m_pointRadius (pointRadius),
49 m_pointsToIsolate (pointsToIsolate),
50 m_modelCoords (modelCoords),
51 m_isChecker (true)
52{
53 LOG4CPP_DEBUG_S ((*mainCat)) << "GridLineFactory::GridLineFactory"
54 << " pointRadius=" << pointRadius
55 << " pointsToIsolate=" << pointsToIsolate.count();
56}

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 71 of file GridLineFactory.cpp.

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

◆ 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 153 of file GridLineFactory.cpp.

158{
159 // At a minimum the transformation must be defined. Also, there is a brief interval between the definition of
160 // the transformation and the initialization of modelGridDisplay (at which point this method gets called again) and
161 // we do not want to create grid lines during that brief interval
162 if (transformation.transformIsDefined() &&
163 modelGridDisplay.stable()) {
164
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 ();
171 unsigned int numX = modelGridDisplay.countX ();
172 unsigned int numY = modelGridDisplay.countY ();
173
174 // Linear or log?
175 bool isLinearX = (m_modelCoords.coordScaleXTheta() == COORD_SCALE_LINEAR);
176 bool isLinearY = (m_modelCoords.coordScaleYRadius() == COORD_SCALE_LINEAR);
177
178 GridLineNormalize normalize (modelMainWindow);
179 normalize.normalize (isLinearX,
180 modelGridDisplay.disableX(),
181 startX,
182 stepX,
183 stopX,
184 numX);
185 normalize.normalize (isLinearY,
186 modelGridDisplay.disableY(),
187 startY,
188 stepY,
189 stopY,
190 numY);
191
192 // Limit the number of grid lines. This is a noop if the limit is not exceeded
193 GridLineLimiter gridLineLimiter;
194 gridLineLimiter.limitForXTheta (document,
195 transformation,
196 m_modelCoords,
197 modelMainWindow,
198 startX,
199 stepX,
200 stopX,
201 numX);
202 gridLineLimiter.limitForYRadius (document,
203 transformation,
204 m_modelCoords,
205 modelMainWindow,
206 startY,
207 stepY,
208 stopY,
209 numY);
210
211 // Apply if possible
212 if (stepX > (isLinearX ? 0 : 1) &&
213 stepY > (isLinearY ? 0 : 1) &&
214 (isLinearX || (startX > 0)) &&
215 (isLinearY || (startY > 0))) {
216
217 QColor color (ColorPaletteToQColor (modelGridDisplay.paletteColor()));
218 QPen pen (QPen (color,
219 modelGridDisplay.lineWidth (),
221
222 for (double x = startX; x <= stopX; (isLinearX ? x += stepX : x *= stepX)) {
223
224 GridLine *gridLine = createGridLine (x, startY, x, stopY, transformation);
225 gridLine->setPen (pen);
226 gridLines.add (gridLine);
227 }
228
229 for (double y = startY; y <= stopY; (isLinearY ? y += stepY : y *= stepY)) {
230
231 GridLine *gridLine = createGridLine (startX, y, stopX, y, transformation);
232 gridLine->setPen (pen);
233 gridLines.add (gridLine);
234 }
235 }
236 }
237}
@ COORD_SCALE_LINEAR
Definition CoordScale.h:13
QColor ColorPaletteToQColor(ColorPalette color)
Definition EnumsToQt.cpp:16
const Qt::PenStyle GRID_LINE_STYLE
GridCoordDisable disableY() const
Get method for y grid line disabled variable.
unsigned int countX() const
Get method for x grid line count.
double startX() const
Get method for x grid line lower bound (inclusive).
GridCoordDisable disableX() const
Get method for x grid line disabled variable.
unsigned int countY() const
Get method for y grid line count.
double stepX() const
Get method for x grid line increment.
double stopX() const
Get method for x grid line upper bound (inclusive).
double stopY() const
Get method for y grid line upper bound (inclusive).
bool stable() const
Get method for stable flag.
ColorPalette paletteColor() const
Get method for color.
double stepY() const
Get method for y grid line increment.
double startY() const
Get method for y grid line lower bound (inclusive).
unsigned int lineWidth() const
Get method for line width.
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 limitForYRadius(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, double &startY, double &stepY, double &stopY, unsigned int numY) const
Limit step value for y/range coordinate. This is a noop if the maximum grid line limit in MainWindowM...
void limitForXTheta(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, double &startX, double &stepX, double &stopX, unsigned int numX) const
Limit step value for x/theta coordinate. This is a noop if the maximum grid line limit in MainWindowM...
void setPen(const QPen &pen)
Set the pen style.
Definition GridLine.cpp:50
void add(GridLine *gridLine)
Add specified grid line. Ownership of all allocated QGraphicsItems is passed to new GridLine.
Definition GridLines.cpp:19
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
QPointF normalize(const QPointF &vec)
Return normalized vector.
Definition mmsubs.cpp:198

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