VTK  9.6.20260708
vtkStaticPointLocator2DPrivate.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-FileCopyrightText: Copyright 2011 Sandia Corporation
3// SPDX-License-Identifier: LicenseRef-BSD-3-Clause-Sandia-USGov
12
13#ifndef vtkStaticPointLocator2DPrivate_h
14#define vtkStaticPointLocator2DPrivate_h
15
16#include "vtkArrayDispatch.h"
18#include "vtkCellArray.h"
19#include "vtkDataArrayRange.h"
20#include "vtkDataSet.h"
21#include "vtkDoubleArray.h"
22#include "vtkMath.h"
23#include "vtkMathUtilities.h" // for SafeCastFromDouble
24#include "vtkPoints.h"
26#include "vtkSMPTools.h"
28#include "vtkStructuredData.h"
29
30VTK_ABI_NAMESPACE_BEGIN
31
32#define Distance2BetweenPoints2D(p1, p2) \
33 ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]))
34
40inline bool IntersectsCircle(
41 const double min[2], const double max[2], const double center[2], double r2)
42{
43 double d2 = 0.0;
44 for (int i = 0; i < 2; ++i)
45 {
46 if (center[i] < min[i])
47 {
48 d2 += (center[i] - min[i]) * (center[i] - min[i]);
49 }
50 else if (center[i] > max[i])
51 {
52 d2 += (center[i] - max[i]) * (center[i] - max[i]);
53 }
54 }
55 return (d2 <= r2);
56}
57
63inline bool InsideCircle(
64 const double min[2], const double max[2], const double center[2], double r2)
65{
66 double dmin = 0.0, dmax = 0.0;
67 for (int i = 0; i < 2; ++i)
68 {
69 double a = (center[i] - min[i]) * (center[i] - min[i]);
70 double b = (center[i] - max[i]) * (center[i] - max[i]);
71 dmax += std::max(a, b);
72 if (min[i] <= center[i] && center[i] <= max[i])
73 {
74 dmin += std::min(a, b);
75 }
76 }
77 return (!(dmin <= r2 && r2 <= dmax));
78}
79
80//------------------------------------------------------------------------------
81// The following code supports threaded point locator construction. The locator
82// is assumed to be constructed once (i.e., it does not allow incremental point
83// insertion). The algorithm proceeds in three steps:
84// 1) All points are assigned a bucket index (combined i-j bucket location).
85// The index is computed in parallel. This requires a one time allocation of an
86// index array (which is also associated with the originating point ids).
87// 2) vtkSMPTools::Sort() is used to sort the index array. Note that the sort
88// carries along the point ids as well. This creates contiguous runs of points
89// all resident in the same bucket.
90// 3) The bucket offsets are updated to refer to the right entry location into
91// the sorted point ids array. This enables quick access, and an indirect count
92// of the number of points in each bucket.
93
94struct NeighborBuckets2D;
95
96//------------------------------------------------------------------------------
97// The bucketed points, including the sorted map. This is just a PIMPLd
98// wrapper around the classes that do the real work.
100{
102 vtkIdType NumPts; // the number of points to bucket
105
106 // These are internal data members used for performance reasons
108 int Divisions[3];
109 double Bounds[6];
110 double H[3];
111 double hX, hY, hX2, hY2;
112 double fX, fY, bX, bY;
114
115 // Used for accelerated performance for certain methods
116 double* FastPoints; // fast path for accessing points
117 double BinRadius; // circumradius of a single bin/bucket
118 int MaxLevel; // the maximum possible level searches can proceed
119
120 // Construction
122 {
123 this->Locator = loc;
124 this->NumPts = numPts;
125 this->NumBuckets = numBuckets;
126 this->BatchSize = 10000; // building the offset array
127 this->DataSet = loc->GetDataSet();
128
129 // Setup internal data members for more efficient processing. Remember this is
130 // a 2D locator so just processing (x,y) points.
131 double spacing[3], bounds[6];
132 loc->GetDivisions(this->Divisions);
133 loc->GetSpacing(spacing);
134 loc->GetBounds(bounds);
135 this->hX = this->H[0] = spacing[0];
136 this->hY = this->H[1] = spacing[1];
137 this->hX2 = this->hX / 2.0;
138 this->hY2 = this->hY / 2.0;
139 this->fX = 1.0 / spacing[0];
140 this->fY = 1.0 / spacing[1];
141 this->bX = this->Bounds[0] = bounds[0];
142 this->Bounds[1] = bounds[1];
143 this->bY = this->Bounds[2] = bounds[2];
144 this->Bounds[3] = bounds[3];
145 this->xD = this->Divisions[0];
146 this->yD = this->Divisions[1];
147 this->zD = 1;
148
149 this->FastPoints = nullptr;
150 this->BinRadius = sqrt(hX * hX + hY * hY) / 2.0;
151 this->MaxLevel = std::max({ this->xD, this->yD, this->zD });
152 }
153
154 // Virtuals for templated subclasses
155 virtual ~vtkBucketList2D() = default;
156 virtual void BuildLocator() = 0;
157
158 // place points in appropriate buckets
160 NeighborBuckets2D* buckets, const int ij[2], const int ndivs[2], int level);
161 void GenerateFace(int face, int i, int j, int k, vtkPoints* pts, vtkCellArray* polys);
162 double Distance2ToBucket(const double x[3], const int nei[3]);
163 double Distance2ToBounds(const double x[3], const double bounds[6]);
164
165 //-----------------------------------------------------------------------------
166 // Inlined for performance. These function invocations must be called after
167 // BuildLocator() is invoked, otherwise the output is indeterminate.
168 void GetBucketIndices(const double* x, int ij[2]) const
169 {
170 // Compute point index. SafeCastFromDouble clamps to the integer type limits
171 // (mapping NaN to 0) so casting a coordinate far outside the locator bounds
172 // (e.g. VTK_DOUBLE_MAX) is not undefined behavior. Make sure it then lies
173 // within the range of the locator.
176
177 ij[0] = std::min(std::max<vtkIdType>(tmp0, 0), xD - 1);
178 ij[1] = std::min(std::max<vtkIdType>(tmp1, 0), yD - 1);
179 }
180
181 //-----------------------------------------------------------------------------
182 vtkIdType GetBucketIndex(const double* x) const
183 {
184 int ij[2];
185 this->GetBucketIndices(x, ij);
186 return ij[0] + ij[1] * xD;
187 }
188
189 //-----------------------------------------------------------------------------
190 // Return the center of the bucket/bin at (i,j). Note, returns a 2D point
191 // center[2].
192 void GetBucketCenter(int i, int j, double center[3])
193 {
194 center[0] = this->bX + this->hX2 + i * this->hX;
195 center[1] = this->bY + this->hY2 + j * this->hY;
196 center[2] = 0.0;
197 }
198
199 //-----------------------------------------------------------------------------
200 // Return the bounding box (min,max) of a specified bucket (i,j,k).
201 void GetBucketBounds(int i, int j, double min[3], double max[3])
202 {
203 min[0] = this->bX + i * this->hX;
204 min[1] = this->bY + j * this->hY;
205 min[2] = 0.0;
206 max[0] = min[0] + this->hX;
207 max[1] = min[1] + this->hY;
208 max[2] = 0.0;
209 }
210
211 //-----------------------------------------------------------------------------
212 // Determine whether a bin/bucket specified by i,j is completely contained
213 // inside the circle (center,r2). Return true if contained; false otherwise.
214 bool BucketInsideCircle(int i, int j, const double center[3], double r2)
215 {
216 double xMin = this->bX + i * this->hX;
217 double xMax = xMin + this->hX;
218 double yMin = this->bY + j * this->hY;
219 double yMax = yMin + this->hY;
220 double dx0 = center[0] - xMin, dx1 = center[0] - xMax;
221 double dy0 = center[1] - yMin, dy1 = center[1] - yMax;
222 double dmax2 = std::max(dx0 * dx0, dx1 * dx1) + std::max(dy0 * dy0, dy1 * dy1);
223 return dmax2 <= r2;
224 }
225}; // vtkBucketList2D
226
227//------------------------------------------------------------------------------
228// This templated class manages the creation of the static locator
229// structures. It also implements the operator() functors which are supplied
230// to vtkSMPTools for threaded processesing.
231template <typename TIds>
233{
234 // Okay the various ivars
235 vtkLocatorTuple<TIds>* Map; // the map to be sorted
236 TIds* Offsets; // offsets for each bucket into the map
237
238 // Construction
239 BucketList2D(vtkStaticPointLocator2D* loc, vtkIdType numPts, int numBuckets)
240 : vtkBucketList2D(loc, numPts, numBuckets)
241 {
242 // one extra to simplify traversal
243 this->Map = new vtkLocatorTuple<TIds>[numPts + 1];
244 this->Map[numPts].Bucket = numBuckets;
245 this->Offsets = new TIds[numBuckets + 1];
246 this->Offsets[numBuckets] = numPts;
247 }
248
249 // Release allocated memory
250 ~BucketList2D() override
251 {
252 delete[] this->Map;
253 delete[] this->Offsets;
254 }
255
256 // The number of point ids in a bucket is determined by computing the
257 // difference between the offsets into the sorted points array.
259 {
260 if (bucketNum < 0 || bucketNum >= this->NumBuckets)
261 {
262 return 0;
263 }
264 return (this->Offsets[bucketNum + 1] - this->Offsets[bucketNum]);
265 }
266
267 // Given a bucket number, return the point ids in that bucket.
269 {
270 return this->Map + this->Offsets[bucketNum];
271 }
272
273 // Given a bucket number, return the point ids in that bucket.
274 void GetIds(vtkIdType bucketNum, vtkIdList* bList)
275 {
276 const vtkLocatorTuple<TIds>* ids = this->GetIds(bucketNum);
277 vtkIdType numIds = this->GetNumberOfIds(bucketNum);
278 bList->SetNumberOfIds(numIds);
279 for (int i = 0; i < numIds; i++)
280 {
281 bList->SetId(i, ids[i].PtId);
282 }
283 }
284
285 // Templated implementations of the locator
286 vtkIdType FindClosestPoint(const double x[3]);
288 double radius, const double x[3], double inputDataLength, double& dist2);
289 void FindClosestNPoints(int N, const double x[3], vtkIdList* result);
290 double FindNPointsInAnnulus(int N, const double x[3], vtkDist2TupleArray& results,
291 double minDist2 = (-0.1), bool sort = true, vtkDoubleArray* petals = nullptr);
292 void FindPointsWithinRadius(double R, const double x[3], vtkIdList* result);
293 int IntersectWithLine(double a0[3], double a1[3], double tol, double& t, double lineX[3],
294 double ptX[3], vtkIdType& ptId);
295 double FindCloseNBoundedPoints(int N, const double x[3], vtkIdList* result);
296
297 void MergePoints(double tol, vtkIdType* pointMap);
298 void GenerateRepresentation(int vtkNotUsed(level), vtkPolyData* pd);
299
300 // Internal methods
301 bool BucketIntersectsCircle(int i, int j, const double center[3], double R2);
303 NeighborBuckets2D* buckets, const double x[3], const int ij[2], double dist, int level);
304 void GetOverlappingBuckets(NeighborBuckets2D* buckets, const double x[3], double dist,
305 int prevMinLevel[2], int prevMaxLevel[2]);
306
307 // Implicit point representation, slower path
308 template <typename T>
310 {
313
315 : BList(blist)
316 , DataSet(ds)
317 {
318 }
319
321 {
322 double p[3];
323 vtkLocatorTuple<T>* t = this->BList->Map + ptId;
324 for (; ptId < end; ++ptId, ++t)
325 {
326 this->DataSet->GetPoint(ptId, p);
327 t->PtId = ptId;
328 t->Bucket = this->BList->GetBucketIndex(p);
329 } // for all points in this batch
330 }
331 };
332
333 template <typename T, typename TPointsArray>
335 {
337 TPointsArray* Points;
338
339 MapPointsArray(BucketList2D<T>* blist, TPointsArray* pts)
340 : BList(blist)
341 , Points(pts)
342 {
343 }
344
346 {
347 double p[3];
348 auto x = vtk::DataArrayTupleRange<3>(this->Points, ptId, end).begin();
349 vtkLocatorTuple<T>* t = this->BList->Map + ptId;
350 for (; ptId < end; ++ptId, ++x, ++t)
351 {
352 x->GetTuple(p);
353 t->PtId = ptId;
354 t->Bucket = this->BList->GetBucketIndex(p);
355 } // for all points in this batch
356 }
357 };
358
360 {
361 template <typename TPointsArray>
362 void operator()(TPointsArray* points, BucketList2D* blist)
363 {
364 MapPointsArray<TIds, TPointsArray> mapper(blist, points);
365 vtkSMPTools::For(0, blist->NumPts, mapper);
366 }
367 };
368
369 // A clever way to build offsets in parallel. Basically each thread builds
370 // offsets across a range of the sorted map. Recall that offsets are an
371 // integral value referring to the locations of the sorted points that
372 // reside in each bucket.
373 template <typename T>
375 {
379
381 : BList(blist)
382 {
383 this->NumPts = this->BList->NumPts;
384 this->NumBuckets = this->BList->NumBuckets;
385 }
386
387 // Traverse sorted points (i.e., tuples) and update bucket offsets.
388 void operator()(vtkIdType batch, vtkIdType batchEnd)
389 {
390 T* offsets = this->BList->Offsets;
391 const vtkLocatorTuple<T>* curPt = this->BList->Map + batch * this->BList->BatchSize;
392 const vtkLocatorTuple<T>* endBatchPt = this->BList->Map + batchEnd * this->BList->BatchSize;
393 const vtkLocatorTuple<T>* endPt = this->BList->Map + this->NumPts;
394 const vtkLocatorTuple<T>* prevPt;
395 endBatchPt = (endBatchPt > endPt ? endPt : endBatchPt);
396
397 // Special case at the very beginning of the mapped points array. If
398 // the first point is in bucket# N, then all buckets up and including
399 // N must refer to the first point.
400 if (curPt == this->BList->Map)
401 {
402 prevPt = this->BList->Map;
403 std::fill_n(offsets, curPt->Bucket + 1, 0); // point to the first points
404 } // at the very beginning of the map (sorted points array)
405
406 // We are entering this functor somewhere in the interior of the
407 // mapped points array. All we need to do is point to the entry
408 // position because we are interested only in prevPt->Bucket.
409 else
410 {
411 prevPt = curPt;
412 } // else in the middle of a batch
413
414 // Okay we have a starting point for a bucket run. Now we can begin
415 // filling in the offsets in this batch. A previous thread should
416 // have/will have completed the previous and subsequent runs outside
417 // of the [batch,batchEnd) range
418 for (curPt = prevPt; curPt < endBatchPt;)
419 {
420 for (; curPt->Bucket == prevPt->Bucket && curPt <= endBatchPt; ++curPt)
421 {
422 // advance
423 }
424 // Fill in any gaps in the offset array
425 std::fill_n(
426 offsets + prevPt->Bucket + 1, curPt->Bucket - prevPt->Bucket, curPt - this->BList->Map);
427 prevPt = curPt;
428 } // for all batches in this range
429 } // operator()
430 };
431
432 // Merge points that are pecisely coincident. Operates in parallel on
433 // locator buckets. Does not need to check neighbor buckets.
434 template <typename T>
436 {
440
442 : BList(blist)
443 , MergeMap(mergeMap)
444 {
445 this->DataSet = blist->DataSet;
446 }
447
448 void operator()(vtkIdType bucket, vtkIdType endBucket)
449 {
450 BucketList2D<T>* bList = this->BList;
451 vtkIdType* mergeMap = this->MergeMap;
452 int i, j;
453 const vtkLocatorTuple<TIds>* ids;
454 double p[3], p2[3];
455 vtkIdType ptId, ptId2, numIds;
456
457 for (; bucket < endBucket; ++bucket)
458 {
459 if ((numIds = bList->GetNumberOfIds(bucket)) > 0)
460 {
461 ids = bList->GetIds(bucket);
462 for (i = 0; i < numIds; i++)
463 {
464 ptId = ids[i].PtId;
465 if (mergeMap[ptId] < 0)
466 {
467 mergeMap[ptId] = ptId;
468 this->DataSet->GetPoint(ptId, p);
469 for (j = i + 1; j < numIds; j++)
470 {
471 ptId2 = ids[j].PtId;
472 if (mergeMap[ptId2] < 0)
473 {
474 this->DataSet->GetPoint(ptId2, p2);
475 if (p[0] == p2[0] && p[1] == p2[1])
476 {
477 mergeMap[ptId2] = ptId;
478 }
479 }
480 }
481 } // if point not yet visited
482 }
483 }
484 }
485 }
486 };
487
488 // Merge points that are coincident within a tolerance. Operates in
489 // parallel on points. Needs to check neighbor buckets which slows it down
490 // considerably. Note that merging is one direction: larger ids are merged
491 // to lower.
492 template <typename T>
494 {
498 double Tol;
499
501
502 MergeClose(BucketList2D<T>* blist, double tol, vtkIdType* mergeMap)
503 : BList(blist)
504 , MergeMap(mergeMap)
505 , Tol(tol)
506 {
507 this->DataSet = blist->DataSet;
508 }
509
510 // Just allocate a little bit of memory to get started.
512 {
513 vtkIdList*& pIds = this->PIds.Local();
514 pIds->Reserve(128); // allocate some memory
515 }
516
517 void operator()(vtkIdType ptId, vtkIdType endPtId)
518 {
519 BucketList2D<T>* bList = this->BList;
520 vtkIdType* mergeMap = this->MergeMap;
521 int i;
522 double p[3];
523 vtkIdType nearId, numIds;
524 vtkIdList*& nearby = this->PIds.Local();
525
526 for (; ptId < endPtId; ++ptId)
527 {
528 if (mergeMap[ptId] < 0)
529 {
530 mergeMap[ptId] = ptId;
531 this->DataSet->GetPoint(ptId, p);
532 bList->FindPointsWithinRadius(this->Tol, p, nearby);
533 if ((numIds = nearby->GetNumberOfIds()) > 0)
534 {
535 for (i = 0; i < numIds; i++)
536 {
537 nearId = nearby->GetId(i);
538 if (ptId < nearId && (mergeMap[nearId] < 0 || ptId < mergeMap[nearId]))
539 {
540 mergeMap[nearId] = ptId;
541 }
542 }
543 }
544 } // if point not yet processed
545 } // for all points in this batch
546 }
547
548 void Reduce() {}
549 };
550
551 // Build the map and other structures to support locator operations
552 void BuildLocator() override
553 {
554 // Place each point in a bucket
555 auto points = this->DataSet->GetPoints()->GetData();
558 points, worker, this))
559 {
560 worker(points, this);
561 }
562
563 // Provide accelerated access to points. Needed for Voronoi bin iterators.
565 {
566 this->FastPoints = static_cast<double*>(vtkDoubleArray::SafeDownCast(points)->GetPointer(0));
567 }
568
569 // Now gather the points into contiguous runs in buckets
570 //
571 vtkSMPTools::Sort(this->Map, this->Map + this->NumPts);
572
573 // Build the offsets into the Map. The offsets are the positions of
574 // each bucket into the sorted list. They mark the beginning of the
575 // list of points in each bucket. Amazingly, this can be done in
576 // parallel.
577 //
578 int numBatches = static_cast<int>(ceil(static_cast<double>(this->NumPts) / this->BatchSize));
579 MapOffsets<TIds> offMapper(this);
580 vtkSMPTools::For(0, numBatches, offMapper);
581 }
582}; // BucketList2D
583
584VTK_ABI_NAMESPACE_END
585#endif // vtkStaticPointLocator2DPrivate_h
586// VTK-HeaderTest-Exclude: vtkStaticPointLocator2DPrivate.h
RealT r2
Definition PyrC2Basis.h:20
ValueType * GetPointer(vtkIdType valueIdx)
Get the address of a particular data index.
object to represent cell connectivity
abstract class to specify dataset behavior
Definition vtkDataSet.h:166
virtual double * GetPoint(vtkIdType ptId)=0
Get point coordinates with ptId such that: 0 <= ptId < NumberOfPoints.
dynamic, self-adjusting array of double
static vtkDoubleArray * SafeDownCast(vtkObjectBase *o)
list of point or cell ids
Definition vtkIdList.h:135
void SetNumberOfIds(vtkIdType number)
Specify the number of ids for this object to hold.
vtkIdType GetNumberOfIds() const noexcept
Return the number of id's in the list.
Definition vtkIdList.h:185
vtkIdType GetId(vtkIdType i)
Return the id at location i.
Definition vtkIdList.h:190
void SetId(vtkIdType i, vtkIdType id)
Set the id at location i.
Definition vtkIdList.h:222
vtkTypeBool Reserve(vtkIdType size)
Reserve the id list to the requested number of ids and preserve data.
virtual vtkDataSet * GetDataSet()
Build the locator from the points/cells defining this dataset.
represent and manipulate 3D points
Definition vtkPoints.h:140
concrete dataset represents vertices, lines, polygons, and triangle strips
Thread local storage for VTK objects.
T *& Local()
Returns an object local to the current thread.
static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
A convenience method for sorting data.
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor &f)
Execute a for operation in parallel.
quickly locate points in 2-space
void GetBounds(double *bounds) override
Provide an accessor to the bounds.
virtual double * GetSpacing()
Provide an accessor to the bucket spacing.
virtual int * GetDivisions()
Set the number of divisions in x-y directions.
A SafeCastFromDouble(double value)
Cast from double, and clamp to output type limits to avoid overlow.
VTK_ITER_INLINE auto DataArrayTupleRange(const ArrayTypePtr &array, TupleIdType start=-1, TupleIdType end=-1) -> typename detail::SelectTupleRange< ArrayTypePtr, TupleSize >::type
Generate an stl and for-range compatible range of tuple iterators from a vtkDataArray.
MapDataSet(BucketList2D< T > *blist, vtkDataSet *ds)
void operator()(vtkIdType ptId, vtkIdType end)
void operator()(vtkIdType batch, vtkIdType batchEnd)
void operator()(TPointsArray *points, BucketList2D *blist)
void operator()(vtkIdType ptId, vtkIdType end)
MapPointsArray(BucketList2D< T > *blist, TPointsArray *pts)
MergeClose(BucketList2D< T > *blist, double tol, vtkIdType *mergeMap)
vtkSMPThreadLocalObject< vtkIdList > PIds
void operator()(vtkIdType ptId, vtkIdType endPtId)
void operator()(vtkIdType bucket, vtkIdType endBucket)
MergePrecise(BucketList2D< T > *blist, vtkIdType *mergeMap)
void FindClosestNPoints(int N, const double x[3], vtkIdList *result)
double FindCloseNBoundedPoints(int N, const double x[3], vtkIdList *result)
const vtkLocatorTuple< TIds > * GetIds(vtkIdType bucketNum)
BucketList2D(vtkStaticPointLocator2D *loc, vtkIdType numPts, int numBuckets)
void MergePoints(double tol, vtkIdType *pointMap)
void GetOverlappingBuckets(NeighborBuckets2D *buckets, const double x[3], const int ij[2], double dist, int level)
void GetOverlappingBuckets(NeighborBuckets2D *buckets, const double x[3], double dist, int prevMinLevel[2], int prevMaxLevel[2])
vtkLocatorTuple< TIds > * Map
void FindPointsWithinRadius(double R, const double x[3], vtkIdList *result)
int IntersectWithLine(double a0[3], double a1[3], double tol, double &t, double lineX[3], double ptX[3], vtkIdType &ptId)
vtkIdType GetNumberOfIds(vtkIdType bucketNum)
bool BucketIntersectsCircle(int i, int j, const double center[3], double R2)
void GetIds(vtkIdType bucketNum, vtkIdList *bList)
vtkIdType FindClosestPointWithinRadius(double radius, const double x[3], double inputDataLength, double &dist2)
vtkIdType FindClosestPoint(const double x[3])
double FindNPointsInAnnulus(int N, const double x[3], vtkDist2TupleArray &results, double minDist2=(-0.1), bool sort=true, vtkDoubleArray *petals=nullptr)
void GenerateRepresentation(int level, vtkPolyData *pd)
Dispatch a single array against all array types mentioned in the ArrayList template parameter.
double Distance2ToBucket(const double x[3], const int nei[3])
void GetBucketBounds(int i, int j, double min[3], double max[3])
double Distance2ToBounds(const double x[3], const double bounds[6])
void GetBucketIndices(const double *x, int ij[2]) const
void GenerateFace(int face, int i, int j, int k, vtkPoints *pts, vtkCellArray *polys)
vtkIdType GetBucketIndex(const double *x) const
bool BucketInsideCircle(int i, int j, const double center[3], double r2)
virtual ~vtkBucketList2D()=default
vtkStaticPointLocator2D * Locator
virtual void BuildLocator()=0
void GetBucketCenter(int i, int j, double center[3])
void GetBucketNeighbors(NeighborBuckets2D *buckets, const int ij[2], const int ndivs[2], int level)
vtkBucketList2D(vtkStaticPointLocator2D *loc, vtkIdType numPts, int numBuckets)
Represent an array of vtkDist2Tuples.
STL-compatible iterable ranges that provide access to vtkDataArray elements.
bool InsideCircle(const double min[2], const double max[2], const double center[2], double r2)
Performant method to determine if a box if fully inside a circle.
bool IntersectsCircle(const double min[2], const double max[2], const double center[2], double r2)
Performant method to intersect a box with a circle.
int vtkIdType
Definition vtkType.h:363
#define max(a, b)