00001
00002
00003
00004
00005 #if !defined (AQSENSE_SAL3DPP_GEOMETRIC_HPP)
00006 #define AQSENSE_SAL3DPP_GEOMETRIC_HPP
00007
00008 #if defined (_MSC_VER) && (_MSC_VER >= 1020)
00009 #pragma once
00010 #endif
00011
00012 #include <cassert>
00013 #include <cmath>
00014 #include <stdexcept>
00015 #include <vector>
00016
00017 #include <sal3d/cop.h>
00018 #include <sal3d/geometric.h>
00019 #include <sal3dpp/Common.hpp>
00020 #include <sal3dpp/COP.hpp>
00021
00022 namespace sal3d
00023 {
00058 namespace Geometric
00059 {
00064 class InsufficientPoints: public std::invalid_argument
00065 {
00066 public:
00067 InsufficientPoints ():
00068 invalid_argument ("insufficient points to find the result")
00069 {
00070 }
00071 };
00072
00081 class Plane
00082 {
00083 public:
00089 Plane () :
00090 _plane ()
00091 {}
00092
00101 explicit Plane (const sal3d_geometric_plane &plane) :
00102 _plane (plane)
00103 {}
00104
00112 Plane (const Plane &plane) :
00113 _plane (plane._plane)
00114 {}
00115
00124 Plane (float A, float B, float C, float D)
00125 {
00126 _plane.p[0] = A;
00127 _plane.p[1] = B;
00128 _plane.p[2] = C;
00129 _plane.p[3] = D;
00130 }
00131
00143 Plane (const Point3D& p1, const Point3D& p2, const Point3D& p3)
00144 {
00145 sal3d_geometric_plane_from_three_points (p1.c_point_3d (),
00146 p2.c_point_3d (), p3.c_point_3d (), &_plane);
00147 }
00148
00154 const sal3d_geometric_plane &
00155 c_plane () const
00156 {
00157 return _plane;
00158 }
00159
00166 const float &
00167 a() const
00168 {
00169 return _plane.p[0];
00170 }
00171
00177 float &
00178 a()
00179 {
00180 return _plane.p[0];
00181 }
00182
00189 const float &
00190 b() const
00191 {
00192 return _plane.p[1];
00193 }
00194
00200 float &
00201 b()
00202 {
00203 return _plane.p[1];
00204 }
00205
00212 const float &
00213 c() const
00214 {
00215 return _plane.p[2];
00216 }
00217
00223 float &
00224 c()
00225 {
00226 return _plane.p[2];
00227 }
00228
00235 const float &
00236 d() const {
00237 return _plane.p[3];
00238 }
00239
00245 float &
00246 d() {
00247 return _plane.p[3];
00248 }
00249
00264 Movement3D
00265 alignToZ (const Point3D& point) const
00266 {
00267 sal3d_movement_3d m;
00268
00269 sal3d_geometric_align_plane_to_z (point.c_point_3d (),
00270 _plane, &m);
00271
00272 return Movement3D (m);
00273 }
00274
00284 Plane &
00285 operator= (const Plane& rhs)
00286 {
00287 for (int i=0; i < 4; ++i)
00288 (*this)[i] = rhs[i];
00289
00290 return *this;
00291 }
00292
00301 const float &
00302 operator[] (int idx) const
00303 {
00304 assert (idx >= 0 && idx < 4 && "invalid index");
00305 return _plane.p[idx];
00306 }
00307
00316 float &
00317 operator[] (int idx)
00318 {
00319 return const_cast<float &> (
00320 static_cast<const Plane &>(*this)[idx]);
00321 }
00322
00323 private:
00325 sal3d_geometric_plane _plane;
00326 };
00327
00336 class Sphere
00337 {
00338 public:
00344 Sphere () :
00345 _sphere ()
00346 {}
00347
00356 explicit Sphere (const sal3d_geometric_sphere &sphere) :
00357 _sphere (sphere)
00358 {}
00359
00367 Sphere (const Sphere &sphere) :
00368 _sphere (sphere._sphere)
00369 {}
00370
00377 Sphere (const Point3D ¢re, float r)
00378 {
00379 _sphere.centre.p[0] = centre.x();
00380 _sphere.centre.p[1] = centre.y();
00381 _sphere.centre.p[2] = centre.z();
00382 _sphere.radius = r;
00383 }
00384
00390 const sal3d_geometric_sphere &
00391 c_sphere () const
00392 {
00393 return _sphere;
00394 }
00395
00401 Point3D
00402 centre () const
00403 {
00404 return Point3D (_sphere.centre.p[0],
00405 _sphere.centre.p[1], _sphere.centre.p[2]);
00406 }
00407
00414 void
00415 setCentre (const Point3D& centre)
00416 {
00417 _sphere.centre.p[0] = centre.x ();
00418 _sphere.centre.p[1] = centre.y ();
00419 _sphere.centre.p[2] = centre.z ();
00420 }
00421
00427 const float &
00428 radius () const
00429 {
00430 return _sphere.radius;
00431 }
00432
00438 float &
00439 radius ()
00440 {
00441 return _sphere.radius;
00442 }
00443
00444 private:
00446 sal3d_geometric_sphere _sphere;
00447 };
00448
00473 inline Plane
00474 getRobustTangentPlane (const COP &cop,
00475 float expectedInliersRatio, float &inliersRatio)
00476 {
00477 sal3d_geometric_plane plane;
00478 std::vector<sal3d_point3d> points (cop.height() *
00479 cop.width());
00480 int size;
00481
00482 Error e;
00483 sal3d_geometric_get_robust_tangent_plane(cop.c_cop(),
00484 expectedInliersRatio, &plane, &points[0], &size,
00485 &inliersRatio, &e.e);
00486
00487 if (e.e.value < 0)
00488 throw e;
00489
00490 return Plane (plane);
00491 }
00492
00518 inline Plane
00519 getRobustTangentPlane (const COP &cop,
00520 float expectedInliersRatio,
00521 std::vector<Point3D> &inliers, float &inliersRatio)
00522 {
00523 sal3d_geometric_plane plane;
00524 std::vector<sal3d_point3d> points (cop.height() *
00525 cop.width());
00526
00527 int size;
00528 Error e;
00529 sal3d_geometric_get_robust_tangent_plane(cop.c_cop(),
00530 expectedInliersRatio, &plane, &points[0], &size,
00531 &inliersRatio, &e.e);
00532
00533 if (e.e.value < 0)
00534 throw e;
00535
00536 inliers.clear ();
00537 inliers.reserve (size);
00538 for (int i = 0; i < size; ++i)
00539 {
00540 Point3D p (points[i]);
00541 inliers.push_back (p);
00542 }
00543
00544 return Plane (plane);
00545 }
00546
00561 inline Plane
00562 getAveragePlane (const COP &cop)
00563 {
00564 sal3d_geometric_plane plane;
00565
00566 sal3d_geometric_get_average_plane(cop.c_cop(), &plane);
00567
00568 return Plane (plane);
00569 }
00570
00591 inline float
00592 distanceToPlane(const Point3D& point, const Plane& plane,
00593 Point3D& intersectionPoint)
00594 {
00595 float distance;
00596 sal3d_point3d intersect;
00597
00598 sal3d_geometric_get_distance_to_plane (point.c_point_3d (),
00599 plane.c_plane (), &intersect ,
00600 &distance);
00601
00602 intersectionPoint = Point3D (intersect);
00603
00604 return distance;
00605 }
00606
00621 inline Sphere
00622 fitSphere (std::vector<Point3D> points)
00623 {
00624 if (points.size() < 4)
00625 throw InsufficientPoints();
00626
00627 std::vector<sal3d_point3d> points_c(points.size());
00628 for (unsigned int i = 0; i < points.size (); ++i)
00629 points_c[i] = points[i].c_point_3d ();
00630
00631 sal3d_geometric_sphere sphere;
00632 sal3d_geometric_fit_sphere (&points_c[0], points_c.size(), &sphere);
00633
00634 return Sphere(sphere);
00635 }
00636
00651 inline Sphere
00652 fitCOPToSphere (const COP &cop)
00653 {
00654 sal3d_geometric_sphere sphere;
00655 sal3d_geometric_fit_cop_to_sphere (cop.c_cop(), &sphere);
00656
00657 return Sphere(sphere);
00658 }
00659
00660 }
00661 }
00662
00663 #endif // !AQSENSE_SAL3DPP_GEOMETRIC_HPP