BVH.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009 Ilya Baran <ibaran@mit.edu>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #include "main.h"
00011 #include <Eigen/StdVector>
00012 #include <Eigen/Geometry>
00013 #include <unsupported/Eigen/BVH>
00014 
00015 namespace Eigen {
00016 
00017 template<typename Scalar, int Dim> AlignedBox<Scalar, Dim> bounding_box(const Matrix<Scalar, Dim, 1> &v) { return AlignedBox<Scalar, Dim>(v); }
00018 
00019 }
00020 
00021 
00022 template<int Dim>
00023 struct Ball
00024 {
00025 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(double, Dim)
00026 
00027   typedef Matrix<double, Dim, 1> VectorType;
00028 
00029   Ball() {}
00030   Ball(const VectorType &c, double r) : center(c), radius(r) {}
00031 
00032   VectorType center;
00033   double radius;
00034 };
00035 template<int Dim> AlignedBox<double, Dim> bounding_box(const Ball<Dim> &b)
00036 { return AlignedBox<double, Dim>(b.center.array() - b.radius, b.center.array() + b.radius); }
00037 
00038 inline double SQR(double x) { return x * x; }
00039 
00040 template<int Dim>
00041 struct BallPointStuff //this class provides functions to be both an intersector and a minimizer, both for a ball and a point and for two trees
00042 {
00043   typedef double Scalar;
00044   typedef Matrix<double, Dim, 1> VectorType;
00045   typedef Ball<Dim> BallType;
00046   typedef AlignedBox<double, Dim> BoxType;
00047 
00048   BallPointStuff() : calls(0), count(0) {}
00049   BallPointStuff(const VectorType &inP) : p(inP), calls(0), count(0) {}
00050 
00051 
00052   bool intersectVolume(const BoxType &r) { ++calls; return r.contains(p); }
00053   bool intersectObject(const BallType &b) {
00054     ++calls;
00055     if((b.center - p).squaredNorm() < SQR(b.radius))
00056       ++count;
00057     return false; //continue
00058   }
00059 
00060   bool intersectVolumeVolume(const BoxType &r1, const BoxType &r2) { ++calls; return !(r1.intersection(r2)).isNull(); }
00061   bool intersectVolumeObject(const BoxType &r, const BallType &b) { ++calls; return r.squaredExteriorDistance(b.center) < SQR(b.radius); }
00062   bool intersectObjectVolume(const BallType &b, const BoxType &r) { ++calls; return r.squaredExteriorDistance(b.center) < SQR(b.radius); }
00063   bool intersectObjectObject(const BallType &b1, const BallType &b2){
00064     ++calls;
00065     if((b1.center - b2.center).norm() < b1.radius + b2.radius)
00066       ++count;
00067     return false;
00068   }
00069   bool intersectVolumeObject(const BoxType &r, const VectorType &v) { ++calls; return r.contains(v); }
00070   bool intersectObjectObject(const BallType &b, const VectorType &v){
00071     ++calls;
00072     if((b.center - v).squaredNorm() < SQR(b.radius))
00073       ++count;
00074     return false;
00075   }
00076 
00077   double minimumOnVolume(const BoxType &r) { ++calls; return r.squaredExteriorDistance(p); }
00078   double minimumOnObject(const BallType &b) { ++calls; return (std::max)(0., (b.center - p).squaredNorm() - SQR(b.radius)); }
00079   double minimumOnVolumeVolume(const BoxType &r1, const BoxType &r2) { ++calls; return r1.squaredExteriorDistance(r2); }
00080   double minimumOnVolumeObject(const BoxType &r, const BallType &b) { ++calls; return SQR((std::max)(0., r.exteriorDistance(b.center) - b.radius)); }
00081   double minimumOnObjectVolume(const BallType &b, const BoxType &r) { ++calls; return SQR((std::max)(0., r.exteriorDistance(b.center) - b.radius)); }
00082   double minimumOnObjectObject(const BallType &b1, const BallType &b2){ ++calls; return SQR((std::max)(0., (b1.center - b2.center).norm() - b1.radius - b2.radius)); }
00083   double minimumOnVolumeObject(const BoxType &r, const VectorType &v) { ++calls; return r.squaredExteriorDistance(v); }
00084   double minimumOnObjectObject(const BallType &b, const VectorType &v){ ++calls; return SQR((std::max)(0., (b.center - v).norm() - b.radius)); }
00085 
00086   VectorType p;
00087   int calls;
00088   int count;
00089 };
00090 
00091 
00092 template<int Dim>
00093 struct TreeTest
00094 {
00095   typedef Matrix<double, Dim, 1> VectorType;
00096   typedef std::vector<VectorType, aligned_allocator<VectorType> > VectorTypeList;
00097   typedef Ball<Dim> BallType;
00098   typedef std::vector<BallType, aligned_allocator<BallType> > BallTypeList;
00099   typedef AlignedBox<double, Dim> BoxType;
00100 
00101   void testIntersect1()
00102   {
00103     BallTypeList b;
00104     for(int i = 0; i < 500; ++i) {
00105         b.push_back(BallType(VectorType::Random(), 0.5 * internal::random(0., 1.)));
00106     }
00107     KdBVH<double, Dim, BallType> tree(b.begin(), b.end());
00108 
00109     VectorType pt = VectorType::Random();
00110     BallPointStuff<Dim> i1(pt), i2(pt);
00111 
00112     for(int i = 0; i < (int)b.size(); ++i)
00113       i1.intersectObject(b[i]);
00114 
00115     BVIntersect(tree, i2);
00116 
00117     VERIFY(i1.count == i2.count);
00118   }
00119 
00120   void testMinimize1()
00121   {
00122     BallTypeList b;
00123     for(int i = 0; i < 500; ++i) {
00124         b.push_back(BallType(VectorType::Random(), 0.01 * internal::random(0., 1.)));
00125     }
00126     KdBVH<double, Dim, BallType> tree(b.begin(), b.end());
00127 
00128     VectorType pt = VectorType::Random();
00129     BallPointStuff<Dim> i1(pt), i2(pt);
00130 
00131     double m1 = (std::numeric_limits<double>::max)(), m2 = m1;
00132 
00133     for(int i = 0; i < (int)b.size(); ++i)
00134       m1 = (std::min)(m1, i1.minimumOnObject(b[i]));
00135 
00136     m2 = BVMinimize(tree, i2);
00137 
00138     VERIFY_IS_APPROX(m1, m2);
00139   }
00140 
00141   void testIntersect2()
00142   {
00143     BallTypeList b;
00144     VectorTypeList v;
00145 
00146     for(int i = 0; i < 50; ++i) {
00147         b.push_back(BallType(VectorType::Random(), 0.5 * internal::random(0., 1.)));
00148         for(int j = 0; j < 3; ++j)
00149             v.push_back(VectorType::Random());
00150     }
00151 
00152     KdBVH<double, Dim, BallType> tree(b.begin(), b.end());
00153     KdBVH<double, Dim, VectorType> vTree(v.begin(), v.end());
00154 
00155     BallPointStuff<Dim> i1, i2;
00156 
00157     for(int i = 0; i < (int)b.size(); ++i)
00158         for(int j = 0; j < (int)v.size(); ++j)
00159             i1.intersectObjectObject(b[i], v[j]);
00160 
00161     BVIntersect(tree, vTree, i2);
00162 
00163     VERIFY(i1.count == i2.count);
00164   }
00165 
00166   void testMinimize2()
00167   {
00168     BallTypeList b;
00169     VectorTypeList v;
00170 
00171     for(int i = 0; i < 50; ++i) {
00172         b.push_back(BallType(VectorType::Random(), 1e-7 + 1e-6 * internal::random(0., 1.)));
00173         for(int j = 0; j < 3; ++j)
00174             v.push_back(VectorType::Random());
00175     }
00176 
00177     KdBVH<double, Dim, BallType> tree(b.begin(), b.end());
00178     KdBVH<double, Dim, VectorType> vTree(v.begin(), v.end());
00179 
00180     BallPointStuff<Dim> i1, i2;
00181 
00182     double m1 = (std::numeric_limits<double>::max)(), m2 = m1;
00183 
00184     for(int i = 0; i < (int)b.size(); ++i)
00185         for(int j = 0; j < (int)v.size(); ++j)
00186             m1 = (std::min)(m1, i1.minimumOnObjectObject(b[i], v[j]));
00187 
00188     m2 = BVMinimize(tree, vTree, i2);
00189 
00190     VERIFY_IS_APPROX(m1, m2);
00191   }
00192 };
00193 
00194 
00195 void test_BVH()
00196 {
00197   for(int i = 0; i < g_repeat; i++) {
00198 #ifdef EIGEN_TEST_PART_1
00199     TreeTest<2> test2;
00200     CALL_SUBTEST(test2.testIntersect1());
00201     CALL_SUBTEST(test2.testMinimize1());
00202     CALL_SUBTEST(test2.testIntersect2());
00203     CALL_SUBTEST(test2.testMinimize2());
00204 #endif
00205 
00206 #ifdef EIGEN_TEST_PART_2
00207     TreeTest<3> test3;
00208     CALL_SUBTEST(test3.testIntersect1());
00209     CALL_SUBTEST(test3.testMinimize1());
00210     CALL_SUBTEST(test3.testIntersect2());
00211     CALL_SUBTEST(test3.testMinimize2());
00212 #endif
00213 
00214 #ifdef EIGEN_TEST_PART_3
00215     TreeTest<4> test4;
00216     CALL_SUBTEST(test4.testIntersect1());
00217     CALL_SUBTEST(test4.testMinimize1());
00218     CALL_SUBTEST(test4.testIntersect2());
00219     CALL_SUBTEST(test4.testMinimize2());
00220 #endif
00221   }
00222 }


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:29:21