Engauge Digitizer 2
Loading...
Searching...
No Matches
GuidelineProjectorConstantX.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2019 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 <algorithm>
9#include <QList>
10#include <QRectF>
11#include "Transformation.h"
12
16
20
21void GuidelineProjectorConstantX::addSide (const Transformation &transformation,
22 double x,
23 const QPointF &p1,
24 const QPointF &p2,
25 QList<QPointF> &intersections)
26{
27 // We start with the vector equation
28 // R = (1-s)*P1 + s*P2
29 // For each corner, intersect just the y components of the vector equation
30 // x = (1-s)*x1 + s*x2
31 // x = x0
32 // to get an s value. To prevent overflow due to division by zero, we use the
33 // trick that only values of s between 0 and 1 (=between the 2 endpoints) are
34 // desired
35 double num = x - p1.x();
36 double den = p2.x () - p1.x ();
37
38 // Prevent divide by zero. Working with s=num/den and 0<s<1 we get 0<num/den<1.
39 // Inequalities have to be flipped if multiplying by a negative number
40 bool okForDenPositive = (den >= 0) && (0.0 * den <= num) && (num < den);
41 bool okForDenNegative = (den < 0) && (0.0 * den >= num) && (num > 1.0 * den);
42
43 if (okForDenPositive || okForDenNegative) {
44 double sIntercept = num / den;
45 QPointF pIntercept ((1.0 - sIntercept) * p1 + sIntercept * p2);
46
47 QPointF posScreen;
48 transformation.transformRawGraphToScreen (pIntercept,
49 posScreen);
50 intersections.push_back (posScreen);
51 }
52}
53
55 const QRectF &sceneRect,
56 double xGraph)
57{
58 QLineF line (0, 0, 0, 0);
59 QPointF posGraphBL, posGraphTL, posGraphTR, posGraphBR;
60 calculateCorners (transformation,
61 sceneRect,
62 posGraphBL,
63 posGraphTL,
64 posGraphTR,
65 posGraphBR);
66
67 // Intersections found on all the sides
68 QList<QPointF> intersections;
69
70 addSide (transformation, xGraph, posGraphBL, posGraphTL, intersections);
71 addSide (transformation, xGraph, posGraphTL, posGraphTR, intersections);
72 addSide (transformation, xGraph, posGraphTR, posGraphBR, intersections);
73 addSide (transformation, xGraph, posGraphBR, posGraphBL, intersections);
74
75 if (intersections.size() == 2) {
76 line = QLineF (intersections.at (0),
77 intersections.at (1));
78 }
79
80 return line;
81}
82
84 const QRectF &sceneRect,
85 const QPointF &posScreen)
86{
87 QPointF posGraph;
88 transformation.transformScreenToRawGraph (posScreen, posGraph);
89
90 return fromCoordinateX (transformation,
91 sceneRect,
92 posGraph.x());
93}
void calculateCorners(const Transformation &transformation, const QRectF &sceneRect, QPointF &posGraphBL, QPointF &posGraphTL, QPointF &posGraphTR, QPointF &posGraphBR) const
Conpute four corners of scene in graph coordinates.
QLineF fromCoordinateX(const Transformation &transformation, const QRectF &sceneRect, double xGraph)
Return line through x in graph coordinates.
QLineF fromPosScreen(const Transformation &transformation, const QRectF &sceneRect, const QPointF &posScreen)
Return line through point in screen coordinates.
Affine transformation between screen and graph coordinates, based on digitized axis points.
void transformRawGraphToScreen(const QPointF &pointRaw, QPointF &pointScreen) const
Transform from raw graph coordinates to linear cartesian graph coordinates, then to screen coordinate...
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.