Added implementation to handleCheckPoint slot function in carmainwindow.cpp. Now...
[speedfreak] / Client / routedialog.cpp
1 /*
2  * RouteDialog class
3  *
4  * @author     Olavi Pulkkinen <olavi.pulkkinen@fudeco.com>
5  * @copyright  (c) 2010 Speed Freak team
6  * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
7  */
8
9 #include "routedialog.h"
10 #include "ui_routedialog.h"
11 #include <cmath>
12 #include <QPainter>
13 #include <QList>
14 //#include <QVector3D>
15 //#include <QDebug>
16 //#include <stdio.h>
17 #include <QMessageBox>
18
19 typedef struct
20 {
21     qreal x, y, z;
22 } VECTOR;
23
24 int left, top, right, bottom;  // Limits in screen coordinates
25 qreal xmax, xmin, ymin, ymax;                        // Limits in world coordinates
26
27 //QList<QVector3D> vertexList;    // Vertecies of route
28 QList<VECTOR> vertexList;
29
30 //QVector3D atPoint, fromPoint, up;
31 //QVector3D a1, a2, a3;
32 VECTOR atPoint, fromPoint, up, a1, a2, a3;
33 // QVector3D dist;
34 qreal offsx, offsy, offsz;
35
36 qreal objxmin, objxmax, objymin, objymax, objzmin, objzmax;
37 qreal t_from;
38 qreal angle;
39 qreal a, b,c,d, dval;
40
41 #define maxof(val1,val2)  ((val1>val2)?val1:val2)
42 #define toradians( degrees) (degrees*0.017453293)
43
44 #define WIDTH 1.8
45
46 int length = 24;
47 int connection[24] = { 1, 5, 8, -4,
48                     5, 6, 7, -8,
49                     6, 2, 3, -7,
50                     1, 4, 3, -2,
51                     8, 7, 3, -4,
52                     6, 5, 1, -2 };
53 /*QVector3D pa[8] = { {1.,1.,1.},{1.,1.,0.},
54                     {1.,0.,0.},{1.,0.,1.},
55                                 {0.,1.,1.},{0.,1.,0.},
56                     {0.,0.,0.},{0.,0.,1.}};*/
57 //QVector3D pa[8];
58 VECTOR pa[8];
59
60 void setAtPoint();
61 void setFromPoint();
62 void setEye();
63
64 RouteDialog::RouteDialog(QWidget *parent) :
65     QDialog(parent),
66     ui(new Ui::RouteDialog)
67 {
68     ui->setupUi(this);
69     left = 50;
70     top = 50;
71     right = 350;
72     bottom = 200;
73     xmin =0.0; xmax=100.0; ymin = 0.0; ymax = 20.0;
74
75     /*vertexList.append(QVector3D(40.02, 10.02, 10.02));
76    vertexList.append(QVector3D(50.01,  5.01, 10));
77    vertexList.append(QVector3D(69.98,  4.98, 10));
78    vertexList.append(QVector3D(80.02,  9.98, 10));
79    vertexList.append(QVector3D(70.01, 15.01, 10));
80    vertexList.append(QVector3D(49.99, 14.97, 10));
81    vertexList.append(QVector3D(40.01, 10.01, 10.02));
82 */
83     /*pa[0] = QVector3D(1.,1.,1.);
84     pa[1] = QVector3D(1.,1.,0.);
85         pa[2] = QVector3D(1.,0.,0.);
86         pa[3] = QVector3D(1.,0.,1.);
87         pa[4] = QVector3D(0.,1.,1.);
88         pa[5] = QVector3D(0.,1.,0.);
89         pa[6] = QVector3D(0.,0.,0.);
90         pa[7] = QVector3D(0.,0.,1.);
91         */
92
93    pa[0].x = 1.; pa[0].y = 1.; pa[0].z =1.;
94    pa[1].x = 1.; pa[1].y = 1.; pa[1].z = 0.;
95    pa[2].x = 1.; pa[2].y = 0.; pa[2].z = 0.;
96    pa[3].x = 1.; pa[3].y = 0.; pa[3].z = 1.;
97    pa[4].x = 0.; pa[4].y = 1.; pa[4].z = 1.;
98    pa[5].x = 0.; pa[5].y = 1.; pa[5].y = 0.;
99    pa[6].x = 0.; pa[6].y = 0.; pa[6].z = 0.;
100    pa[7].x = 0.; pa[7].y = 0.; pa[7].z = 1.;
101
102    fromPoint.x = 1.0; fromPoint.y = 0.0; fromPoint.z = 0.0;
103    atPoint.x = 0.0; atPoint.y = 0.0; atPoint.z = 0.0;
104    up.x = 0.0; up.y = 0.0; up.z = 1.0;
105
106    a = 350/2;
107    b = 1 - a*(-1);
108    c = 200/2;
109    d = 200 - c*(-1);
110    angle = toradians(60);
111    t_from = 1.0;
112
113    setAtPoint();
114    setFromPoint();
115    setEye();
116 }
117
118 RouteDialog::~RouteDialog()
119 {
120     delete ui;
121 }
122
123 void RouteDialog::changeEvent(QEvent *e)
124 {
125     QDialog::changeEvent(e);
126     switch (e->type()) {
127     case QEvent::LanguageChange:
128         ui->retranslateUi(this);
129         break;
130     default:
131         break;
132     }
133 }
134
135
136 /**
137   * Draws route to the route dialog
138   * @param QPaintEvent
139  *
140 void RouteDialog::paintEvent(QPaintEvent *)
141 {
142     // 2d draw
143     int i, maxi;
144     qreal x1, y1, x2, y2;
145     int scx1, scy1, scx2, scy2;
146
147         QPainter painter(this);
148
149         painter.setRenderHint(QPainter::Antialiasing, true);
150         painter.setPen(QPen((Qt::black),2));
151         painter.setBrush(QBrush((Qt::yellow), Qt::SolidPattern));
152
153         // Draw route window frsme
154         painter.drawLine(left,top,right,top);
155         painter.drawLine(right,top,right,bottom);
156         painter.drawLine(left,top,left,bottom);
157         painter.drawLine(left,bottom,right,bottom);
158
159         //maxi = vertexList.size();
160         for (i=0; i<maxi-1; i++)
161         {
162             x1 = vertexList.at(i).x();
163             y1 = vertexList.at(i).y();
164             x2 = vertexList.at(i+1).x();
165             y2 = vertexList.at(i+1).y();
166
167             scx1 = left + (x1-xmin)/(xmax-xmin)*(right-left);
168             scy1 = top + (ymax-y1)/(ymax-ymin)*(bottom-top);
169             scx2 = left + (x2-xmin)/(xmax-xmin)*(right-left);
170             scy2 = top + (ymax-y2)/(ymax-ymin)*(bottom-top);
171
172             painter.drawLine( scx1, scy1, scx2, scy2);
173         }
174 }
175 */
176
177 void RouteDialog::on_closePushButton_clicked()
178 {
179     close();
180 }
181
182 // Next functions below for 3D
183 void dataMinMax( void)
184 {
185     int i, maxi;
186     qreal x,y,z;
187
188     objxmax = objxmin = pa[0].x; //vertexList.at(0).x();
189     objymax = objymin = pa[0].y; //vertexList.at(0).y();
190     objzmax = objzmin = pa[0].z; //vertexList.at(0).z();
191
192     //maxi = vertexList.size();
193     maxi = 8;
194     for (i=1; i<maxi; i++)
195     {
196         x = pa[i].x; // vertexList.at(i).x();
197         y = pa[i].y; //vertexList.at(i).y();
198         z = pa[i].z; //vertexList.at(i).z();
199
200         if (x < objxmin)
201         {
202                 objxmin = x;
203         }
204         else if (x > objxmax)
205         {
206                objxmax = x;
207         }
208
209         if (y < objymin)
210         {
211                 objymin = y;
212         }
213         else if (y > objymax)
214         {
215                objymax = y;
216         }
217
218         if (z < objzmin)
219         {
220                 objzmin = z;
221         }
222         else if (z > objzmax)
223         {
224                objzmax = z;
225         }
226     }
227     //qDebug() << "ojbxmin";
228     //fprintf(stdout,"objxmin");
229     //QString jono = QString("ojxmin %1 objxmax %2").arg(objxmin).arg(objxmax);
230     //QString jono = QString("ojymin %1 objymax %2").arg(objymin).arg(objymax);
231     //QString jono = QString("ojzmin %1 objzmax %2").arg(objzmin).arg(objzmax);
232     //QMessageBox::about(0,"Tark", jono);
233 }
234
235 void setAtPoint()
236 {
237     dataMinMax();
238     /*atPoint.setX((objxmax+objxmin)/2.0);
239     atPoint.setY((objymax+objymin)/2.0);
240     atPoint.setZ((objzmax+objzmin)/2.0);
241     */
242     atPoint.x = (objxmax+objxmin)/2.0;
243     atPoint.y = (objymax+objymin)/2.0;
244     atPoint.z = (objzmax+objzmin)/2.0;
245     //QString jono = QString("AtX %1 Aty %2 AtZ %3").arg(atPoint.x()).arg(atPoint.y()).arg(atPoint.z());
246     //QMessageBox::about(0,"At point", jono);
247 }
248
249 void setFromPoint()
250 {
251     /*fromPoint.setX( atPoint.x() + (objxmax-objxmin)/2.0 + WIDTH*maxof((objzmax-objzmin)/2.0,(objymax-objymin)/2.0));
252     fromPoint.setY( atPoint.y());
253     fromPoint.setZ( atPoint.z());
254     */
255     fromPoint.x = ( atPoint.x + (objxmax-objxmin)/2.0 + WIDTH*maxof((objzmax-objzmin)/2.0,(objymax-objymin)/2.0));
256     fromPoint.y = atPoint.y;
257     fromPoint.z = atPoint.z;
258
259     //QString jono = QString("FromX %1 FromY %2 FromZ %3").arg(fromPoint.x()).arg(fromPoint.y()).arg(fromPoint.z());
260     //QMessageBox::about(0,"From point", jono); // (1.9,
261 }
262
263 VECTOR CrossProduct( VECTOR a, VECTOR b)
264 {
265     VECTOR c;
266
267     c.x = a.y*b.z - a.z*b.y;
268     c.y = a.z*b.x - a.x*b.z;
269     c.z = a.x*b.y - a.y*b.x;
270
271     return c;
272 }
273
274 void setEye()
275 {
276     double amarkmag, tempmag;
277     //QVector3D temp;
278     //QVector3D dist;
279     VECTOR temp, dist;
280
281     dval = cos(angle/2.0)/sin(angle/2.0);
282     //dist = atPoint-fromPoint;
283     dist.x = atPoint.x - fromPoint.x;
284     dist.y = atPoint.y - fromPoint.y;
285     dist.z = atPoint.z - fromPoint.z;
286     //amarkmag = dist.length();
287     amarkmag = sqrt( dist.x*dist.x + dist.y*dist.y + dist.z*dist.z);
288     //QString jono = QString("amarkmag %1").arg(amarkmag);
289     //QMessageBox::about(0,"amarkmag", jono); // 1.4
290     //a3 = dist.operator /=(amarkmag);
291     a3.x = dist.x/amarkmag;
292     a3.y = dist.y/amarkmag;
293     a3.z = dist.z/amarkmag;
294
295     //temp.crossProduct( dist, up);
296     temp = CrossProduct( dist, up);
297     //tempmag = temp.length();
298     tempmag = sqrt( temp.x*temp.x + temp.y*temp.y + temp.z*temp.z);
299     //a1 = temp.operator /=(tempmag);
300     a1.x = temp.x/tempmag;
301     a1.y = temp.y/tempmag;
302     a1.z = temp.z/tempmag;
303
304     //temp.crossProduct( a1, a3);
305     temp = CrossProduct( a1, a3);
306     //tempmag = temp.length();
307     tempmag = sqrt( temp.x*temp.x + temp.y*temp.y + temp.z*temp.z);
308     //a2 = temp.operator /=(tempmag);
309     a2.x = temp.x/tempmag;
310     a2.y = temp.y/tempmag;
311     a2.z = temp.z/tempmag;
312
313     /*offsx = -a1.x()*fromPoint.x() - a1.y()*fromPoint.y() - a1.z()*fromPoint.z();
314     offsy = -a2.x()*fromPoint.x() - a2.y()*fromPoint.y() - a2.z()*fromPoint.z();
315     offsz = -a3.x()*fromPoint.x() - a3.y()*fromPoint.y() - a3.z()*fromPoint.z();
316 */
317     offsx = -a1.x*fromPoint.x - a1.y*fromPoint.y - a1.z*fromPoint.z;
318     offsy = -a2.x*fromPoint.x - a2.y*fromPoint.y - a2.z*fromPoint.z;
319     offsz = -a3.x*fromPoint.x - a3.y*fromPoint.y - a3.z*fromPoint.z;
320
321     //QString jono2 = QString("offsx %1 offsy %2 offsz %3").arg(offsx).arg(offsy).arg(offsz);
322     //QMessageBox::about(0,"offs x y z", jono2);
323 }
324
325 #define NOEDGE     0x00
326 #define LEFTEDGE   0x01
327 #define RIGHTEDGE  0x02
328 #define BOTTOMEDGE 0x04
329 #define TOPEDGE    0x08
330
331 int code( qreal x, qreal y, qreal z)
332 {
333     int c;
334
335     c = NOEDGE;
336     if (x<-z) c |= LEFTEDGE;
337     if (x>z) c |= RIGHTEDGE;
338     if (y<-z) c |= BOTTOMEDGE;
339     if (y>z) c |= TOPEDGE;
340
341     return c;
342 }
343
344 void WORLDtoSCREEN( qreal xw, qreal yw, int *xpc, int *ypc)
345 {
346     *xpc = (int) (a+xw+b);
347     *ypc = (int) (c+yw+d);
348 }
349
350
351 void clip3d( qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2, int *xpc1, int *ypc1, int *xpc2, int *ypc2)
352 {
353     int c,c1,c2; //, xpc1, ypc1, xpc2, ypc2;
354     qreal x,y,z,t;
355
356     c1 = code(x1,y1,z1);
357     c2 = code(x2,y2,z2);
358
359     while (c1!= NOEDGE || c2 != NOEDGE)
360     {
361         if ((c1 & c2 ) != NOEDGE) return;
362         c = c1;
363         if (c == NOEDGE) c = c2;
364         if ((c&LEFTEDGE) == LEFTEDGE)
365         {
366                 // Crosses left edge
367                 t = (z1+x1)/((x1-x2)-(z2-z1));
368                 z = t*(z2-z1)+z1;
369                 x = -z;
370                 y = t*(y2-y1)+y1;
371         }
372         else if ((c&RIGHTEDGE) == RIGHTEDGE)
373         {
374                 // Crosses right edge
375                 t = (z1-x1)/((x2-x2)-(z2-z1));
376                 z = t*(z2-z1)+z1;
377                 x = z;
378                 y = t*(y2-y1)+y1;
379         }
380         else if ((c&BOTTOMEDGE) == BOTTOMEDGE)
381         {
382                 // Crosses left edge
383                 t = (z1+y1)/((y1-y2)-(z2-z1));
384                 z = t*(z2-z1)+z1;
385                 x = t*(x2-x1)+x1;
386                 y = -z;
387         }
388         else if ((c&TOPEDGE) == TOPEDGE)
389         {
390                 // Crosses left edge
391                 t = (z1-y1)/((y2-y1)-(z2-z1));
392                 z = t*(z2-z1)+z1;
393                 x = t*(x2-x1)+x1;
394                 y = z;
395         }
396
397         if (c == c1)
398         {
399             x1=x; y1=y; z1=z;
400             c1 = code(x,y,z);
401         }
402         else
403         {
404             x2=x; y2=y; z2=z;
405             c2 = code(x,y,z);
406         }
407     }
408
409     if (z1 != 0)
410     {
411         WORLDtoSCREEN(x1/z1,y1/z1,xpc1, ypc1);
412         WORLDtoSCREEN(x2/z2,y2/z2,xpc2, ypc2);
413     }
414     else
415     {
416         WORLDtoSCREEN(x1,y1,xpc1, ypc1);
417         WORLDtoSCREEN(x2,y2,xpc2, ypc2);
418     }
419     //line( xpc1, ypc1, xpc2, ypc2);
420     //painter.drawLine(xpc1, ypc1, xpc2, ypc2);
421 }
422
423 //void transformseg( QVector3D *v1, QVector3D *v2, int *xpc1, int *ypc1, int *xpc2, int *ypc2 )
424 void transformseg( VECTOR *v1, VECTOR *v2, int *xpc1, int *ypc1, int *xpc2, int *ypc2 )
425 {
426     qreal x1, y1, z1, x2, y2, z2;
427
428     /*x1 = (a1.x()*v1->x() + a1.y()*v1->y() + a1.z()*v1->z() + offsx)*dval;
429     y1 = (a2.x()*v1->x() + a2.y()*v1->y() + a2.z()*v1->z() + offsy)*dval;
430     z1 = a3.x()*v1->x() + a3.y()*v1->y() + a3.z()*v1->z() + offsz;*/
431     x1 = (a1.x*v1->x + a1.y*v1->y + a1.z*v1->z + offsx)*dval;
432     y1 = (a2.x*v1->x + a2.y*v1->y + a2.z*v1->z + offsy)*dval;
433     z1 = a3.x*v1->x + a3.y*v1->y + a3.z*v1->z + offsz;
434
435     /*x2 = (a1.x()*v2->x() + a1.y()*v2->y() + a1.z()*v2->z() + offsx)*dval;
436     y2 = (a2.x()*v2->x() + a2.y()*v2->y() + a2.z()*v2->z() + offsy)*dval;
437     z2 = a3.x()*v2->x() + a3.y()*v2->y() + a3.z()*v2->z() + offsz;*/
438     x2 = (a1.x*v2->x + a1.y*v2->y + a1.z*v2->z + offsx)*dval;
439     y2 = (a2.x*v2->x + a2.y*v2->y + a2.z*v2->z + offsy)*dval;
440     z2 = a3.x*v2->x + a3.y*v2->y + a3.z*v2->z + offsz;
441
442     clip3d(x1,y1,z1,x2,y2,z2, xpc1, ypc1, xpc2, ypc2 );
443 }
444
445 void RouteDialog::paintEvent(QPaintEvent *)
446 {
447     //int i, maxi;
448     int i, startofside;
449     qreal x1, y1, x2, y2;
450     int scx1, scy1, scx2, scy2;
451     int xpc1, ypc1, xpc2, ypc2;
452
453     QPainter painter(this);
454
455     painter.setRenderHint(QPainter::Antialiasing, true);
456     painter.setPen(QPen((Qt::black),2));
457     painter.setBrush(QBrush((Qt::yellow), Qt::SolidPattern));
458
459     // Draw route window frsme
460     painter.drawLine(left,top,right,top);
461     painter.drawLine(right,top,right,bottom);
462     painter.drawLine(left,top,left,bottom);
463     painter.drawLine(left,bottom,right,bottom);
464
465 //void view( void)
466 //{
467     //int i, startofside;
468     i=1;
469     while(i<length)
470     {
471         startofside = i;
472         i++;
473         while (connection[i] > 0)
474         {
475             transformseg( &pa[connection[i-1]],&pa[connection[i]], &xpc1, &ypc1, &xpc2, &ypc2);
476             painter.drawLine(xpc1, ypc1, xpc2, ypc2);
477             i++;
478         }
479         transformseg( &pa[connection[i-1]],&pa[-connection[i]],&xpc1, &ypc1, &xpc2, &ypc2);
480         painter.drawLine(xpc1, ypc1, xpc2, ypc2);
481         transformseg( &pa[-connection[i]],&pa[connection[startofside]],&xpc1, &ypc1, &xpc2, &ypc2);
482         painter.drawLine(xpc1, ypc1, xpc2, ypc2);
483         i++;
484     }
485 }