1
#ifndef MERKAARTOR_LINEF_
2
#define MERKAARTOR_LINEF_
6
#include <QtCore/QPointF>
10
#define M_PI 3.14159265358979323846
13
#define M_PI_2 1.57079632679489661923
16
inline double distance(const QPointF& A, const QPointF& B)
18
double dx = A.x()-B.x();
19
double dy = A.y()-B.y();
20
return sqrt( dx*dx+dy*dy );
23
inline double length(const QPointF& A)
25
return sqrt(A.x()*A.x()+A.y()*A.y());
28
inline double angle(const QPointF& A, const QPointF& B)
30
double d = A.x()*B.x()+A.y()*B.y();
31
double x = A.x()*B.y()-A.y()*B.x();
32
// numerical stability : in extreme cases the argument of asin gets slightly larger than 1
33
if (fabs(d) < 0.00001)
34
return (x>0)?M_PI_2:-M_PI;
35
x = asin(x/(length(A)*length(B)));
47
inline double angle(const QPointF& A)
49
return atan2(A.y(),A.x());
52
inline QPointF toQt(const Coord& C)
54
return QPointF(C.lat(),C.lon());
57
inline Coord toCoord(const QPointF& F)
59
return Coord(int(F.x()),int(F.y()));
65
LineF(const QPointF& aP1, const QPointF& aP2)
66
: P1(aP1), P2(aP2), Valid(true)
71
LineF(const QPoint& aP1, const QPoint& aP2)
72
: P1(aP1), P2(aP2), Valid(true)
77
LineF(const Coord& aP1, const Coord& aP2)
78
: P1(aP1.lat(),aP1.lon()), P2(aP2.lat(),aP2.lon()), Valid(true)
87
C = -P1.y()*B-P1.x()*A;
88
double F = sqrt(A*A+B*B);
101
C += d*sqrt(A*A+B*B);
104
double distance(const QPointF& P) const
107
return fabs(A*P.x()+B*P.y()+C);
109
return sqrt( (P.x()-P1.x())*(P.x()-P1.x()) + (P.y()-P1.y())*(P.y()-P1.y()) );
112
//double capDistance(const QPointF& P) const
116
// double dx = P2.x()-P1.x();
117
// double dy = P2.y()-P1.y();
118
// double px = P.x()-P1.x();
119
// double py = P.y()-P1.y();
120
// if ( (dx*px+dy*py) < 0)
121
// return ::distance(P,P1);
122
// px = P.x()-P2.x();
123
// py = P.y()-P2.y();
124
// if ( (dx*px+dy*py) > 0)
125
// return ::distance(P,P2);
126
// return fabs(A*P.x()+B*P.y()+C);
129
// return sqrt( (P.x()-A)*(P.x()-A) + (P.y()-B)*(P.y()-B) );
132
double capDistance(const Coord& cd)
134
QPointF P(cd.lat(), cd.lon());
137
double dx = P2.x()-P1.x();
138
double dy = P2.y()-P1.y();
139
double px = P.x()-P1.x();
140
double py = P.y()-P1.y();
141
if ( (dx*px+dy*py) < 0)
142
return ::distance(P,P1);
145
if ( (dx*px+dy*py) > 0)
146
return ::distance(P,P2);
147
return fabs(A*P.x()+B*P.y()+C);
150
return sqrt( (P.x()-A)*(P.x()-A) + (P.y()-B)*(P.y()-B) );
151
//return capDistance(QPointF(P.lat(),P.lon()));
154
Coord project(const Coord& P)
158
double SD = A*P.lat()+B*P.lon()+C;
159
return Coord(int(P.lat()-A*SD),int(P.lon()-B*SD));
161
return Coord(int(P1.x()),int(P1.y()));
163
QPointF project(const QPointF& P)
167
double SD = A*P.x()+B*P.y()+C;
168
return QPointF(P.x()-A*SD,P.y()-B*SD);
172
QPointF project(const QPoint& P)
174
return project(QPointF(P));
177
bool intersectsWith(const CoordBox& C) const
179
QPointF intersection;
180
if ( QLineF(P1, P2).intersect( QLineF( C.topLeft().toPointF(), C.topRight().toPointF() ), &intersection) == QLineF::BoundedIntersection ) return true;
181
if ( QLineF(P1, P2).intersect( QLineF( C.topRight().toPointF(), C.bottomRight().toPointF() ), &intersection) == QLineF::BoundedIntersection ) return true;
182
if ( QLineF(P1, P2).intersect( QLineF( C.bottomRight().toPointF(), C.bottomLeft().toPointF() ), &intersection) == QLineF::BoundedIntersection ) return true;
183
if ( QLineF(P1, P2).intersect( QLineF( C.bottomLeft().toPointF(), C.topLeft().toPointF() ), &intersection) == QLineF::BoundedIntersection ) return true;
187
void intersectionWith(const CoordBox& C, Coord* C1, Coord* C2) const
189
QPointF intersection;
192
if ( QLineF(P1, P2).intersect( QLineF( C.topLeft().toPointF(), C.topRight().toPointF() ), &intersection) == QLineF::BoundedIntersection ) {
196
if ( QLineF(P1, P2).intersect( QLineF( C.topRight().toPointF(), C.bottomRight().toPointF() ), &intersection) == QLineF::BoundedIntersection ) {
205
if ( QLineF(P1, P2).intersect( QLineF( C.bottomRight().toPointF(), C.bottomLeft().toPointF() ), &intersection) == QLineF::BoundedIntersection ) {
214
if ( QLineF(P1, P2).intersect( QLineF( C.bottomLeft().toPointF(), C.topLeft().toPointF() ), &intersection) == QLineF::BoundedIntersection ) {
225
QPointF intersectionWith(const LineF& L)
227
double D = A*L.B - L.A*B;
228
if (fabs(D) < 0.00001)
230
double x = B*L.C - L.B*C;
231
double y = L.A*C - A*L.C;
232
return QPointF(x/D,y/D);
235
bool segmentContains(const QPointF& X)
238
( ((P1.x() <= X.x()) && (X.x() <= P2.x())) ||
239
((P1.x() >= X.x()) && (X.x() >= P2.x())) ) &&
240
( ((P1.y() <= X.y()) && (X.y() <= P2.y())) ||
241
((P1.y() >= X.y()) && (X.y() >= P2.y())) );
254
BezierF(const QPointF& aA, const QPointF& aB, const QPointF& aC, const QPointF& aD)
255
: A(aA), B(aB), C(aC), D(aD)
258
BezierF(const QPoint& aA, const QPoint& aB, const QPoint& aC, const QPoint& aD)
259
: A(aA), B(aB), C(aC), D(aD)
263
BezierF(const Coord& aA, const Coord& aB, const Coord& aC, const Coord& aD)
264
: A(toQt(aA)), B(toQt(aB)), C(toQt(aC)), D(toQt(aD))
268
double distance(const QPointF& T) const
270
double LowestZ = ::distance(A,T);
271
for (qreal t=0;t<1.0125; t+=0.025)
273
QPointF P = A*(1-t)*(1-t)*(1-t) + 3*B*(1-t)*(1-t)*t + 3*C*(1-t)*t*t + D*t*t*t;
274
double z = ::distance(P,T);
281
QPointF project(const QPointF& T) const
283
double LowestZ = ::distance(A,T);
285
for (qreal t=0;t<1.0125; t+=0.025)
287
QPointF P = A*(1-t)*(1-t)*(1-t) + 3*B*(1-t)*(1-t)*t + 3*C*(1-t)*t*t + D*t*t*t;
288
double z = ::distance(P,T);