00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef GEO_H
00029 #define GEO_H
00030
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/math/CMatrixTemplateNumeric.h>
00033 #include <mrpt/poses/CPoint2D.h>
00034 #include <mrpt/poses/CPoint3D.h>
00035 #include <mrpt/poses/CPose2D.h>
00036 #include <mrpt/poses/CPose3D.h>
00037 #include <mrpt/math/lightweight_geom_data.h>
00038 #include <mrpt/math/CSparseMatrixTemplate.h>
00039 #include <mrpt/math/utils.h>
00040
00041
00042
00043
00044 namespace mrpt
00045 {
00046 namespace math
00047 {
00048 using std::vector;
00049 using namespace mrpt::utils;
00050 using namespace mrpt::poses;
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 extern double BASE_IMPEXP geometryEpsilon;
00061
00062
00063
00064
00065
00066 class BASE_IMPEXP TPolygonWithPlane {
00067 public:
00068
00069
00070
00071 TPolygon3D poly;
00072
00073
00074
00075 TPlane plane;
00076
00077
00078
00079
00080 mrpt::poses::CPose3D pose;
00081
00082
00083
00084
00085 mrpt::poses::CPose3D inversePose;
00086
00087
00088
00089
00090 TPolygon2D poly2D;
00091
00092
00093
00094 TPolygonWithPlane(const TPolygon3D &p);
00095
00096
00097
00098
00099 TPolygonWithPlane() {}
00100
00101
00102
00103 static void getPlanes(const vector<TPolygon3D> &oldPolys,vector<TPolygonWithPlane> &newPolys);
00104 };
00105
00106
00107
00108
00109
00110
00111
00112
00113 bool BASE_IMPEXP intersect(const TSegment3D &s1,const TSegment3D &s2,TObject3D &obj);
00114
00115
00116
00117
00118 bool BASE_IMPEXP intersect(const TSegment3D &s1,const TPlane &p2,TObject3D &obj);
00119
00120
00121
00122
00123 bool BASE_IMPEXP intersect(const TSegment3D &s1,const TLine3D &r2,TObject3D &obj);
00124
00125
00126
00127
00128 inline bool intersect(const TPlane &p1,const TSegment3D &s2,TObject3D &obj) {
00129 return intersect(s2,p1,obj);
00130 }
00131
00132
00133
00134
00135 bool BASE_IMPEXP intersect(const TPlane &p1,const TPlane &p2,TObject3D &obj);
00136
00137
00138
00139
00140 bool BASE_IMPEXP intersect(const TPlane &p1,const TLine3D &p2,TObject3D &obj);
00141
00142
00143
00144
00145 inline bool intersect(const TLine3D &r1,const TSegment3D &s2,TObject3D &obj) {
00146 return intersect(s2,r1,obj);
00147 }
00148
00149
00150
00151
00152 inline bool intersect(const TLine3D &r1,const TPlane &p2,TObject3D &obj) {
00153 return intersect(p2,r1,obj);
00154 }
00155
00156
00157
00158
00159 bool BASE_IMPEXP intersect(const TLine3D &r1,const TLine3D &r2,TObject3D &obj);
00160
00161
00162
00163
00164 bool BASE_IMPEXP intersect(const TLine2D &r1,const TLine2D &r2,TObject2D &obj);
00165
00166
00167
00168
00169 bool BASE_IMPEXP intersect(const TLine2D &r1,const TSegment2D &s2,TObject2D &obj);
00170
00171
00172
00173
00174 inline bool intersect(const TSegment2D &s1,const TLine2D &r2,TObject2D &obj) {
00175 return intersect(r2,s1,obj);
00176 }
00177
00178
00179
00180
00181 bool BASE_IMPEXP intersect(const TSegment2D &s1,const TSegment2D &s2,TObject2D &obj);
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 double BASE_IMPEXP getAngle(const TPlane &p1,const TPlane &p2);
00192
00193
00194
00195 double BASE_IMPEXP getAngle(const TPlane &p1,const TLine3D &r2);
00196
00197
00198
00199 inline double getAngle(const TLine3D &r1,const TPlane &p2) {
00200 return getAngle(p2,r1);
00201 }
00202
00203
00204
00205 double BASE_IMPEXP getAngle(const TLine3D &r1,const TLine3D &r2);
00206
00207
00208
00209 double BASE_IMPEXP getAngle(const TLine2D &r1,const TLine2D &r2);
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 void BASE_IMPEXP createFromPoseX(const CPose3D &p,TLine3D &r);
00221
00222
00223
00224
00225 void BASE_IMPEXP createFromPoseY(const CPose3D &p,TLine3D &r);
00226
00227
00228
00229
00230 void BASE_IMPEXP createFromPoseZ(const CPose3D &p,TLine3D &r);
00231
00232
00233
00234
00235 void BASE_IMPEXP createFromPoseAndVector(const CPose3D &p,const double (&vector)[3],TLine3D &r);
00236
00237
00238
00239
00240 void BASE_IMPEXP createFromPoseX(const TPose2D &p,TLine2D &r);
00241
00242
00243
00244
00245 void BASE_IMPEXP createFromPoseY(const TPose2D &p,TLine2D &r);
00246
00247
00248
00249
00250 void BASE_IMPEXP createFromPoseAndVector(const TPose2D &p,const double (&vector)[2],TLine2D &r);
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 bool BASE_IMPEXP conformAPlane(const std::vector<TPoint3D> &points);
00262
00263
00264
00265
00266 bool BASE_IMPEXP conformAPlane(const std::vector<TPoint3D> &points,TPlane &p);
00267
00268
00269
00270
00271 bool BASE_IMPEXP areAligned(const std::vector<TPoint2D> &points);
00272
00273
00274
00275
00276 bool BASE_IMPEXP areAligned(const std::vector<TPoint2D> &points,TLine2D &r);
00277
00278
00279
00280
00281 bool BASE_IMPEXP areAligned(const std::vector<TPoint3D> &points);
00282
00283
00284
00285 bool BASE_IMPEXP areAligned(const std::vector<TPoint3D> &points,TLine3D &r);
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 inline void project3D(const TPoint3D &point, const CPose3D &newXYpose,TPoint3D &newPoint) {
00296 newXYpose.composePoint(point.x,point.y,point.z,newPoint.x,newPoint.y,newPoint.z);
00297 }
00298
00299
00300
00301 inline void project3D(const TSegment3D &segment,const CPose3D &newXYpose,TSegment3D &newSegment) {
00302 project3D(segment.point1,newXYpose,newSegment.point1);
00303 project3D(segment.point2,newXYpose,newSegment.point2);
00304 }
00305
00306
00307
00308 void BASE_IMPEXP project3D(const TLine3D &line,const CPose3D &newXYpose,TLine3D &newLine);
00309
00310
00311
00312 void BASE_IMPEXP project3D(const TPlane &plane,const CPose3D &newXYpose,TPlane &newPlane);
00313
00314
00315
00316 void BASE_IMPEXP project3D(const TPolygon3D &polygon,const CPose3D &newXYpose,TPolygon3D &newPolygon);
00317
00318
00319
00320 void BASE_IMPEXP project3D(const TObject3D &object,const CPose3D &newXYPose,TObject3D &newObject);
00321
00322
00323
00324
00325 template<class T> void project3D(const T &obj,const TPlane &newXYPlane,T &newObj) {
00326 CPose3D pose;
00327 TPlane(newXYPlane).getAsPose3D(pose);
00328 project3D(obj,-pose,newObj);
00329 }
00330
00331
00332
00333
00334 template<class T> void project3D(const T &obj,const TPlane &newXYPlane,const TPoint3D &newOrigin,T &newObj) {
00335 CPose3D pose;
00336
00337 TPlane(newXYPlane).getAsPose3D(pose);
00338 project3D(obj,-pose,newObj);
00339 }
00340
00341
00342
00343
00344 template<class T> void project3D(const std::vector<T> &objs,const CPose3D &newXYpose,std::vector<T> &newObjs) {
00345 size_t N=objs.size();
00346 newObjs.resize(N);
00347 for (size_t i=0;i<N;i++) project3D(objs[i],newXYpose,newObjs[i]);
00348 }
00349
00350
00351
00352
00353 inline void project2D(const TPoint2D &point,const CPose2D &newXpose,TPoint2D &newPoint) {
00354 newPoint=newXpose+CPoint2D(point);
00355 }
00356
00357
00358
00359 inline void project2D(const TSegment2D &segment,const CPose2D &newXpose,TSegment2D &newSegment) {
00360 project2D(segment.point1,newXpose,newSegment.point1);
00361 project2D(segment.point2,newXpose,newSegment.point2);
00362 }
00363
00364
00365
00366
00367 void BASE_IMPEXP project2D(const TLine2D &line,const CPose2D &newXpose,TLine2D &newLine);
00368
00369
00370
00371 void BASE_IMPEXP project2D(const TPolygon2D &polygon,const CPose2D &newXpose,TPolygon2D &newPolygon);
00372
00373
00374
00375 void BASE_IMPEXP project2D(const TObject2D &object,const CPose2D &newXpose,TObject2D &newObject);
00376
00377
00378
00379
00380 template<class T> void project2D(const T &obj,const TLine2D &newXLine,T &newObj) {
00381 CPose2D pose;
00382 newXLine.getAsPose2D(pose);
00383 project2D(obj,CPose2D(0,0,0)-pose,newObj);
00384 }
00385
00386
00387
00388
00389 template<class T> void project2D(const T &obj,const TLine2D &newXLine,const TPoint2D &newOrigin,T &newObj) {
00390 CPose2D pose;
00391 newXLine.getAsPose2DForcingOrigin(newOrigin,pose);
00392 project2D(obj,CPose2D(0,0,0)-pose,newObj);
00393 }
00394
00395
00396
00397
00398 template<class T> void project2D(const std::vector<T> &objs,const CPose2D &newXpose,std::vector<T> &newObjs) {
00399 size_t N=objs.size();
00400 newObjs.resize(N);
00401 for (size_t i=0;i<N;i++) project2D(objs[i],newXpose,newObjs[i]);
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 bool BASE_IMPEXP intersect(const TPolygon2D &p1,const TSegment2D &s2,TObject2D &obj);
00414
00415
00416
00417
00418 bool BASE_IMPEXP intersect(const TPolygon2D &p1,const TLine2D &r2,TObject2D &obj);
00419
00420
00421
00422
00423 bool BASE_IMPEXP intersect(const TPolygon2D &p1,const TPolygon2D &p2,TObject2D &obj);
00424
00425
00426
00427
00428 inline bool intersect(const TSegment2D &s1,const TPolygon2D &p2,TObject2D &obj) {
00429 return intersect(p2,s1,obj);
00430 }
00431
00432
00433
00434
00435 inline bool intersect(const TLine2D &r1,const TPolygon2D &p2,TObject2D &obj) {
00436 return intersect(p2,r1,obj);
00437 }
00438
00439
00440
00441
00442 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TSegment3D &s2,TObject3D &obj);
00443
00444
00445
00446
00447 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TLine3D &r2,TObject3D &obj);
00448
00449
00450
00451
00452 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TPlane &p2,TObject3D &obj);
00453
00454
00455
00456
00457 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TPolygon3D &p2,TObject3D &obj);
00458
00459
00460
00461
00462 inline bool intersect(const TSegment3D &s1,const TPolygon3D &p2,TObject3D &obj) {
00463 return intersect(p2,s1,obj);
00464 }
00465
00466
00467
00468
00469 inline bool intersect(const TLine3D &r1,const TPolygon3D &p2,TObject3D &obj) {
00470 return intersect(p2,r1,obj);
00471 }
00472
00473
00474
00475
00476 inline bool intersect(const TPlane &p1,const TPolygon3D &p2,TObject3D &obj) {
00477 return intersect(p2,p1,obj);
00478 }
00479
00480
00481
00482
00483
00484 size_t BASE_IMPEXP intersect(const std::vector<TPolygon3D> &v1,const std::vector<TPolygon3D> &v2,CSparseMatrixTemplate<TObject3D> &objs);
00485
00486
00487
00488
00489 size_t BASE_IMPEXP intersect(const std::vector<TPolygon3D> &v1,const std::vector<TPolygon3D> &v2,std::vector<TObject3D> &objs);
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 template<class T,class U,class O> size_t intersect(const std::vector<T> &v1,const std::vector<U> &v2,CSparseMatrixTemplate<O> &objs) {
00501 size_t M=v1.size(),N=v2.size();
00502 O obj;
00503 objs.clear();
00504 objs.resize(M,N);
00505 for (size_t i=0;i<M;i++) for (size_t j=0;j<M;j++) if (intersect(v1[i],v2[j],obj)) objs(i,j)=obj;
00506 return objs.getNonNullElements();
00507 }
00508
00509
00510
00511
00512
00513 template<class T,class U,class O> size_t intersect(const std::vector<T> &v1,const std::vector<U> &v2,std::vector<O> objs) {
00514 objs.resize(0);
00515 O obj;
00516 for (typename std::vector<T>::const_iterator it1=v1.begin();it1!=v1.end();it1++) {
00517 const T &elem1=*it1;
00518 for (typename std::vector<U>::const_iterator it2=v2.begin();it2!=v2.end();it2++) if (intersect(elem1,*it2,obj)) objs.push_back(obj);
00519 }
00520 return objs.size();
00521 }
00522
00523
00524
00525
00526 bool BASE_IMPEXP intersect(const TObject2D &o1,const TObject2D &o2,TObject2D &obj);
00527
00528
00529
00530 bool BASE_IMPEXP intersect(const TObject3D &o1,const TObject3D &o2,TObject3D &obj);
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 double BASE_IMPEXP distance(const TPoint2D &p1,const TPoint2D &p2);
00541
00542
00543
00544 double BASE_IMPEXP distance(const TPoint3D &p1,const TPoint3D &p2);
00545
00546
00547
00548 double BASE_IMPEXP distance(const TLine2D &r1,const TLine2D &r2);
00549
00550
00551
00552 double BASE_IMPEXP distance(const TLine3D &r1,const TLine3D &r2);
00553
00554
00555
00556 double BASE_IMPEXP distance(const TPlane &p1,const TPlane &p2);
00557
00558
00559
00560
00561 double BASE_IMPEXP distance(const TPolygon2D &p1,const TPolygon2D &p2);
00562
00563
00564
00565 double BASE_IMPEXP distance(const TPolygon2D &p1,const TSegment2D &s2);
00566
00567
00568
00569 inline double distance(const TSegment2D &s1,const TPolygon2D &p2) {
00570 return distance(p2,s1);
00571 }
00572
00573
00574
00575 double BASE_IMPEXP distance(const TPolygon2D &p1,const TLine2D &l2);
00576 inline double distance(const TLine2D &l1,const TPolygon2D &p2) {
00577 return distance(p2,l1);
00578 }
00579
00580
00581
00582 double BASE_IMPEXP distance(const TPolygon3D &p1,const TPolygon3D &p2);
00583
00584
00585
00586 double BASE_IMPEXP distance(const TPolygon3D &p1,const TSegment3D &s2);
00587
00588
00589
00590 inline double distance(const TSegment3D &s1,const TPolygon3D &p2) {
00591 return distance(p2,s1);
00592 }
00593
00594
00595
00596 double BASE_IMPEXP distance(const TPolygon3D &p1,const TLine3D &l2);
00597
00598
00599
00600 inline double distance(const TLine3D &l1,const TPolygon3D &p2) {
00601 return distance(p2,l1);
00602 }
00603
00604
00605
00606 double BASE_IMPEXP distance(const TPolygon3D &po,const TPlane &pl);
00607
00608
00609
00610 inline double distance(const TPlane &pl,const TPolygon3D &po) {
00611 return distance(po,pl);
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 void BASE_IMPEXP getRectangleBounds(const std::vector<TPoint2D> &poly,TPoint2D &pMin,TPoint2D &pMax);
00623
00624
00625
00626 void BASE_IMPEXP getPrismBounds(const std::vector<TPoint3D> &poly,TPoint3D &pMin,TPoint3D &pMax);
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 void BASE_IMPEXP createPlaneFromPoseXY(const CPose3D &pose,TPlane &plane);
00638
00639
00640
00641
00642 void BASE_IMPEXP createPlaneFromPoseXZ(const CPose3D &pose,TPlane &plane);
00643
00644
00645
00646
00647 void BASE_IMPEXP createPlaneFromPoseYZ(const CPose3D &pose,TPlane &plane);
00648
00649
00650
00651
00652 void BASE_IMPEXP createPlaneFromPoseAndNormal(const CPose3D &pose,const double (&normal)[3],TPlane &plane);
00653
00654
00655
00656 void BASE_IMPEXP generateAxisBaseFromDirectionAndAxis(const double (&vec)[3],char coord,CMatrixDouble &matrix);
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 double BASE_IMPEXP getRegressionLine(const std::vector<TPoint2D> &points,TLine2D &line);
00668
00669
00670
00671
00672 double BASE_IMPEXP getRegressionLine(const std::vector<TPoint3D> &points,TLine3D &line);
00673
00674
00675
00676
00677 double BASE_IMPEXP getRegressionPlane(const std::vector<TPoint3D> &points,TPlane &plane);
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 void BASE_IMPEXP assemblePolygons(const std::vector<TSegment3D> &segms,std::vector<TPolygon3D> &polys);
00688
00689
00690
00691 void BASE_IMPEXP assemblePolygons(const std::vector<TSegment3D> &segms,std::vector<TPolygon3D> &polys,std::vector<TSegment3D> &remainder);
00692
00693
00694
00695 void BASE_IMPEXP assemblePolygons(const std::vector<TObject3D> &objs,std::vector<TPolygon3D> &polys);
00696
00697
00698
00699 void BASE_IMPEXP assemblePolygons(const std::vector<TObject3D> &objs,std::vector<TPolygon3D> &polys,std::vector<TObject3D> &remainder);
00700
00701
00702
00703 void BASE_IMPEXP assemblePolygons(const std::vector<TObject3D> &objs,std::vector<TPolygon3D> &polys,std::vector<TSegment3D> &remainder1,std::vector<TObject3D> &remainder2);
00704
00705
00706
00707
00708
00709 inline void setEpsilon(double nE) {
00710 geometryEpsilon=nE;
00711 }
00712
00713
00714
00715
00716 inline double getEpsilon() {
00717 return geometryEpsilon;
00718 }
00719
00720
00721
00722
00723 bool BASE_IMPEXP splitInConvexComponents(const TPolygon2D &poly,vector<TPolygon2D> &components);
00724
00725
00726
00727
00728 bool BASE_IMPEXP splitInConvexComponents(const TPolygon3D &poly,vector<TPolygon3D> &components);
00729
00730
00731
00732
00733 void BASE_IMPEXP getSegmentBisector(const TSegment2D &sgm,TLine2D &bis);
00734
00735
00736
00737 void BASE_IMPEXP getSegmentBisector(const TSegment3D &sgm,TPlane &bis);
00738
00739
00740
00741 void BASE_IMPEXP getAngleBisector(const TLine2D &l1,const TLine2D &l2,TLine2D &bis);
00742
00743
00744
00745
00746 void BASE_IMPEXP getAngleBisector(const TLine3D &l1,const TLine3D &l2,TLine3D &bis);
00747
00748
00749
00750
00751
00752 bool BASE_IMPEXP traceRay(const vector<TPolygonWithPlane> &vec,const mrpt::poses::CPose3D &pose,double &dist);
00753
00754
00755
00756
00757 inline bool traceRay(const vector<TPolygon3D> &vec,const mrpt::poses::CPose3D &pose,double &dist) {
00758 vector<TPolygonWithPlane> pwp;
00759 TPolygonWithPlane::getPlanes(vec,pwp);
00760 return traceRay(pwp,pose,dist);
00761 }
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 template<class T,class U,class V>
00775 inline void crossProduct3D(const T &v0,const U &v1,V& vOut) {
00776 vOut[0]=v0[1]*v1[2]-v0[2]*v1[1];
00777 vOut[1]=v0[2]*v1[0]-v0[0]*v1[2];
00778 vOut[2]=v0[0]*v1[1]-v0[1]*v1[0];
00779 }
00780
00781
00782 template<class T>
00783 inline void crossProduct3D(
00784 const std::vector<T> &v0,
00785 const std::vector<T> &v1,
00786 std::vector<T> &v_out )
00787 {
00788 ASSERT_(v0.size()==3)
00789 ASSERT_(v1.size()==3);
00790 v_out.resize(3);
00791 v_out[0] = v0[1]*v1[2] - v0[2]*v1[1];
00792 v_out[1] = -v0[0]*v1[2] + v0[2]*v1[0];
00793 v_out[2] = v0[0]*v1[1] - v0[1]*v1[0];
00794 }
00795
00796
00797 template<class VEC1,class VEC2>
00798 inline Eigen::Matrix<double,3,1> crossProduct3D(const VEC1 &v0,const VEC2 &v1) {
00799 Eigen::Matrix<double,3,1> vOut;
00800 vOut[0]=v0[1]*v1[2]-v0[2]*v1[1];
00801 vOut[1]=v0[2]*v1[0]-v0[0]*v1[2];
00802 vOut[2]=v0[0]*v1[1]-v0[1]*v1[0];
00803 return vOut;
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 template<class VECTOR,class MATRIX>
00816 inline void skew_symmetric3(const VECTOR &v,MATRIX& M) {
00817 ASSERT_(v.size()==3)
00818 M.setSize(3,3);
00819 M.set_unsafe(0,0, 0); M.set_unsafe(0,1, -v[2]); M.set_unsafe(0,2, v[1]);
00820 M.set_unsafe(1,0, v[2]); M.set_unsafe(1,1, 0); M.set_unsafe(1,2, -v[0]);
00821 M.set_unsafe(2,0, -v[1]); M.set_unsafe(2,1, v[0]); M.set_unsafe(2,2, 0);
00822 }
00823
00824 template<class VECTOR>
00825 inline mrpt::math::CMatrixDouble33 skew_symmetric3(const VECTOR &v) {
00826 mrpt::math::CMatrixDouble33 M(UNINITIALIZED_MATRIX);
00827 skew_symmetric3(v,M);
00828 return M;
00829 }
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 template<class VECTOR,class MATRIX>
00841 inline void skew_symmetric3_neg(const VECTOR &v,MATRIX& M) {
00842 ASSERT_(v.size()==3)
00843 M.setSize(3,3);
00844 M.set_unsafe(0,0, 0); M.set_unsafe(0,1, v[2]); M.set_unsafe(0,2, -v[1]);
00845 M.set_unsafe(1,0, -v[2]); M.set_unsafe(1,1, 0); M.set_unsafe(1,2, v[0]);
00846 M.set_unsafe(2,0, v[1]); M.set_unsafe(2,1, -v[0]); M.set_unsafe(2,2, 0);
00847 }
00848
00849 template<class VECTOR>
00850 inline mrpt::math::CMatrixDouble33 skew_symmetric3_neg(const VECTOR &v) {
00851 mrpt::math::CMatrixDouble33 M(UNINITIALIZED_MATRIX);
00852 skew_symmetric3_neg(v,M);
00853 return M;
00854 }
00855
00856
00857
00858
00859
00860 template<class T,class U> inline bool vectorsAreParallel2D(const T &v1,const U &v2) {
00861 return abs(v1[0]*v2[1]-v2[0]*v1[1])<geometryEpsilon;
00862 }
00863
00864
00865
00866
00867 template<class T,class U>
00868 inline bool vectorsAreParallel3D(const T &v1,const U &v2) {
00869 if (abs(v1[0]*v2[1]-v2[0]*v1[1])>=geometryEpsilon) return false;
00870 if (abs(v1[1]*v2[2]-v2[1]*v1[2])>=geometryEpsilon) return false;
00871 return abs(v1[2]*v2[0]-v2[2]*v1[0])<geometryEpsilon;
00872 }
00873
00874
00875
00876 double BASE_IMPEXP minimumDistanceFromPointToSegment(
00877 const double & Px,
00878 const double & Py,
00879 const double & x1,
00880 const double & y1,
00881 const double & x2,
00882 const double & y2,
00883 double & out_x,
00884 double & out_y);
00885
00886
00887
00888 double BASE_IMPEXP minimumDistanceFromPointToSegment(
00889 const double & Px,
00890 const double & Py,
00891 const double & x1,
00892 const double & y1,
00893 const double & x2,
00894 const double & y2,
00895 float & out_x,
00896 float & out_y);
00897
00898
00899
00900
00901
00902 void BASE_IMPEXP closestFromPointToSegment(
00903 const double & Px,
00904 const double & Py,
00905 const double & x1,
00906 const double & y1,
00907 const double & x2,
00908 const double & y2,
00909 double &out_x,
00910 double &out_y);
00911
00912
00913
00914
00915 void BASE_IMPEXP closestFromPointToLine(
00916 const double & Px,
00917 const double & Py,
00918 const double & x1,
00919 const double & y1,
00920 const double & x2,
00921 const double & y2,
00922 double &out_x,
00923 double &out_y);
00924
00925
00926
00927 double BASE_IMPEXP closestSquareDistanceFromPointToLine(
00928 const double & Px,
00929 const double & Py,
00930 const double & x1,
00931 const double & y1,
00932 const double & x2,
00933 const double & y2 );
00934
00935
00936
00937 template <typename T>
00938 T distanceBetweenPoints(const T x1,const T y1,const T x2,const T y2) {
00939 return std::sqrt( square(x1-x2)+square(y1-y2) );
00940 }
00941
00942
00943 template <typename T>
00944 T distanceBetweenPoints(const T x1,const T y1,const T z1, const T x2,const T y2, const T z2) {
00945 return std::sqrt( square(x1-x2)+square(y1-y2)+square(z1-z2) );
00946 }
00947
00948
00949 template <typename T>
00950 T distanceSqrBetweenPoints(const T x1,const T y1,const T x2,const T y2) {
00951 return square(x1-x2)+square(y1-y2);
00952 }
00953
00954
00955 template <typename T>
00956 T distanceSqrBetweenPoints(const T x1,const T y1,const T z1, const T x2,const T y2, const T z2) {
00957 return square(x1-x2)+square(y1-y2)+square(z1-z2);
00958 }
00959
00960
00961
00962 bool BASE_IMPEXP SegmentsIntersection(
00963 const double & x1,const double & y1,
00964 const double & x2,const double & y2,
00965 const double & x3,const double & y3,
00966 const double & x4,const double & y4,
00967 double &ix,double &iy);
00968
00969
00970
00971 bool BASE_IMPEXP SegmentsIntersection(
00972 const double & x1,const double & y1,
00973 const double & x2,const double & y2,
00974 const double & x3,const double & y3,
00975 const double & x4,const double & y4,
00976 float &ix,float &iy);
00977
00978
00979
00980
00981 bool BASE_IMPEXP pointIntoPolygon2D(const double & px, const double & py, unsigned int polyEdges, const double *poly_xs, const double *poly_ys );
00982
00983
00984
00985
00986 template <typename T>
00987 bool pointIntoQuadrangle(
00988 T x, T y,
00989 T v1x, T v1y,
00990 T v2x, T v2y,
00991 T v3x, T v3y,
00992 T v4x, T v4y )
00993 {
00994 using mrpt::utils::sign;
00995
00996 const T a1 = atan2( v1y - y , v1x - x );
00997 const T a2 = atan2( v2y - y , v2x - x );
00998 const T a3 = atan2( v3y - y , v3x - x );
00999 const T a4 = atan2( v4y - y , v4x - x );
01000
01001
01002
01003 const T da1 = mrpt::math::wrapToPi( a2-a1 );
01004 const T da2 = mrpt::math::wrapToPi( a3-a2 );
01005 if (sign(da1)!=sign(da2)) return false;
01006
01007 const T da3 = mrpt::math::wrapToPi( a4-a3 );
01008 if (sign(da2)!=sign(da3)) return false;
01009
01010 const T da4 = mrpt::math::wrapToPi( a1-a4 );
01011 return (sign(da3)==sign(da4) && (sign(da4)==sign(da1)));
01012 }
01013
01014
01015
01016 double BASE_IMPEXP distancePointToPolygon2D(const double & px, const double & py, unsigned int polyEdges, const double *poly_xs, const double *poly_ys );
01017
01018
01019
01020
01021
01022
01023
01024
01025 bool BASE_IMPEXP minDistBetweenLines(
01026 const double & p1_x, const double & p1_y, const double & p1_z,
01027 const double & p2_x, const double & p2_y, const double & p2_z,
01028 const double & p3_x, const double & p3_y, const double & p3_z,
01029 const double & p4_x, const double & p4_y, const double & p4_z,
01030 double &x, double &y, double &z,
01031 double &dist);
01032
01033
01034
01035
01036
01037
01038
01039 bool BASE_IMPEXP RectanglesIntersection(
01040 const double & R1_x_min, const double & R1_x_max,
01041 const double & R1_y_min, const double & R1_y_max,
01042 const double & R2_x_min, const double & R2_x_max,
01043 const double & R2_y_min, const double & R2_y_max,
01044 const double & R2_pose_x,
01045 const double & R2_pose_y,
01046 const double & R2_pose_phi );
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 template<class T>
01080 CMatrixTemplateNumeric<T> generateAxisBaseFromDirection( T dx, T dy, T dz )
01081 {
01082 MRPT_START
01083
01084 if (dx==0 && dy==0 && dz==0)
01085 THROW_EXCEPTION("Invalid input: Direction vector is (0,0,0)!");
01086
01087 CMatrixTemplateNumeric<T> P(3,3);
01088
01089
01090 T n_xy = square(dx)+square(dy);
01091 T n = sqrt(n_xy+square(dz));
01092 n_xy = sqrt(n_xy);
01093 P(0,0) = dx / n;
01094 P(1,0) = dy / n;
01095 P(2,0) = dz / n;
01096
01097
01098 if (fabs(dx)>1e-4 || fabs(dy)>1e-4)
01099 {
01100 P(0,1) = -dy / n_xy;
01101 P(1,1) = dx / n_xy;
01102 P(2,1) = 0;
01103 }
01104 else
01105 {
01106
01107 P(0,1) = 1;
01108 P(1,1) = 0;
01109 P(2,1) = 0;
01110 }
01111
01112
01113 P.col(2) = crossProduct3D(P.col(0),P.col(1));
01114
01115 return P;
01116 MRPT_END
01117 }
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 template <typename VECTOR_LIKE, typename Precision, typename MATRIX_LIKE>
01134 inline void rodrigues_so3_exp(const VECTOR_LIKE& w, const Precision A,const Precision B,MATRIX_LIKE & R)
01135 {
01136 ASSERT_EQUAL_(w.size(),3)
01137 ASSERT_EQUAL_(R.getColCount(),3)
01138 ASSERT_EQUAL_(R.getRowCount(),3)
01139 {
01140 const Precision wx2 = (Precision)w[0]*w[0];
01141 const Precision wy2 = (Precision)w[1]*w[1];
01142 const Precision wz2 = (Precision)w[2]*w[2];
01143 R(0,0) = 1.0 - B*(wy2 + wz2);
01144 R(1,1) = 1.0 - B*(wx2 + wz2);
01145 R(2,2) = 1.0 - B*(wx2 + wy2);
01146 }
01147 {
01148 const Precision a = A*w[2];
01149 const Precision b = B*(w[0]*w[1]);
01150 R(0,1) = b - a;
01151 R(1,0) = b + a;
01152 }
01153 {
01154 const Precision a = A*w[1];
01155 const Precision b = B*(w[0]*w[2]);
01156 R(0,2) = b + a;
01157 R(2,0) = b - a;
01158 }
01159 {
01160 const Precision a = A*w[0];
01161 const Precision b = B*(w[1]*w[2]);
01162 R(1,2) = b - a;
01163 R(2,1) = b + a;
01164 }
01165 }
01166
01167
01168
01169
01170
01171 }
01172
01173 }
01174 #endif