Engauge Digitizer  2
CallbackPointOrdinal.cpp
1 /******************************************************************************************************
2  * (C) 2014 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 "CallbackPointOrdinal.h"
8 #include "EngaugeAssert.h"
9 #include "Logger.h"
10 #include "mmsubs.h"
11 #include "Point.h"
12 #include <qmath.h>
13 #include "Transformation.h"
14 
16  const Transformation &transformation,
17  const QPointF &posScreen) :
18  m_lineStyle (lineStyle),
19  m_transformation (transformation),
20  m_posScreen (posScreen),
21  m_haveMinimumDistanceToLine (false),
22  m_minimumDistanceToLine (0.0),
23  m_minimumProjectedDistanceOutsideLine (0.0),
24  m_ordinal (0)
25 {
26 }
27 
28 CallbackSearchReturn CallbackPointOrdinal::callback (const Point &pointStart,
29  const Point &pointStop)
30 {
31  double xProjection, yProjection, projectedDistanceOutsideLine, distanceToLine;
32 
33  projectPointOntoLine(m_posScreen.x(),
34  m_posScreen.y(),
35  pointStart.posScreen().x(),
36  pointStart.posScreen().y(),
37  pointStop.posScreen().x(),
38  pointStop.posScreen().y(),
39  &xProjection,
40  &yProjection,
41  &projectedDistanceOutsideLine,
42  &distanceToLine);
43 
44  // Compare to best so far
45  if (!m_haveMinimumDistanceToLine ||
46  (distanceToLine < m_minimumDistanceToLine) ||
47  (distanceToLine == m_minimumDistanceToLine && projectedDistanceOutsideLine < m_minimumProjectedDistanceOutsideLine)) {
48 
49  // Compute ordinal
50  if (projectedDistanceOutsideLine == 0) {
51 
52  // Put new point inside the line segment
53  m_ordinal = (pointStart.ordinal() + pointStop.ordinal()) / 2.0;
54 
55  } else {
56 
57  // Put new point just outside the line segment
58  double distanceProjectionToStart = qSqrt ((xProjection - pointStart.posScreen().x()) * (xProjection - pointStart.posScreen().x()) +
59  (yProjection - pointStart.posScreen().y()) * (yProjection - pointStart.posScreen().y()));
60  double distanceProjectionToStop = qSqrt ((xProjection - pointStop.posScreen().x()) * (xProjection - pointStop.posScreen().x()) +
61  (yProjection - pointStop.posScreen().y()) * (yProjection - pointStop.posScreen().y()));
62  if (distanceProjectionToStart < distanceProjectionToStop) {
63 
64  // Before start point
65  m_ordinal = pointStart.ordinal() - 0.5;
66 
67  } else {
68 
69  // After stop point
70  m_ordinal = pointStop.ordinal() + 0.5;
71  }
72  }
73 
74  // Save as new 'best'
75  m_haveMinimumDistanceToLine = true;
76  m_minimumDistanceToLine = distanceToLine;
77  m_minimumProjectedDistanceOutsideLine = projectedDistanceOutsideLine;
78  }
79 
80  return CALLBACK_SEARCH_RETURN_CONTINUE;
81 }
82 
84 {
85  return m_ordinal;
86 }
CallbackSearchReturn callback(const Point &pointStart, const Point &pointStop)
Callback method.
CallbackPointOrdinal(const LineStyle &lineStyle, const Transformation &transformation, const QPointF &posScreen)
Single constructor.
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:23
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:392
double ordinal(ApplyHasCheck applyHasCheck=KEEP_HAS_CHECK) const
Get method for ordinal. Skip check if copying one instance to another.
Definition: Point.cpp:374
Affine transformation between screen and graph coordinates, based on digitized axis points...
Details for a specific Line.
Definition: LineStyle.h:19
double ordinal() const
Computed ordinal.