library of assembled shared sources

http://lass.cocamware.com

aabp_tree.inl

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 
00044 
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_AABP_TREE_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_SPAT_AABP_TREE_INL
00047 
00048 #include "spat_common.h"
00049 #include "aabp_tree.h"
00050 
00051 namespace lass
00052 {
00053 namespace spat
00054 {
00055 
00056 // --- public --------------------------------------------------------------------------------------
00057 
00058 template <typename O, typename OT, typename SH>
00059 AabpTree<O, OT, SH>::AabpTree():
00060     aabb_(TObjectTraits::aabbEmpty()),
00061     objects_(),
00062     nodes_(),
00063     end_()
00064 {
00065 }
00066 
00067 
00068 
00069 template <typename O, typename OT, typename SH>
00070 AabpTree<O, OT, SH>::AabpTree(TObjectIterator first, TObjectIterator last):
00071     aabb_(TObjectTraits::aabbEmpty()),
00072     objects_(),
00073     nodes_(),
00074     end_(last)
00075 {
00076     if (first != last)
00077     {
00078         TInputs inputs;
00079         for (TObjectIterator i = first; i != last; ++i)
00080         {
00081             TAabb aabb = TObjectTraits::objectAabb(i);
00082             aabb_ = TObjectTraits::aabbJoin(aabb_, aabb);
00083             inputs.push_back(Input(aabb, i));
00084         }
00085         balance(inputs.begin(), inputs.end());
00086     }
00087 }
00088 
00089 
00090 
00091 template <typename O, typename OT, typename SH>
00092 void AabpTree<O, OT, SH>::reset()
00093 {
00094     TSelf temp;
00095     swap(temp);
00096 }
00097 
00098 
00099 
00100 template <typename O, typename OT, typename SH>
00101 void AabpTree<O, OT, SH>::reset(TObjectIterator first, TObjectIterator last)
00102 {
00103     TSelf temp(first, last);
00104     swap(temp);
00105 }
00106 
00107 
00108 
00109 template <typename O, typename OT, typename SH>
00110 const typename AabpTree<O, OT, SH>::TAabb& 
00111 AabpTree<O, OT, SH>::aabb() const
00112 {
00113     return aabb_;
00114 }
00115 
00116 
00117 
00118 template <typename O, typename OT, typename SH>
00119 const bool AabpTree<O, OT, SH>::contains(const TPoint& point, const TInfo* info) const
00120 {
00121     if (isEmpty() || !TObjectTraits::aabbContains(aabb_, point))
00122     {
00123         return false;
00124     }
00125     return doContains(0, point, info);
00126 }
00127 
00128 
00129 
00130 template <typename O, typename OT, typename SH>
00131 template <typename OutputIterator>
00132 OutputIterator AabpTree<O, OT, SH>::find(
00133         const TPoint& point, OutputIterator result, const TInfo* info) const
00134 {
00135     if (isEmpty() || !TObjectTraits::aabbContains(aabb_, point))
00136     {
00137         return result;
00138     }
00139     return doFind(0, point, result, info);
00140 }
00141 
00142 
00143 
00144 template <typename O, typename OT, typename SH>
00145 const typename AabpTree<O, OT, SH>::TObjectIterator
00146 AabpTree<O, OT, SH>::intersect(const TRay& ray, TReference t, TParam tMin, const TInfo* info) const
00147 {
00148     TValue tNear;
00149     if (isEmpty() || !TObjectTraits::aabbIntersect(aabb_, ray, tNear, tMin))
00150     {
00151         return end_;
00152     }
00153     TValue tFar;
00154     if (!TObjectTraits::aabbIntersect(aabb_, ray, tFar, tNear))
00155     {
00156         tFar = tNear;
00157         tNear = tMin;
00158     }
00159     const TVector reciprocalDirection = TObjectTraits::vectorReciprocal(TObjectTraits::rayDirection(ray));
00160     TObjectIterator hit = doIntersect(0, ray, t, tMin, info, reciprocalDirection, tNear, tFar);
00161     LASS_ASSERT((t > tMin && t >= tNear && t <= tFar * (1 + 1e-7f)) || hit == end_);
00162     return hit;
00163 }
00164 
00165 
00166 
00167 template <typename O, typename OT, typename SH>
00168 const bool AabpTree<O, OT, SH>::intersects(
00169         const TRay& ray, TParam tMin, TParam tMax, const TInfo* info) const
00170 {
00171     TValue tNear;
00172     if (isEmpty() || !TObjectTraits::aabbIntersect(aabb_, ray, tNear, tMin))
00173     {
00174         return false;
00175     }
00176     TValue tFar;
00177     if (!TObjectTraits::aabbIntersect(aabb_, ray, tFar, tNear))
00178     {
00179         tFar = tNear;
00180         tNear = tMin;
00181     }
00182     if (tNear > tMax || tFar < tMin)
00183     {
00184         return false;
00185     }
00186     const TVector reciprocalDirection = TObjectTraits::vectorReciprocal(TObjectTraits::rayDirection(ray));
00187     return doIntersects(0, ray, tMin, tMax, info, reciprocalDirection, tNear, tFar);
00188 }
00189 
00190 
00191 
00192 template <typename O, typename OT, typename SH>
00193 const typename AabpTree<O, OT, SH>::Neighbour
00194 AabpTree<O, OT, SH>::nearestNeighbour(const TPoint& target, const TInfo* info) const
00195 {
00196     Neighbour nearest(end_, std::numeric_limits<TValue>::infinity());
00197     if (!isEmpty())
00198     {
00199         doNearestNeighbour(0, target, info, nearest);
00200     }
00201     return nearest;
00202 }
00203 
00204 
00205 
00206 template <class O, class OT, typename SH>
00207 template <typename RandomAccessIterator>
00208 RandomAccessIterator
00209 AabpTree<O, OT, SH>::rangeSearch(
00210         const TPoint& target, TParam maxRadius, size_t maxCount, RandomAccessIterator first, 
00211         const TInfo* info) const
00212 {
00213     if (isEmpty() || maxRadius == 0)
00214     {
00215         return first;
00216     }
00217     TValue squaredRadius = maxRadius * maxRadius;
00218     return doRangeSearch(0, target, squaredRadius, maxCount, first, first, info);
00219 }
00220 
00221 
00222 
00223 template <typename O, typename OT, typename SH>
00224 void AabpTree<O, OT, SH>::swap(TSelf& other)
00225 {
00226     std::swap(aabb_, other.aabb_);
00227     nodes_.swap(other.nodes_);
00228     objects_.swap(other.objects_);
00229     std::swap(end_, other.end_);
00230 }
00231 
00232 
00233 
00234 template <typename O, typename OT, typename SH>
00235 const bool AabpTree<O, OT, SH>::isEmpty() const
00236 {
00237     return objects_.empty();
00238 }
00239 
00240 
00241 
00242 template <typename O, typename OT, typename SH>
00243 const typename AabpTree<O, OT, SH>::TObjectIterator
00244 AabpTree<O, OT, SH>::end() const
00245 {
00246     return end_;
00247 }
00248 
00249 
00250 
00251 // --- protected -----------------------------------------------------------------------------------
00252 
00253 
00254 
00255 // --- private -------------------------------------------------------------------------------------
00256 
00257 template <typename O, typename OT, typename SH>
00258 const typename AabpTree<O, OT, SH>::BalanceResult 
00259 AabpTree<O, OT, SH>::balance(TInputIterator first, TInputIterator last)
00260 {
00261     const SplitInfo<OT> split = TSplitHeuristics::template split<OT>(first, last);  
00262     if (split.axis < 0)
00263     {
00264         return BalanceResult(split.aabb, addLeafNode(first, last));
00265     }
00266 
00267     TInputIterator middle = std::partition(first, last, impl::Splitter<TObjectTraits>(split));
00268     if (middle == first || middle == last)
00269     {
00270         const ptrdiff_t halfSize = (last - first) / 2;
00271         LASS_ASSERT(halfSize > 0);
00272         middle = first + halfSize;
00273         std::nth_element(first, middle, last, impl::LessAxis<TObjectTraits>(split.axis));
00274     }
00275     LASS_ASSERT(middle != first && middle != last);
00276 
00277     const int index = addInternalNode(split.axis);
00278     const BalanceResult left = balance(first, middle);
00279     const BalanceResult right = balance(middle, last);
00280     
00281     Node& node = nodes_[index];
00282     node.leftBound() = TObjectTraits::coord(TObjectTraits::aabbMax(left.aabb), split.axis);
00283     node.rightBound() = TObjectTraits::coord(TObjectTraits::aabbMin(right.aabb), split.axis);
00284     LASS_ASSERT(left.index == index + 1);
00285     node.right() = right.index;
00286     
00287     return BalanceResult(split.aabb, index);
00288 }
00289 
00290 
00291 
00292 template <typename O, typename OT, typename SH>
00293 const int AabpTree<O, OT, SH>::addLeafNode(TInputIterator first, TInputIterator last)
00294 {
00295     const int begin = static_cast<int>(objects_.size());
00296     while (first != last)
00297     {
00298         objects_.push_back((first++)->object);
00299     }
00300     const int end = static_cast<int>(objects_.size());
00301     
00302     LASS_ASSERT(begin >= 0 && end >= 0);
00303     nodes_.push_back(Node(begin, end));
00304 
00305     LASS_ASSERT(static_cast<int>(nodes_.size()) > 0);
00306     return static_cast<int>(nodes_.size()) - 1;
00307 }
00308 
00309 
00310 
00311 template <typename O, typename OT, typename SH>
00312 const int AabpTree<O, OT, SH>::addInternalNode(int axis)
00313 {
00314     nodes_.push_back(Node(axis));
00315     LASS_ASSERT(static_cast<int>(nodes_.size()) > 0);
00316     return static_cast<int>(nodes_.size()) - 1;
00317 }
00318 
00319 
00320 
00321 template <typename O, typename OT, typename SH>
00322 const bool AabpTree<O, OT, SH>::doContains(int index, const TPoint& point, const TInfo* info) const
00323 {
00324     LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
00325     LASS_ASSERT(index >= 0 && static_cast<size_t>(index) < nodes_.size());
00326     const Node& node = nodes_[index];
00327     
00328     if (node.isLeaf())
00329     {
00330         for (int i = node.first(); i != node.last(); ++i)
00331         {
00332             LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
00333             if (TObjectTraits::objectContains(objects_[i], point, info))
00334             {
00335                 return true;
00336             }
00337         }
00338         return false;
00339     }
00340 
00341     const TValue x = TObjectTraits::coord(point, node.axis());
00342     if (x <= node.leftBound() && doContains(index + 1, point, info))
00343     {
00344         return true;
00345     }
00346     if (x >= node.rightBound() && doContains(node.right(), point, info))
00347     {
00348         return true;
00349     }
00350     return false;
00351 }
00352 
00353 
00354 
00355 template <typename O, typename OT, typename SH>
00356 template <typename OutputIterator>
00357 OutputIterator AabpTree<O, OT, SH>::doFind(
00358         int index, const TPoint& point, OutputIterator result, const TInfo* info) const
00359 {
00360     LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
00361     LASS_ASSERT(index >= 0 && static_cast<size_t>(index) < nodes_.size());
00362     const Node& node = nodes_[index];
00363 
00364     if (node.isLeaf())
00365     {
00366         for (int i = node.first(); i != node.last(); ++i)
00367         {
00368             LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
00369             if (TObjectTraits::objectContains(objects_[i], point, info))
00370             {
00371                 *result++ = objects_[i];
00372             }
00373         }
00374         return result;
00375     }
00376 
00377     const TValue x = TObjectTraits::coord(point, node.axis());
00378     if (x <= node.leftBound())
00379     {
00380         result = doFind(index + 1, point, result, info);
00381     }
00382     if (x >= node.rightBound())
00383     {
00384         result = doFind(node.right(), point, result, info);
00385     }
00386     return result;
00387 }
00388 
00389 
00390 
00391 template <typename O, typename OT, typename SH>
00392 const typename AabpTree<O, OT, SH>::TObjectIterator
00393 AabpTree<O, OT, SH>::doIntersect(
00394         int index, const TRay& ray, TReference t, TParam tMin, const TInfo* info,
00395         const TVector& reciprocalDirection, TParam tNear, TParam tFar) const
00396 {
00397     LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
00398     LASS_ASSERT(index >= 0 && static_cast<size_t>(index) < nodes_.size());
00399     LASS_ASSERT(tFar > tNear);
00400     const Node& node = nodes_[index];
00401 
00402     if (node.isLeaf())
00403     {
00404         TValue tBest = 0;
00405         TObjectIterator best = end_;
00406         for (int i = node.first(); i != node.last(); ++i)
00407         {
00408             LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
00409             TValue tCandidate = 0;
00410             if (TObjectTraits::objectIntersect(objects_[i], ray, tCandidate, tMin, info))
00411             {
00412                 LASS_ASSERT(tCandidate > tMin);
00413                 if (best == end_ || tCandidate < tBest)
00414                 {
00415                     //LASS_ASSERT(tCandidate > tMin && tCandidate >= tNear && tCandidate <= tFar * (1 + 1e-7f));
00416                     best = objects_[i];
00417                     tBest = tCandidate;
00418                 }
00419             }
00420         }
00421         if (best != end_)
00422         {
00423             t = tBest;
00424         }
00425         return best;
00426     }
00427 
00428     // check children
00429     const int leftIndex = index + 1;
00430     const int rightIndex = node.right();
00431     const TValue s = TObjectTraits::coord(TObjectTraits::raySupport(ray), node.axis());
00432     const TValue d = TObjectTraits::coord(TObjectTraits::rayDirection(ray), node.axis());
00433     const TValue invD = TObjectTraits::coord(reciprocalDirection, node.axis());
00434     const TValue tLeftBound = (node.leftBound() - s) * invD;
00435     const TValue tRightBound = (node.rightBound() - s) * invD;
00436     
00437     TValue tLeft = 0;
00438     TValue tRight = 0;
00439     TObjectIterator objectLeft = end_;
00440     TObjectIterator objectRight = end_;
00441     if (d > 0)
00442     {
00443         if (tLeftBound > tNear)
00444         {
00445             objectLeft = doIntersect(leftIndex, ray, tLeft, tMin, info, reciprocalDirection, 
00446                 tNear, std::min(tLeftBound, tFar));
00447         }
00448         if (tRightBound < tFar)
00449         {
00450             objectRight = doIntersect(rightIndex, ray, tRight, tMin, info, reciprocalDirection, 
00451                 std::max(tRightBound, tNear), tFar);
00452         }
00453     }
00454     else if (d < 0)
00455     {
00456         if (tLeftBound < tFar)
00457         {
00458             objectLeft = doIntersect(leftIndex, ray, tLeft, tMin, info, reciprocalDirection, 
00459                 std::max(tLeftBound, tNear), tFar);
00460         }
00461         if (tRightBound > tNear)
00462         {
00463             objectRight = doIntersect(rightIndex, ray, tRight, tMin, info, reciprocalDirection, 
00464                 tNear, std::min(tRightBound, tFar)); 
00465         }
00466     }
00467     else // if (d == TNumTraits::zero)
00468     {
00469         if (s <= node.leftBound())
00470         {
00471             objectLeft = doIntersect(leftIndex, ray, tLeft, tMin, info, reciprocalDirection, 
00472                 tNear, tFar);
00473         }
00474         if (s >= node.rightBound())
00475         {
00476             objectRight = doIntersect(rightIndex, ray, tRight, tMin, info, reciprocalDirection, 
00477                 tNear, tFar);
00478         }
00479     }
00480     
00481     // determine result
00482     if (objectLeft != end_ && (objectRight == end_ || tLeft < tRight))
00483     {
00484         LASS_ASSERT(tLeft > tMin);
00485         t = tLeft;
00486         return objectLeft;
00487     }
00488     if (objectRight != end_)
00489     {
00490         LASS_ASSERT(objectLeft == end_ || !(tLeft < tRight));
00491         LASS_ASSERT(tRight > tMin);
00492         t = tRight;
00493         return objectRight;
00494     }
00495     return end_;
00496 }
00497 
00498 
00499 
00500 template <typename O, typename OT, typename SH>
00501 const bool AabpTree<O, OT, SH>::doIntersects(
00502         int index, const TRay& ray, TParam tMin, TParam tMax, const TInfo* info,
00503         const TVector& reciprocalDirection, TParam tNear, TParam tFar) const
00504 {
00505     LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
00506     LASS_ASSERT(index >= 0 && static_cast<size_t>(index) < nodes_.size());
00507     LASS_ASSERT(tMax > tMin);
00508     const Node& node = nodes_[index];
00509 
00510     if (node.isLeaf())
00511     {
00512         for (int i = node.first(); i != node.last(); ++i)
00513         {
00514             LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
00515             if (TObjectTraits::objectIntersects(objects_[i], ray, tMin, tMax, info))
00516             {
00517                 return true;
00518             }
00519         }
00520         return false;
00521     }
00522 
00523     // check children
00524     const int leftIndex = index + 1;
00525     const int rightIndex = node.right();
00526     const TValue s = TObjectTraits::coord(TObjectTraits::raySupport(ray), node.axis());
00527     const TValue d = TObjectTraits::coord(TObjectTraits::rayDirection(ray), node.axis());
00528     const TValue invD = TObjectTraits::coord(reciprocalDirection, node.axis());
00529     const TValue tLeftBound = (node.leftBound() - s) * invD;
00530     const TValue tRightBound = (node.rightBound() - s) * invD;
00531     
00532     if (d > 0)
00533     {
00534         if ((tLeftBound > tNear) && doIntersects(leftIndex, ray, tMin, tMax, info, 
00535                 reciprocalDirection, tNear, std::min(tLeftBound, tFar)))
00536         {
00537             return true;
00538         }
00539         if ((tRightBound < tFar) && doIntersects(rightIndex, ray, tMin, tMax, info,
00540                 reciprocalDirection, std::max(tRightBound, tNear), tFar))
00541         {
00542             return true;
00543         }
00544     }
00545     else if (d < 0)
00546     {
00547         if ((tLeftBound < tFar) && doIntersects(leftIndex, ray, tMin, tMax, info,
00548                 reciprocalDirection, std::max(tLeftBound, tNear), tFar))
00549         {
00550             return true;
00551         }
00552         if ((tRightBound > tNear) && doIntersects(rightIndex, ray, tMin, tMax, info,
00553                 reciprocalDirection, tNear, std::min(tRightBound, tFar)))
00554         {
00555             return true;
00556         }
00557     }
00558     else // if (d == TNumTraits::zero)
00559     {
00560         if ((s <= node.leftBound()) && doIntersects(rightIndex, ray, tMin, tMax, info,
00561                 reciprocalDirection, tNear, tFar))
00562         {
00563             return true;
00564         }
00565         if ((s >= node.rightBound()) && doIntersects(rightIndex, ray, tMin, tMax, info,
00566                 reciprocalDirection, tNear, tFar))
00567         {
00568             return true;
00569         }
00570     }
00571     return false;
00572 }
00573 
00574 
00575 
00576 template <typename O, typename OT, typename SH>
00577 void AabpTree<O, OT, SH>::doNearestNeighbour(
00578         int index, const TPoint& target, const TInfo* info, Neighbour& best) const
00579 {
00580     LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
00581     LASS_ASSERT(best.squaredDistance() >= 0);
00582 
00583     const Node& node = nodes_[index];
00584 
00585     if (node.isLeaf())
00586     {
00587         for (int i = node.first(); i != node.last(); ++i)
00588         {
00589             LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
00590             const TValue squaredDistance = 
00591                 TObjectTraits::objectSquaredDistance(objects_[i], target, info);
00592             if (squaredDistance < best.squaredDistance())
00593             {
00594                 best = Neighbour(objects_[i], squaredDistance);
00595             }
00596         }
00597     }
00598     else
00599     {
00600         int children[2];
00601         TValue signedDist[2];
00602         getChildren(index, target, children, signedDist);
00603         if (signedDist[0] <= 0 || (signedDist[0] * signedDist[0]) < best.squaredDistance())
00604         {
00605             doNearestNeighbour(children[0], target, info, best);
00606             if (signedDist[1] <= 0 || (signedDist[1] * signedDist[1]) < best.squaredDistance())
00607             {
00608                 doNearestNeighbour(children[1], target, info, best);
00609             }
00610         }
00611     }
00612 }
00613 
00614 
00615 
00616 template <typename O, typename OT, typename SH>
00617 template <typename RandomIterator>
00618 RandomIterator AabpTree<O, OT, SH>::doRangeSearch(
00619     int index, const TPoint& target, TReference squaredRadius, size_t maxCount,
00620     RandomIterator first, RandomIterator last, const TInfo* info) const
00621 {
00622     LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
00623     LASS_ASSERT(squaredRadius >= 0);
00624 
00625     const Node& node = nodes_[index];
00626 
00627     if (node.isLeaf())
00628     {
00629         for (int i = node.first(); i != node.last(); ++i)
00630         {
00631             LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
00632             const TValue sqrDist = TObjectTraits::objectSquaredDistance(objects_[i], target, info);
00633             if (sqrDist < squaredRadius)
00634             {
00635                 *last++ = Neighbour(objects_[i], sqrDist);
00636                 std::push_heap(first, last);
00637                 LASS_ASSERT(last >= first);
00638                 if (static_cast<size_t>(last - first) > maxCount)
00639                 {
00640                     std::pop_heap(first, last);
00641                     --last;
00642                     squaredRadius = first->squaredDistance();
00643                 }
00644             }
00645         }
00646         return last;
00647     }
00648     
00649     int children[2];
00650     TValue signedDist[2];
00651     getChildren(index, target, children, signedDist);
00652     if (signedDist[0] <= 0 || (signedDist[0] * signedDist[0]) < squaredRadius)
00653     {
00654         last = doRangeSearch(children[0], target, squaredRadius, maxCount, first, last, info);
00655         if (signedDist[1] <= 0 || (signedDist[1] * signedDist[1]) < squaredRadius)
00656         {
00657             last = doRangeSearch(children[1], target, squaredRadius, maxCount, first, last, info);
00658         }
00659     }
00660     return last;
00661 }
00662 
00663 
00664 
00665 template <typename O, typename OT, typename SH>
00666 void AabpTree<O, OT, SH>::getChildren(
00667         int index, const TPoint& target, int indices[2], TValue signedDistances[2]) const
00668 {
00669     const Node& node = nodes_[index];
00670     indices[0] = index + 1;
00671     indices[1] = node.right();
00672     const TValue x = TObjectTraits::coord(target, node.axis());
00673     signedDistances[0] = x - node.leftBound(); 
00674     signedDistances[1] = node.rightBound() - x; 
00675 
00676     if (signedDistances[1] < signedDistances[0])
00677     {
00678         std::swap(signedDistances[0], signedDistances[1]);
00679         std::swap(indices[0], indices[1]);
00680     }
00681 }
00682 
00683 
00684 
00685 // --- free ----------------------------------------------------------------------------------------
00686 
00687 }
00688 
00689 }
00690 
00691 #endif
00692 
00693 // EOF

Generated on Mon Nov 10 14:19:59 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo