eLynx SDK
v3.0.1 C++ image processing API reference |
00001 //============================================================================ 00002 // Geometry.h Math.Component package 00003 //============================================================================ 00004 // Usage : 00005 //---------------------------------------------------------------------------- 00006 // Copyright (C) 2007 by eLynx project 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 // See the GNU Library General Public License for more details. 00017 //---------------------------------------------------------------------------- 00018 #ifndef __Geometry_h__ 00019 #define __Geometry_h__ 00020 00021 #include <elx/core/CoreTypes.h> 00022 #include <elx/core/CoreMacros.h> 00023 #include "MathLib.h" 00024 #include <vector> 00025 00026 namespace eLynx { 00027 namespace Math { 00028 00029 //============================================================================ 00030 // Point2<T> 00031 //============================================================================ 00032 template<typename T> 00033 class ExportedByMath Point2 00034 { 00035 public: 00036 00038 Point2() : _x(), _y() {} 00039 Point2(T iX, T iY) : _x(iX), _y(iY) {} 00040 template<typename U> 00041 Point2(U iX, U iY) : _x(T(iX)), _y(T(iY)) {} 00042 00043 bool operator==(const Point2& iPoint) const 00044 { return _x==iPoint._x && _y==iPoint._y; } 00045 00046 public: 00047 T _x,_y; 00048 }; 00049 00050 template<typename T> 00051 double elxGetDistance(const Point2<T>& iP0, const Point2<T>& iP1); 00052 00053 template<typename T> 00054 Point2<T> elxGetMiddle(const Point2<T>& iP0, const Point2<T>& iP1); 00055 00056 template <class T> 00057 Point2<T> elxGetMiddle(const Point2<T>& iP0, const Point2<T>& iP1, const Point2<T>& iP2); 00058 00059 template<typename T> 00060 bool elxComparePoints(const Point2<T>& iP0, const Point2<T>& iP1); 00061 00062 template<typename T> 00063 bool elxEqualPoints(const Point2<T>& iP0, const Point2<T>& iP1); 00064 00065 template <class T> 00066 Point2<T> elxNormalizePoint(const Point2<T>& iP); 00067 00068 template <class T> 00069 T elxDotProduct(const Point2<T>& iP0, const Point2<T>& iP1); 00070 00071 template <class T> 00072 Point2<T> elxSubstructPoints(const Point2<T>& iP0, const Point2<T>& iP1); 00073 00074 template <class T> 00075 Point2<T> elxAddPoints(const Point2<T>& iP0, const Point2<T>& iP1); 00076 00077 00078 //============================================================================ 00079 // Point3<T> 00080 //============================================================================ 00081 template<typename T> 00082 class ExportedByMath Point3 00083 { 00084 public: 00085 00087 Point3() : _x(), _y(), _z() {} 00088 Point3(T iX, T iY, T iZ) : _x(iX), _y(iY), _z(iZ) {} 00089 template<typename U> 00090 Point3(U iX, U iY, U iZ) : _x(iX), _y(iY), _z(iZ) {} 00091 bool operator==(const Point3& iPoint) const 00092 { return _x==iPoint._x && _y==iPoint._y && _z==iPoint._z; } 00093 00094 public: 00095 T _x, _y, _z; 00096 }; 00097 00098 template<typename T> 00099 double elxGetDistance(const Point3<T>& iP0, const Point3<T>& iP1); 00100 00101 template<typename T> 00102 Point3<T> elxGetMiddle(const Point3<T>& iP0, const Point3<T>& iP1); 00103 00104 template <class T> 00105 Point3<T> elxGetMiddle(const Point3<T>& iP0, const Point3<T>& iP1, const Point3<T>& iP2); 00106 00107 template<typename T> 00108 bool elxComparePoints(const Point3<T>& iP0, const Point3<T>& iP1); 00109 00110 template<typename T> 00111 bool elxEqualPoints(const Point3<T>& iP0, const Point3<T>& iP1); 00112 00113 template <class T> 00114 Point3<T> elxNormalizePoint(const Point3<T>& iP); 00115 00116 template <class T> 00117 Point3<T> elxCrossProduct(const Point3<T>& iP0, const Point3<T>& iP1); 00118 00119 template <class T> 00120 T elxDotProduct(const Point3<T>& iP0, const Point3<T>& iP1); 00121 00122 template <class T> 00123 Point3<T> elxSubstructPoints(const Point3<T>& iP0, const Point3<T>& iP1); 00124 00125 template <class T> 00126 Point3<T> elxAddPoints(const Point3<T>& iP0, const Point3<T>& iP1); 00127 00128 00131 // declare all suitable point types. 00132 typedef Point2<int32> Point2i; 00133 typedef Point2<int64> Point2l; 00134 typedef Point2<float> Point2f; 00135 typedef Point2<double> Point2d; 00136 00137 typedef Point3<int32> Point3i; 00138 typedef Point3<int64> Point3l; 00139 typedef Point3<float> Point3f; 00140 typedef Point3<double> Point3d; 00142 00143 typedef std::vector<Point2i> Point2iList; 00144 typedef std::vector<Point2l> Point2lList; 00145 typedef std::vector<Point2f> Point2fList; 00146 typedef std::vector<Point2d> Point2dList; 00147 00148 00149 //============================================================================ 00150 // Segment2<T> 00151 //============================================================================ 00152 template<typename T> 00153 class ExportedByMath Segment2 00154 { 00155 public: 00157 Segment2() {} 00158 Segment2(const Point2<T>& iP0, const Point2<T>& iP1) : _P0(iP0), _P1(iP1) {} 00159 template<typename U> 00160 Segment2(const Point2<U>& iP0, const Point2<U>& iP1) : _P0(iP0), _P1(iP1) {} 00161 bool operator==(const Segment2& iSegment) const 00162 { return _P0==iSegment._P0 && _P1==iSegment._P1; } 00163 00164 public: 00165 Point2<T> _P0, _P1; 00166 }; 00167 00168 //============================================================================ 00169 // Segment3<T> 00170 //============================================================================ 00171 template<typename T> 00172 class ExportedByMath Segment3 00173 { 00174 public: 00176 Segment3() {} 00177 Segment3(const Point3<T>& iP0, const Point3<T>& iP1) : _P0(iP0), _P1(iP1) {} 00178 template<typename U> 00179 Segment3(const Point3<U>& iP0, const Point3<U>& iP1) : _P0(iP0), _P1(iP1) {} 00180 bool operator==(const Segment3& iSegment) const 00181 { return _P0==iSegment._P0 && _P1==iSegment._P1; } 00182 00183 public: 00184 Point3<T> _P0, _P1; 00185 }; 00186 00189 // declare all suitable point types. 00190 typedef Segment2<int32> Segment2i; 00191 typedef Segment2<int64> Segment2l; 00192 typedef Segment2<float> Segment2f; 00193 typedef Segment2<double> Segment2d; 00194 00195 typedef Segment3<int32> Segment3i; 00196 typedef Segment3<int64> Segment3l; 00197 typedef Segment3<float> Segment3f; 00198 typedef Segment3<double> Segment3d; 00200 00201 00202 //============================================================================ 00203 // Rectangle2<T> 00204 //============================================================================ 00205 template<typename T> 00206 class ExportedByMath Rectangle2 00207 { 00208 public: 00210 Rectangle2() {} 00211 Rectangle2(const Point2<T>& iP0, const Point2<T>& iP1) : 00212 _P0(iP0), _P1(iP1) {} 00213 00214 template<typename U> 00215 Rectangle2(const Point2<U>& iP0, const Point2<U>& iP1) : 00216 _P0(iP0), _P1(iP1) {} 00217 00218 T GetWidth() const { return 1+elxAbs(_P1._x - _P0._x); } 00219 T GetHeight() const { return 1+elxAbs(_P1._y - _P0._y); } 00220 00221 bool operator==(const Rectangle2& iRectangle) const 00222 { return _P0==iRectangle._P0 && _P1==iRectangle._P1; } 00223 public: 00224 Point2<T> _P0, _P1; 00225 }; 00226 00229 // declare all suitable point types. 00230 typedef Rectangle2<int32> Rectangle2i; 00231 typedef Rectangle2<int64> Rectangle2l; 00232 typedef Rectangle2<float> Rectangle2f; 00233 typedef Rectangle2<double> Rectangle2d; 00235 00236 00237 //============================================================================ 00238 // Axix Oriented Bouding Box 2d : AOBBox2<T> 00239 //============================================================================ 00240 template<typename T> 00241 class ExportedByMath AOBBox2 00242 { 00243 public: 00245 AOBBox2() {} 00246 AOBBox2(T iX, T iY, T iW, T iH) : _x(iX), _y(iY), _w(iW), _h(iH) {} 00247 AOBBox2(const Point2<T>& iP0, const Point2<T>& iP1) 00248 { 00249 if (iP0._x > iP1._x) 00250 { _x = iP1._x, _y = iP1._y; _w = 1 + iP0._x-iP1._x; } 00251 else 00252 { _x = iP0._x, _y = iP0._y; _w = 1 + iP1._x-iP0._x; } 00253 _h = 1 + elxAbs(iP1._y - iP0._y); 00254 } 00255 Point2<T> GetPosition() const { return Point2<T>(_x,_y); } 00256 Point2<T> GetCenter() const { return Point2<T>(_x+_w/2, _y+_h/2); } 00257 bool IsInside(T iX, T iY) const { return ((GetXStart() <= iX) && (iX <=GetXEnd()) && (GetYStart() <= iY) && (iY <=GetYEnd())); } 00258 bool IsPoint() const { return ((1 == _w) && (1 == _h)); } 00259 T GetXStart() const { return _x; } 00260 T GetYStart() const { return _y; } 00261 T GetXEnd() const { return _x+_w-1; } 00262 T GetYEnd() const { return _y+_h-1; } 00263 T GetWidth() const { return _w; } 00264 T GetHeight() const { return _h; } 00265 public: 00266 T _x,_y,_w,_h; 00267 }; 00268 00271 // declare all suitable Axix Oriented Bouding Box 2d types. 00272 typedef AOBBox2<int32> AOBBox2i; 00273 typedef AOBBox2<int64> AOBBox2l; 00274 typedef AOBBox2<float> AOBBox2f; 00275 typedef AOBBox2<double> AOBBox2d; 00277 00278 typedef std::vector<AOBBox2i> AOBBox2iList; 00279 typedef std::vector<AOBBox2l> AOBBox2lList; 00280 typedef std::vector<AOBBox2f> AOBBox2fList; 00281 typedef std::vector<AOBBox2d> AOBBox2dList; 00282 00283 00284 //============================================================================ 00285 // Triangle2<T> 00286 //============================================================================ 00287 template<typename T> 00288 class ExportedByMath Triangle2 00289 { 00290 public: 00292 Triangle2() {} 00293 Triangle2(const Point2<T>& iP0, const Point2<T>& iP1, const Point2<T>& iP2) : 00294 _P0(iP0), _P1(iP1), _P2(iP2) {} 00295 template<typename U> 00296 Triangle2(const Point2<U>& iP0, const Point2<U>& iP1, const Point2<U>& iP2) : 00297 _P0(iP0), _P1(iP1), _P2(iP2) {} 00298 bool operator==(const Triangle2& iTriangle) const 00299 { return _P0==iTriangle._P0 && _P1==iTriangle._P1 && _P2==iTriangle._P2; } 00300 00301 public: 00302 Point2<T> _P0, _P1, _P2; 00303 }; 00304 00305 //============================================================================ 00306 // Triangle3<T> 00307 //============================================================================ 00308 template<typename T> 00309 class ExportedByMath Triangle3 00310 { 00311 public: 00313 Triangle3() {} 00314 Triangle3(const Point3<T>& iP0, const Point3<T>& iP1, const Point3<T>& iP2) : 00315 _P0(iP0), _P1(iP1), _P2(iP2) {} 00316 template<typename U> 00317 Triangle3(const Point3<U>& iP0, const Point3<U>& iP1, const Point3<U>& iP2) : 00318 _P0(iP0), _P1(iP1), _P2(iP2) {} 00319 00320 bool operator==(const Triangle3& iTriangle) const 00321 { return _P0==iTriangle._P0 && _P1==iTriangle._P1 && _P2==iTriangle._P2; } 00322 00323 public: 00324 Point3<T> _P0, _P1, _P2; 00325 }; 00326 00329 // declare all suitable point types. 00330 typedef Triangle2<int32> Triangle2i; 00331 typedef Triangle2<int64> Triangle2l; 00332 typedef Triangle2<float> Triangle2f; 00333 typedef Triangle2<double> Triangle2d; 00334 00335 typedef Triangle3<int32> Triangle3i; 00336 typedef Triangle3<int64> Triangle3l; 00337 typedef Triangle3<float> Triangle3f; 00338 typedef Triangle3<double> Triangle3d; 00340 00341 //============================================================================ 00342 // Triangle with point indexes 00343 //============================================================================ 00344 class ExportedByMath TriangleIdx 00345 { 00346 public: 00347 TriangleIdx() {} 00348 TriangleIdx(const uint32 iP0, const uint32 iP1, const uint32 iP2) : 00349 _P0(iP0), _P1(iP1), _P2(iP2) {} 00350 00351 bool operator==(const TriangleIdx& iTriangle) const 00352 { return _P0==iTriangle._P0 && _P1==iTriangle._P1 && _P2==iTriangle._P2; } 00353 00354 public: 00355 uint32 _P0, _P1, _P2; 00356 }; 00357 00358 typedef std::vector<TriangleIdx> TriangleIdxList; 00359 00360 //============================================================================ 00361 // Trianglulation Data 00362 //============================================================================ 00363 struct ExportedByMath TriangulationData 00364 { 00365 struct Edge; 00366 struct Vertex 00367 { 00368 Point2d _position; // Vertex's coordinates in 2 dimentional space 00369 std::vector<Edge*> _edges; // Pointers to all edges from that vertex 00370 }; 00371 00372 struct Triangle; 00373 00374 struct Edge 00375 { 00376 Vertex* _vertex[2]; // Pointers to two vertices comprising the edge 00377 Triangle* _triangle[2];// Pointers to two (or one) triangles sharing the edge 00378 }; 00379 00380 struct Triangle 00381 { 00382 Vertex* _vertex[3]; // Pointers to three vertices comprising the triangle 00383 Edge* _edge[3]; // Pointers to three edges comprising the triangle 00384 }; 00385 00386 std::vector<Vertex> _vertices; 00387 std::vector<Edge> _edges; 00388 std::vector<Triangle> _triangles; 00389 }; 00390 00391 00392 // Sources in Delaunay.cpp/hpp 00393 bool ExportedByMath elxTriangulate(const Point2iList& iPoints, TriangleIdxList& oTriangles); 00394 bool ExportedByMath elxTriangulate(const Point2iList& iPoints, TriangulationData& oTriangles); 00395 00396 //============================================================================ 00397 // 2d Line processing at every integer coordinates 00398 // sources in inl\Line.inl 00399 //============================================================================ 00400 template <class Operator> 00401 void ExportedByMath elxProcessLine2i( 00402 int32 iX1, int32 iY1, int32 iX2, int32 iY2, 00403 int32 iW, int32 iH, 00404 Operator& iOperator); 00405 00406 template <class Operator> 00407 void ExportedByMath elxProcessLine2i( 00408 const Math::Point2i& iP1, const Math::Point2i& iP2, 00409 int32 iW, int32 iH, 00410 Operator& iOperator); 00411 00412 void ExportedByMath elxComputeLinePoints( 00413 const Point2i& iP1, const Point2i& iP2, int32 iW, int32 iH, 00414 Point2iList& iPoints); 00415 00416 //============================================================================ 00417 // Intersections 00418 //============================================================================ 00419 template <typename T> 00420 bool ExportedByMath elxIntersectLineLine( 00421 const Point2<T>& iPoint11, const Point2<T>& iPoint12, 00422 const Point2<T>& iPoint21, const Point2<T>& iPoint22, Point2<T>& oPoint); 00423 00424 template <typename T> 00425 bool ExportedByMath elxIntersectLineLine( 00426 const T iX11, const T iY11, const T iX12, const T iY12, 00427 const T iX21, const T iY21, const T iX22, const T iY22, 00428 T& X, T& Y); 00429 00430 template <typename T, typename U> 00431 bool ExportedByMath elxIntersectLineLine( 00432 const Point2<T>& iPoint11, const Point2<T>& iPoint12, 00433 const Point2<T>& iPoint21, const Point2<T>& iPoint22, Point2<U>& oPoint); 00434 00435 template <typename T, typename U> 00436 bool ExportedByMath elxIntersectLineLine( 00437 const T iX11, const T iY11, const T iX12, const T iY12, 00438 const T iX21, const T iY21, const T iX22, const T iY22, 00439 U& X, U& Y); 00440 00441 template <typename T> 00442 bool ExportedByMath elxIntersectLineSegment( 00443 const Point2<T>& iPoint1, const Point2<T>& iPoint2, 00444 const Segment2<T>& iSegment, 00445 Point2<T>& oPoint); 00446 /* 00447 template <typename T> 00448 bool ExportedByMath elxIntersectLineRectangle( 00449 const Point2<T>& iPoint1, const Point2<T>& iPoint2, 00450 const Rectangle2<T>& iRectangle, 00451 Segment2<T>& oSegment); 00452 */ 00453 bool ExportedByMath elxIntersectLineRectangle( 00454 const Point2<int32>& iPoint1, const Point2<int32>& iPoint2, 00455 const Rectangle2<int32>& iRectangle, 00456 Segment2<int32>& oSegment); 00457 00458 template <typename T> 00459 bool ExportedByMath elxIntersectCircleRectangle( 00460 const Rectangle2<T>& iRectangle, const Point2<T>& iPoint, T iRadius); 00461 00462 //============================================================================ 00463 // Barycentric coordinates 00464 //============================================================================ 00465 template<typename T> 00466 struct BarycentricCoordinates2 00467 { 00468 // The context triangle must not be degenerate 00469 BarycentricCoordinates2(const Triangle2<T>& iTriangle); 00470 BarycentricCoordinates2( 00471 const Point2<T>& iP0, const Point2<T>& iP1, const Point2<T>& iP2); 00472 BarycentricCoordinates2(T iX0, T iY0, T iX1, T iY1, T iX2, T iY2); 00473 00474 // Swaps verticies 00475 void Swap(const uint32 iVertex1, const uint32 iVertex2); 00476 00477 // Calculates barycentric coordinates for a given point 00478 void GetCoordinates(const Point2<T>& iPoint, T& oU, T& oV, T& oW) const; 00479 void GetCoordinates(const T iX, const T iY, T& oU, T& oV, T& oW) const; 00480 00481 private: 00482 void Init(); 00483 00484 T _x0, _y0, _x1, _y1, _x2, _y2; 00485 T _a, _b, _c, _d, _e, _f, _aebd; 00486 }; 00487 00488 } // namespace Math 00489 } // namespace eLynx 00490 00491 #include "inl/Geometry.inl" 00492 00493 #endif //__Geometry_h__