VTK  9.6.20260216
vtkVoronoiTile.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
45
46#ifndef vtkVoronoiTile_h
47#define vtkVoronoiTile_h
48
49#include "vtkDoubleArray.h" // Support double points
50#include "vtkFiltersMeshingModule.h" // For export macro
51#include "vtkMath.h" // Euclidean norm
52#include "vtkVoronoiCore.h" // Enum: clip intersection status
53
54#include <vector> // array support
55
56VTK_ABI_NAMESPACE_BEGIN
57
58class vtkPolyData;
59class vtkSpheres;
60
61//======= Define the convex polygon class used to produce Voronoi tiles.
62
63// The data structure for representing a Voronoi tile vertex and implicitly,
64// the connected Voronoi tile edge. The tile vertex has a position X, and the
65// current value of the half-space clipping function. In the counterclockwise
66// direction, the NeiId refers to the point id in the neighboring tile that,
67// together with this tile's point id, produced a tile edge between the two
68// points (i.e., a spoke).
70{
71 double X[2]; // position of this vertex
72 vtkIdType NeiId; // generating point id for the associated edge
73 double Val; // current value of the current half-space clipping function
74 double R2; // Radius**2 of circumcircle / flower petal
75
76 vtkTilePoint(double tileX[2], double x[2], vtkIdType neiId)
77 : X{ x[0], x[1] }
78 , NeiId(neiId)
79 , Val(0.0)
80 {
81 this->R2 = vtkMath::Distance2BetweenPoints2D(X, tileX);
82 }
83
84 vtkTilePoint(const vtkTilePoint& v) = default;
85};
86
87// Typedefs defined for convenience.
88using PointRingType = std::vector<vtkTilePoint>;
89using PointRingIterator = std::vector<vtkTilePoint>::iterator;
90
95class VTKFILTERSMESHING_EXPORT vtkVoronoiTile
96{
97public:
103 : PtId(-1)
104 , X{ 0, 0, 0 } // z-component specifies location in z-plane
105 , NumClips(0)
106 , PruneTolerance(1.0e-13)
108 , RecomputePetals(true)
109 , CircumFlower2(0.0)
110 , MinRadius2(0.0)
111 , MaxRadius2(0.0)
112 {
113 // Preallocate some space
114 this->Points.reserve(256);
115 this->NewPoints.reserve(256);
116
117 // Supporting data structures
118 this->SortP.reserve(256);
120 this->Petals->SetNumberOfComponents(3); // x-y-R2
121 this->Petals->Allocate(256); // initial allocation
122 }
123
129 void Initialize(vtkIdType genPtId, const double genPt[3], double bds[4]);
130
137 vtkIdType ptId, const double x[3], vtkPoints* pts, vtkIdType nPts, const vtkIdType* p);
138
145 ClipIntersectionStatus Clip(vtkIdType neiPtId, const double neiPt[2]);
146
155 {
156 if (this->RecomputeCircumFlower)
157 {
158 this->ComputeCircumFlower();
159 }
160 return this->CircumFlower2;
161 }
162 bool InCircumFlower(double r2) // radius**2 of point from generator
163 {
164 // Only recompute the circumflower if necessary; that is, when
165 // a maximal point is eliminated by a plane clip.
166 if (this->RecomputeCircumFlower)
167 {
168 this->ComputeCircumFlower();
169 }
171 }
172 bool InFlower(const double x[2]);
173 void UpdatePetals(double cf2);
175 {
176 if (this->RecomputePetals)
177 {
178 this->UpdatePetals(this->CircumFlower2);
179 }
180 return (this->Petals->GetNumberOfTuples() > 0 ? this->Petals : nullptr);
181 }
182
189 void ProducePolyData(vtkPolyData* pd) { this->ProducePolyData(pd, nullptr); }
190
196 double* GetGeneratorPosition() { return this->X; }
197 vtkIdType GetNumberOfPoints() { return this->Points.size(); }
198 const PointRingType& GetPoints() { return this->Points; }
199
200 // Data members purposely left public for using classes to extract
201 // information.
202
203 // Information used to define the polyhedron- its generating point id and
204 // position, plus region classification. Indicate whether degenerate faces
205 // (i.e., those having ~zero area) can be deleted (i.e., pruned).
206 vtkIdType PtId; // Generating point id
207 double X[3]; // Generating point position. Note X[2] is z-plane position
208 vtkIdType NumClips; // The total number of clip operations since Initialize()
209 double PruneTolerance; // Specify the prune tolerance
210
211 // These data members represent the constructed polygon.
212 PointRingType Points; // counterclockwise ordered loop of points/vertices defining the tile
213 PointRingType NewPoints; // accumulate new points/vertices to construct the tile
214
215protected:
216 // Convenience method for moving around the modulo ring of the tile
217 // vertices.
219 {
220 if (itr == (this->Points.end() - 1))
221 {
222 return this->Points.begin();
223 }
224 return (itr + 1);
225 }
226
227 // The core geometric intersection operation.
228 ClipIntersectionStatus IntersectWithLine(double origin[2], double normal[2], vtkIdType neiPtId);
229
230 // These tolerances are for managing degeneracies.
231 double Tol;
232 double Tol2;
233
234 // Indicate whether the Voronoi circumflower needs recomputing, and
235 // keep track of the current circumflower and related information.
236 void ComputeCircumFlower();
242 std::vector<vtkTilePoint*> SortP; // Points sorted on radius**2
243 vtkSmartPointer<vtkDoubleArray> Petals; // Flower petals w/ radii > annular radius
244
245}; // vtkVoronoiTile
246
247//------------------------------------------------------------------------------
249{
250 // Compute the circumflower, and compute some info about
251 // the flower radii.
254
255 // Determine the circumflower and minimal sphere radius by
256 // checking against each of the flower petals.
257 for (const auto& p : this->Points)
258 {
259 double r2 = p.R2;
260 this->MinRadius2 = std::min(r2, this->MinRadius2);
261 this->MaxRadius2 = std::max(r2, this->MaxRadius2);
262 }
263 this->CircumFlower2 = (4.0 * this->MaxRadius2); // (2*(max petal radius))**2
264 this->RecomputeCircumFlower = false; // circumflower is up to date
265}
266
267//------------------------------------------------------------------------------
268inline bool vtkVoronoiTile::InFlower(const double x[2])
269{
270 // Check against the flower petals
271 for (const auto& p : this->Points)
272 {
273 double r2 = vtkMath::Distance2BetweenPoints2D(p.X, x);
274 if (r2 <= p.R2)
275 {
276 return true;
277 }
278 }
279
280 // Point not in the flower
281 return false;
282}
283
284VTK_ABI_NAMESPACE_END
285#endif
286// VTK-HeaderTest-Exclude: vtkVoronoiTile.h
RealT r2
Definition PyrC2Basis.h:20
dynamic, self-adjusting array of double
static double Distance2BetweenPoints2D(const double p1[2], const double p2[2])
Compute distance squared between two 2D points p1 and p2.
Definition vtkMath.h:2072
represent and manipulate 3D points
Definition vtkPoints.h:140
concrete dataset represents vertices, lines, polygons, and triangle strips
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
implicit function for a set of spheres
Definition vtkSpheres.h:32
void ProducePolyData(vtkPolyData *pd)
double GetCircumFlower2()
Methods to determine whether a point x[2] is within the Voronoi flower, or Voronoi circumflower.
vtkVoronoiTile()
Constructor.
void Initialize(vtkIdType ptId, const double x[3], vtkPoints *pts, vtkIdType nPts, const vtkIdType *p)
Initialize with a convex polygon.
vtkSmartPointer< vtkDoubleArray > Petals
PointRingIterator Next(PointRingIterator &itr)
void Initialize(vtkIdType genPtId, const double genPt[3], double bds[4])
Method to initiate the construction of the polygon.
vtkDoubleArray * GetPetals()
void ComputeCircumFlower()
double * GetGeneratorPosition()
vtkIdType GetNumberOfPoints()
void UpdatePetals(double cf2)
const PointRingType & GetPoints()
void ProducePolyData(vtkPolyData *pd, vtkSpheres *spheres)
Produce a vtkPolyData (and optional implicit function) from the current polygon.
ClipIntersectionStatus IntersectWithLine(double origin[2], double normal[2], vtkIdType neiPtId)
PointRingType Points
bool InFlower(const double x[2])
bool InCircumFlower(double r2)
ClipIntersectionStatus Clip(vtkIdType neiPtId, const double neiPt[2])
Method to clip the current convex tile with a plane defined by a neighboring point.
vtkIdType GetGeneratorPointId()
Obtain information about the generated tile.
PointRingType NewPoints
std::vector< vtkTilePoint * > SortP
vtkTilePoint(double tileX[2], double x[2], vtkIdType neiId)
vtkTilePoint(const vtkTilePoint &v)=default
vtkIdType NeiId
int vtkIdType
Definition vtkType.h:363
#define VTK_FLOAT_MIN
Definition vtkType.h:199
#define VTK_FLOAT_MAX
Definition vtkType.h:200
ClipIntersectionStatus
Classes, structs, and typedefs in support of Voronoi processing.
std::vector< vtkTilePoint > PointRingType
std::vector< vtkTilePoint >::iterator PointRingIterator