00001
00031 #include "CoordinateFrame.h"
00032
00033 #include <stdio.h>
00034
00035 using namespace Utils3D;
00036
00037
00041
00042 CoordinateFrame::CoordinateFrame(CvPoint3D32f position, CvPoint3D32f rotation)
00043 {
00044 this->pos = position;
00045 this->rot = rotation;
00046 }
00047
00048 CoordinateFrame::CoordinateFrame(float posX, float posY, float posZ, float rotX, float rotY, float rotZ)
00049 {
00050 this->pos = cvPoint3D32f(posX,posY,posZ);
00051 this->rot = cvPoint3D32f(rotX,rotY,rotZ);
00052 }
00053
00054 CoordinateFrame::CoordinateFrame(CvPoint3D32f position, float rotX, float rotY, float rotZ)
00055 {
00056 this->pos = position;
00057 this->rot = cvPoint3D32f(rotX,rotY,rotZ);
00058 }
00059
00060 CoordinateFrame::CoordinateFrame(float posX, float posY, float posZ, CvPoint3D32f rotation)
00061 {
00062 this->pos = cvPoint3D32f(posX,posY,posZ);
00063 this->rot = rotation;
00064 }
00065
00066 CoordinateFrame::CoordinateFrame(CvPoint3D32f* p1, CvPoint3D32f* p2, CvPoint3D32f* p3)
00067 {
00068 orthonormalizePoints(p1,p2,p3);
00069 CvPoint3D32f vx;
00070 CvPoint3D32f vy;
00071 CvPoint3D32f vz;
00072
00073 subPoints(p2,p1,&vx);
00074 subPoints(p3,p1,&vy);
00075
00076 crossProduct(&vx,&vy,&vz);
00077
00078 float phi = atan2(vx.y,vx.x);
00079 float psi = atan2(vy.z,vz.z);
00080 float theta = atan2(-vx.z,vx.x*cos(phi)+vx.y*sin(phi));
00081
00082 pos = *p1;
00083 rot = cvPoint3D32f(psi,theta,phi);
00084 }
00085
00086 CoordinateFrame::CoordinateFrame(cv::Point3f p1, cv::Point3f p2, cv::Point3f p3)
00087 {
00088 cv::Point3f e1, e2;
00089
00090 e1 = p2 - p1;
00091 e2 = p3 - p1;
00092
00093 cv::norm(e1);
00094 cv::norm(e2);
00095
00096 cv::Point3f e3 = e1.cross(e2);
00097 cv::norm(e3);
00098 e2 = e3.cross(e1);
00099 cv::norm(e2);
00100
00101 e1 += p1;
00102 e2 += p2;
00103
00104
00105 cv::Point3f b1(p1), b2(e1), b3(e2);
00106 cv::Point3f vx = b2 - b1;
00107 cv::Point3f vy = b3 - b1;
00108 cv::Point3f vz = vx.cross(vz);
00109
00110 double phi = atan2(vx.y, vx.x);
00111 double psi = atan2(vy.z, vz.z);
00112 double theta = atan2(-vx.z, vx.x*cos(phi)+vx.y*sin(phi));
00113 pos = b1;
00114 rot = cv::Point3d(psi, theta, phi);
00115 }
00116
00117
00118 CoordinateFrame::CoordinateFrame(CvMat* trafoMat)
00119 {
00120
00121 if ( trafoMat )
00122 {
00123 CvMat* thisToBaseMat = trafoMat;
00124
00125
00126
00127 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00128 CvPoint3D32f p2 = cvPoint3D32f(1,0,0);
00129 CvPoint3D32f p3 = cvPoint3D32f(0,1,0);
00130
00131 transformPoint(&p1, thisToBaseMat);
00132 transformPoint(&p2, thisToBaseMat);
00133 transformPoint(&p3, thisToBaseMat);
00134
00135 CvPoint3D32f vx;
00136 CvPoint3D32f vy;
00137 CvPoint3D32f vz;
00138
00139 subPoints(&p2,&p1,&vx);
00140 subPoints(&p3,&p1,&vy);
00141
00142 crossProduct(&vx,&vy,&vz);
00143
00144 float phi = atan2(vx.y,vx.x);
00145 float psi = atan2(vy.z,vz.z);
00146 float theta = atan2(-vx.z,vx.x*cos(phi)+vx.y*sin(phi));
00147
00148 pos = p1;
00149 rot = cvPoint3D32f(psi,theta,phi);
00150
00151 }
00152 }
00153
00154 CoordinateFrame::CoordinateFrame()
00155 {
00156 this->pos = cvPoint3D32f(0,0,0);
00157 this->rot = cvPoint3D32f(0,0,0);
00158 }
00159
00160
00161 CoordinateFrame::~CoordinateFrame()
00162 {
00163
00164 }
00165
00166 CvMat* CoordinateFrame::createTransformationMatrix()
00167 {
00168 return Utils3D::createTransformationMatrix(&(this->pos), &(this->rot));
00169 }
00170
00171 CvMat* CoordinateFrame::createTransformationMatrix3x3()
00172 {
00173
00174 CvMat * mat4x4 = Utils3D::createTransformationMatrix(&(this->pos), &(this->rot));
00175
00176 CvMat * mat3x3 = cvCreateMat(3,3,CV_64FC1);
00177
00178 for ( int i = 0; i < 3; i ++ )
00179 {
00180 for ( int j = 0; j < 3; j ++ )
00181 {
00182 CV_MAT_ELEM(*mat3x3,double,i,j) = CV_MAT_ELEM(*mat4x4,double,i,j);
00183 }
00184 }
00185
00186 cvReleaseMat(&mat4x4);
00187
00188 return mat3x3;
00189 }
00190
00191 void CoordinateFrame::getThreePoints(CvPoint3D32f* p0,CvPoint3D32f* p1,CvPoint3D32f* p2)
00192 {
00193 assert(p0);
00194 assert(p1);
00195 assert(p2);
00196
00197 CvMat* thisToWorldMat = this->createTransformationMatrix();
00198
00199 Utils3D::setCoords(p0,0,0,0);
00200 Utils3D::setCoords(p1,1,0,0);
00201 Utils3D::setCoords(p2,0,1,0);
00202
00203 transformPoint(p0, thisToWorldMat);
00204 transformPoint(p1, thisToWorldMat);
00205 transformPoint(p2, thisToWorldMat);
00206 }
00207
00208
00209 CoordinateFrame * CoordinateFrame::cInFrame(CoordinateFrame * base)
00210 {
00211 assert(base);
00212
00213 CoordinateFrame *retpos = new CoordinateFrame(0.,0.,0.,0.,0.,0.);
00214
00215 CvMat* baseToWorldMat = base->createTransformationMatrix();
00216 CvMat* thisToWorldMat = this->createTransformationMatrix();
00217
00218 CvMat * worldToBaseMat = createIdentityMatrix();
00219
00220 cvInvert(baseToWorldMat,worldToBaseMat);
00221
00222 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00223 CvPoint3D32f p2 = cvPoint3D32f(1,0,0);
00224 CvPoint3D32f p3 = cvPoint3D32f(0,1,0);
00225
00226 transformPoint(&p1, thisToWorldMat);
00227 transformPoint(&p2, thisToWorldMat);
00228 transformPoint(&p3, thisToWorldMat);
00229
00230 transformPoint(&p1, worldToBaseMat);
00231 transformPoint(&p2, worldToBaseMat);
00232 transformPoint(&p3, worldToBaseMat);
00233
00234 CvPoint3D32f vx;
00235 CvPoint3D32f vy;
00236 CvPoint3D32f vz;
00237
00238 subPoints(&p2,&p1,&vx);
00239 subPoints(&p3,&p1,&vy);
00240
00241 crossProduct(&vx,&vy,&vz);
00242
00243 float phi = atan2(vx.y,vx.x);
00244 float psi = atan2(vy.z,vz.z);
00245 float theta = atan2(-vx.z,vx.x*cos(phi)+vx.y*sin(phi));
00246
00247 retpos->pos = p1;
00248 retpos->rot = cvPoint3D32f(psi,theta,phi);
00249
00250 cvReleaseMat(& thisToWorldMat);
00251 cvReleaseMat(& baseToWorldMat);
00252
00253 return retpos;
00254 }
00255
00256
00257 CoordinateFrame * CoordinateFrame::cInWorld(CoordinateFrame * base)
00258 {
00259
00260 assert(base);
00261
00262 CoordinateFrame *retpos = new CoordinateFrame(0.,0.,0.,0.,0.,0.);
00263
00264 CvMat* thisToBaseMat = this->createTransformationMatrix();
00265 CvMat* baseToWorldMat = base->createTransformationMatrix();
00266
00267 CvMat* thisToWorldMat = createIdentityMatrix();
00268 cvMatMul(baseToWorldMat,thisToBaseMat,thisToWorldMat);
00269
00270
00271 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00272 CvPoint3D32f p2 = cvPoint3D32f(1,0,0);
00273 CvPoint3D32f p3 = cvPoint3D32f(0,1,0);
00274
00275 transformPoint(&p1, thisToWorldMat);
00276 transformPoint(&p2, thisToWorldMat);
00277 transformPoint(&p3, thisToWorldMat);
00278
00279 CvPoint3D32f vx;
00280 CvPoint3D32f vy;
00281 CvPoint3D32f vz;
00282
00283 subPoints(&p2,&p1,&vx);
00284 subPoints(&p3,&p1,&vy);
00285
00286 crossProduct(&vx,&vy,&vz);
00287
00288 float phi = atan2(vx.y,vx.x);
00289 float psi = atan2(vy.z,vz.z);
00290 float theta = atan2(-vx.z,vx.x*cos(phi)+vx.y*sin(phi));
00291
00292 retpos->pos = p1;
00293 retpos->rot = cvPoint3D32f(psi,theta,phi);
00294
00295 cvReleaseMat(& thisToBaseMat);
00296 cvReleaseMat(& thisToWorldMat);
00297 cvReleaseMat(& baseToWorldMat);
00298
00299 return retpos;
00300 }
00301
00302 CoordinateFrame * CoordinateFrame::cMakeFrame(CoordinateFrame * base)
00303 {
00304 CvPoint3D32f p0 = cvPoint3D32f(0,0,0);
00305 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00306 CvPoint3D32f p2 = cvPoint3D32f(0,0,0);
00307 this->getThreePoints(&p0,&p1,&p2);
00308 return cMakeFrame(&p0,&p1,&p2);
00309 }
00310
00311 CoordinateFrame * CoordinateFrame::cMakeFrame(CvPoint3D32f* p0,CvPoint3D32f* p1,CvPoint3D32f* p2)
00312 {
00313
00314 CvPoint3D32f org = cvPoint3D32f(0,0,0);
00315 CvPoint3D32f rot = cvPoint3D32f(0,0,0);
00316
00317 Utils3D::setCoords(p0,&org);
00318
00319 CvPoint3D32f vx = cvPoint3D32f(0,0,0);
00320 CvPoint3D32f vy = cvPoint3D32f(0,0,0);
00321 CvPoint3D32f vz = cvPoint3D32f(0,0,0);
00322 CvPoint3D32f vv = cvPoint3D32f(0,0,0);
00323 CvPoint3D32f vw = cvPoint3D32f(0,0,0);
00324
00325
00326 Utils3D::subPoints(p1,p0,&vx);
00327
00328 Utils3D::normalize(&vx);
00329
00330 Utils3D::subPoints(p2,p0,&vv);
00331
00332 Utils3D::crossProduct(&vx,&vv,&vw);
00333
00334 Utils3D::normalize(&vw);
00335
00336 Utils3D::crossProduct(&vx,&vw,&vy);
00337
00338 Utils3D::normalize(&vy);
00339
00340 Utils3D::crossProduct(&vx,&vy,&vz);
00341
00342 Utils3D::normalize(&vz);
00343
00344 float phi = atan2(vx.y,vx.x);
00345 float psi = atan2(vy.z,vz.z);
00346 float theta = atan2(-vx.z,vx.x*cos(phi)+vx.y*sin(phi));
00347
00348 rot.x = psi;
00349 rot.y = theta;
00350 rot.z = phi;
00351
00352 CoordinateFrame* localBase = new CoordinateFrame(org,rot);
00353
00354 return localBase;
00355 }
00356
00357 void CoordinateFrame::setPos(CvPoint3D32f* pos_)
00358 {
00359 this->pos = * pos_;
00360 }
00361
00362 void CoordinateFrame::setRot(CvPoint3D32f* rot_)
00363 {
00364 this->rot = * rot_;
00365 }
00366
00367 void CoordinateFrame::getXAxis(CvPoint3D32f* normal)
00368 {
00369 CvPoint3D32f p0 = cvPoint3D32f(0,0,0);
00370 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00371 CvPoint3D32f p2 = cvPoint3D32f(0,0,0);
00372 this->getThreePoints(&p0,&p1,&p2);
00373 Utils3D::subPoints(&p1,&p0,normal);
00374 Utils3D::normalize(normal);
00375 }
00376
00377 void CoordinateFrame::getYAxis(CvPoint3D32f* normal)
00378 {
00379 CvPoint3D32f p0 = cvPoint3D32f(0,0,0);
00380 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00381 CvPoint3D32f p2 = cvPoint3D32f(0,0,0);
00382 this->getThreePoints(&p0,&p1,&p2);
00383 Utils3D::subPoints(&p2,&p0,normal);
00384 Utils3D::normalize(normal);
00385 }
00386
00387 void CoordinateFrame::getZAxis(CvPoint3D32f* normal)
00388 {
00389 CvPoint3D32f p0 = cvPoint3D32f(0,0,0);
00390 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00391 CvPoint3D32f p2 = cvPoint3D32f(0,0,0);
00392 this->getThreePoints(&p0,&p1,&p2);
00393 CvPoint3D32f p2p0 = cvPoint3D32f(0,0,0);
00394 Utils3D::subPoints(&p2,&p0,&p2p0);
00395 CvPoint3D32f p1p0 = cvPoint3D32f(0,0,0);
00396 Utils3D::subPoints(&p1,&p0,&p1p0);
00397 Utils3D::crossProduct(&p1p0,&p2p0,normal);
00398 Utils3D::normalize(normal);
00399 }
00400
00401 void CoordinateFrame::toggleZDirection()
00402 {
00403 CvPoint3D32f p0 = cvPoint3D32f(0,0,0);
00404 CvPoint3D32f p1 = cvPoint3D32f(0,0,0);
00405 CvPoint3D32f p2 = cvPoint3D32f(0,0,0);
00406 this->getThreePoints(&p0,&p1,&p2);
00407 CvPoint3D32f p2p0 = cvPoint3D32f(0,0,0);
00408 Utils3D::subPoints(&p2,&p0,&p2p0);
00409 Utils3D::scalePoint(&p2p0,-1);
00410 Utils3D::addPoints(&p0,&p2p0,&p2);
00411 CoordinateFrame tmp = CoordinateFrame(&p0,&p1,&p2);
00412 this->setPos(tmp.getPos());
00413 this->setRot(tmp.getRot());
00414 }