#include <cmath>
#include <QPainter>
#include <QList>
-//#include <QVector3D>
-//#include <QDebug>
-//#include <stdio.h>
-#include <QMessageBox>
+//#include <QMessageBox>
-typedef struct
+/*
+ * Vector class
+ */
+class Vector
{
qreal x, y, z;
-} VECTOR;
+public:
+ Vector() { x=0.; y=0. ; z=0.; };
+ Vector( qreal initX, qreal initY, qreal initZ) { x = initX, y = initY; z = initZ; };
+ void setX( qreal newX) { x = newX; };
+ void setY( qreal newY) { y = newY; };
+ void setZ( qreal newZ) { z = newZ; };
+ qreal getX() { return x; };
+ qreal getY() { return y; };
+ qreal getZ() { return z; };
+ qreal length() { return sqrt(x*x+y*y+z*z); };
+ Vector operator+(Vector v)
+ {
+ x = x + v.x; y = y + v.y; z = z + v.z;
+ return *this;
+ };
+ Vector operator-(Vector v)
+ {
+ x = x - v.x; y = y - v.y; z = z - v.z;
+ return *this;
+ };
+ Vector operator/(qreal c)
+ {
+ x = x/c; y = y/c; z = z/c;
+ return *this;
+ };
+ Vector crossProduct( Vector a, Vector b)
+ {
+ x = a.y*b.z - a.z*b.y;
+ y = a.z*b.x - a.x*b.z;
+ z = a.x*b.y - a.y*b.x;
+ return *this;
+ };
+};
-int left, top, right, bottom; // Limits in screen coordinates
-qreal xmax, xmin, ymin, ymax; // Limits in world coordinates
+int left, top, right, bottom; // Limits in screen coordinates
+qreal xmax, xmin, ymin, ymax; // Limits in world coordinates
-//QList<QVector3D> vertexList; // Vertecies of route
-QList<VECTOR> vertexList;
+QList<Vector> vertexList; // Vertecies of route
-//QVector3D atPoint, fromPoint, up;
-//QVector3D a1, a2, a3;
-VECTOR atPoint, fromPoint, up, a1, a2, a3;
-// QVector3D dist;
+Vector atPoint, fromPoint, up, a1, a2, a3;
qreal offsx, offsy, offsz;
qreal objxmin, objxmax, objymin, objymax, objzmin, objzmax;
-qreal t_from;
qreal angle;
qreal a, b,c,d, dval;
#define WIDTH 1.8
int length = 24;
-int connection[24] = { 1, 5, 8, -4,
- 5, 6, 7, -8,
- 6, 2, 3, -7,
- 1, 4, 3, -2,
- 8, 7, 3, -4,
- 6, 5, 1, -2 };
-/*QVector3D pa[8] = { {1.,1.,1.},{1.,1.,0.},
- {1.,0.,0.},{1.,0.,1.},
- {0.,1.,1.},{0.,1.,0.},
- {0.,0.,0.},{0.,0.,1.}};*/
-//QVector3D pa[8];
-VECTOR pa[8];
+int connection[30];
void setAtPoint();
void setFromPoint();
ui(new Ui::RouteDialog)
{
ui->setupUi(this);
- left = 50;
- top = 50;
- right = 350;
- bottom = 200;
+ //left = 50; top = 50; right = 350; bottom = 200;
+ left = 5; top = 5; right = 395; bottom = 295;
xmin =0.0; xmax=100.0; ymin = 0.0; ymax = 20.0;
+ // Ruudun koko 400 x 300
/*vertexList.append(QVector3D(40.02, 10.02, 10.02));
vertexList.append(QVector3D(50.01, 5.01, 10));
vertexList.append(QVector3D(49.99, 14.97, 10));
vertexList.append(QVector3D(40.01, 10.01, 10.02));
*/
- /*pa[0] = QVector3D(1.,1.,1.);
- pa[1] = QVector3D(1.,1.,0.);
- pa[2] = QVector3D(1.,0.,0.);
- pa[3] = QVector3D(1.,0.,1.);
- pa[4] = QVector3D(0.,1.,1.);
- pa[5] = QVector3D(0.,1.,0.);
- pa[6] = QVector3D(0.,0.,0.);
- pa[7] = QVector3D(0.,0.,1.);
- */
-
- pa[0].x = 1.; pa[0].y = 1.; pa[0].z =1.;
- pa[1].x = 1.; pa[1].y = 1.; pa[1].z = 0.;
- pa[2].x = 1.; pa[2].y = 0.; pa[2].z = 0.;
- pa[3].x = 1.; pa[3].y = 0.; pa[3].z = 1.;
- pa[4].x = 0.; pa[4].y = 1.; pa[4].z = 1.;
- pa[5].x = 0.; pa[5].y = 1.; pa[5].y = 0.;
- pa[6].x = 0.; pa[6].y = 0.; pa[6].z = 0.;
- pa[7].x = 0.; pa[7].y = 0.; pa[7].z = 1.;
-
- fromPoint.x = 1.0; fromPoint.y = 0.0; fromPoint.z = 0.0;
- atPoint.x = 0.0; atPoint.y = 0.0; atPoint.z = 0.0;
- up.x = 0.0; up.y = 0.0; up.z = 1.0;
-
- a = 350/2;
+ vertexList.append(Vector(0.0, 0.0, 0.0));
+ vertexList.append(Vector(1.0, 1.0, 1.0));
+ vertexList.append(Vector(1.0, 1.0, 0.0));
+
+ vertexList.append(Vector(1.0, 0.0, 0.0));
+ vertexList.append(Vector(1.0, 0.0, 1.0));
+ vertexList.append(Vector(0.0, 1.0, 1.0));
+
+ vertexList.append(Vector(0.0, 1.0, 0.0));
+ vertexList.append(Vector(0.0, 0.0, 0.0));
+ vertexList.append(Vector(0.0, 0.0, 1.0));
+
+ connection[0] = 0;
+ connection[1] = 1; connection[2] = 5; connection[3] = 8; connection[4] = -4;
+ connection[5] = 5; connection[6] = 6; connection[7] = 7; connection[8] = -8;
+ connection[9] = 6; connection[10] = 2; connection[11] = 3; connection[12] = -7;
+ connection[13] = 1; connection[14] = 4; connection[15] = 3; connection[16] = -2;
+ connection[17] = 8; connection[18] = 7; connection[19] = 3; connection[20] = -4;
+ connection[21] = 6; connection[22] = 5; connection[23] = 1; connection[24] = -2;
+
+ fromPoint.setX( 1.0); fromPoint.setY( 0.0); fromPoint.setZ( 0.0);
+ atPoint.setX( 0.0); atPoint.setY( 0.0); atPoint.setZ( 0.0);
+ up.setX( 0.0); up.setY( 0.0); up.setZ(1.0);
+
+ a = 400/2.;
b = 1 - a*(-1);
- c = 200/2;
- d = 200 - c*(-1);
+ c = -300/2.;
+ d = 300 - c*(-1);
angle = toradians(60);
- t_from = 1.0;
setAtPoint();
setFromPoint();
{
int i, maxi;
qreal x,y,z;
+ Vector temp;
- objxmax = objxmin = pa[0].x; //vertexList.at(0).x();
- objymax = objymin = pa[0].y; //vertexList.at(0).y();
- objzmax = objzmin = pa[0].z; //vertexList.at(0).z();
+ temp = vertexList.at(0);
+ objxmax = objxmin = temp.getX();
+ objymax = objymin = temp.getY();
+ objzmax = objzmin = temp.getZ();
- //maxi = vertexList.size();
- maxi = 8;
+ maxi = vertexList.size();
+ //maxi = 9;
for (i=1; i<maxi; i++)
{
- x = pa[i].x; // vertexList.at(i).x();
- y = pa[i].y; //vertexList.at(i).y();
- z = pa[i].z; //vertexList.at(i).z();
+ temp = vertexList.at(i);
+ x = temp.getX();
+ y = temp.getY();
+ z = temp.getZ();
if (x < objxmin)
{
objzmax = z;
}
}
- //qDebug() << "ojbxmin";
- //fprintf(stdout,"objxmin");
//QString jono = QString("ojxmin %1 objxmax %2").arg(objxmin).arg(objxmax);
//QString jono = QString("ojymin %1 objymax %2").arg(objymin).arg(objymax);
//QString jono = QString("ojzmin %1 objzmax %2").arg(objzmin).arg(objzmax);
void setAtPoint()
{
dataMinMax();
- /*atPoint.setX((objxmax+objxmin)/2.0);
+ atPoint.setX((objxmax+objxmin)/2.0);
atPoint.setY((objymax+objymin)/2.0);
atPoint.setZ((objzmax+objzmin)/2.0);
- */
- atPoint.x = (objxmax+objxmin)/2.0;
- atPoint.y = (objymax+objymin)/2.0;
- atPoint.z = (objzmax+objzmin)/2.0;
//QString jono = QString("AtX %1 Aty %2 AtZ %3").arg(atPoint.x()).arg(atPoint.y()).arg(atPoint.z());
+ //QString jono = QString("AtX %1 Aty %2 AtZ %3").arg(atPoint.x).arg(atPoint.y).arg(atPoint.z);
//QMessageBox::about(0,"At point", jono);
}
void setFromPoint()
{
- /*fromPoint.setX( atPoint.x() + (objxmax-objxmin)/2.0 + WIDTH*maxof((objzmax-objzmin)/2.0,(objymax-objymin)/2.0));
- fromPoint.setY( atPoint.y());
- fromPoint.setZ( atPoint.z());
- */
- fromPoint.x = ( atPoint.x + (objxmax-objxmin)/2.0 + WIDTH*maxof((objzmax-objzmin)/2.0,(objymax-objymin)/2.0));
- fromPoint.y = atPoint.y;
- fromPoint.z = atPoint.z;
-
+ //fromPoint.setX( atPoint.getX() + (objxmax-objxmin)/2.0 + WIDTH*maxof((objzmax-objzmin)/2.0,(objymax-objymin)/2.0));
+ fromPoint.setX(3.0);
+ fromPoint.setY( atPoint.getY());
+ fromPoint.setZ( atPoint.getZ());
//QString jono = QString("FromX %1 FromY %2 FromZ %3").arg(fromPoint.x()).arg(fromPoint.y()).arg(fromPoint.z());
- //QMessageBox::about(0,"From point", jono); // (1.9,
-}
-
-VECTOR CrossProduct( VECTOR a, VECTOR b)
-{
- VECTOR c;
-
- c.x = a.y*b.z - a.z*b.y;
- c.y = a.z*b.x - a.x*b.z;
- c.z = a.x*b.y - a.y*b.x;
-
- return c;
+ //QString jono = QString("FromX %1 FromY %2 FromZ %3").arg(fromPoint.x).arg(fromPoint.y).arg(fromPoint.z);
+ //QMessageBox::about(0,"From point", jono); // (1.9, 0.5, 0.5)
}
void setEye()
{
double amarkmag, tempmag;
- //QVector3D temp;
- //QVector3D dist;
- VECTOR temp, dist;
+ Vector temp, dist;
dval = cos(angle/2.0)/sin(angle/2.0);
- //dist = atPoint-fromPoint;
- dist.x = atPoint.x - fromPoint.x;
- dist.y = atPoint.y - fromPoint.y;
- dist.z = atPoint.z - fromPoint.z;
- //amarkmag = dist.length();
- amarkmag = sqrt( dist.x*dist.x + dist.y*dist.y + dist.z*dist.z);
- //QString jono = QString("amarkmag %1").arg(amarkmag);
- //QMessageBox::about(0,"amarkmag", jono); // 1.4
- //a3 = dist.operator /=(amarkmag);
- a3.x = dist.x/amarkmag;
- a3.y = dist.y/amarkmag;
- a3.z = dist.z/amarkmag;
-
- //temp.crossProduct( dist, up);
- temp = CrossProduct( dist, up);
- //tempmag = temp.length();
- tempmag = sqrt( temp.x*temp.x + temp.y*temp.y + temp.z*temp.z);
- //a1 = temp.operator /=(tempmag);
- a1.x = temp.x/tempmag;
- a1.y = temp.y/tempmag;
- a1.z = temp.z/tempmag;
-
- //temp.crossProduct( a1, a3);
- temp = CrossProduct( a1, a3);
- //tempmag = temp.length();
- tempmag = sqrt( temp.x*temp.x + temp.y*temp.y + temp.z*temp.z);
- //a2 = temp.operator /=(tempmag);
- a2.x = temp.x/tempmag;
- a2.y = temp.y/tempmag;
- a2.z = temp.z/tempmag;
-
- /*offsx = -a1.x()*fromPoint.x() - a1.y()*fromPoint.y() - a1.z()*fromPoint.z();
- offsy = -a2.x()*fromPoint.x() - a2.y()*fromPoint.y() - a2.z()*fromPoint.z();
- offsz = -a3.x()*fromPoint.x() - a3.y()*fromPoint.y() - a3.z()*fromPoint.z();
-*/
- offsx = -a1.x*fromPoint.x - a1.y*fromPoint.y - a1.z*fromPoint.z;
- offsy = -a2.x*fromPoint.x - a2.y*fromPoint.y - a2.z*fromPoint.z;
- offsz = -a3.x*fromPoint.x - a3.y*fromPoint.y - a3.z*fromPoint.z;
+ dist = atPoint-fromPoint;
+ amarkmag = dist.length();
+ a3 = dist/amarkmag;
+
+ temp.crossProduct( dist, up);
+ tempmag = temp.length();
+ a1 = temp/tempmag;
+
+ temp.crossProduct( a1, a3);
+ tempmag = temp.length();
+ a2 = temp/tempmag;
+ offsx = -a1.getX()*fromPoint.getX() - a1.getY()*fromPoint.getY() - a1.getZ()*fromPoint.getZ();
+ offsy = -a2.getX()*fromPoint.getX() - a2.getY()*fromPoint.getY() - a2.getZ()*fromPoint.getZ();
+ offsz = -a3.getX()*fromPoint.getX() - a3.getY()*fromPoint.getY() - a3.getZ()*fromPoint.getZ();
//QString jono2 = QString("offsx %1 offsy %2 offsz %3").arg(offsx).arg(offsy).arg(offsz);
//QMessageBox::about(0,"offs x y z", jono2);
}
#define RIGHTEDGE 0x02
#define BOTTOMEDGE 0x04
#define TOPEDGE 0x08
-
+/*
+ * Returns a code specifying which edge in the viewing pyramid was crossed.
+ * There may be more than one.
+ */
int code( qreal x, qreal y, qreal z)
{
int c;
return c;
}
-
-void WORLDtoSCREEN( qreal xw, qreal yw, int *xpc, int *ypc)
+/*
+ * Converts clipped world coordinates to screen coordinates.
+ */
+void WORLDtoSCREEN( qreal xWorld, qreal yWorld, int *xScreen, int *yScreen)
{
- *xpc = (int) (a+xw+b);
- *ypc = (int) (c+yw+d);
+ *xScreen = (int) (a*xWorld+b);
+ *yScreen = (int) (c*yWorld+d);
}
-
-void clip3d( qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2, int *xpc1, int *ypc1, int *xpc2, int *ypc2)
+/*
+ * Clips the line segment in three-dimensional coordinates to the
+ * viewing pyramid.
+ */
+void clip3d( qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2, int *xscreen1, int *yscreen1, int *xscreen2, int *yscreen2)
{
- int c,c1,c2; //, xpc1, ypc1, xpc2, ypc2;
+ int c,c1,c2;
qreal x,y,z,t;
c1 = code(x1,y1,z1);
else if ((c&RIGHTEDGE) == RIGHTEDGE)
{
// Crosses right edge
- t = (z1-x1)/((x2-x2)-(z2-z1));
+ t = (z1-x1)/((x2-x1)-(z2-z1));
z = t*(z2-z1)+z1;
x = z;
y = t*(y2-y1)+y1;
}
else if ((c&BOTTOMEDGE) == BOTTOMEDGE)
{
- // Crosses left edge
+ // Crosses bottom edge
t = (z1+y1)/((y1-y2)-(z2-z1));
z = t*(z2-z1)+z1;
x = t*(x2-x1)+x1;
}
else if ((c&TOPEDGE) == TOPEDGE)
{
- // Crosses left edge
+ // Crosses top edge
t = (z1-y1)/((y2-y1)-(z2-z1));
z = t*(z2-z1)+z1;
x = t*(x2-x1)+x1;
if (z1 != 0)
{
- WORLDtoSCREEN(x1/z1,y1/z1,xpc1, ypc1);
- WORLDtoSCREEN(x2/z2,y2/z2,xpc2, ypc2);
+ WORLDtoSCREEN(x1/z1,y1/z1,xscreen1, yscreen1);
+ WORLDtoSCREEN(x2/z2,y2/z2,xscreen2, yscreen2);
}
else
{
- WORLDtoSCREEN(x1,y1,xpc1, ypc1);
- WORLDtoSCREEN(x2,y2,xpc2, ypc2);
+ WORLDtoSCREEN(x1,y1,xscreen1, yscreen1);
+ WORLDtoSCREEN(x2,y2,xscreen2, yscreen2);
}
- //line( xpc1, ypc1, xpc2, ypc2);
- //painter.drawLine(xpc1, ypc1, xpc2, ypc2);
+ //line( xscreen1, yscreen1, xscreen2, yscreen2);
}
-//void transformseg( QVector3D *v1, QVector3D *v2, int *xpc1, int *ypc1, int *xpc2, int *ypc2 )
-void transformseg( VECTOR *v1, VECTOR *v2, int *xpc1, int *ypc1, int *xpc2, int *ypc2 )
+/*
+ * Transform the segment connecting the two vectors into the viewing plane.
+ * clip3d() clips the line if needed.
+ */
+void transformseg( Vector *v1, Vector *v2, int *xscreen1, int *yscreen1, int *xscreen2, int *yscreen2 )
+
{
qreal x1, y1, z1, x2, y2, z2;
- /*x1 = (a1.x()*v1->x() + a1.y()*v1->y() + a1.z()*v1->z() + offsx)*dval;
- y1 = (a2.x()*v1->x() + a2.y()*v1->y() + a2.z()*v1->z() + offsy)*dval;
- z1 = a3.x()*v1->x() + a3.y()*v1->y() + a3.z()*v1->z() + offsz;*/
- x1 = (a1.x*v1->x + a1.y*v1->y + a1.z*v1->z + offsx)*dval;
- y1 = (a2.x*v1->x + a2.y*v1->y + a2.z*v1->z + offsy)*dval;
- z1 = a3.x*v1->x + a3.y*v1->y + a3.z*v1->z + offsz;
-
- /*x2 = (a1.x()*v2->x() + a1.y()*v2->y() + a1.z()*v2->z() + offsx)*dval;
- y2 = (a2.x()*v2->x() + a2.y()*v2->y() + a2.z()*v2->z() + offsy)*dval;
- z2 = a3.x()*v2->x() + a3.y()*v2->y() + a3.z()*v2->z() + offsz;*/
- x2 = (a1.x*v2->x + a1.y*v2->y + a1.z*v2->z + offsx)*dval;
- y2 = (a2.x*v2->x + a2.y*v2->y + a2.z*v2->z + offsy)*dval;
- z2 = a3.x*v2->x + a3.y*v2->y + a3.z*v2->z + offsz;
-
- clip3d(x1,y1,z1,x2,y2,z2, xpc1, ypc1, xpc2, ypc2 );
+ x1 = (a1.getX()*v1->getX() + a1.getY()*v1->getY() + a1.getZ()*v1->getZ() + offsx)*dval;
+ y1 = (a2.getX()*v1->getX() + a2.getY()*v1->getY() + a2.getZ()*v1->getZ() + offsy)*dval;
+ z1 = a3.getX()*v1->getX() + a3.getY()*v1->getY() + a3.getZ()*v1->getZ() + offsz;
+
+ x2 = (a1.getX()*v2->getX() + a1.getY()*v2->getY() + a1.getZ()*v2->getZ() + offsx)*dval;
+ y2 = (a2.getX()*v2->getX() + a2.getY()*v2->getY() + a2.getZ()*v2->getZ() + offsy)*dval;
+ z2 = a3.getX()*v2->getX() + a3.getY()*v2->getY() + a3.getZ()*v2->getZ() + offsz;
+
+ clip3d(x1,y1,z1,x2,y2,z2, xscreen1, yscreen1, xscreen2, yscreen2 );
}
void RouteDialog::paintEvent(QPaintEvent *)
{
- //int i, maxi;
int i, startofside;
qreal x1, y1, x2, y2;
int scx1, scy1, scx2, scy2;
int xpc1, ypc1, xpc2, ypc2;
+ Vector temp1, temp2;
QPainter painter(this);
painter.setBrush(QBrush((Qt::yellow), Qt::SolidPattern));
// Draw route window frsme
- painter.drawLine(left,top,right,top);
- painter.drawLine(right,top,right,bottom);
- painter.drawLine(left,top,left,bottom);
- painter.drawLine(left,bottom,right,bottom);
-
-//void view( void)
-//{
- //int i, startofside;
+ //painter.drawLine(left,top,right,top);
+ //painter.drawLine(right,top,right,bottom);
+ //painter.drawLine(left,top,left,bottom);
+ //painter.drawLine(left,bottom,right,bottom);
+
i=1;
while(i<length)
{
i++;
while (connection[i] > 0)
{
- transformseg( &pa[connection[i-1]],&pa[connection[i]], &xpc1, &ypc1, &xpc2, &ypc2);
+ //transformseg( &pa[connection[i-1]],&pa[connection[i]], &xpc1, &ypc1, &xpc2, &ypc2);
+ temp1 = vertexList.at(connection[i-1]);
+ temp2 = vertexList.at(connection[i]);
+ transformseg( &temp1,&temp2, &xpc1, &ypc1, &xpc2, &ypc2);
+
painter.drawLine(xpc1, ypc1, xpc2, ypc2);
i++;
}
- transformseg( &pa[connection[i-1]],&pa[-connection[i]],&xpc1, &ypc1, &xpc2, &ypc2);
+ // to last segment
+ //transformseg( &pa[connection[i-1]],&pa[-connection[i]],&xpc1, &ypc1, &xpc2, &ypc2);
+ temp1 = vertexList.at(connection[i-1]);
+ temp2 = vertexList.at(-connection[i]);
+ transformseg( &temp1,&temp2, &xpc1, &ypc1, &xpc2, &ypc2);
painter.drawLine(xpc1, ypc1, xpc2, ypc2);
- transformseg( &pa[-connection[i]],&pa[connection[startofside]],&xpc1, &ypc1, &xpc2, &ypc2);
+ // from last segemt to start
+ //transformseg( &pa[-connection[i]],&pa[connection[startofside]],&xpc1, &ypc1, &xpc2, &ypc2);
+ temp1 = vertexList.at(-connection[i]);
+ temp2 = vertexList.at(connection[startofside]);
+ transformseg( &temp1,&temp2, &xpc1, &ypc1, &xpc2, &ypc2);
painter.drawLine(xpc1, ypc1, xpc2, ypc2);
i++;
}