Corrections to reading route from file
[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 <QMessageBox>
15 #include <QFile>
16 #include <QFileDialog>
17
18 /*
19   * Vector class
20   */
21 class Vector
22 {
23     qreal x, y, z;
24 public:
25     Vector() { x=0.; y=0. ; z=0.; };
26     Vector( qreal initX, qreal initY, qreal initZ) { x = initX, y = initY; z = initZ; };
27     void setX( qreal newX) { x = newX; };
28     void setY( qreal newY) { y = newY; };
29     void setZ( qreal newZ) { z = newZ; };
30     qreal getX() { return x; };
31     qreal getY() { return y; };
32     qreal getZ() { return z; };
33     qreal length() { return sqrt(x*x+y*y+z*z); };
34     Vector operator+(Vector v)
35     {
36         x = x + v.x; y = y + v.y; z = z + v.z;
37         return *this;
38     };
39     Vector operator-(Vector v)
40     {
41         x = x - v.x; y = y - v.y; z = z - v.z;
42         return *this;
43     };
44     Vector operator/(qreal c)
45     {
46         x = x/c; y = y/c; z = z/c;
47         return *this;
48     };
49     Vector crossProduct( Vector a, Vector b)
50     {
51         x = a.y*b.z - a.z*b.y;
52         y = a.z*b.x - a.x*b.z;
53         z = a.x*b.y - a.y*b.x;
54         return *this;
55     };
56 };
57
58
59 class Viewing
60 {
61     Vector atPoint, fromPoint, up, a1, a2, a3;
62     qreal offsx, offsy, offsz;
63     qreal dval;
64     qreal angle;
65 public:
66     qreal getOffsx() { return offsx; };
67     qreal getOffsy() { return offsx; };
68     qreal getOffsz() { return offsz; };
69     qreal getDval() { return dval; };
70     void setAngle( qreal newA) { angle = newA; };
71     void setUp( qreal newUpX, qreal newUpY, qreal newUpZ)
72     {
73         up.setX(newUpX); up.setY(newUpY); up.setZ(newUpZ);
74     };
75     void setAtPoint( qreal newX, qreal newY, qreal newZ)
76     {
77         atPoint.setX(newX); atPoint.setY(newY); atPoint.setZ(newZ);
78     };
79     void setFromPoint(qreal newX, qreal newY, qreal newZ)
80     {
81         fromPoint.setX(newX); fromPoint.setY(newY); fromPoint.setZ(newZ);
82     }
83     void setEye()
84     {
85         double amarkmag, tempmag;
86         Vector temp, dist;
87
88         dval = cos(angle/2.0)/sin(angle/2.0);
89         dist = atPoint-fromPoint;
90         amarkmag = dist.length();
91         a3 = dist/amarkmag;
92
93         temp.crossProduct( dist, up);
94         tempmag = temp.length();
95         a1 = temp/tempmag;
96
97         temp.crossProduct( a1, a3);
98         tempmag = temp.length();
99         a2 = temp/tempmag;
100
101         offsx = -a1.getX()*fromPoint.getX() - a1.getY()*fromPoint.getY() - a1.getZ()*fromPoint.getZ();
102         offsy = -a2.getX()*fromPoint.getX() - a2.getY()*fromPoint.getY() - a2.getZ()*fromPoint.getZ();
103         offsz = -a3.getX()*fromPoint.getX() - a3.getY()*fromPoint.getY() - a3.getZ()*fromPoint.getZ();
104         QString jono2 = QString("offsx %1 offsy %2 offsz %3").arg(offsx).arg(offsy).arg(offsz);
105         QMessageBox::about(0,"offs x y z", jono2);
106     } ;
107     Vector getAtPoint() { return atPoint; };
108     Vector getFromPoint() { return fromPoint; };
109     Vector getA1() { return a1; };
110     Vector getA2() { return a2; };
111     Vector getA3() { return a3; };
112     Viewing () {};
113 };
114
115 qreal xmax, xmin, ymin, ymax;       // Limits in world coordinates
116
117 QList<Vector> vertexList;           // Vertecies of route
118
119 //Vector atPoint, fromPoint, up, a1, a2, a3;
120 //qreal offsx, offsy, offsz;
121
122 qreal objxmin, objxmax, objymin, objymax, objzmin, objzmax;
123 //qreal angle;
124 qreal a, b,c,d; //, dval;
125
126 #define maxof(val1,val2)  ((val1>val2)?val1:val2)
127 #define toradians( degrees) (degrees*0.017453293)
128
129 #define WIDTH 1.8
130
131 int length = 34; // 24;
132 int connection[50];
133
134 void setAtPoint( Viewing *v);
135 void setFromPoint( Viewing *v);
136 //void setEye();
137
138 Viewing view3d;
139
140 void dataMinMax( void);
141
142
143
144 RouteDialog::RouteDialog(QWidget *parent) :
145     QDialog(parent),
146     ui(new Ui::RouteDialog)
147 {
148     ui->setupUi(this);
149     left = 5; top = 5; right = 395; bottom = 195; // Limits in screen coordinates
150 }
151
152 RouteDialog::~RouteDialog()
153 {
154     delete ui;
155 }
156
157 void RouteDialog::changeEvent(QEvent *e)
158 {
159     QDialog::changeEvent(e);
160     switch (e->type()) {
161     case QEvent::LanguageChange:
162         ui->retranslateUi(this);
163         break;
164     default:
165         break;
166     }
167 }
168
169
170 /**
171   * Draws route to the route dialog
172   * @param QPaintEvent
173  */
174 /* */
175 void RouteDialog::paintEvent(QPaintEvent *)
176 {
177     // 2d draw
178     int startx, starty; // Starting point of the route
179     int i, maxi;
180     qreal x1, y1, x2, y2;
181     int scx1, scy1, scx2, scy2;
182     Vector v1, v2;
183     QPainter painter(this);
184
185     painter.setRenderHint(QPainter::Antialiasing, true);
186     painter.setPen(QPen((Qt::white),2));
187     painter.setBrush(QBrush((Qt::yellow), Qt::SolidPattern));
188
189     // Draw route window frame
190     /*painter.drawLine(left,top,right,top);
191     painter.drawLine(right,top,right,bottom);
192     painter.drawLine(left,top,left,bottom);
193     painter.drawLine(left,bottom,right,bottom);
194     */
195
196     maxi = vertexList.size()-1; // -1 to remove wrong last point !!!
197     for (i=0; i<maxi-1; i++)
198     {
199         v1 = vertexList.at(i);
200         v2 = vertexList.at(i+1);
201         x1 = v1.getX(); y1 = v1.getY();
202         x2 = v2.getX(); y2 = v2.getY();
203         //QString jono = QString("x: %1 y: %2").arg(x1).arg(y1);
204         //QMessageBox::about(0,"Tark",jono);
205
206         scx1 = left + (x1-xmin)/(xmax-xmin)*(right-left);
207         scy1 = top + (ymax-y1)/(ymax-ymin)*(bottom-top);
208         scx2 = left + (x2-xmin)/(xmax-xmin)*(right-left);
209         scy2 = top + (ymax-y2)/(ymax-ymin)*(bottom-top);
210
211         // Show with circle if starting point
212         if (i==0)
213         {
214             // Starting point
215             startx = scx1; starty = scy1;
216             painter.drawEllipse( scx1-5, scy1-5, 10, 10);
217         }
218         painter.drawLine( scx1, scy1, scx2, scy2);
219     }
220     // Show the endig point if different than the starting point
221     if (scx2 != startx || scy2 != starty)
222     {
223         painter.drawEllipse( scx2-5, scy2-5, 10, 10);
224     }
225 }
226 /* */
227
228 void RouteDialog::on_closePushButton_clicked()
229 {
230     close();
231 }
232
233 bool RouteDialog::readRouteFromFile( QString &filename)
234 {
235 /* 2d */
236     Vector temp;
237     int i;
238     QString rivi;
239     QFile file;
240     //file.setFileName("route.txt");
241     QString fileName = QFileDialog::getOpenFileName(this,
242     tr("Read Route"), "./", tr("Route Files (*.txt)"));
243
244     file.setFileName( fileName);
245     if (!file.open(QIODevice::ReadOnly))
246     {
247         QMessageBox::about(0, "Error", "File not found");
248         return false;
249     }
250
251     vertexList.clear();
252     i = 0;
253     //while( file.canReadLine())
254     while(!file.atEnd())
255     {
256         QString str1, str2, str3;
257         rivi = file.readLine();
258
259         str1 = rivi.section(" ", 0, 0);
260         if (str1.compare("Start:") == 0 || str1.compare("Stop:") == 0)
261         {
262
263         }
264         else
265         {
266             //QMessageBox::about(0, "LUKEE", file.readLine());
267             str1 = rivi.section(" ",  2, 2); // latitude y-value
268             str2 = rivi.section(" ",  4, 4); // longitude x-value
269             str3 = rivi.section(" ",  6, 6); // altitude z-value
270             QString str = QString("la: %1 lo: %2 al: %3").arg(str1).arg(str2).arg(str3);
271             //QMessageBox::about(0, "LUKEE", str);
272
273             double x, y, z;
274             x = str2.toDouble();
275             y = str1.toDouble();
276             z = str3.toDouble();
277             temp.setX( x); // Longitude
278             temp.setY( y);// Latitude
279             temp.setZ( z);// altitude
280
281            vertexList.append(temp);
282         }
283         i++;
284     }
285
286    // la: lo: al:
287     file.close();
288
289    /* */
290      /* for 3D test */
291      /*vertexList.append(Vector(0.0, 0.0, 0.0));
292      vertexList.append(Vector(1.0, 1.0, 1.0));
293      vertexList.append(Vector(1.0, 1.0, 0.0));
294
295      vertexList.append(Vector(1.0, 0.0, 0.0));
296      vertexList.append(Vector(1.0, 0.0, 1.0));
297      vertexList.append(Vector(0.0, 1.0, 1.0));
298
299      vertexList.append(Vector(0.0, 1.0, 0.0));
300      vertexList.append(Vector(0.0, 0.0, 0.0));
301      vertexList.append(Vector(0.0, 0.0, 1.0));
302 */
303      /* For 3d */
304      //int i;
305      for(i= 0; i<35; i++)
306      {
307          connection[i] = i;
308      }
309  /* connection[0] = 0;
310  connection[1] = 1; connection[2] = 5; connection[3] = 8; connection[4] = -4;
311  connection[5] =  5; connection[6] = 6; connection[7] = 7; connection[8] = -8;
312  connection[9] =  6; connection[10] = 2; connection[11] = 3; connection[12] = -7;
313  connection[13] = 1; connection[14] = 4; connection[15] = 3; connection[16] = -2;
314  connection[17] = 8; connection[18] = 7; connection[19] = 3; connection[20] = -4;
315  connection[21] = 6;  connection[22] = 5; connection[23] = 1;  connection[24] = -2;*/
316
317      /********  in 3d use only */
318      a = 400/2.;
319      b = 1 - a*(-1);
320      c = -300/2.;
321      d = 300 - c*(-1);
322      //angle = toradians(60);
323
324      view3d.setUp( 0.0, 0.0, 1.0);
325      view3d.setAngle(toradians(60));
326      setAtPoint( &view3d);
327      xmin = objxmin; xmax = objxmax; ymin = objymin; ymax = objymax;
328      setFromPoint( &view3d);
329      view3d.setEye();
330      /****** end of 3d *****/
331      return true;
332 }
333
334 /*
335   * Find out data range for x-, y- and z-coordinates
336   */
337 void dataMinMax( void)
338 {
339     int i, maxi;
340     qreal x,y,z;
341     Vector temp;
342
343     temp = vertexList.at(0);
344     objxmax = objxmin = temp.getX();
345     objymax = objymin = temp.getY();
346     objzmax = objzmin = temp.getZ();
347
348     maxi = vertexList.size()-1; // Wrong last data
349     //maxi = 9;
350     for (i=1; i<maxi; i++)
351     {
352         temp = vertexList.at(i);
353         x = temp.getX();
354         y = temp.getY();
355         z = temp.getZ();
356
357         if (x < objxmin)
358         {
359                 objxmin = x;
360         }
361         else if (x > objxmax)
362         {
363                objxmax = x;
364         }
365
366         if (y < objymin)
367         {
368                 objymin = y;
369         }
370         else if (y > objymax)
371         {
372                objymax = y;
373         }
374
375         if (z < objzmin)
376         {
377                 objzmin = z;
378         }
379         else if (z > objzmax)
380         {
381                objzmax = z;
382         }
383     }
384     //QString jono = QString("ojxmin %1 objxmax %2").arg(objxmin).arg(objxmax);
385     //QString jono = QString("ojymin %1 objymax %2").arg(objymin).arg(objymax);
386     //QString jono = QString("ojzmin %1 objzmax %2").arg(objzmin).arg(objzmax);
387     //QMessageBox::about(0,"Tark", jono);
388 }
389
390
391 void setAtPoint( Viewing *v)
392 {
393     qreal x, y, z;
394     dataMinMax();
395     Vector test;
396     //atPoint.setX((
397             x = (objxmax+objxmin)/2.0;
398     //atPoint.setY(
399             y= (objymax+objymin)/2.0;
400     //atPoint.setZ(
401             z= (objzmax+objzmin)/2.0;
402             v->setAtPoint( x, y, z);
403     //QString jono = QString("AtX %1 Aty %2 AtZ %3").arg(atPoint.x()).arg(atPoint.y()).arg(atPoint.z());
404     //QString jono = QString("AtX %1 Aty %2 AtZ %3").arg(atPoint.x).arg(atPoint.y).arg(atPoint.z);
405
406     /* *
407     test = v->getAtPoint();
408     QString jono = QString("AtX %1 Aty %2 AtZ %3").arg(test.getX()).arg(test.getY()).arg(test.getZ());
409     QMessageBox::about(0,"At point", jono);
410     * */
411 }
412
413 void setFromPoint( Viewing *v)
414 {
415     qreal x, y, z;
416     Vector point;
417     point = v->getAtPoint();
418     Vector test;
419     //fromPoint.setX( atPoint.getX() + (objxmax-objxmin)/2.0 + WIDTH*maxof((objzmax-objzmin)/2.0,(objymax-objymin)/2.0));
420     //fromPoint.setX(
421             //x = 3.0;
422             x = point.getX() + 300; //25;
423     //fromPoint.setY(
424             y = point.getY();
425     //fromPoint.setZ(
426             z = point.getZ(); // + 150;
427             v->setFromPoint(x,y,z);
428     //QString jono = QString("FromX %1 FromY %2 FromZ %3").arg(fromPoint.x()).arg(fromPoint.y()).arg(fromPoint.z());
429     //QString jono = QString("FromX %1 FromY %2 FromZ %3").arg(fromPoint.x).arg(fromPoint.y).arg(fromPoint.z);
430     /* *
431     test = v->getFromPoint();
432     QString jono = QString("FromX %1 FromY %2 FromZ %3").arg(test.getX()).arg(test.getY()).arg(test.getZ());
433     QMessageBox::about(0,"From point", jono); // (1.9, 0.5, 0.5)
434     * */
435 }
436
437 /*void setEye()
438 {
439     double amarkmag, tempmag;
440     Vector temp, dist;
441
442     dval = cos(angle/2.0)/sin(angle/2.0);
443     dist = atPoint-fromPoint;
444     amarkmag = dist.length();
445     a3 = dist/amarkmag;
446
447     temp.crossProduct( dist, up);
448     tempmag = temp.length();
449     a1 = temp/tempmag;
450
451     temp.crossProduct( a1, a3);
452     tempmag = temp.length();
453     a2 = temp/tempmag;
454
455     offsx = -a1.getX()*fromPoint.getX() - a1.getY()*fromPoint.getY() - a1.getZ()*fromPoint.getZ();
456     offsy = -a2.getX()*fromPoint.getX() - a2.getY()*fromPoint.getY() - a2.getZ()*fromPoint.getZ();
457     offsz = -a3.getX()*fromPoint.getX() - a3.getY()*fromPoint.getY() - a3.getZ()*fromPoint.getZ();
458     //QString jono2 = QString("offsx %1 offsy %2 offsz %3").arg(offsx).arg(offsy).arg(offsz);
459     //QMessageBox::about(0,"offs x y z", jono2);
460 }*/
461
462 #define NOEDGE     0x00
463 #define LEFTEDGE   0x01
464 #define RIGHTEDGE  0x02
465 #define BOTTOMEDGE 0x04
466 #define TOPEDGE    0x08
467 /*
468   * Returns a code specifying which edge in the viewing pyramid was crossed.
469   * There may be more than one.
470   */
471 int code( qreal x, qreal y, qreal z)
472 {
473     int c;
474
475     c = NOEDGE;
476     if (x<-z) c |= LEFTEDGE;
477     if (x>z) c |= RIGHTEDGE;
478     if (y<-z) c |= BOTTOMEDGE;
479     if (y>z) c |= TOPEDGE;
480
481     return c;
482 }
483 /*
484   * Converts clipped world coordinates to screen coordinates.
485   */
486 void WORLDtoSCREEN( qreal xWorld, qreal yWorld, int *xScreen, int *yScreen)
487 {
488    *xScreen = (int) (a*xWorld+b);
489    *yScreen = (int) (c*yWorld+d);
490 }
491
492 /*
493   * Clips the line segment in three-dimensional coordinates to the
494   * viewing pyramid.
495   */
496 void clip3d( qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2, int *xscreen1, int *yscreen1, int *xscreen2, int *yscreen2)
497 {
498     int c,c1,c2;
499     qreal x,y,z,t;
500
501     c1 = code(x1,y1,z1);
502     c2 = code(x2,y2,z2);
503
504     while (c1!= NOEDGE || c2 != NOEDGE)
505     {
506         if ((c1 & c2 ) != NOEDGE) return;
507         c = c1;
508         if (c == NOEDGE) c = c2;
509         if ((c&LEFTEDGE) == LEFTEDGE)
510         {
511                 // Crosses left edge
512                 t = (z1+x1)/((x1-x2)-(z2-z1));
513                 z = t*(z2-z1)+z1;
514                 x = -z;
515                 y = t*(y2-y1)+y1;
516         }
517         else if ((c&RIGHTEDGE) == RIGHTEDGE)
518         {
519                 // Crosses right edge
520                 t = (z1-x1)/((x2-x1)-(z2-z1));
521                 z = t*(z2-z1)+z1;
522                 x = z;
523                 y = t*(y2-y1)+y1;
524         }
525         else if ((c&BOTTOMEDGE) == BOTTOMEDGE)
526         {
527                 // Crosses bottom edge
528                 t = (z1+y1)/((y1-y2)-(z2-z1));
529                 z = t*(z2-z1)+z1;
530                 x = t*(x2-x1)+x1;
531                 y = -z;
532         }
533         else if ((c&TOPEDGE) == TOPEDGE)
534         {
535                 // Crosses top edge
536                 t = (z1-y1)/((y2-y1)-(z2-z1));
537                 z = t*(z2-z1)+z1;
538                 x = t*(x2-x1)+x1;
539                 y = z;
540         }
541
542         if (c == c1)
543         {
544             x1=x; y1=y; z1=z;
545             c1 = code(x,y,z);
546         }
547         else
548         {
549             x2=x; y2=y; z2=z;
550             c2 = code(x,y,z);
551         }
552     }
553
554     if (z1 != 0)
555     {
556         WORLDtoSCREEN(x1/z1,y1/z1,xscreen1, yscreen1);
557         WORLDtoSCREEN(x2/z2,y2/z2,xscreen2, yscreen2);
558     }
559     else
560     {
561         WORLDtoSCREEN(x1,y1,xscreen1, yscreen1);
562         WORLDtoSCREEN(x2,y2,xscreen2, yscreen2);
563     }
564     //line( xscreen1, yscreen1, xscreen2, yscreen2);
565 }
566
567 /*
568   * Transform the segment connecting the two vectors into the viewing plane.
569   * clip3d() clips the line if needed.
570   */
571 void transformseg( Viewing *v, Vector *v1, Vector *v2, int *xscreen1, int *yscreen1, int *xscreen2, int *yscreen2 )
572
573 {
574     qreal x1, y1, z1, x2, y2, z2;
575     qreal offsx, offsy, offsz;
576     qreal dval;
577     Vector a1, a2, a3;
578     a1 = v->getA1();
579     a2 = v->getA2();
580     a3 = v->getA3();
581     offsx = v->getOffsx();
582     offsy = v->getOffsy();
583     offsz = v->getOffsz();
584     dval = v->getDval();
585
586     x1 = (a1.getX()*v1->getX() + a1.getY()*v1->getY() + a1.getZ()*v1->getZ() + offsx)*dval;
587     y1 = (a2.getX()*v1->getX() + a2.getY()*v1->getY() + a2.getZ()*v1->getZ() + offsy)*dval;
588     z1 = a3.getX()*v1->getX() + a3.getY()*v1->getY() + a3.getZ()*v1->getZ() + offsz;
589
590     x2 = (a1.getX()*v2->getX() + a1.getY()*v2->getY() + a1.getZ()*v2->getZ() + offsx)*dval;
591     y2 = (a2.getX()*v2->getX() + a2.getY()*v2->getY() + a2.getZ()*v2->getZ() + offsy)*dval;
592     z2 = a3.getX()*v2->getX() + a3.getY()*v2->getY() + a3.getZ()*v2->getZ() + offsz;
593
594     clip3d(x1,y1,z1,x2,y2,z2, xscreen1, yscreen1, xscreen2, yscreen2 );
595 }
596
597 /*
598   *
599   * 3D route viewing
600 *
601 void RouteDialog::paintEvent(QPaintEvent *)
602 {
603     int i, startofside;
604     int xscreen1, yscreen1, xscreen2, yscreen2;
605     Vector temp1, temp2;
606
607     QPainter painter(this);
608
609     painter.setRenderHint(QPainter::Antialiasing, true);
610     painter.setPen(QPen((Qt::black),2));
611     painter.setBrush(QBrush((Qt::yellow), Qt::SolidPattern));
612
613     // Draw route window frsme
614     //painter.drawLine(left,top,right,top);
615     //painter.drawLine(right,top,right,bottom);
616     //painter.drawLine(left,top,left,bottom);
617     //painter.drawLine(left,bottom,right,bottom);
618
619     i = 1;
620     while (i<length)
621     {
622         temp1 = vertexList.at(connection[i-1]);
623         temp2 = vertexList.at(connection[i]);
624         transformseg( &view3d, &temp1,&temp2, &xscreen1, &yscreen1, &xscreen2, &yscreen2);
625
626         painter.drawLine(xscreen1, yscreen1, xscreen2, yscreen2);
627         if (i==1)
628         {
629             painter.drawEllipse( xscreen1-5, yscreen1-5, 10, 10);
630         }
631         i++;
632     }
633     /*
634     i=1;
635     while(i<length)
636     {
637         startofside = i;
638         i++;
639         while (connection[i] > 0)
640         {
641             //transformseg( &pa[connection[i-1]],&pa[connection[i]], &xpc1, &ypc1, &xpc2, &ypc2);
642             temp1 = vertexList.at(connection[i-1]);
643             temp2 = vertexList.at(connection[i]);
644             transformseg( &view3d, &temp1,&temp2, &xscreen1, &yscreen1, &xscreen2, &yscreen2);
645
646             painter.drawLine(xscreen1, yscreen1, xscreen2, yscreen2);
647             if (i==2)
648             {
649                 painter.drawEllipse( xscreen1-5, yscreen1-5, 10, 10);
650             }
651             i++;
652         }
653         // to last segment
654         //transformseg( &pa[connection[i-1]],&pa[-connection[i]],&xpc1, &ypc1, &xpc2, &ypc2);
655         temp1 = vertexList.at(connection[i-1]);
656         temp2 = vertexList.at(-connection[i]);
657         transformseg( &view3d, &temp1,&temp2, &xscreen1, &yscreen1, &xscreen2, &yscreen2);
658         painter.drawLine(xscreen1, yscreen1, xscreen2, yscreen2);
659         // from last segemt to start
660         //transformseg( &pa[-connection[i]],&pa[connection[startofside]],&xpc1, &ypc1, &xpc2, &ypc2);
661         temp1 = vertexList.at(-connection[i]);
662         temp2 = vertexList.at(connection[startofside]);
663         transformseg( &view3d, &temp1,&temp2, &xscreen1, &yscreen1, &xscreen2, &yscreen2);
664         painter.drawLine(xscreen1, yscreen1, xscreen2, yscreen2);
665         i++;
666     }
667     *
668 }
669 ** */