Main MRPT website > C++ reference
MRPT logo
geometry.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
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         Class
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                 /** \addtogroup geometry_grp Geometry: lines, planes, intersections, SLERP, "lightweight" point & pose classes
00054                   *  \ingroup mrpt_base_grp
00055                   * @{ */
00056 
00057                 /**
00058                   * Global epsilon to overcome small precision errors
00059                   */
00060                 extern double BASE_IMPEXP geometryEpsilon;
00061 
00062                 /**
00063                   * Slightly heavyweight type to speed-up calculations with polygons in 3D
00064                   * \sa TPolygon3D,TPlane
00065                   */
00066                 class BASE_IMPEXP TPolygonWithPlane     {
00067                 public:
00068                         /**
00069                           * Actual polygon.
00070                           */
00071                         TPolygon3D poly;
00072                         /**
00073                           * Plane containing the polygon.
00074                           */
00075                         TPlane plane;
00076                         /**
00077                           * Plane's pose.
00078                           * \sa inversePose
00079                           */
00080                         mrpt::poses::CPose3D pose;
00081                         /**
00082                           * Plane's inverse pose.
00083                           * \sa pose
00084                           */
00085                         mrpt::poses::CPose3D inversePose;
00086                         /**
00087                           * Polygon, after being projected to the plane using inversePose.
00088                           * \sa inversePose
00089                           */
00090                         TPolygon2D poly2D;
00091                         /**
00092                           * Constructor. Takes a polygon and computes each parameter.
00093                           */
00094                         TPolygonWithPlane(const TPolygon3D &p);
00095                         /**
00096                           * Basic constructor. Needed to create containers.
00097                           * \sa TPolygonWithPlane(const TPolygon3D &)
00098                           */
00099                         TPolygonWithPlane()     {}
00100                         /**
00101                           * Static method for vectors. Takes a set of polygons and creates every TPolygonWithPlane
00102                           */
00103                         static void getPlanes(const vector<TPolygon3D> &oldPolys,vector<TPolygonWithPlane> &newPolys);
00104                 };
00105 
00106                 /** @name Simple intersection operations, relying basically on geometrical operations.
00107                         @{
00108                  */
00109                 /**
00110                   * Gets the intersection between two 3D segments.
00111                   * \sa TObject3D
00112                   */
00113                 bool BASE_IMPEXP intersect(const TSegment3D &s1,const TSegment3D &s2,TObject3D &obj);
00114                 /**
00115                   * Gets the intersection between a 3D segment and a plane.
00116                   * \sa TObject3D
00117                   */
00118                 bool BASE_IMPEXP intersect(const TSegment3D &s1,const TPlane &p2,TObject3D &obj);
00119                 /**
00120                   * Gets the intersection between a 3D segment and a 3D line.
00121                   * \sa TObject3D
00122                   */
00123                 bool BASE_IMPEXP intersect(const TSegment3D &s1,const TLine3D &r2,TObject3D &obj);
00124                 /**
00125                   * Gets the intersection between a plane and a 3D segment.
00126                   * \sa TObject3D
00127                   */
00128                 inline bool intersect(const TPlane &p1,const TSegment3D &s2,TObject3D &obj)     {
00129                         return intersect(s2,p1,obj);
00130                 }
00131                 /**
00132                   * Gets the intersection between two planes.
00133                   * \sa TObject3D
00134                   */
00135                 bool BASE_IMPEXP intersect(const TPlane &p1,const TPlane &p2,TObject3D &obj);
00136                 /**
00137                   * Gets the intersection between a plane and a 3D line.
00138                   * \sa TObject3D
00139                   */
00140                 bool BASE_IMPEXP intersect(const TPlane &p1,const TLine3D &p2,TObject3D &obj);
00141                 /**
00142                   * Gets the intersection between a 3D line and a 3D segment.
00143                   * \sa TObject3D
00144                   */
00145                 inline bool intersect(const TLine3D &r1,const TSegment3D &s2,TObject3D &obj)    {
00146                         return intersect(s2,r1,obj);
00147                 }
00148                 /**
00149                   * Gets the intersection between a 3D line and a plane.
00150                   * \sa TObject3D
00151                   */
00152                 inline bool intersect(const TLine3D &r1,const TPlane &p2,TObject3D &obj)        {
00153                         return intersect(p2,r1,obj);
00154                 }
00155                 /**
00156                   * Gets the intersection between two 3D lines.
00157                   * \sa TObject3D
00158                   */
00159                 bool BASE_IMPEXP intersect(const TLine3D &r1,const TLine3D &r2,TObject3D &obj);
00160                 /**
00161                   * Gets the intersection between two 2D lines.
00162                   * \sa TObject2D
00163                   */
00164                 bool BASE_IMPEXP intersect(const TLine2D &r1,const TLine2D &r2,TObject2D &obj);
00165                 /**
00166                   * Gets the intersection between a 2D line and a 2D segment.
00167                   * \sa TObject2D
00168                   */
00169                 bool BASE_IMPEXP intersect(const TLine2D &r1,const TSegment2D &s2,TObject2D &obj);
00170                 /**
00171                   * Gets the intersection between a 2D line and a 2D segment.
00172                   * \sa TObject2D
00173                   */
00174                 inline bool intersect(const TSegment2D &s1,const TLine2D &r2,TObject2D &obj)    {
00175                         return intersect(r2,s1,obj);
00176                 }
00177                 /**
00178                   * Gets the intersection between two 2D segments.
00179                   * \sa TObject2D
00180                   */
00181                 bool BASE_IMPEXP intersect(const TSegment2D &s1,const TSegment2D &s2,TObject2D &obj);
00182                 /** @}
00183                  */
00184 
00185                 /** @name Angle retrieval methods. Methods which use TSegments will automatically use TLines' implicit constructors.
00186                         @{
00187                  */
00188                 /**
00189                   * Computes the angle between two planes.
00190                   */
00191                 double BASE_IMPEXP getAngle(const TPlane &p1,const TPlane &p2);
00192                 /**
00193                   * Computes the angle between a plane and a 3D line or segment (implicit constructor will be used if passing a segment instead of a line).
00194                   */
00195                 double BASE_IMPEXP getAngle(const TPlane &p1,const TLine3D &r2);
00196                 /**
00197                   * Computes the angle between a 3D line or segment and a plane (implicit constructor will be used if passing a segment instead of a line).
00198                   */
00199                 inline double getAngle(const TLine3D &r1,const TPlane &p2)      {
00200                         return getAngle(p2,r1);
00201                 }
00202                 /**
00203                   * Computes the angle between two 3D lines or segments (implicit constructor will be used if passing a segment instead of a line).
00204                   */
00205                 double BASE_IMPEXP getAngle(const TLine3D &r1,const TLine3D &r2);
00206                 /**
00207                   * Computes the angle between two 2D lines or segments (implicit constructor will be used if passing a segment instead of a line).
00208                   */
00209                 double BASE_IMPEXP getAngle(const TLine2D &r1,const TLine2D &r2);
00210                 /** @}
00211                  */
00212 
00213                 /** @name Creation of lines from poses.
00214                         @{
00215                  */
00216                 /**
00217                   * Gets a 3D line corresponding to the X axis in a given pose. An implicit constructor is used if a TPose3D is given.
00218                   * \sa createFromPoseY,createFromPoseZ,createFromPoseAndVector
00219                   */
00220                 void BASE_IMPEXP createFromPoseX(const CPose3D &p,TLine3D &r);
00221                 /**
00222                   * Gets a 3D line corresponding to the Y axis in a given pose. An implicit constructor is used if a TPose3D is given.
00223                   * \sa createFromPoseX,createFromPoseZ,createFromPoseAndVector
00224                   */
00225                 void BASE_IMPEXP createFromPoseY(const CPose3D &p,TLine3D &r);
00226                 /**
00227                   * Gets a 3D line corresponding to the Z axis in a given pose. An implicit constructor is used if a TPose3D is given.
00228                   * \sa createFromPoseX,createFromPoseY,createFromPoseAndVector
00229                   */
00230                 void BASE_IMPEXP createFromPoseZ(const CPose3D &p,TLine3D &r);
00231                 /**
00232                   * Gets a 3D line corresponding to any arbitrary vector, in the base given by the pose. An implicit constructor is used if a TPose3D is given.
00233                   * \sa createFromPoseX,createFromPoseY,createFromPoseZ
00234                   */
00235                 void BASE_IMPEXP createFromPoseAndVector(const CPose3D &p,const double (&vector)[3],TLine3D &r);
00236                 /**
00237                   * Gets a 2D line corresponding to the X axis in a given pose. An implicit constructor is used if a CPose2D is given.
00238                   * \sa createFromPoseY,createFromPoseAndVector
00239                   */
00240                 void BASE_IMPEXP createFromPoseX(const TPose2D &p,TLine2D &r);
00241                 /**
00242                   * Gets a 2D line corresponding to the Y axis in a given pose. An implicit constructor is used if a CPose2D is given.
00243                   * \sa createFromPoseX,createFromPoseAndVector
00244                   */
00245                 void BASE_IMPEXP createFromPoseY(const TPose2D &p,TLine2D &r);
00246                 /**
00247                   * Gets a 2D line corresponding to any arbitrary vector, in the base given the given pose. An implicit constructor is used if a CPose2D is given.
00248                   * \sa createFromPoseY,createFromPoseAndVector
00249                   */
00250                 void BASE_IMPEXP createFromPoseAndVector(const TPose2D &p,const double (&vector)[2],TLine2D &r);
00251                 /** @}
00252                  */
00253 
00254                 /** @name Other line or plane related methods.
00255                         @{
00256                  */
00257                 /**
00258                   * Checks whether this polygon or set of points acceptably fits a plane.
00259                   * \sa TPolygon3D,geometryEpsilon
00260                   */
00261                 bool BASE_IMPEXP conformAPlane(const std::vector<TPoint3D> &points);
00262                 /**
00263                   * Checks whether this polygon or set of points acceptably fits a plane, and if it's the case returns it in the second argument.
00264                   * \sa TPolygon3D,geometryEpsilon
00265                   */
00266                 bool BASE_IMPEXP conformAPlane(const std::vector<TPoint3D> &points,TPlane &p);
00267                 /**
00268                   * Checks whether this set of points acceptably fits a 2D line.
00269                   * \sa geometryEpsilon
00270                   */
00271                 bool BASE_IMPEXP areAligned(const std::vector<TPoint2D> &points);
00272                 /**
00273                   * Checks whether this set of points acceptably fits a 2D line, and if it's the case returns it in the second argument.
00274                   * \sa geometryEpsilon
00275                   */
00276                 bool BASE_IMPEXP areAligned(const std::vector<TPoint2D> &points,TLine2D &r);
00277                 /**
00278                   * Checks whether this set of points acceptably fits a 3D line.
00279                   * \sa geometryEpsilon
00280                   */
00281                 bool BASE_IMPEXP areAligned(const std::vector<TPoint3D> &points);
00282                 /**
00283                   * Checks whether this set of points acceptably fits a 3D line, and if it's the case returns it in the second argument.
00284                   */
00285                 bool BASE_IMPEXP areAligned(const std::vector<TPoint3D> &points,TLine3D &r);
00286                 /** @}
00287                  */
00288 
00289                 /** @name Projections
00290                         @{
00291                  */
00292                 /**
00293                   * Uses the given pose 3D to project a point into a new base.
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                   * Uses the given pose 3D to project a segment into a new base.
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                   * Uses the given pose 3D to project a line into a new base.
00307                   */
00308                 void BASE_IMPEXP project3D(const TLine3D &line,const CPose3D &newXYpose,TLine3D &newLine);
00309                 /**
00310                   * Uses the given pose 3D to project a plane into a new base.
00311                   */
00312                 void BASE_IMPEXP project3D(const TPlane &plane,const CPose3D &newXYpose,TPlane &newPlane);
00313                 /**
00314                   * Uses the given pose 3D to project a polygon into a new base.
00315                   */
00316                 void BASE_IMPEXP project3D(const TPolygon3D &polygon,const CPose3D &newXYpose,TPolygon3D &newPolygon);
00317                 /**
00318                   * Uses the given pose 3D to project any 3D object into a new base.
00319                   */
00320                 void BASE_IMPEXP project3D(const TObject3D &object,const CPose3D &newXYPose,TObject3D &newObject);
00321 
00322                 /**
00323                   * Projects any 3D object into the plane's base, using its inverse pose. If the object is exactly inside the plane, this projection will zero its Z coordinates.
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                   * Projects any 3D object into the plane's base, using its inverse pose and forcing the position of the new coordinates origin. If the object is exactly inside the plane, this projection will zero its Z coordinates.
00333                   */
00334                 template<class T> void project3D(const T &obj,const TPlane &newXYPlane,const TPoint3D &newOrigin,T &newObj)     {
00335                         CPose3D pose;
00336                         //TPlane(newXYPlane).getAsPose3DForcingOrigin(newOrigin,pose);
00337                         TPlane(newXYPlane).getAsPose3D(pose);
00338                         project3D(obj,-pose,newObj);
00339                 }
00340 
00341                 /**
00342                   * Projects a set of 3D objects into the plane's base.
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                   * Uses the given pose 2D to project a point into a new base.
00352                   */
00353                 inline void project2D(const TPoint2D &point,const CPose2D &newXpose,TPoint2D &newPoint) {
00354                         newPoint=newXpose+CPoint2D(point);
00355                 }
00356                 /**
00357                   * Uses the given pose 2D to project a segment into a new base.
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                   * Uses the given pose 2D to project a line into a new base.
00366                   */
00367                 void BASE_IMPEXP project2D(const TLine2D &line,const CPose2D &newXpose,TLine2D &newLine);
00368                 /**
00369                   * Uses the given pose 2D to project a polygon into a new base.
00370                   */
00371                 void BASE_IMPEXP project2D(const TPolygon2D &polygon,const CPose2D &newXpose,TPolygon2D &newPolygon);
00372                 /**
00373                   * Uses the given pose 2D to project any 2D object into a new base.
00374                   */
00375                 void BASE_IMPEXP project2D(const TObject2D &object,const CPose2D &newXpose,TObject2D &newObject);
00376 
00377                 /**
00378                   * Projects any 2D object into the line's base, using its inverse pose. If the object is exactly inside the line, this projection will zero its Y coordinate.
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                   * Projects any 2D object into the line's base, using its inverse pose and forcing the position of the new coordinate origin. If the object is exactly inside the line, this projection will zero its Y coordinate.
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                   * Projects a set of 2D objects into the line's base.
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                 /** @name Polygon intersections. These operations rely more on spatial reasoning than in raw numerical operations.
00407                         @{
00408                  */
00409                 /**
00410                   * Gets the intersection between a 2D polygon and a 2D segment.
00411                   * \sa TObject2D
00412                   */
00413                 bool BASE_IMPEXP intersect(const TPolygon2D &p1,const TSegment2D &s2,TObject2D &obj);
00414                 /**
00415                   * Gets the intersection between a 2D polygon and a 2D line.
00416                   * \sa TObject2D
00417                   */
00418                 bool BASE_IMPEXP intersect(const TPolygon2D &p1,const TLine2D &r2,TObject2D &obj);
00419                 /**
00420                   * Gets the intersection between two 2D polygons.
00421                   * \sa TObject2D
00422                   */
00423                 bool BASE_IMPEXP intersect(const TPolygon2D &p1,const TPolygon2D &p2,TObject2D &obj);
00424                 /**
00425                   * Gets the intersection between a 2D segment and a 2D polygon.
00426                   * \sa TObject2D
00427                   */
00428                 inline bool intersect(const TSegment2D &s1,const TPolygon2D &p2,TObject2D &obj) {
00429                         return intersect(p2,s1,obj);
00430                 }
00431                 /**
00432                   * Gets the intersection between a 2D line and a 2D polygon.
00433                   * \sa TObject2D
00434                   */
00435                 inline bool intersect(const TLine2D &r1,const TPolygon2D &p2,TObject2D &obj)    {
00436                         return intersect(p2,r1,obj);
00437                 }
00438                 /**
00439                   * Gets the intersection between a 3D polygon and a 3D segment.
00440                   * \sa TObject3D
00441                   */
00442                 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TSegment3D &s2,TObject3D &obj);
00443                 /**
00444                   * Gets the intersection between a 3D polygon and a 3D line.
00445                   * \sa TObject3D
00446                   */
00447                 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TLine3D &r2,TObject3D &obj);
00448                 /**
00449                   * Gets the intersection between a 3D polygon and a plane.
00450                   * \sa TObject3D
00451                   */
00452                 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TPlane &p2,TObject3D &obj);
00453                 /**
00454                   * Gets the intersection between two 3D polygons.
00455                   * \sa TObject3D
00456                   */
00457                 bool BASE_IMPEXP intersect(const TPolygon3D &p1,const TPolygon3D &p2,TObject3D &obj);
00458                 /**
00459                   * Gets the intersection between a 3D segment and a 3D polygon.
00460                   * \sa TObject3D
00461                   */
00462                 inline bool intersect(const TSegment3D &s1,const TPolygon3D &p2,TObject3D &obj) {
00463                         return intersect(p2,s1,obj);
00464                 }
00465                 /**
00466                   * Gets the intersection between a 3D line and a 3D polygon.
00467                   * \sa TObject3D
00468                   */
00469                 inline bool intersect(const TLine3D &r1,const TPolygon3D &p2,TObject3D &obj)    {
00470                         return intersect(p2,r1,obj);
00471                 }
00472                 /**
00473                   * Gets the intersection between a plane and a 3D polygon.
00474                   * \sa TObject3D
00475                   */
00476                 inline bool intersect(const TPlane &p1,const TPolygon3D &p2,TObject3D &obj)     {
00477                         return intersect(p2,p1,obj);
00478                 }
00479 
00480                 /**
00481                   * Gets the intersection between two sets of 3D polygons. The intersection is returned as an sparse matrix with each pair of polygons' intersections, and the return value is the amount of intersections found.
00482                   * \sa TObject3D,CSparseMatrixTemplate
00483                   */
00484                 size_t BASE_IMPEXP intersect(const std::vector<TPolygon3D> &v1,const std::vector<TPolygon3D> &v2,CSparseMatrixTemplate<TObject3D> &objs);
00485                 /**
00486                   * Gets the intersection between two sets of 3D polygons. The intersection is returned as a vector with every intersection found, and the return value is the amount of intersections found.
00487                   * \sa TObject3D
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                 /** @name Other intersections
00494                         @{
00495                  */
00496                 /**
00497                   * Gets the intersection between vectors of geometric objects and returns it in a sparse matrix of either TObject2D or TObject3D.
00498                   * \sa TObject2D,TObject3D,CSparseMatrix
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                   * Gets the intersection between vectors of geometric objects and returns it in a vector of either TObject2D or TObject3D.
00511                   * \sa TObject2D,TObject3D
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                   * Gets the intersection between any pair of 2D objects.
00525                   */
00526                 bool BASE_IMPEXP intersect(const TObject2D &o1,const TObject2D &o2,TObject2D &obj);
00527                 /**
00528                   * Gets the intersection between any pair of 3D objects.
00529                   */
00530                 bool BASE_IMPEXP intersect(const TObject3D &o1,const TObject3D &o2,TObject3D &obj);
00531                 /** @}
00532                  */
00533 
00534                 /** @name Distances
00535                         @{
00536                  */
00537                 /**
00538                   * Gets the distance between two points in a 2D space.
00539                   */
00540                 double BASE_IMPEXP distance(const TPoint2D &p1,const TPoint2D &p2);
00541                 /**
00542                   * Gets the distance between two points in a 3D space.
00543                   */
00544                 double BASE_IMPEXP distance(const TPoint3D &p1,const TPoint3D &p2);
00545                 /**
00546                   * Gets the distance between two lines in a 2D space.
00547                   */
00548                 double BASE_IMPEXP distance(const TLine2D &r1,const TLine2D &r2);
00549                 /**
00550                   * Gets the distance between two lines in a 3D space.
00551                   */
00552                 double BASE_IMPEXP distance(const TLine3D &r1,const TLine3D &r2);
00553                 /**
00554                   * Gets the distance between two planes. It will be zero if the planes are not parallel.
00555                   */
00556                 double BASE_IMPEXP distance(const TPlane &p1,const TPlane &p2);
00557 
00558                 /**
00559                   * Gets the distance between two polygons in a 2D space.
00560                   */
00561                 double BASE_IMPEXP distance(const TPolygon2D &p1,const TPolygon2D &p2);
00562                 /**
00563                   * Gets the distance between a polygon and a segment in a 2D space.
00564                   */
00565                 double BASE_IMPEXP distance(const TPolygon2D &p1,const TSegment2D &s2);
00566                 /**
00567                   * Gets the distance between a segment and a polygon in a 2D space.
00568                   */
00569                 inline double distance(const TSegment2D &s1,const TPolygon2D &p2)       {
00570                         return distance(p2,s1);
00571                 }
00572                 /**
00573                   * Gets the distance between a polygon and a line in a 2D space.
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                   * Gets the distance between two polygons in a 3D space.
00581                   */
00582                 double BASE_IMPEXP distance(const TPolygon3D &p1,const TPolygon3D &p2);
00583                 /**
00584                   * Gets the distance between a polygon and a segment in a 3D space.
00585                   */
00586                 double BASE_IMPEXP distance(const TPolygon3D &p1,const TSegment3D &s2);
00587                 /**
00588                   * Gets the distance between a segment and a polygon in a 3D space.
00589                   */
00590                 inline double distance(const TSegment3D &s1,const TPolygon3D &p2)       {
00591                         return distance(p2,s1);
00592                 }
00593                 /**
00594                   * Gets the distance between a polygon and a line in a 3D space.
00595                   */
00596                 double BASE_IMPEXP distance(const TPolygon3D &p1,const TLine3D &l2);
00597                 /**
00598                   * Gets the distance between a line and a polygon in a 3D space.
00599                   */
00600                 inline double distance(const TLine3D &l1,const TPolygon3D &p2)  {
00601                         return distance(p2,l1);
00602                 }
00603                 /**
00604                   * Gets the distance between a polygon and a plane.
00605                   */
00606                 double BASE_IMPEXP distance(const TPolygon3D &po,const TPlane &pl);
00607                 /**
00608                   * Gets the distance between a plane and a polygon.
00609                   */
00610                 inline double distance(const TPlane &pl,const TPolygon3D &po)   {
00611                         return distance(po,pl);
00612                 }
00613                 /** @}
00614                  */
00615 
00616                 /** @name Bound checkers
00617                         @{
00618                  */
00619                 /**
00620                   * Gets the rectangular bounds of a 2D polygon or set of 2D points.
00621                   */
00622                 void BASE_IMPEXP getRectangleBounds(const std::vector<TPoint2D> &poly,TPoint2D &pMin,TPoint2D &pMax);
00623                 /**
00624                   * Gets the prism bounds of a 3D polygon or set of 3D points.
00625                   */
00626                 void BASE_IMPEXP getPrismBounds(const std::vector<TPoint3D> &poly,TPoint3D &pMin,TPoint3D &pMax);
00627                 /** @}
00628                  */
00629 
00630                 /** @name Creation of planes from poses
00631                         @{
00632                  */
00633                 /**
00634                   * Given a pose, creates a plane orthogonal to its Z vector.
00635                   * \sa createPlaneFromPoseXZ,createPlaneFromPoseYZ,createPlaneFromPoseAndNormal
00636                   */
00637                 void BASE_IMPEXP createPlaneFromPoseXY(const CPose3D &pose,TPlane &plane);
00638                 /**
00639                   * Given a pose, creates a plane orthogonal to its Y vector.
00640                   * \sa createPlaneFromPoseXY,createPlaneFromPoseYZ,createPlaneFromPoseAndNormal
00641                   */
00642                 void BASE_IMPEXP createPlaneFromPoseXZ(const CPose3D &pose,TPlane &plane);
00643                 /**
00644                   * Given a pose, creates a plane orthogonal to its X vector.
00645                   * \sa createPlaneFromPoseXY,createPlaneFromPoseXZ,createPlaneFromPoseAndNormal
00646                   */
00647                 void BASE_IMPEXP createPlaneFromPoseYZ(const CPose3D &pose,TPlane &plane);
00648                 /**
00649                   * Given a pose and any vector, creates a plane orthogonal to that vector in the pose's coordinates.
00650                   * \sa createPlaneFromPoseXY,createPlaneFromPoseXZ,createPlaneFromPoseYZ
00651                   */
00652                 void BASE_IMPEXP createPlaneFromPoseAndNormal(const CPose3D &pose,const double (&normal)[3],TPlane &plane);
00653                 /**
00654                   * Creates a rotation matrix so that the coordinate given (0 for x, 1 for y, 2 for z) corresponds to the vector.
00655                   */
00656                 void BASE_IMPEXP generateAxisBaseFromDirectionAndAxis(const double (&vec)[3],char coord,CMatrixDouble &matrix);
00657                 /** @}
00658                  */
00659 
00660                 /** @name Linear regression methods
00661                         @{
00662                  */
00663                 /**
00664                   * Using eigenvalues, gets the best fitting line for a set of 2D points. Returns an estimation of the error.
00665                   * \sa spline, leastSquareLinearFit
00666                   */
00667                 double BASE_IMPEXP getRegressionLine(const std::vector<TPoint2D> &points,TLine2D &line);
00668                 /**
00669                   * Using eigenvalues, gets the best fitting line for a set of 3D points. Returns an estimation of the error.
00670                   * \sa spline, leastSquareLinearFit
00671                   */
00672                 double BASE_IMPEXP getRegressionLine(const std::vector<TPoint3D> &points,TLine3D &line);
00673                 /**
00674                   * Using eigenvalues, gets the best fitting plane for a set of 3D points. Returns an estimation of the error.
00675                   * \sa spline, leastSquareLinearFit
00676                   */
00677                 double BASE_IMPEXP getRegressionPlane(const std::vector<TPoint3D> &points,TPlane &plane);
00678                 /** @}
00679                  */
00680 
00681                 /** @name Miscellaneous Geometry methods
00682                         @{
00683                  */
00684                 /**
00685                   * Tries to assemble a set of segments into a set of closed polygons.
00686                   */
00687                 void BASE_IMPEXP assemblePolygons(const std::vector<TSegment3D> &segms,std::vector<TPolygon3D> &polys);
00688                 /**
00689                   * Tries to assemble a set of segments into a set of closed polygons, returning the unused segments as another out parameter.
00690                   */
00691                 void BASE_IMPEXP assemblePolygons(const std::vector<TSegment3D> &segms,std::vector<TPolygon3D> &polys,std::vector<TSegment3D> &remainder);
00692                 /**
00693                   * Extracts all the polygons, including those formed from segments, from the set of objects.
00694                   */
00695                 void BASE_IMPEXP assemblePolygons(const std::vector<TObject3D> &objs,std::vector<TPolygon3D> &polys);
00696                 /**
00697                   * Extracts all the polygons, including those formed from segments, from the set of objects.
00698                   */
00699                 void BASE_IMPEXP assemblePolygons(const std::vector<TObject3D> &objs,std::vector<TPolygon3D> &polys,std::vector<TObject3D> &remainder);
00700                 /**
00701                   * Extracts all the polygons, including those formed from segments, from the set of objects.
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                   * Changes the value of the geometric epsilon.
00707                   * \sa geometryEpsilon,getEpsilon
00708                   */
00709                 inline void setEpsilon(double nE)       {
00710                         geometryEpsilon=nE;
00711                 }
00712                 /**
00713                   * Gets the value of the geometric epsilon.
00714                   * \sa geometryEpsilon,setEpsilon
00715                   */
00716                 inline double getEpsilon()      {
00717                         return geometryEpsilon;
00718                 }
00719 
00720                 /**
00721                   * Splits a 2D polygon into convex components.
00722                   */
00723                 bool BASE_IMPEXP splitInConvexComponents(const TPolygon2D &poly,vector<TPolygon2D> &components);
00724                 /**
00725                   * Splits a 3D polygon into convex components.
00726                   * \throw std::logic_error if the polygon can't be fit into a plane.
00727                   */
00728                 bool BASE_IMPEXP splitInConvexComponents(const TPolygon3D &poly,vector<TPolygon3D> &components);
00729 
00730                 /**
00731                   * Gets the bisector of a 2D segment.
00732                   */
00733                 void BASE_IMPEXP getSegmentBisector(const TSegment2D &sgm,TLine2D &bis);
00734                 /**
00735                   * Gets the bisector of a 3D segment.
00736                   */
00737                 void BASE_IMPEXP getSegmentBisector(const TSegment3D &sgm,TPlane &bis);
00738                 /**
00739                   * Gets the bisector of two lines or segments (implicit constructor will be used if necessary)
00740                   */
00741                 void BASE_IMPEXP getAngleBisector(const TLine2D &l1,const TLine2D &l2,TLine2D &bis);
00742                 /**
00743                   * Gets the bisector of two lines or segments (implicit constructor will be used if necessary)
00744                   * \throw std::logic_error if the lines do not fit in a single plane.
00745                   */
00746                 void BASE_IMPEXP getAngleBisector(const TLine3D &l1,const TLine3D &l2,TLine3D &bis);
00747 
00748                 /**
00749                   * Fast ray tracing method using polygons' properties.
00750                   * \sa CRenderizable::rayTrace
00751                   */
00752                 bool BASE_IMPEXP traceRay(const vector<TPolygonWithPlane> &vec,const mrpt::poses::CPose3D &pose,double &dist);
00753                 /**
00754                   * Fast ray tracing method using polygons' properties.
00755                   * \sa CRenderizable::rayTrace
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                 /** Computes the cross product of two 3D vectors, returning a vector normal to both.
00764                   *  It uses the simple implementation:
00765 
00766                     \f[  v_out = \left(
00767                                         \begin{array}{c c c}
00768                                         \hat{i} ~ \hat{j} ~ \hat{k} \\
00769                                         x0 ~ y0 ~ z0 \\
00770                                         x1 ~ y1 ~ z1 \\
00771                                         \end{array} \right)
00772                         \f]
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                 //! \overload
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                 //! \overload (returning a vector of size 3 by value).
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                 /** Computes the 3x3 skew symmetric matrix from a 3-vector or 3-array:
00807                   * \f[  M([x ~ y ~ z]^\top) = \left(
00808                   *     \begin{array}{c c c}
00809                   *     0 & -z & y \\
00810                   *     z & 0 & -x \\
00811                   *     -y & x & 0
00812                   *     \end{array} \right)
00813                   * \f]
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                 //! \overload
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                 /** Computes the negative version of a 3x3 skew symmetric matrix from a 3-vector or 3-array:
00832                   * \f[  -M([x ~ y ~ z]^\top) = \left(
00833                   *     \begin{array}{c c c}
00834                   *     0 & z & -y \\
00835                   *     -z & 0 & x \\
00836                   *     y & -x & 0
00837                   *     \end{array} \right)
00838                   * \f]
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                 //! \overload
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                   * Returns true if two 2D vectors are parallel. The arguments may be points, arrays, etc.
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                   * Returns true if two 3D vectors are parallel. The arguments may be points, arrays, etc.
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                 /** Computes the closest point from a given point to a segment, and returns that minimum distance.
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                 /** Computes the closest point from a given point to a segment, and returns that minimum distance.
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                 /** Computes the closest point from a given point to a segment.
00900                   * \sa closestFromPointToLine
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                 /** Computes the closest point from a given point to a (infinite) line.
00913                   * \sa closestFromPointToSegment
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                 /** Returns the square distance from a point to a line.
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                 /** Returns the distance between 2 points in 2D. */
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                 /** Returns the distance between 2 points in 3D. */
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                 /** Returns the square distance between 2 points in 2D. */
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                 /** Returns the square distance between 2 points in 3D. */
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                 /** Returns the intersection point, and if it exists, between two segments.
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                 /** Returns the intersection point, and if it exists, between two segments.
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                 /** Returns true if the 2D point (px,py) falls INTO the given polygon.
00979                   * \sa pointIntoQuadrangle
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                 /** Specialized method to check whether a point (x,y) falls into a quadrangle.
00984                   * \sa pointIntoPolygon2D
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                         // The point is INSIDE iff all the signs of the angles between each vertex
01002                         //  and the next one are equal.
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                 /** Returns the closest distance of a given 2D point to a polygon, or "0" if the point is INTO the polygon or its perimeter.
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                 /** Calculates the minimum distance between a pair of lines.
01019                   The lines are given by:
01020                         - Line 1 = P1 + f (P2-P1)
01021                         - Line 2 = P3 + f (P4-P3)
01022                   The Euclidean distance is returned in "dist", and the mid point between the lines in (x,y,z)
01023                   \return It returns false if there is no solution, i.e. lines are (almost, up to EPS) parallel.
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                 /** Returns wether two rotated rectangles intersect.
01034                  *  The first rectangle is not rotated and given by (R1_x_min,R1_x_max)-(R1_y_min,R1_y_max).
01035                  *  The second rectangle is given is a similar way, but it is internally rotated according
01036                  *   to the given coordinates translation (R2_pose_x,R2_pose_y,R2_pose_phi(radians)), relative
01037                  *   to the coordinates system of rectangle 1.
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                 /** Computes an axis base (a set of three 3D normal vectors) with the given vector being the first of them.
01049                   * NOTE: Make sure of passing all floats or doubles and that the template of the receiving matrix is of the same type!
01050                   *
01051                   *  If   \f$ d = [ dx ~ dy ~ dz ] \f$ is the input vector, then this function returns a matrix \f$ M \f$ such as:
01052                   *
01053                     \f[  M = \left(
01054                                         \begin{array}{c c c}
01055                                         v^1_x ~ v^2_x ~ v^3_x \\
01056                                         v^1_y ~ v^2_y ~ v^3_y \\
01057                                         v^1_z ~ v^2_z ~ v^3_z
01058                                         \end{array} \right)
01059                         \f]
01060                   *
01061                   *   And the three normal vectors are computed as:
01062 
01063                           \f[ v^1 = \frac{d}{|d|}  \f]
01064 
01065                           If (dx!=0 or dy!=0):
01066                                 \f[ v^2 = \frac{[-dy ~ dx ~ 0 ]}{\sqrt{dx^2+dy^2}}  \f]
01067                           otherwise (the direction vector is vertical):
01068                                 \f[ v^2 = [1 ~ 0 ~ 0]  \f]
01069 
01070                           And finally, the third vector is the cross product of the others:
01071 
01072                             \f[ v^3 = v^1 \times v^2  \f]
01073                   *
01074                   * \return The 3x3 matrix (CMatrixTemplateNumeric<T>), containing one vector per column.
01075                   * \except Throws an std::exception on invalid input (i.e. null direction vector)
01076                   *
01077                   * (JLB @ 18-SEP-2007)
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                         // 1st vector:
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                         // 2nd perpendicular vector:
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                                 // Any vector in the XY plane will work:
01107                                 P(0,1) = 1;
01108                                 P(1,1) = 0;
01109                                 P(2,1) = 0;
01110                         }
01111 
01112                         // 3rd perpendicular vector: cross product of the two last vectors:
01113                         P.col(2) = crossProduct3D(P.col(0),P.col(1));
01114 
01115                         return P;
01116                         MRPT_END
01117                 }
01118 
01119 
01120                 /** Compute a rotation exponential using the Rodrigues Formula.
01121                   * The rotation axis is given by \f$\vec{w}\f$, and the rotation angle must
01122                   * be computed using \f$ \theta = |\vec{w}|\f$. This is provided as a separate
01123                   * function primarily to allow fast and rough matrix exponentials using fast
01124                   * and rough approximations to \e A and \e B.
01125                   *
01126                   * \param w Vector about which to rotate.
01127                   * \param A \f$\frac{\sin \theta}{\theta}\f$
01128                   * \param B \f$\frac{1 - \cos \theta}{\theta^2}\f$
01129                   * \param R Matrix to hold the return value.
01130                   * \sa CPose3D
01131                   * \note Method from TooN (C) Tom Drummond (GNU GPL)
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                 /** @} */  // end of misc. geom. methods
01168 
01169                 /** @} */  // end of grouping
01170 
01171         } // End of namespace
01172 
01173 } // End of namespace
01174 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011