Engauge Digitizer
2
Toggle main menu visibility
Loading...
Searching...
No Matches
Spline
SplineDrawer.cpp
Go to the documentation of this file.
1
/******************************************************************************************************
2
* (C) 2018 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3
* under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4
* LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5
******************************************************************************************************/
6
7
#include "
EngaugeAssert.h
"
8
#include "
LineStyle.h
"
9
#include <qmath.h>
10
#include "
Spline.h
"
11
#include "
SplineDrawer.h
"
12
13
SplineDrawer::SplineDrawer
(
const
Transformation
&transformation) :
14
m_transformation (transformation)
15
{
16
}
17
18
void
SplineDrawer::bindToSpline
(
const
LineStyle
&lineStyle,
19
int
numSegments,
20
const
Spline
&spline)
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
) &&
34
segmentIsMultiValued
(spline,
35
numSegments,
36
segment)) {
37
itsAKeeper =
false
;
38
}
39
40
// Invisible or visible?
41
m_segmentOperations [segment] = (itsAKeeper ?
42
SPLINE_DRAWER_ENUM_VISIBLE_DRAW
:
43
SPLINE_DRAWER_ENUM_INVISIBLE_MOVE
);
44
}
45
}
46
}
47
48
bool
SplineDrawer::segmentIsMultiValued
(
const
Spline
&spline,
49
int
numSegments,
50
int
segment)
const
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
());
66
double
pixelDistance = qSqrt (deltaX * deltaX + deltaY * deltaY);
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
81
QPointF posScreenBefore (spBefore.x(), spBefore.y());
82
QPointF posScreenCurrent (spCurrent.
x
(), spCurrent.
y
());
83
QPointF posScreenAfter (spAfter.
x
(), spAfter.
y
());
84
85
QPointF posGraphBefore, posGraphCurrent, posGraphAfter;
86
m_transformation.transformScreenToRawGraph (posScreenBefore,
87
posGraphBefore);
88
m_transformation.transformScreenToRawGraph (posScreenCurrent,
89
posGraphCurrent);
90
m_transformation.transformScreenToRawGraph (posScreenAfter,
91
posGraphAfter);
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
95
double
deltaXBefore = posGraphCurrent.x() - posGraphBefore.x();
96
double
deltaXAfter = posGraphAfter.x() - posGraphCurrent.x();
97
98
if
((deltaXBefore > 0 && deltaXAfter < 0) ||
99
(deltaXBefore < 0 && deltaXAfter > 0)) {
100
101
// Multi-valued
102
return
true
;
103
}
104
}
105
}
106
107
return
false
;
108
}
109
110
SplineDrawerOperation
SplineDrawer::segmentOperation
(
int
segment)
const
111
{
112
if
(segment < m_segmentOperations.count()) {
113
return
m_segmentOperations.at (segment);
114
}
else
{
115
return
SPLINE_DRAWER_ENUM_INVISIBLE_MOVE
;
116
}
117
}
CONNECT_AS_FUNCTION_SMOOTH
@ CONNECT_AS_FUNCTION_SMOOTH
Definition
CurveConnectAs.h:13
EngaugeAssert.h
ENGAUGE_ASSERT
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT.
Definition
EngaugeAssert.h:17
LineStyle.h
SplineDrawer.h
SplineDrawerOperation
SplineDrawerOperation
Definition
SplineDrawer.h:17
SPLINE_DRAWER_ENUM_INVISIBLE_MOVE
@ SPLINE_DRAWER_ENUM_INVISIBLE_MOVE
Definition
SplineDrawer.h:18
SPLINE_DRAWER_ENUM_VISIBLE_DRAW
@ SPLINE_DRAWER_ENUM_VISIBLE_DRAW
Definition
SplineDrawer.h:19
Spline.h
LineStyle
Details for a specific Line.
Definition
LineStyle.h:20
LineStyle::curveConnectAs
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition
LineStyle.cpp:63
SplineDrawer::bindToSpline
void bindToSpline(const LineStyle &lineStyle, int numSegments, const Spline &spline)
Analyze each segment in the Spline.
Definition
SplineDrawer.cpp:18
SplineDrawer::SplineDrawer
SplineDrawer(const Transformation &transformation)
Single constructor.
Definition
SplineDrawer.cpp:13
SplineDrawer::segmentOperation
SplineDrawerOperation segmentOperation(int segment) const
Indicate if, and how, segment is to be drawn.
Definition
SplineDrawer.cpp:110
SplineDrawer::segmentIsMultiValued
bool segmentIsMultiValued(const Spline &spline, int numSegments, int segment) const
Return true if specified segment is multi-valued, else false.
Definition
SplineDrawer.cpp:48
SplinePair
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition
SplinePair.h:15
SplinePair::y
double y() const
Get method for y.
Definition
SplinePair.cpp:96
SplinePair::x
double x() const
Get method for x.
Definition
SplinePair.cpp:91
Spline
Cubic interpolation given independent and dependent value vectors.
Definition
Spline.h:30
Spline::interpolateCoeff
SplinePair interpolateCoeff(double t) const
Return interpolated y for specified x.
Definition
Spline.cpp:233
Transformation
Affine transformation between screen and graph coordinates, based on digitized axis points.
Definition
Transformation.h:32
Generated on
for Engauge Digitizer by
1.17.0