-
Notifications
You must be signed in to change notification settings - Fork 2
/
arcitem.cpp
120 lines (94 loc) · 2.97 KB
/
arcitem.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "arcitem.h"
ArcItem::ArcItem(double sx1, double sy1, double ex1, double ey1, double centx1, double centy1, bool cw1, int index1)
: ItemToBase(index1), sx(sx1), sy(sy1), ex(ex1), ey(ey1), centx(centx1), centy(centy1), cw(cw1), radius(0), angleStart(0), angleDelta(0)
{
}
PosItem ArcItem::computeExtents()
{
PosItem extents(sx, sy, ex, ey);
radius = qSqrt(((sx - centx) * (sx - centx)) + ((sy - centy) * (sy - centy)));
if (cw)
{
double angle1 = qAtan2(ey - centy, ex - centx);
double angle2 = qAtan2(sy - centy, sx - centx);
if (angle1 > 0 && angle2 < 0)
angle2 += TWO_PI;
angleStart = angle2;
angleDelta = angle1 - angle2;
}
else
{
double angle1 = qAtan2(sy - centy, sx - centx);
double angle2 = qAtan2(ey - centy, ex - centx);
if (angle1 > 0 && angle2 < 0)
angle2 += TWO_PI;
angleStart = angle2;
angleDelta = angle1 - angle2;
}
// sample points along the curve
double angleEnd = angleStart + angleDelta;
for (double angle = angleStart;
(angleDelta < 0 ? angle > angleEnd : angle < angleEnd);
angle += (angleDelta < 0 ? -0.4 : 0.4))
{
double x = qCos(angle) * radius + centx;
double y = qSin(angle) * radius + centy;
PosItem curr(x, y, x, y);
// expand rectange if it exceeds our last rectangle
extents.expand(curr);
}
return extents;
}
void ArcItem::addToPath(QPainterPath& path)
{
// need to convert our coordinates into arcTo arguments (rectangle boxes and angles, etc.)
// Also, we are at this point in screen coordinates, not machine coordinates, i.e. Y positive is down!
// first, we know for a fact that we are dealing with a circular arc, not an ellipse
// (code could be put here to verify that is true)
// Thus our radius is also our bounding box determined from the center of the arc/circle
if (cw)
{
path.moveTo(screenX(sx), screenY(sy));
}
else
{
path.moveTo(screenX(ex), screenY(ey));
}
double x = centx - radius;
double y = centy + radius;
double wd = radius * 2;
double ht = wd;
double fx = screenX(x);
double fy = screenY(y);
double w = wd * scale;
double h = ht * scale;
double angleStartDeg = toDegrees(angleStart);
double angleDeltaDeg = toDegrees(angleDelta);
path.arcTo(fx, fy, w, h, angleStartDeg, angleDeltaDeg);
path.moveTo(screenX(ex), screenY(ey));
}
void ArcItem::moveToFirst(QPainterPath& path)
{
// not applicable! generate error!
Q_UNUSED(path);
}
double ArcItem::getXScr()
{
return screenX(ex);
}
double ArcItem::getYScr()
{
return screenY(ey);
}
double ArcItem::getXRaw()
{
return ex;
}
double ArcItem::getYRaw()
{
return ey;
}
double ArcItem::toDegrees(double rad)
{
return 360 * rad / TWO_PI;
}