Engauge Digitizer 2
Loading...
Searching...
No Matches
Public Member Functions | Friends | List of all members
SplineDrawer Class Reference

This class takes the output from Spline and uses that to draw the curve in the graphics window, as a sequence of moves and draws. More...

#include <SplineDrawer.h>

Collaboration diagram for SplineDrawer:
Collaboration graph

Public Member Functions

 SplineDrawer (const Transformation &transformation)
 Single constructor.
 
void bindToSpline (const LineStyle &lineStyle, int numSegments, const Spline &spline)
 Analyze each segment in the Spline.
 
bool segmentIsMultiValued (const Spline &spline, int numSegments, int segment) const
 Return true if specified segment is multi-valued, else false.
 
SplineDrawerOperation segmentOperation (int segment) const
 Indicate if, and how, segment is to be drawn.
 

Friends

class TestSplineDrawer
 

Detailed Description

This class takes the output from Spline and uses that to draw the curve in the graphics window, as a sequence of moves and draws.

The moves and draws by themselves would be trivial (move,draw,draw,draw...) but this actually draws, when needed, differently styled curve segments to indicate each curve segment should be CONNECT_AS_FUNCTION_SMOOTH but actually is not single-valued (=not a function)

This class is aware of the Transformation, unlike the Spline class which is decoupled from that for simplicity. Specifically, this class converts the screen coordinates to graph coordinates to check for single-valuedness.

The algorithm used here has to work in cartesian, polar, linear and/or log coordinates. This requirement, along with the goal of keeping the Spline class simple, pretty much requires using the Transformation and working in graph coordinates.

Definition at line 35 of file SplineDrawer.h.

Constructor & Destructor Documentation

◆ SplineDrawer()

SplineDrawer::SplineDrawer ( const Transformation & transformation)

Single constructor.

Definition at line 13 of file SplineDrawer.cpp.

13 :
14 m_transformation (transformation)
15{
16}

Member Function Documentation

◆ bindToSpline()

void SplineDrawer::bindToSpline ( const LineStyle & lineStyle,
int numSegments,
const Spline & spline )

Analyze each segment in the Spline.

Definition at line 18 of file SplineDrawer.cpp.

21{
22 m_segmentOperations.resize (numSegments);
23
24 // Loop through segments to get move/draw choice. We do not need to worry about
25 // applying a move (versus a draw) for the first segment since that first point
26 // is handled by external code
27 for (int segment = 0; segment < numSegments; segment++) {
28
29 bool itsAKeeper = true;
30 if (m_transformation.transformIsDefined()) {
31
32 // We have the graph<->screen transformation so let's use it. Could there be an ambiguity issue?
33 if ((lineStyle.curveConnectAs() == CONNECT_AS_FUNCTION_SMOOTH) &&
36 segment)) {
37 itsAKeeper = false;
38 }
39
40 // Invisible or visible?
41 m_segmentOperations [segment] = (itsAKeeper ?
44 }
45 }
46}
@ CONNECT_AS_FUNCTION_SMOOTH
const int INNER_RADIUS_MIN
@ SPLINE_DRAWER_ENUM_INVISIBLE_MOVE
@ SPLINE_DRAWER_ENUM_VISIBLE_DRAW
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition LineStyle.cpp:63
bool segmentIsMultiValued(const Spline &spline, int numSegments, int segment) const
Return true if specified segment is multi-valued, else false.
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.

◆ segmentIsMultiValued()

bool SplineDrawer::segmentIsMultiValued ( const Spline & spline,
int numSegments,
int segment ) const

Return true if specified segment is multi-valued, else false.

Definition at line 48 of file SplineDrawer.cpp.

51{
52 ENGAUGE_ASSERT (m_transformation.transformIsDefined());
53
54 if (segment < numSegments - 1) {
55
56 // Not at very end
57 double tI = double (segment);
58 double tIp1 = double (segment + 1);
59
60 // Compute number of pixels between endpoints
61 SplinePair posScreenStart = spline.interpolateCoeff (tI);
62 SplinePair posScreenEnd = spline.interpolateCoeff (tIp1);
63
64 int deltaX = qFloor (posScreenEnd.x() - posScreenStart.x());
65 int deltaY = qFloor (posScreenEnd.y() - posScreenStart.y());
67 double numSteps = pixelDistance;
68
69 // Search through a sufficiently large number of points to verify single-valuedness
70 double tIDelta = 1.0 / numSteps;
71 for (int itI = 1; itI < numSteps - 1; itI++) {
72
73 double tIm1 = segment + (itI - 1) * tIDelta;
74 double tI = segment + (itI ) * tIDelta;
75 double tIp1 = segment + (itI + 1) * tIDelta;
76
77 SplinePair spBefore = spline.interpolateCoeff (tIm1);
78 SplinePair spCurrent = spline.interpolateCoeff (tI);
79 SplinePair spAfter = spline.interpolateCoeff (tIp1);
80
84
92
93 // In between the start and end points we look for deltaXBefore>0 and deltaXAfter<0,
94 // or deltaXBefore<0 and deltaXAfter>0, either of those two cases indicates multi-valued
96 double deltaXAfter = posGraphAfter.x() - posGraphCurrent.x();
97
98 if ((deltaXBefore > 0 && deltaXAfter < 0) ||
100
101 // Multi-valued
102 return true;
103 }
104 }
105 }
106
107 return false;
108}
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition SplinePair.h:14
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.

◆ segmentOperation()

SplineDrawerOperation SplineDrawer::segmentOperation ( int segment) const

Indicate if, and how, segment is to be drawn.

Definition at line 110 of file SplineDrawer.cpp.

111{
112 if (segment < m_segmentOperations.count()) {
113 return m_segmentOperations.at (segment);
114 } else {
116 }
117}

Friends And Related Symbol Documentation

◆ TestSplineDrawer

Definition at line 38 of file SplineDrawer.h.


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