65#ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_IMPL_QUAD_TREE_HELPER_H
66#define LASS_GUARDIAN_OF_INCLUSION_SPAT_IMPL_QUAD_TREE_HELPER_H
79template <
typename ObjectTraits,
typename Po
intType>
82 enum { dimension = ObjectTraits::dimension };
84 typedef ObjectTraits TObjectTraits;
85 typedef typename ObjectTraits::TPoint TPoint;
86 typedef typename ObjectTraits::TVector TVector;
87 typedef typename ObjectTraits::TValue TValue;
89 static TValue minComponent(
const TVector& v)
91 TValue best = TObjectTraits::coord(v, 0);
92 for (
size_t k = 1; k < dimension; ++k)
94 best = std::min(best, TObjectTraits::coord(v, k));
99 static TValue maxComponent(
const TVector& v)
101 TValue best = TObjectTraits::coord(v, 0);
102 for (
size_t k = 1; k < dimension; ++k)
104 best = std::max(best, TObjectTraits::coord(v, k));
109 template <
typename V>
110 static const V middle(
const V& a,
const V& b)
113 for (
size_t k = 0; k < dimension; ++k)
115 TObjectTraits::coord(result, k, (TObjectTraits::coord(a, k) + TObjectTraits::coord(b, k)) / 2);
120 static const TValue squaredDistance(
const TPoint& a,
const TPoint& b)
123 for (
size_t k = 0; k < dimension; ++k)
125 d +=
num::sqr(TObjectTraits::coord(a, k) - TObjectTraits::coord(b, k));
130 static size_t entryNode(
const TVector& tNear,
const TVector& tMiddle)
132 const TValue tEntry = maxComponent(tNear);
134 for (
size_t k = 0, mask = 1; k < dimension; ++k, mask *= 2)
136 iEntry |= (TObjectTraits::coord(tMiddle, k) < tEntry) ? mask : 0;
141 static size_t nextNode(
size_t i,
const TVector& tFar)
144 TValue min = TObjectTraits::coord(tFar, 0);
145 for (
size_t k = 1, mask = 2; k < dimension; ++k, mask *= 2)
147 const TValue x = TObjectTraits::coord(tFar, k);
161 static size_t findSubNode(
const TPoint& center,
const TPoint& point)
164 for (
size_t k = 0, mask = 1; k < dimension; ++k, mask *= 2)
166 i |= TObjectTraits::coord(point, k) >= TObjectTraits::coord(center, k) ? mask : 0;
171 static size_t forcePositiveDirection(
const TPoint& center, TPoint& support, TVector& direction)
174 for (
size_t k = 0, mask = 1; k < dimension; ++k, mask *= 2)
176 const TValue d = TObjectTraits::coord(direction, k);
179 TObjectTraits::coord(support, k,
180 2 * TObjectTraits::coord(center, k) - TObjectTraits::coord(support, k));
181 TObjectTraits::coord(direction, k, -d);
188 static void nearAndFar(
const TPoint& min,
const TPoint& max,
const TPoint& support,
189 const TVector& reciprocalDirection, TVector& tNear, TVector& tFar)
191 for (
size_t k = 0; k < dimension; ++k)
193 TObjectTraits::coord(tNear, k, TObjectTraits::coord(reciprocalDirection, k) *
194 (TObjectTraits::coord(min, k) - TObjectTraits::coord(support, k)));
195 TObjectTraits::coord(tFar, k, TObjectTraits::coord(reciprocalDirection, k) *
196 (TObjectTraits::coord(max, k) - TObjectTraits::coord(support, k)));
200 static void childNearAndFar(TVector& tNear, TVector& tFar,
const TVector& tMiddle,
size_t iChild)
202 for (
size_t k = 0, mask = 1; k < dimension; ++k, mask *= 2)
206 TObjectTraits::coord(tNear, k, TObjectTraits::coord(tMiddle, k));
210 TObjectTraits::coord(tFar, k, TObjectTraits::coord(tMiddle, k));
218template <
typename ObjectTraits,
typename T>
219class QuadTreeHelper<ObjectTraits, prim::Point2D<T> >
222 typedef ObjectTraits TObjectTraits;
223 typedef typename ObjectTraits::TPoint TPoint;
224 typedef typename ObjectTraits::TVector TVector;
225 typedef typename ObjectTraits::TValue TValue;
226 enum { dimension = 2 };
228 static TValue minComponent(
const TVector& v)
230 return std::min(v.x, v.y);
233 static TValue maxComponent(
const TVector& v)
235 return std::max(v.x, v.y);
238 template <
typename V>
239 static const V middle(
const V& a,
const V& b)
241 return V((a.x + b.x) / 2, (a.y + b.y) / 2);
244 static const TValue squaredDistance(
const TPoint& a,
const TPoint& b)
246 return prim::squaredDistance(a, b);
249 static size_t entryNode(
const TVector& tNear,
const TVector& tMiddle)
251 const TValue tEntry = maxComponent(tNear);
252 return (tMiddle.x < tEntry ? 0x1 : 0) | (tMiddle.y < tEntry ? 0x2 : 0);
255 static size_t nextNode(
size_t i,
const TVector& tFar)
259 return i & 0x1 ? size_t(-1) : i | 0x1;
263 return i & 0x2 ? size_t(-1) : i | 0x2;
267 static size_t findSubNode(
const TPoint& center,
const TPoint& point)
269 return (point.x >= center.x ? 0x1 : 0x0) | (point.y >= center.y ? 0x2 : 0x0);
272 static size_t forcePositiveDirection(
const TPoint& center, TPoint& support, TVector& direction)
277 support.x = 2 * center.x - support.x;
278 direction.x = -direction.x;
283 support.y = 2 * center.y - support.y;
284 direction.y = -direction.y;
297 static size_t forceMinToMax(TVector& near, TVector& far)
302 std::swap(near.x, far.x);
307 std::swap(near.y, far.y);
313 static void nearAndFar(
const TPoint& min,
const TPoint& max,
const TPoint& support,
314 const TVector& reciprocalDirection, TVector& tNear, TVector& tFar)
316 tNear = reciprocalDirection * (min - support);
317 tFar = reciprocalDirection * (max - support);
320 static void childNearAndFar(TVector& tNear, TVector& tFar,
const TVector& tMiddle,
size_t iChild)
322 (iChild & 0x1 ? tNear : tFar).x = tMiddle.x;
323 (iChild & 0x2 ? tNear : tFar).y = tMiddle.y;
329template <
typename ObjectTraits,
typename T>
330class QuadTreeHelper<ObjectTraits, prim::Point3D<T> >
332 enum { dimension = 3 };
334 typedef ObjectTraits TObjectTraits;
335 typedef typename ObjectTraits::TPoint TPoint;
336 typedef typename ObjectTraits::TVector TVector;
337 typedef typename ObjectTraits::TValue TValue;
339 static TValue minComponent(
const TVector& v)
341 return std::min(std::min(v.x, v.y), v.z);
344 static TValue maxComponent(
const TVector& v)
346 return std::max(std::max(v.x, v.y), v.z);
349 template <
typename V>
350 static const V middle(
const V& a,
const V& b)
358 static const TValue squaredDistance(
const TPoint& a,
const TPoint& b)
360 return prim::squaredDistance(a, b);
363 static size_t entryNode(
const TVector& tNear,
const TVector& tMiddle)
365 const TValue tEntry = maxComponent(tNear);
366 return (tMiddle.x < tEntry ? 0x1 : 0)
367 | (tMiddle.y < tEntry ? 0x2 : 0)
368 | (tMiddle.z < tEntry ? 0x4 : 0);
371 static size_t nextNode(
size_t i,
const TVector& tFar)
373 if (tFar.x < tFar.y && tFar.x < tFar.z)
375 return i & 0x1 ? size_t(-1) : i | 0x1;
377 else if (tFar.y < tFar.z)
379 return i & 0x2 ? size_t(-1) : i | 0x2;
383 return i & 0x4 ? size_t(-1) : i | 0x4;
387 static size_t findSubNode(
const TPoint& center,
const TPoint& point)
389 return (point.x >= center.x ? 0x1 : 0x0)
390 | (point.y >= center.y ? 0x2 : 0x0)
391 | (point.z >= center.z ? 0x4 : 0x0);
394 static size_t forcePositiveDirection(
const TPoint& center, TPoint& support, TVector& direction)
397 for (
size_t k = 0, mask = 1; k < dimension; ++k, mask *= 2)
399 if (direction[k] < 0)
401 support[k] = 2 * center[k] - support[k];
402 direction[k] = -direction[k];
416 static size_t forceMinToMax(TVector& near, TVector& far)
421 std::swap(near.x, far.x);
426 std::swap(near.y, far.y);
431 std::swap(near.z, far.z);
437 static void nearAndFar(
const TPoint& min,
const TPoint& max,
const TPoint& support,
438 const TVector& reciprocalDirection, TVector& tNear, TVector& tFar)
440 tNear = reciprocalDirection * (min - support);
441 tFar = reciprocalDirection * (max - support);
444 static void childNearAndFar(TVector& tNear, TVector& tFar,
const TVector& tMiddle,
size_t iChild)
446 (iChild & 0x1 ? tNear : tFar).x = tMiddle.x;
447 (iChild & 0x2 ? tNear : tFar).y = tMiddle.y;
448 (iChild & 0x4 ? tNear : tFar).z = tMiddle.z;
T sqr(const T &x)
return x * x
spatial subdivisions, quadtrees, octrees, meshes in 2D and 3D, triangulators, ...
Library for Assembled Shared Sources.