-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbiaswidget.cpp
362 lines (294 loc) · 13.2 KB
/
biaswidget.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
#include "biaswidget.h"
#include <QLineF>
#include <QDebug>
#include "fontsize.h" // using only the linearTransform function
#include <QPainterPath>
BiasWidget::BiasWidget(QWidget *parent, int _frameWidth, int _frameHeight) : QWidget(parent)
{
frameWidth = _frameWidth;
frameHeight = _frameHeight;
// pen used to create background arrows (not the ones created by real bias)
int penWidth = 4;
backgroundArrowPen = new QPen();
backgroundArrowPen->setStyle(Qt::SolidLine); // tried using DashedLine here instead but it doesnt fill up 100% at the end
backgroundArrowPen->setWidth(penWidth);
backgroundArrowPen->setBrush(Qt::darkGray);
// set fontSize
fontSize = frameWidth / 18;
// We need to pad the points on the frame to allow rendering of text after an arrow
double spacing = fontSize * 2;
// Points on the frame that correspond to where the different arrow should point
middle = QPointF(frameWidth/2, frameHeight/2); // middle point
up = QPointF(frameWidth/2, spacing); // top middle
east = QPointF(frameWidth - spacing, frameHeight / 3); // right upper
south = QPointF(frameWidth - spacing, (frameHeight * 2) / 3); // right lower
down = QPointF(frameWidth/2, frameHeight - spacing); // bottom middle
west = QPointF(spacing, (frameHeight * 2) / 3); // left lower
north = QPointF(spacing, frameHeight / 3); // left upper
// class used store all the background arrow lines
backgroundArrowLines = new ArrowLines();
// Creates the actual lines and store them in the class
backgroundArrowLines->up = QLineF(middle, up);
backgroundArrowLines->east = QLineF(middle, east);
backgroundArrowLines->south = QLineF(middle,south);
backgroundArrowLines->down = QLineF(middle, down);
backgroundArrowLines->west = QLineF(middle, west);
backgroundArrowLines->north = QLineF(middle, north);
// class used to store all the real bias arrow lines
biasArrowLines = new ArrowLines();
biasArrowLines->up = QLineF(middle, up);
biasArrowLines->east = QLineF(middle, east);
biasArrowLines->south = QLineF(middle,south);
biasArrowLines->down = QLineF(middle, down);
biasArrowLines->west = QLineF(middle, west);
biasArrowLines->north = QLineF(middle, north);
// create a copy
biasArrowLinesOriginal = new ArrowLines();
biasArrowLinesOriginal->up = QLineF(middle, up);
biasArrowLinesOriginal->east = QLineF(middle, east);
biasArrowLinesOriginal->south = QLineF(middle,south);
biasArrowLinesOriginal->down = QLineF(middle, down);
biasArrowLinesOriginal->west = QLineF(middle, west);
biasArrowLinesOriginal->north = QLineF(middle, north);
// calculate the length of bias arrows
arrowLengthDown = middle.y() - down.y();
arrowLengthNorth = sqrt(pow(middle.x() - north.x(), 2) + pow(north.y() - middle.y(), 2));
arrowLengthEast = arrowLengthNorth;
// set default length to zero
biasArrowLines->up.setLength(0);
biasArrowLines->east.setLength(0);
biasArrowLines->south.setLength(0);
biasArrowLines->down.setLength(0);
biasArrowLines->west.setLength(0);
biasArrowLines->north.setLength(0);
// create the different pens used with real bias arrows
biasArrowPenNorth = new QPen();
biasArrowPenNorth->setWidth(penWidth);
biasArrowPenNorth->setBrush(Qt::red);
biasArrowPenEast = new QPen();
biasArrowPenEast->setWidth(penWidth);
biasArrowPenEast->setBrush(Qt::yellow);
biasArrowPenDown = new QPen();
biasArrowPenDown->setWidth(penWidth);
biasArrowPenDown->setBrush(Qt::green);
}
/// Draws the entire widget, is called every time component updates
/// @param QPaintEvent * event Check QPainter spec
void BiasWidget::paintEvent(QPaintEvent * ) {
QPainter painter( this );
// sets the window and viewport to be the same size as parent
painter.setWindow(QRect(0, 0, frameWidth, frameHeight));
painter.setViewport(0, 0, frameWidth, frameHeight);
// Activate anti aliasing to improve rendering
painter.setRenderHint(QPainter::Antialiasing, true);
// draw all the background arrows
drawBackgroundArrows(&painter);
// draw the arrow letters
drawBiasArrowLetters(&painter);
// update length of real bias arrows:
// testing func: updateBias(-359,200,-50);
// draw all the real bias arrows
drawBiasArrows(&painter);
}
/// Draws all the background arrows
/// @param * painter The QPainter object created in paintEvent
void BiasWidget::drawBackgroundArrows(QPainter *painter) {
painter->setPen(*backgroundArrowPen);
painter->drawLine(backgroundArrowLines->up);
painter->drawLine(backgroundArrowLines->east);
painter->drawLine(backgroundArrowLines->south);
painter->drawLine(backgroundArrowLines->down);
painter->drawLine(backgroundArrowLines->west);
painter->drawLine(backgroundArrowLines->north);
drawArrowHead(painter, backgroundArrowLines->up, backgroundArrowPen->brush());
drawArrowHead(painter, backgroundArrowLines->east, backgroundArrowPen->brush());
drawArrowHead(painter, backgroundArrowLines->south, backgroundArrowPen->brush());
drawArrowHead(painter, backgroundArrowLines->down, backgroundArrowPen->brush());
drawArrowHead(painter, backgroundArrowLines->west, backgroundArrowPen->brush());
drawArrowHead(painter, backgroundArrowLines->north, backgroundArrowPen->brush());
}
/// Draws all the real bias arrows
/// @param * painter The QPainter object created in paintEvent
void BiasWidget::drawBiasArrows(QPainter *painter) {
// we set new pens on every axis because they should have different colors
painter->setPen(*biasArrowPenNorth);
// We need to extract the brush because somehow it is not avaible to extract from painter for some reason
QBrush brush = biasArrowPenNorth->brush();
// We must only draw the lines if their length is above zero. If we try to draw them with 0 length they will create a dot instead of nothing
if (biasArrowLines->north.length() > 0) {
painter->drawLine(biasArrowLines->north);
drawArrowHead(painter, biasArrowLines->north, brush);
}
if (biasArrowLines->south.length() > 0) {
painter->drawLine(biasArrowLines->south);
drawArrowHead(painter, biasArrowLines->south, brush);
}
painter->setPen(*biasArrowPenEast);
brush = biasArrowPenEast->brush();
if (biasArrowLines->west.length() > 0) {
painter->drawLine(biasArrowLines->west);
drawArrowHead(painter, biasArrowLines->west, brush);
}
if (biasArrowLines->east.length() > 0) {
painter->drawLine(biasArrowLines->east);
drawArrowHead(painter, biasArrowLines->east, brush);
}
painter->setPen(*biasArrowPenDown);
brush = biasArrowPenDown->brush();
if (biasArrowLines->up.length() > 0) {
painter->drawLine(biasArrowLines->up);
drawArrowHead(painter, biasArrowLines->up, brush);
}
if (biasArrowLines->down.length() > 0) {
painter->drawLine(biasArrowLines->down);
drawArrowHead(painter, biasArrowLines->down, brush);
}
}
/// @brief Draws an arrowhead on the end of the given line
/// @param painter is the painter given in paintEvent
/// @param line is the line to draw an arrow on top of
/// @param brush is the brush that will be used to draw the triangle
void BiasWidget::drawArrowHead(QPainter *painter, QLineF line, QBrush brush) {
/*
* 1. get the three points of the triangle polygon with correct position and angle
* 2. draw a the polygon path
* 3. draw and fill the path
*/
// make a copy of the line and invert it so that the starting point is now at the end point
QLineF *bottomLine = new QLineF(line.p2(), line.p1());
// set the size of the arrow
qreal arrowSize = fontSize / 2;
// extend the original line to get the top arrow point
line.setLength(line.length() + arrowSize);
QPointF newP3 = line.p2();
// shorten the length
bottomLine->setLength(arrowSize);
// rotate the line to be perpendicular
bottomLine->setAngle(bottomLine->angle() - 90);
// record the new p1 point
QPointF newP1 = bottomLine->p2();
//rotate it 180 degrees to mirror it
bottomLine->setAngle(bottomLine->angle() + 180);
// record the new p2 point
QPointF newP2 = bottomLine->p2();
// create a path for the triangle
QPainterPath path;
path.moveTo(newP1);
path.lineTo(newP2);
path.lineTo(newP3);
path.lineTo(newP1);
// finally paint the triangle
painter->fillPath(path, brush);
}
void BiasWidget::drawBiasArrowLetters(QPainter *painter) {
QString n = "N";
QString e = "E";
QString d = "D";
QString s = "S";
QString w = "W";
QString u = "U";
QPointF n_p = north;
QPointF e_p = east;
QPointF d_p = down;
QPointF s_p = south;
QPointF w_p = west;
QPointF u_p = up; // hue hue
// adjust the points to better place the letters
double spacing = frameWidth / 20; // random reference point
n_p.setX( n_p.x() - spacing * 1.4);
s_p.setX( s_p.x() + spacing * 0.6 );
s_p.setY( s_p.y() + spacing * 0.7);
e_p.setX( e_p.x() + spacing * 0.6 );
e_p.setY( e_p.y() + spacing * 0.2 );
w_p.setX( w_p.x() - spacing * 1.6 );
w_p.setY( w_p.y() + spacing * 0.8 );
u_p.setX( u_p.x() - spacing * 0.35 );
u_p.setY( u_p.y() - spacing * 0.8 );
d_p.setX( d_p.x() - spacing * 0.35 );
d_p.setY( d_p.y() + spacing * 1.6 );
// set the font size
QFont font = painter->font();
font.setPixelSize(fontSize);
painter->setFont(font);
// Finally draw the text
painter->drawText(n_p, n);
painter->drawText(s_p, s);
painter->drawText(e_p, e);
painter->drawText(w_p, w);
painter->drawText(u_p, u);
painter->drawText(d_p, d);
}
/// Updates the length of the bias arrows
/// @param double _north => the bias gotten from controller - [-400,400]
/// @param double _east => [-400,400]
/// @param double _down => [-200,200]
void BiasWidget::updateBias(double _north, double _east, double _down) {
qDebug() << "Updating bias with " << _north << _east << _down;
// update _north and south axis:
if(_north > 0) {
// set south length to 0
biasArrowLines->south.setLength(0);
// transform from [0,400] to [0, maxArrowLength]
double newLength = FontSize::linearTransform(_north, 0, 400, 0, arrowLengthNorth);
// here we have to make a copy of the original line because somehow setLength doesnt work when length is set to zero
biasArrowLines->north = biasArrowLinesOriginal->north;
// set the new length
biasArrowLines->north.setLength(newLength);
qDebug() << newLength << biasArrowLines->north.length();
} else if (_north < 0) {
// set _north length to 0
biasArrowLines->north.setLength(0);
double newLength = FontSize::linearTransform(abs(_north), 0, 400, 0, arrowLengthNorth);
biasArrowLines->south = biasArrowLinesOriginal->south;
biasArrowLines->south.setLength(newLength);
} else {
// set both to zero
biasArrowLines->north.setLength(0);
biasArrowLines->south.setLength(0);
}
// east and west axis
if (_east > 0) {
biasArrowLines->west.setLength(0);
double newLength = FontSize::linearTransform(_east, 0, 400, 0, arrowLengthEast);
biasArrowLines->east = biasArrowLinesOriginal->east;
biasArrowLines->east.setLength(newLength);
} else if (_east < 0) {
biasArrowLines->east.setLength(0);
double newLength = FontSize::linearTransform(abs(_east), 0, 400, 0, arrowLengthEast);
biasArrowLines->west = biasArrowLinesOriginal->west;
biasArrowLines->west.setLength(newLength);
} else {
biasArrowLines->east.setLength(0);
biasArrowLines->west.setLength(0);
}
// up and down axis
qDebug() << "Down " << _down;
if (_down > 0) {
biasArrowLines->down.setLength(0);
double newLength = FontSize::linearTransform(abs(_down), 0, 200, 0, arrowLengthDown);
biasArrowLines->up = biasArrowLinesOriginal->up;
biasArrowLines->up.setLength(newLength);
} else if (_down < 0) {
biasArrowLines->up.setLength(0);
double newLength = FontSize::linearTransform(abs(_down), 0, 200, 0, arrowLengthDown);
biasArrowLines->down = biasArrowLinesOriginal->down;
biasArrowLines->down.setLength(newLength);
} else {
biasArrowLines->down.setLength(0);
biasArrowLines->up.setLength(0);
}
// update the component, this will call the paintEvent
update();
}
/// Sets the minimum size - should never be called tho?
/// @return QSize - the size of the window
QSize BiasWidget::minimumSizeHint() const
{
return QSize(200, 200);
}
/// Sets the size of the widget
/// @return QSize - the wanted size of the widget based on parent witdh and height
QSize BiasWidget::sizeHint() const
{
return QSize(frameWidth, frameHeight);
}