00001
00031 #include "Utils3D.h"
00032
00033 using namespace Utils3D;
00034
00035 namespace Utils3D
00036 {
00037
00038
00039
00040 CvMat* createIdentityMatrix()
00041 {
00042 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00043 cvmSet(mat,0,0,1);
00044 cvmSet(mat,0,1,0);
00045 cvmSet(mat,0,2,0);
00046 cvmSet(mat,0,3,0);
00047 cvmSet(mat,1,0,0);
00048 cvmSet(mat,1,1,1);
00049 cvmSet(mat,1,2,0);
00050 cvmSet(mat,1,3,0);
00051 cvmSet(mat,2,0,0);
00052 cvmSet(mat,2,1,0);
00053 cvmSet(mat,2,2,1);
00054 cvmSet(mat,2,3,0);
00055 cvmSet(mat,3,0,0);
00056 cvmSet(mat,3,1,0);
00057 cvmSet(mat,3,2,0);
00058 cvmSet(mat,3,3,1);
00059 return mat;
00060 }
00061
00062 CvMat* createRotationMatrixX( double angle )
00063 {
00064 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00065 cvmSet(mat,0,0,1);
00066 cvmSet(mat,0,1,0);
00067 cvmSet(mat,0,2,0);
00068 cvmSet(mat,0,3,0);
00069 cvmSet(mat,1,0,0);
00070 cvmSet(mat,1,1,cos(angle));
00071 cvmSet(mat,1,2,-sin(angle));
00072 cvmSet(mat,1,3,0);
00073 cvmSet(mat,2,0,0);
00074 cvmSet(mat,2,1,sin(angle));
00075 cvmSet(mat,2,2,cos(angle));
00076 cvmSet(mat,2,3,0);
00077 cvmSet(mat,3,0,0);
00078 cvmSet(mat,3,1,0);
00079 cvmSet(mat,3,2,0);
00080 cvmSet(mat,3,3,1);
00081 return mat;
00082 }
00083
00084
00085 CvMat* createRotationMatrixY( double angle )
00086 {
00087 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00088 cvmSet(mat,0,0,cos(angle));
00089 cvmSet(mat,0,1,0);
00090 cvmSet(mat,0,2,sin(angle));
00091 cvmSet(mat,0,3,0);
00092 cvmSet(mat,1,0,0);
00093 cvmSet(mat,1,1,1);
00094 cvmSet(mat,1,2,0);
00095 cvmSet(mat,1,3,0);
00096 cvmSet(mat,2,0,-sin(angle));
00097 cvmSet(mat,2,1,0);
00098 cvmSet(mat,2,2,cos(angle));
00099 cvmSet(mat,2,3,0);
00100 cvmSet(mat,3,0,0);
00101 cvmSet(mat,3,1,0);
00102 cvmSet(mat,3,2,0);
00103 cvmSet(mat,3,3,1);
00104 return mat;
00105 }
00106
00107
00108 CvMat* createRotationMatrixZ( double angle )
00109 {
00110 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00111 cvmSet(mat,0,0,cos(angle));
00112 cvmSet(mat,0,1,-sin(angle));
00113 cvmSet(mat,0,2,0);
00114 cvmSet(mat,0,3,0);
00115 cvmSet(mat,1,0,sin(angle));
00116 cvmSet(mat,1,1,cos(angle));
00117 cvmSet(mat,1,2,0);
00118 cvmSet(mat,1,3,0);
00119 cvmSet(mat,2,0,0);
00120 cvmSet(mat,2,1,0);
00121 cvmSet(mat,2,2,1);
00122 cvmSet(mat,2,3,0);
00123 cvmSet(mat,3,0,0);
00124 cvmSet(mat,3,1,0);
00125 cvmSet(mat,3,2,0);
00126 cvmSet(mat,3,3,1);
00127 return mat;
00128 }
00129
00130
00131 CvMat* createTranslationMatrix( CvPoint3D32f* trans )
00132 {
00133 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00134 cvmSet(mat,0,0,1);
00135 cvmSet(mat,0,1,0);
00136 cvmSet(mat,0,2,0);
00137 cvmSet(mat,0,3,trans->x);
00138 cvmSet(mat,1,0,0);
00139 cvmSet(mat,1,1,1);
00140 cvmSet(mat,1,2,0);
00141 cvmSet(mat,1,3,trans->y);
00142 cvmSet(mat,2,0,0);
00143 cvmSet(mat,2,1,0);
00144 cvmSet(mat,2,2,1);
00145 cvmSet(mat,2,3,trans->z);
00146 cvmSet(mat,3,0,0);
00147 cvmSet(mat,3,1,0);
00148 cvmSet(mat,3,2,0);
00149 cvmSet(mat,3,3,1);
00150 return mat;
00151 }
00152
00153 CvMat* createRotationCoordinateSystemMatrixX( double angle )
00154 {
00155 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00156 cvmSet(mat,0,0,1);
00157 cvmSet(mat,0,1,0);
00158 cvmSet(mat,0,2,0);
00159 cvmSet(mat,0,3,0);
00160 cvmSet(mat,1,0,0);
00161 cvmSet(mat,1,1,cos(angle));
00162 cvmSet(mat,1,2,sin(angle));
00163 cvmSet(mat,1,3,0);
00164 cvmSet(mat,2,0,0);
00165 cvmSet(mat,2,1,-sin(angle));
00166 cvmSet(mat,2,2,cos(angle));
00167 cvmSet(mat,2,3,0);
00168 cvmSet(mat,3,0,0);
00169 cvmSet(mat,3,1,0);
00170 cvmSet(mat,3,2,0);
00171 cvmSet(mat,3,3,1);
00172 return mat;
00173 }
00174
00175
00176 CvMat* createRotationCoordinateSystemMatrixY( double angle )
00177 {
00178 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00179 cvmSet(mat,0,0,cos(angle));
00180 cvmSet(mat,0,1,0);
00181 cvmSet(mat,0,2,-sin(angle));
00182 cvmSet(mat,0,3,0);
00183 cvmSet(mat,1,0,0);
00184 cvmSet(mat,1,1,1);
00185 cvmSet(mat,1,2,0);
00186 cvmSet(mat,1,3,0);
00187 cvmSet(mat,2,0,sin(angle));
00188 cvmSet(mat,2,1,0);
00189 cvmSet(mat,2,2,cos(angle));
00190 cvmSet(mat,2,3,0);
00191 cvmSet(mat,3,0,0);
00192 cvmSet(mat,3,1,0);
00193 cvmSet(mat,3,2,0);
00194 cvmSet(mat,3,3,1);
00195 return mat;
00196 }
00197
00198
00199 CvMat* createRotationCoordinateSystemMatrixZ( double angle )
00200 {
00201 CvMat * mat = cvCreateMat(4,4,CV_64FC1);
00202 cvmSet(mat,0,0,cos(angle));
00203 cvmSet(mat,0,1,sin(angle));
00204 cvmSet(mat,0,2,0);
00205 cvmSet(mat,0,3,0);
00206 cvmSet(mat,1,0,-sin(angle));
00207 cvmSet(mat,1,1,cos(angle));
00208 cvmSet(mat,1,2,0);
00209 cvmSet(mat,1,3,0);
00210 cvmSet(mat,2,0,0);
00211 cvmSet(mat,2,1,0);
00212 cvmSet(mat,2,2,1);
00213 cvmSet(mat,2,3,0);
00214 cvmSet(mat,3,0,0);
00215 cvmSet(mat,3,1,0);
00216 cvmSet(mat,3,2,0);
00217 cvmSet(mat,3,3,1);
00218 return mat;
00219 }
00220
00221 void generatePlaneVectorsFromNormal(CvPoint3D32f*plainNormal,CvPoint3D32f* v1,CvPoint3D32f*v2)
00222 {
00223 CvPoint3D32f xAxis = cvPoint3D32f(1,0,0);
00224 CvPoint3D32f yAxis = cvPoint3D32f(0,1,0);
00225 CvPoint3D32f zAxis = cvPoint3D32f(0,0,1);
00226
00227 CvPoint3D32f vis1 = cvPoint3D32f(0,0,0);
00228 CvPoint3D32f vis2 = cvPoint3D32f(0,0,0);
00229
00230 Utils3D::crossProduct(plainNormal,&xAxis,&vis1);
00231 Utils3D::crossProduct(&vis1,plainNormal,&vis2);
00232
00233
00234 if ( fabs(plainNormal->x) > .999999f )
00235 {
00236 Utils3D::setCoords(&yAxis ,&vis1);
00237 if ( plainNormal->x < 0)
00238 Utils3D::scalePoint(&vis1,-1);
00239
00240 Utils3D::setCoords(&zAxis ,&vis2);
00241 }
00242
00243 if ( fabs(plainNormal->y) > .999999f )
00244 {
00245 Utils3D::setCoords(&yAxis ,&vis1);
00246 if ( plainNormal->y < 0)
00247 Utils3D::scalePoint(&vis1,-1);
00248 Utils3D::setCoords(&zAxis ,&vis2);
00249 }
00250
00251 Utils3D::normalize(& vis1);
00252 Utils3D::normalize(& vis2);
00253
00254
00255 Utils3D::setCoords(&vis1,v1);
00256 Utils3D::setCoords(&vis2,v2);
00257
00258 }
00259
00260 CvMat* createTransformationMatrix(CvPoint3D32f* trans, double rotX, double rotY, double rotZ)
00261 {
00262 CvMat * mat = createIdentityMatrix();
00263 CvMat * rotMx = createRotationMatrixX(rotX);
00264 CvMat * rotMy = createRotationMatrixY(rotY);
00265 CvMat * rotMz = createRotationMatrixZ(rotZ);
00266 CvMat * transM = createTranslationMatrix(trans);
00267
00268 cvMatMul(rotMx, mat, mat);
00269 cvMatMul(rotMy, mat, mat);
00270 cvMatMul(rotMz, mat, mat);
00271 cvMatMul(transM, mat, mat);
00272
00273 cvReleaseMat(&rotMx);
00274 cvReleaseMat(&rotMy);
00275 cvReleaseMat(&rotMz);
00276 cvReleaseMat(&transM);
00277
00278 return mat;
00279 }
00280
00281
00282
00283
00284
00285
00286 CvMat* createTransformationMatrix(CvPoint3D32f* trans, CvPoint3D32f* rot)
00287 {
00288 return createTransformationMatrix(trans, rot->x, rot->y, rot->z);
00289 }
00290
00291
00292
00293 void transformPoint(CvPoint3D32f* point, CvMat* transformationMat)
00294 {
00295 CvMat * pointVec = cvCreateMat(4,1,CV_64FC1);
00296
00297 cvmSet(pointVec,0,0,point->x);
00298 cvmSet(pointVec,1,0,point->y);
00299 cvmSet(pointVec,2,0,point->z);
00300 cvmSet(pointVec,3,0,1);
00301
00302 cvMatMul(transformationMat, pointVec, pointVec);
00303
00304 double w = cvmGet(pointVec,3,0);
00305
00306 if (w == 0)
00307 {
00308 cout << "ERROR in transformPoint... w==0" << endl;
00309 exit(-2357232);
00310 }
00311 else
00312 {
00313 point->x = float( cvmGet(pointVec,0,0) / w );
00314 point->y = float( cvmGet(pointVec,1,0) / w );
00315 point->z = float( cvmGet(pointVec,2,0) / w );
00316 }
00317 cvReleaseMat(&pointVec);
00318 }
00319
00320
00321 void transformDirection(CvPoint3D32f* dir, CvMat* transformationMat)
00322 {
00323
00324 CvMat * dirVec = cvCreateMat(4,1,CV_64FC1);
00325
00326 cvmSet(dirVec,0,0,dir->x);
00327 cvmSet(dirVec,1,0,dir->y);
00328 cvmSet(dirVec,2,0,dir->z);
00329 cvmSet(dirVec,3,0,0);
00330
00331 cvMatMul(transformationMat, dirVec, dirVec);
00332
00333 dir->x = float( cvmGet(dirVec,0,0) );
00334 dir->y = float( cvmGet(dirVec,1,0) );
00335 dir->z = float( cvmGet(dirVec,2,0) );
00336
00337 normalize(dir);
00338
00339 }
00340
00341
00342 void normalize(CvPoint3D32f* vec)
00343 {
00344 float length = sqrt((vec->x * vec->x) + (vec->y * vec->y) + (vec->z * vec->z));
00345 if(length > 0)
00346 {
00347 vec->x = vec->x / length;
00348 vec->y = vec->y / length;
00349 vec->z = vec->z / length;
00350 }
00351 else
00352 {
00353
00354
00355
00356
00357 }
00358 }
00359
00360 void fillStraightLine(CvPoint3D32f loc, CvPoint3D32f dir, STRAIGHTLINE * line)
00361 {
00362 fillStraightLine(loc.x,loc.y,loc.z,dir.x,dir.y,dir.z, line);
00363 }
00364
00365 void fillStraightLine(float locX, float locY, float locZ, float dirX, float dirY, float dirZ, STRAIGHTLINE * line)
00366 {
00367 line->loc.x = locX;
00368 line->loc.y = locY;
00369 line->loc.z = locZ;
00370
00371 line->dir.x = dirX;
00372 line->dir.y = dirY;
00373 line->dir.z = dirZ;
00374
00375 normalize(&(line->dir));
00376 }
00377
00378
00379
00380 void fillPlane(CvPoint3D32f loc, CvPoint3D32f dir1, CvPoint3D32f dir2, PLANE * plane)
00381 {
00382 fillPlane(loc.x, loc.y, loc.z, dir1.x, dir1.y, dir1.z, dir2.x, dir2.y, dir2.z, plane);
00383 }
00384
00385 void fillPlane(float locX, float locY, float locZ, float dir1X, float dir1Y, float dir1Z, float dir2X, float dir2Y, float dir2Z, PLANE * plane)
00386 {
00387 plane->loc.x = locX;
00388 plane->loc.y = locY;
00389 plane->loc.z = locZ;
00390
00391 plane->dir1.x = dir1X;
00392 plane->dir1.y = dir1Y;
00393 plane->dir1.z = dir1Z;
00394
00395 plane->dir2.x = dir2X;
00396 plane->dir2.y = dir2Y;
00397 plane->dir2.z = dir2Z;
00398
00399 normalize(&(plane->dir1));
00400 normalize(&(plane->dir2));
00401
00402 }
00403
00404 void transformStraightLine(STRAIGHTLINE* line, CvMat* transformationMat)
00405 {
00406 transformPoint(&(line->loc), transformationMat);
00407 transformDirection(&(line->dir), transformationMat);
00408 }
00409
00410
00411 void transformPlane(PLANE* plane, CvMat* transformationMat)
00412 {
00413 transformPoint(&(plane->loc), transformationMat);
00414 transformDirection(&(plane->dir1), transformationMat);
00415 transformDirection(&(plane->dir2), transformationMat);
00416 }
00417
00418
00419 double intersectLinePlane(STRAIGHTLINE line, PLANE plain)
00420 {
00421 #if 0
00422 double a[3][4];
00423
00424
00425
00426
00427
00428
00429
00430 a[0][0] = plain.dir1.x; a[0][1] = plain.dir2.x; a[0][2] = - line.dir.x; a[0][3] = line.loc.x - plain.loc.x;
00431 a[1][0] = plain.dir1.y; a[1][1] = plain.dir2.y; a[1][2] = - line.dir.y; a[1][3] = line.loc.y - plain.loc.y;
00432 a[2][0] = plain.dir1.z; a[2][1] = plain.dir2.z; a[2][2] = - line.dir.z; a[2][3] = line.loc.z - plain.loc.z;
00433
00434
00435 if (a[0][0] == 0.0)
00436 {
00437 for(int i = 0; i < 4; i++)
00438 {
00439 double t = a[0][i];
00440 a[0][i] = a[1][i];
00441 a[1][i] = t;
00442 }
00443
00444 }
00445 if (a[0][0] == 0.0)
00446 {
00447 for(int i = 0; i < 4; i++)
00448 {
00449 double t = a[0][i];
00450 a[0][i] = a[2][i];
00451 a[2][i] = t;
00452 }
00453 }
00454
00455
00456 if (a[1][0] != 0.0)
00457 {
00458 double d = a[1][0] / a[0][0];
00459 for(int i = 0; i < 4; i++) a[1][i] = a[1][i] - (d*a[0][i]);
00460 }
00461
00462
00463
00464 if (a[2][0] != 0.0)
00465 {
00466 double d = a[2][0] / a[0][0];
00467 for(int i = 0; i < 4; i++) a[2][i] = a[2][i] - (d*a[0][i]);
00468 }
00469
00470
00471 if (a[1][1] == 0.0)
00472 {
00473 for(int i = 0; i < 4; i++)
00474 {
00475 double t = a[1][i];
00476 a[1][i] = a[2][i];
00477 a[2][i] = t;
00478 }
00479 }
00480
00481
00482
00483 if (a[2][1] != 0.0)
00484 {
00485 double d = a[2][1] / a[1][1];
00486 for(int i = 0; i < 4; i++) a[2][i] = a[2][i] - (d*a[1][i]);
00487 }
00488
00489 double x3;
00490
00491 if (a[2][3] == 0.0) x3 = 0.0;
00492 else x3 = a[2][3]/a[2][2];
00493
00494 return (float) x3;
00495 #else
00496
00497 CvPoint3D32f n = cvPoint3D32f(0,0,0);
00498 crossProduct(&plain.dir1,&plain.dir2,&n);
00499 CvPoint3D32f diff = cvPoint3D32f(0,0,0);
00500 Utils3D::subPoints(&plain.loc,&line.loc,&diff);
00501 double scal = dotProd(&n,&line.dir)/getNorm(&n)/getNorm(&line.dir);
00502 if ( scal == 0)
00503 {
00504
00505 }
00506 return dotProd(&n,&diff)/scal;
00507 #endif
00508 }
00509
00510 STRAIGHTLINE intersectPlanes(PLANE2 P1,PLANE2 P2)
00511 {
00512 STRAIGHTLINE line;
00513 crossProduct(&P1.norm,&P2.norm,&line.dir);
00514
00515
00516
00517 STRAIGHTLINE tline;
00518
00519 CvPoint3D32f pPoint = projectPointOnPlane(P1,P2.loc);
00520
00521 subPoints(&P1.loc,&pPoint,&tline.dir);
00522
00523 tline.loc = P1.loc;
00524
00525 double l = intersectLinePlane(tline,P2);
00526
00527 scalePoint(&tline.dir, l);
00528
00529 addPoints(&tline.loc,&tline.dir,&line.loc);
00530
00531 return line;
00532 }
00533
00534 double getPointPlaneDistance(PLANE2 P, CvPoint3D32f p)
00535 {
00536 CvPoint3D32f diff = cvPoint3D32f(0,0,0);
00537 subPoints(&P.loc,&p,&diff);
00538 return dotProd(&diff,&P.norm);
00539 }
00540
00541 CvPoint3D32f projectPointOnPlane(PLANE2 P,CvPoint3D32f p)
00542 {
00543 double dist = getPointPlaneDistance(P,p);
00544 CvPoint3D32f n = cvPoint3D32f(0,0,0);
00545 setCoords(&P.norm,&n);
00546 scalePoint(&n,-dist);
00547 CvPoint3D32f r = cvPoint3D32f(0,0,0);
00548 addPoints(&p,&n,&r);
00549 return r;
00550 }
00551
00552 CvPoint3D32f projectPointOnLine(STRAIGHTLINE line,CvPoint3D32f* p)
00553 {
00554 CvPoint3D32f d = cvPoint3D32f(0,0,0);
00555 subPoints(&line.loc,p,&d);
00556 float k = (float)dotProd(&d,&line.dir);
00557 addWPoints(&line.loc,1,&line.dir,-k,&d);
00558 return d;
00559 }
00560
00561 double intersectLinePlane(STRAIGHTLINE line, PLANE2 plane)
00562 {
00563 double d = getPointPlaneDistance(plane,line.loc);
00564 double scal = dotProd(&line.dir,&plane.norm);
00565 if ( scal == 0)
00566 {
00567
00568 }
00569 return d * getNorm(&plane.norm)*getNorm(&line.dir) / scal;
00570 }
00571
00572 double distPoints(CvPoint3D32f* p1, CvPoint3D32f * p2)
00573 {
00574 CvPoint3D32f d = cvPoint3D32f(0,0,0);
00575 subPoints(p1,p2,&d);
00576 return getNorm(&d);
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 double dotProd(CvPoint3D32f* p1, CvPoint3D32f* p2 )
00592 {
00593 return p1->x * p2->x + p1->y * p2->y + p1->z * p2->z;
00594 }
00595
00596 double getAngle(CvPoint3D32f* p1, CvPoint3D32f* p2 )
00597 {
00598 return acos (dotProd ( p1 , p2 ) / getNorm(p1) / getNorm(p2));
00599 }
00600
00601 CvPoint3D32f * cAddPoints(CvPoint3D32f* p1, CvPoint3D32f * p2)
00602 {
00603 return cAddWPoints(p1,1,p2,1);
00604 }
00605
00606 void addPoints(CvPoint3D32f* p1, CvPoint3D32f * p2,CvPoint3D32f*res)
00607 {
00608 addWPoints(p1,1,p2,1,res);
00609 }
00610
00611 CvPoint3D32f * cAddWPoints(CvPoint3D32f * p1, float w1, CvPoint3D32f * p2, float w2 )
00612 {
00613 CvPoint3D32f * np = new CvPoint3D32f;
00614 np->x = w1* p1->x + w2 * p2->x;
00615 np->y = w1* p1->y + w2 * p2->y;
00616 np->z = w1* p1->z + w2 * p2->z;
00617 return np;
00618 }
00619
00620 void addWPoints(CvPoint3D32f * p1, float w1, CvPoint3D32f * p2, float w2, CvPoint3D32f*np )
00621 {
00622 np->x = w1* p1->x + w2 * p2->x;
00623 np->y = w1* p1->y + w2 * p2->y;
00624 np->z = w1* p1->z + w2 * p2->z;
00625 }
00626
00627 CvPoint3D32f * cSubPoints(CvPoint3D32f* p1, CvPoint3D32f * p2)
00628 {
00629 return cAddWPoints(p1,1,p2,-1);
00630 }
00631
00632 void subPoints(CvPoint3D32f* p1, CvPoint3D32f * p2,CvPoint3D32f* res)
00633 {
00634 addWPoints(p1,1,p2,-1,res);
00635 }
00636
00637 CvPoint3D32f * cCrossProduct(CvPoint3D32f* p1, CvPoint3D32f* p2)
00638 {
00639 CvPoint3D32f * np = new CvPoint3D32f;
00640 np->x = p1->y * p2->z - p1->z * p2->y;
00641 np->y = p1->z * p2->x - p1->x * p2->z;
00642 np->z = p1->x * p2->y - p1->y * p2->x;
00643 return np;
00644 }
00645
00646 void crossProduct(CvPoint3D32f* p1, CvPoint3D32f* p2,CvPoint3D32f* np)
00647 {
00648 np->x = p1->y * p2->z - p1->z * p2->y;
00649 np->y = p1->z * p2->x - p1->x * p2->z;
00650 np->z = p1->x * p2->y - p1->y * p2->x;
00651 }
00652
00653 CvPoint3D32f * cGetPoint(float x, float y, float z )
00654 {
00655 CvPoint3D32f * p = new CvPoint3D32f;
00656 p->x = x;
00657 p->y = y;
00658 p->z = z;
00659 return p;
00660 }
00661
00662 CvPoint3D32f * cCopyPoint(CvPoint3D32f* p )
00663 {
00664 CvPoint3D32f * o = new CvPoint3D32f ();
00665 o->x = p->x;
00666 o->y = p->y;
00667 o->z = p->z;
00668 return o;
00669 }
00670
00671 void swapPoints(CvPoint3D32f* p1, CvPoint3D32f* p2)
00672 {
00673 CvPoint3D32f* p = cCopyPoint(p1);
00674 p1->x = p2->x;
00675 p1->y = p2->y;
00676 p1->z = p2->z;
00677 p2->x = p->x;
00678 p2->y = p->y;
00679 p2->z = p->z;
00680 delete p;
00681 }
00682
00683 double getNorm(CvPoint3D32f* p )
00684 {
00685 return sqrt(p->x*p->x + p->y*p->y + p->z*p->z );
00686 }
00687
00688
00689 void setCoords (CvPoint3D32f * in, CvPoint3D32f * out)
00690 {
00691 out->x = in->x;
00692 out->y = in->y;
00693 out->z = in->z;
00694 }
00695
00696 void setCoords (CvPoint3D32f * out, float x, float y, float z)
00697 {
00698
00699 out->x = x;
00700 out->y = y;
00701 out->z = z;
00702 }
00703
00704 void scalePoint(CvPoint3D32f* p, double scale)
00705 {
00706 p->x *= (float)scale;
00707 p->y *= (float)scale;
00708 p->z *= (float)scale;
00709 }
00710
00711 void orthonormalizePoints(CvPoint3D32f* p1, CvPoint3D32f* p2,CvPoint3D32f*p3)
00712 {
00713 orthonormalizePoints(p1,p2,p3,1);
00714 }
00715
00716 void orthonormalizePoints(CvPoint3D32f* p1, CvPoint3D32f* p2,CvPoint3D32f*p3,double scale)
00717 {
00718 CvPoint3D32f * e1 = cSubPoints(p2,p1);
00719 CvPoint3D32f * e2 = cSubPoints(p3,p1);
00720
00721 normalize(e1);
00722 normalize(e2);
00723
00724 CvPoint3D32f * e3 = cCrossProduct(e1,e2);
00725
00726 normalize(e3);
00727
00728 delete e2;
00729
00730 e2 = cCrossProduct(e3,e1);
00731
00732 delete e3;
00733
00734 normalize(e2);
00735
00736 scalePoint(e1,scale);
00737 scalePoint(e2,scale);
00738
00739 addPoints(p1,e1,e1);
00740 addPoints(p1,e2,e2);
00741 setCoords(e1,p2);
00742 setCoords(e2,p3);
00743
00744 delete e2;
00745 delete e1;
00746
00747 }
00748
00749
00750 CvMat* cGetBasisFrom3Points(CvPoint3D32f* p1, CvPoint3D32f * p2, CvPoint3D32f * p3 )
00751 {
00752
00753 orthonormalizePoints(p1,p2,p3);
00754
00755 CvPoint3D32f * e1 = cSubPoints(p2,p1);
00756 normalize(e1);
00757 CvPoint3D32f * e2 = cSubPoints(p3,p1);
00758 normalize(e2);
00759 CvPoint3D32f * e3 = cCrossProduct(e1,e2);
00760 normalize(e3);
00761
00762 double b[] = {e1->x,e2->x,e3->x, 0,
00763 e1->y,e2->y,e3->y, 0,
00764 e1->z,e2->z,e3->z, 0,
00765 0 , 0 , 0 , 1};
00766
00767 CvMat tmp;
00768
00769 cvInitMatHeader(&tmp,4,4,CV_64FC1,b);
00770
00771 CvMat * P = cvCloneMat(&tmp);
00772
00773 delete e1;
00774 delete e2;
00775 delete e3;
00776
00777 return P;
00778 }
00779
00780 CvMat* cGetBasisFrom3Points3x3(CvPoint3D32f* p1, CvPoint3D32f * p2, CvPoint3D32f * p3 )
00781 {
00782
00783 orthonormalizePoints(p1,p2,p3);
00784
00785 CvPoint3D32f * e1 = cSubPoints(p2,p1);
00786 normalize(e1);
00787 CvPoint3D32f * e2 = cSubPoints(p3,p1);
00788 normalize(e2);
00789 CvPoint3D32f * e3 = cCrossProduct(e1,e2);
00790 normalize(e3);
00791
00792 double b[] = {e1->x,e2->x,e3->x,
00793 e1->y,e2->y,e3->y,
00794 e1->z,e2->z,e3->z};
00795
00796 CvMat tmp;
00797
00798 cvInitMatHeader(&tmp,3,3,CV_64FC1,b);
00799
00800 CvMat * P = cvCloneMat(&tmp);
00801
00802 delete e1;
00803 delete e2;
00804 delete e3;
00805
00806 return P;
00807 }
00808
00809 CvMat * createMatrixFrom3Points(CvPoint3D32f* p1, CvPoint3D32f* p2,CvPoint3D32f* p3)
00810 {
00811 CvMat * ret = cvCreateMat(3,3,CV_32FC1);
00812 cvmSet(ret,0,0,p1->x);
00813 cvmSet(ret,0,1,p1->y);
00814 cvmSet(ret,0,2,p1->z);
00815
00816 cvmSet(ret,1,0,p2->x);
00817 cvmSet(ret,1,1,p2->y);
00818 cvmSet(ret,1,2,p2->z);
00819
00820 cvmSet(ret,2,0,p3->x);
00821 cvmSet(ret,2,1,p3->y);
00822 cvmSet(ret,2,2,p3->z);
00823
00824 return ret;
00825 }
00826
00827 CvMat * cGetMat32fFrom64d(CvMat* mat64d)
00828 {
00829 CvMat * mat32f = cvCreateMat(mat64d->rows,mat64d->cols,CV_32FC1);
00830 cvCvtScale(mat64d,mat32f);
00831 return mat32f;
00832 }
00833
00834 CvMat * cGetMat64dFrom32f(CvMat* mat32f)
00835 {
00836 CvMat * mat64d = cvCreateMat(mat32f->rows,mat32f->cols,CV_64FC1);
00837 cvCvtScale(mat32f,mat64d);
00838 return mat64d;
00839 }
00840
00841
00842 CvPoint3D32f * cRectifyPoint(CvPoint3D32f * oriPoint, float sensorLengthScale, float sensorWidthScale, float sensorHeightScale, CvMat * map_matrix)
00843 {
00844 CvPoint3D32f * retVal = new CvPoint3D32f();
00845
00846 retVal->y = oriPoint->y * sensorLengthScale;
00847 retVal->z = (oriPoint->z * 16) * sensorHeightScale;
00848
00849 CvMat* vec = cvCreateMat( 3, 1, CV_32F );
00850 cvmSet( vec, 0, 0, oriPoint->x );
00851 cvmSet( vec, 1, 0, 8192 - (oriPoint->z * 16) );
00852 cvmSet( vec, 2, 0, 1);
00853
00854 CvMat* erg = cvCreateMat( 3, 1, CV_32F );
00855 cvMatMul(map_matrix, vec, erg);
00856
00857 retVal->x = (float)( cvmGet(erg, 0, 0) / cvmGet(erg, 2, 0));
00858
00859 cvReleaseMat( &vec );
00860 cvReleaseMat( &erg );
00861
00862 if(sensorWidthScale != 0)
00863 {
00864 retVal->x *= sensorWidthScale;
00865 }
00866
00867 return retVal;
00868 }
00869
00870 CvPoint3D32f * cInverseRectifyPoint(CvPoint3D32f * oriPoint, float sensorLenghtScale, float sensorWidthScale, float sensorHeightScale, CvMat * map_matrix)
00871 {
00872 assert(sensorWidthScale != 0);
00873 assert(sensorLenghtScale != 0);
00874 assert(sensorHeightScale != 0);
00875 assert(map_matrix);
00876
00877 CvPoint3D32f * retVal = new CvPoint3D32f();
00878
00879 CvMat * inverse_map_matrix = cvCreateMat( 3, 3, CV_32F );
00880 cvInvert( map_matrix, inverse_map_matrix, CV_LU );
00881
00882 retVal->y = oriPoint->y / sensorLenghtScale;
00883 retVal->z = (oriPoint->z / 16) / sensorHeightScale;
00884
00885 CvMat* vec = cvCreateMat( 3, 1, CV_32F );
00886 cvmSet( vec, 0, 0, oriPoint->x / sensorWidthScale );
00887 cvmSet( vec, 1, 0, 8192 - ((oriPoint->z) / sensorHeightScale));
00888 cvmSet( vec, 2, 0, 1);
00889
00890 CvMat* erg = cvCreateMat( 3, 1, CV_32F );
00891 cvMatMul(inverse_map_matrix, vec, erg);
00892
00893 retVal->x = (float) (cvmGet(erg, 0, 0) / cvmGet(erg, 2, 0));
00894
00895 cvReleaseMat( &vec );
00896 cvReleaseMat( &erg );
00897 cvReleaseMat( &inverse_map_matrix );
00898
00899 return retVal;
00900 }
00901
00902 CvMat* cCalcRectificationMatrix(CvPoint2D32f* oriP1, CvPoint2D32f* oriP2, CvPoint2D32f* oriP3, CvPoint2D32f* oriP4, CvPoint2D32f* dstP1, CvPoint2D32f* dstP2,CvPoint2D32f* dstP3,CvPoint2D32f* dstP4)
00903 {
00904 CvMat * map_matrix = cvCreateMat( 3, 3, CV_32F );
00905 CvPoint2D32f src[4];
00906 CvPoint2D32f dst[4];
00907
00908 src[0] = *oriP1;
00909 src[1] = *oriP2;
00910 src[2] = *oriP3;
00911 src[3] = *oriP4;
00912
00913 dst[0] = *dstP1;
00914 dst[1] = *dstP2;
00915 dst[2] = *dstP3;
00916 dst[3] = *dstP4;
00917
00918 cvGetPerspectiveTransform( src,dst, map_matrix );
00919 return map_matrix;
00920 }
00921
00922
00923 float getShortestDistanceBetweenTwoLines( STRAIGHTLINE line1, STRAIGHTLINE line2, float * d1, float * d2)
00924 {
00925 CvPoint3D32f n;
00926 crossProduct(&line1.dir,&line2.dir,&n);
00927 CvMat* m = cvCreateMat(3,3,CV_MAT32F);
00928 CV_MAT_ELEM(*m,float,0,0) = line1.dir.x;
00929 CV_MAT_ELEM(*m,float,1,0) = line1.dir.y;
00930 CV_MAT_ELEM(*m,float,2,0) = line1.dir.z;
00931
00932 CV_MAT_ELEM(*m,float,0,1) = -line2.dir.x;
00933 CV_MAT_ELEM(*m,float,1,1) = -line2.dir.y;
00934 CV_MAT_ELEM(*m,float,2,1) = -line2.dir.z;
00935
00936 CV_MAT_ELEM(*m,float,0,2) = -n.x;
00937 CV_MAT_ELEM(*m,float,1,2) = -n.y;
00938 CV_MAT_ELEM(*m,float,2,2) = -n.z;
00939
00940 CvPoint3D32f diff;
00941
00942 subPoints(&line2.loc,&line1.loc,&diff);
00943
00944 CvMat* p = cvCreateMat(3,1,CV_MAT32F);
00945 CV_MAT_ELEM(*p,float,0,0) = diff.x;
00946 CV_MAT_ELEM(*p,float,1,0) = diff.y;
00947 CV_MAT_ELEM(*p,float,2,0) = diff.z;
00948
00949
00950 cvInvert(m,m);
00951
00952 cvMatMul(m,p,p);
00953
00954 *d1 = CV_MAT_ELEM(*p,float,0,0);
00955 *d2 = CV_MAT_ELEM(*p,float,1,0);
00956 float ret = CV_MAT_ELEM(*p,float,2,0);
00957
00958 cvReleaseMat(&m);
00959 cvReleaseMat(&p);
00960
00961 return ret;
00962 }
00963
00964 float getLineParameter(STRAIGHTLINE line, CvPoint3D32f p)
00965 {
00966 CvPoint3D32f d = cvPoint3D32f(0,0,0);
00967 subPoints(&line.loc,&p,&d);
00968 float k = (float) dotProd(&d,&line.dir);
00969 return -k;
00970 }
00971
00972 CvPoint3D32f getLinePoint(STRAIGHTLINE line, float param);
00973
00974 CvPoint3D32f getLinePoint(STRAIGHTLINE line, float param)
00975 {
00976 CvPoint3D32f p;
00977 addWPoints(&line.loc,1,&line.dir,param,&p);
00978 return p;
00979 }
00980 }