# Kstars

houghline.cpp
1/*
2 SPDX-FileCopyrightText: 2019 Patrick Molenaar <pr_molenaar@hotmail.com>
3
5*/
6
7#include "houghline.h"
8
9#include <qmath.h>
10#include <QVector>
11#include <fits_debug.h>
12
13/**
14 * Initialises the hough line
15 */
16HoughLine::HoughLine(double theta, double r, int width, int height, int score)
17 : QLineF()
18{
19 this->theta = theta;
20 this->r = r;
21 this->score = score;
22
23 setP1(RotatePoint(0, r, theta, width, height));
24 setP2(RotatePoint(width - 1, r, theta, width, height));
25}
26
27QPointF HoughLine::RotatePoint(int x1, double r, double theta, int width, int height)
28{
29 int hx, hy;
30
31 hx = qFloor((width + 1) / 2.0);
32 hy = qFloor((height + 1) / 2.0);
33
34 double sinAngle = qSin(-theta);
35 double cosAngle = qCos(-theta);
36
37 // translate point back to origin:
38 double x2 = x1 - hx;
39 double y2 = r - hy;
40
41 // rotate point
42 double xnew = x2 * cosAngle - y2 * sinAngle;
43 double ynew = x2 * sinAngle + y2 * cosAngle;
44
45 // translate point back:
46 x2 = xnew + hx;
47 y2 = ynew + hy;
48
49 return QPointF(x2, y2);
50}
51
52int HoughLine::getScore() const
53{
54 return score;
55}
56
57double HoughLine::getR() const
58{
59 return r;
60}
61
62double HoughLine::getTheta() const
63{
64 return theta;
65}
66
67void HoughLine::setTheta(const double theta)
68{
69 this->theta = theta;
70}
71
72bool HoughLine::compareByScore(const HoughLine *line1,const HoughLine *line2)
73{
74 return (line1->getScore() < line2->getScore());
75}
76
77bool HoughLine::compareByTheta(const HoughLine *line1,const HoughLine *line2)
78{
79 return (line1->getTheta() < line2->getTheta());
80}
81
82void HoughLine::printHoughLine()
83{
84 qCDebug(KSTARS_FITS) << "Houghline: [score: " << score << ", r: " << r << ", theta: " << theta << " [rad]="
85 << (theta * 180.0 / M_PI) << " [deg], p1: " << p1().x() << ", " << p1().y() << ", p2: "
86 << p2().x() << ", " << p2().y() << "]";
87}
88
89/**
90 * Sources for intersection and distance calculations came from
91 * http://paulbourke.net/geometry/pointlineplane/
92 * Also check https://doc.qt.io/archives/qt-4.8/qlinef.html for more line methods
93 */
94HoughLine::IntersectResult HoughLine::Intersect(const HoughLine& other_line, QPointF& intersection)
95{
96 double denom = ((other_line.p2().y() - other_line.p1().y()) * (p2().x() - p1().x())) -
97 ((other_line.p2().x() - other_line.p1().x()) * (p2().y() - p1().y()));
98
99 double nume_a = ((other_line.p2().x() - other_line.p1().x()) * (p1().y() - other_line.p1().y())) -
100 ((other_line.p2().y() - other_line.p1().y()) * (p1().x() - other_line.p1().x()));
101
102 double nume_b = ((p2().x() - p1().x()) * (p1().y() - other_line.p1().y())) -
103 ((p2().y() - p1().y()) * (p1().x() - other_line.p1().x()));
104
105 if (denom == 0.0f)
106 {
107 if(nume_a == 0.0f && nume_b == 0.0f)
108 {
109 return COINCIDENT;
110 }
111 return PARALLEL;
112 }
113
114 double ua = nume_a / denom;
115 double ub = nume_b / denom;
116
117 if(ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f)
118 {
119 // Get the intersection point.
120 intersection.setX(qreal(p1().x() + ua * (p2().x() - p1().x())));
121 intersection.setY(qreal(p1().y() + ua * (p2().y() - p1().y())));
122 return INTERESECTING;
123 }
124
125 return NOT_INTERESECTING;
126}
127
128double HoughLine::Magnitude(const QPointF& point1, const QPointF& point2)
129{
130 QPointF vector = point2 - point1;
131 return qSqrt(vector.x() * vector.x() + vector.y() * vector.y());
132}
133
134bool HoughLine::DistancePointLine(const QPointF& point, QPointF& intersection, double& distance)
135{
136 double lineMag = length();
137
138 double U = qreal((((point.x() - p1().x()) * (p2().x() - p1().x())) +
139 ((point.y() - p1().y()) * (p2().y() - p1().y()))) /
140 (lineMag * lineMag));
141
142 if (U < 0.0 || U > 1.0) {
143 return false; // closest point does not fall within the line segment
144 }
145
146 intersection.setX(p1().x() + U * (p2().x() - p1().x()));
147 intersection.setY(p1().y() + U * (p2().y() - p1().y()));
148
149 distance = Magnitude(point, intersection);
150
151 return true;
152}
153
154void HoughLine::Offset(const int offsetX, const int offsetY)
155{
156 setP1(QPointF(p1().x() + offsetX, p1().y() + offsetY));
157 setP2(QPointF(p2().x() + offsetX, p2().y() + offsetY));
158}
159
160void HoughLine::getSortedTopThreeLines(QVector<HoughLine*> &houghLines, QVector<HoughLine*> &top3Lines)
161{
162 // Sort houghLines by score (highest scores are clearest lines)
163 // For use of sort compare methods see: https://www.off-soft.net/en/develop/qt/qtb1.html
164 std::sort(houghLines.begin(), houghLines.end(), HoughLine::compareByScore);
165
166 // Get top three lines (these should represent the three lines matching the bahtinov mask lines
167 top3Lines = houghLines.mid(0, 3);
168 // Verify the angle of these lines with regard to the bahtinov mask angle, correct the angle if necessary
172 double thetaR = lineR->getTheta();
173 double thetaG = lineG->getTheta();
174 double thetaB = lineB->getTheta();
175 // Calculate angle between each line
177 double dGR = thetaR - thetaG;
178 double dBG = thetaB - thetaG;
179 double dBR = thetaB - thetaR;
181 // lineR has theta that is 180 degrees rotated
182 thetaR -= M_PI;
183 // update theta
184 lineR->setTheta(thetaR);
185 }
187 // lineB has theta that is 180 degrees rotated
188 thetaB -= M_PI;
189 // update theta
190 lineB->setTheta(thetaB);
191 }
193 // lineG has theta that is 180 degrees rotated
194 thetaG -= M_PI;
195 // update theta
196 lineG->setTheta(thetaG);
197 }
198 // Now sort top3lines array according to calculated new angles
199 std::sort(top3Lines.begin(),top3Lines.end(), HoughLine::compareByTheta);
200}
Line representation for HoughTransform Based on the java implementation found on http://vase....
Definition houghline.h:23
IntersectResult Intersect(const HoughLine &other_line, QPointF &intersection)
Sources for intersection and distance calculations came from http://paulbourke.net/geometry/pointline...
Definition houghline.cpp:94
HoughLine(double theta, double r, int width, int height, int score)
Initialises the hough line.
Definition houghline.cpp:16
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
qreal length() const const
QPointF p1() const const
QPointF p2() const const
void setP1(const QPointF &p1)
void setP2(const QPointF &p2)
qreal x1() const const
qreal x2() const const
qreal y2() const const
void setX(qreal x)
void setY(qreal y)
qreal x() const const
qreal y() const const
This file is part of the KDE documentation.