00001
00002
00008 #if !defined(__geom_ISS_SignedDistance_h__)
00009 #define __geom_ISS_SignedDistance_h__
00010
00011 #if defined(DEBUG_geom) && !defined(DEBUG_ISS_SignedDistance)
00012 #define DEBUG_ISS_SignedDistance
00013 #endif
00014
00015 #include "SimplexAdj.h"
00016 #include "ISS_SimplexQuery.h"
00017
00018 #include "../simplex/simplex_distance.h"
00019
00020 #include "../../tree/BBoxTree.h"
00021
00022 #include "../../../ads/algorithm/sign.h"
00023
00024 #include <set>
00025 #include <map>
00026
00027 BEGIN_NAMESPACE_GEOM
00028
00030
00035 template <class ISS, int N = ISS::N>
00036 class ISS_SignedDistance;
00037
00038 END_NAMESPACE_GEOM
00039
00040 #define __geom_ISS_SignedDistance_2_ipp__
00041 #include "ISS_SignedDistance_2.ipp"
00042 #undef __geom_ISS_SignedDistance_2_ipp__
00043
00044 #define __geom_ISS_SignedDistance_3_ipp__
00045 #include "ISS_SignedDistance_3.ipp"
00046 #undef __geom_ISS_SignedDistance_3_ipp__
00047
00048 BEGIN_NAMESPACE_GEOM
00049
00050
00052
00056 template<class ISS>
00057 class ISS_Distance :
00058 public std::unary_function<typename ISS_SimplexQuery<ISS>::Vertex,
00059 typename ISS_SimplexQuery<ISS>::Number> {
00060
00061 typedef std::unary_function<typename ISS_SimplexQuery<ISS>::Vertex,
00062 typename ISS_SimplexQuery<ISS>::Number> Base;
00063
00064
00065 const ISS_SimplexQuery<ISS>& _sq;
00066
00067
00068 ISS_Distance();
00069 ISS_Distance& operator=(const ISS_Distance&);
00070
00071 public:
00073 typedef typename Base::argument_type argument_type;
00075 typedef typename Base::result_type result_type;
00076
00078 explicit
00079 ISS_Distance(const ISS_SimplexQuery<ISS>& sq) :
00080 _sq(sq)
00081 {}
00082
00084 ISS_Distance(const ISS_Distance& other) :
00085 _sq(other._sq)
00086 {}
00087
00089 result_type
00090 operator()(const argument_type& x) const {
00091 return _sq.computeMinimumDistance(x);
00092 }
00093 };
00094
00095
00096
00097
00099 template<class ISS>
00100 class ISS_SD_Distance :
00101 public std::unary_function<const typename
00102 ISS_SignedDistance<ISS>::Vertex&,
00103 typename ISS_SignedDistance<ISS>::Number>
00104 {
00105
00106 typedef std::unary_function<const typename
00107 ISS_SignedDistance<ISS>::Vertex&,
00108 typename ISS_SignedDistance<ISS>::Number> Base;
00109
00110
00111 const ISS_SignedDistance<ISS>& _sd;
00112
00113
00114 ISS_SD_Distance();
00115 ISS_SD_Distance& operator=(const ISS_SD_Distance&);
00116
00117 public:
00119 typedef typename Base::argument_type argument_type;
00121 typedef typename Base::result_type result_type;
00122
00124 ISS_SD_Distance(const ISS_SignedDistance<ISS>& sd) :
00125 _sd(sd)
00126 {}
00127
00129 ISS_SD_Distance(const ISS_SD_Distance& other) :
00130 _sd(other._sd)
00131 {}
00132
00134 result_type
00135 operator()(argument_type x) const {
00136 return _sd(x);
00137 }
00138 };
00139
00140
00141
00143 template<class ISS>
00144 class ISS_SD_ClosestPoint :
00145 public std::unary_function<const typename
00146 ISS_SignedDistance<ISS>::Vertex&,
00147 const typename
00148 ISS_SignedDistance<ISS>::Vertex&> {
00149
00150 typedef std::unary_function<const typename
00151 ISS_SignedDistance<ISS>::Vertex&,
00152 const typename
00153 ISS_SignedDistance<ISS>::Vertex&> Base;
00154
00155
00156 const ISS_SignedDistance<ISS>& _sd;
00157
00158
00159 ISS_SD_ClosestPoint();
00160 ISS_SD_ClosestPoint& operator=(const ISS_SD_ClosestPoint&);
00161
00162 public:
00164 typedef typename Base::argument_type argument_type;
00166 typedef typename Base::result_type result_type;
00167
00169 ISS_SD_ClosestPoint(const ISS_SignedDistance<ISS>& sd) :
00170 _sd(sd)
00171 {}
00172
00174 ISS_SD_ClosestPoint(const ISS_SD_ClosestPoint& other) :
00175 _sd(other._sd)
00176 {}
00177
00179 result_type
00180 operator()(argument_type x) const {
00181 return _sd.computeClosestPoint(x);
00182 }
00183 };
00184
00185
00186
00188 template<class ISS>
00189 class ISS_SD_ClosestPointDirection :
00190 public std::unary_function<const typename
00191 ISS_SignedDistance<ISS>::Vertex&,
00192 const typename
00193 ISS_SignedDistance<ISS>::Vertex&> {
00194
00195 typedef std::unary_function<const typename
00196 ISS_SignedDistance<ISS>::Vertex&,
00197 const typename
00198 ISS_SignedDistance<ISS>::Vertex&> Base;
00199
00200 typedef typename ISS_SignedDistance<ISS>::Vertex Vertex;
00201
00202 public:
00204 typedef typename Base::argument_type argument_type;
00206 typedef typename Base::result_type result_type;
00208 typedef typename ISS_SignedDistance<ISS>::Number Number;
00209
00210 private:
00211
00212
00213 const ISS_SignedDistance<ISS>& _sd;
00214 int _maxIterations;
00215 Number _tolerance;
00216 mutable Vertex _p, _q, _offset;
00217
00218
00219 ISS_SD_ClosestPointDirection();
00220 ISS_SD_ClosestPointDirection&
00221 operator=(const ISS_SD_ClosestPointDirection&);
00222
00223 public:
00224
00226 ISS_SD_ClosestPointDirection
00227 (const ISS_SignedDistance<ISS>& sd,
00228 const int max_iterations = 5,
00229 const Number tolerance =
00230 std::sqrt(std::numeric_limits<Number>::epsilon())) :
00231 _sd(sd),
00232 _maxIterations(max_iterations),
00233 _tolerance(tolerance)
00234 {}
00235
00237 ISS_SD_ClosestPointDirection(const ISS_SD_ClosestPointDirection& other) :
00238 _sd(other._sd),
00239 _maxIterations(other._maxIterations),
00240 _tolerance(other._tolerance)
00241 {}
00242
00244
00248 result_type
00249 operator()(argument_type x, argument_type dir) const {
00250 _p = x;
00251 Number distance = _tolerance;
00252 for (int iter = 0; iter != _maxIterations && distance >= _tolerance;
00253 ++iter) {
00254
00255 distance = std::abs(_sd(_p, &_q));
00256
00257 _q -= _p;
00258 _offset = dir;
00259 _offset *= ads::sign(geom::computeDotProduct(_q, dir)) *
00260 geom::computeMagnitude(_q);
00261 _p += _offset;
00262 }
00263 return _sd.computeClosestPoint(_p);
00264 }
00265 };
00266
00267
00268
00269
00270
00272 template<class ISS>
00273 class ISS_SD_CloserPointDirection :
00274 public std::unary_function<const typename
00275 ISS_SignedDistance<ISS>::Vertex&,
00276 const typename
00277 ISS_SignedDistance<ISS>::Vertex&> {
00278
00279 typedef std::unary_function<const typename
00280 ISS_SignedDistance<ISS>::Vertex&,
00281 const typename
00282 ISS_SignedDistance<ISS>::Vertex&> Base;
00283
00284 typedef typename ISS_SignedDistance<ISS>::Vertex Vertex;
00285
00286 public:
00288 typedef typename Base::argument_type argument_type;
00290 typedef typename Base::result_type result_type;
00292 typedef typename ISS_SignedDistance<ISS>::Number Number;
00293
00294 private:
00295
00296
00297 const ISS_SignedDistance<ISS>& _sd;
00298 Number _max_distance;
00299 int _maxIterations;
00300 Number _tolerance;
00301 mutable Vertex _p, _q, _offset;
00302
00303
00304 ISS_SD_CloserPointDirection();
00305 ISS_SD_CloserPointDirection&
00306 operator=(const ISS_SD_CloserPointDirection&);
00307
00308 public:
00309
00311 ISS_SD_CloserPointDirection
00312 (const ISS_SignedDistance<ISS>& sd,
00313 const Number max_distance,
00314 const int max_iterations = 5,
00315 const Number tolerance =
00316 std::sqrt(std::numeric_limits<Number>::epsilon())) :
00317 _sd(sd),
00318 _max_distance(max_distance),
00319 _maxIterations(max_iterations),
00320 _tolerance(tolerance)
00321 {}
00322
00324 ISS_SD_CloserPointDirection(const ISS_SD_CloserPointDirection& other) :
00325 _sd(other._sd),
00326 _max_distance(other._max_distance),
00327 _maxIterations(other._maxIterations),
00328 _tolerance(other._tolerance)
00329 {}
00330
00332
00336 result_type
00337 operator()(argument_type x, argument_type dir) const {
00338
00339
00340
00341 _p = x;
00342 Number distance = _tolerance;
00343 for (int iter = 0; iter != _maxIterations && distance >= _tolerance;
00344 ++iter) {
00345
00346 distance = std::abs(_sd(_p, &_q));
00347
00348 _q -= _p;
00349 _offset = dir;
00350 _offset *= ads::sign(geom::computeDotProduct(_q, dir)) *
00351 geom::computeMagnitude(_q);
00352 _p += _offset;
00353 }
00354 _p = _sd.computeClosestPoint(_p);
00355
00356
00357
00358
00359
00360 distance = geom::computeDistance(x, _p);
00361
00362 if (distance > _max_distance) {
00363
00364 _p -= x;
00365
00366 _p *= (_max_distance / distance);
00367
00368 _p += x;
00369 }
00370
00371
00372 return _p;
00373 }
00374 };
00375
00376
00377
00378
00379
00381 template<class ISS>
00382 class ISS_SD_CloserPoint :
00383 public std::unary_function<const typename
00384 ISS_SignedDistance<ISS>::Vertex&,
00385 const typename
00386 ISS_SignedDistance<ISS>::Vertex&> {
00387
00388 typedef typename ISS_SignedDistance<ISS>::Vertex Vertex;
00389 typedef typename ISS_SignedDistance<ISS>::Number Number;
00390 typedef std::unary_function<const Vertex&, const Vertex&> Base;
00391
00392
00393 const ISS_SignedDistance<ISS>& _sd;
00394 Number _maxDistance;
00395 mutable Vertex _cp;
00396
00397
00398 ISS_SD_CloserPoint();
00399 ISS_SD_CloserPoint& operator=(const ISS_SD_CloserPoint&);
00400
00401 public:
00403 typedef typename Base::argument_type argument_type;
00405 typedef typename Base::result_type result_type;
00406
00408 ISS_SD_CloserPoint(const ISS_SignedDistance<ISS>& sd,
00409 const Number max_distance) :
00410 _sd(sd),
00411 _maxDistance(max_distance)
00412 {}
00413
00415 ISS_SD_CloserPoint(const ISS_SD_CloserPoint& other) :
00416 _sd(other._sd),
00417 _maxDistance(other._maxDistance)
00418 {}
00419
00421 result_type
00422 operator()(argument_type x) const {
00423
00424 Number d = _sd(x, &_cp);
00425
00426
00427 if (d > _maxDistance) {
00428
00429 _cp -= x;
00430
00431 _cp *= (_maxDistance / d);
00432
00433 _cp += x;
00434 }
00435
00436
00437 return _cp;
00438 }
00439 };
00440
00441
00442 END_NAMESPACE_GEOM
00443
00444
00445 #endif