64 fInit = Initialization::UNINITIALIZED;
69 if (
n == 0 || !
x || !
y || !z )
return;
72 xmin = *std::min_element(
x,
x+
n);
73 xmax = *std::max_element(
x,
x+
n);
75 ymin = *std::min_element(
y,
y+
n);
76 ymax = *std::max_element(
y,
y+
n);
144 if(
fInit.load(std::memory_order::memory_order_relaxed) == Initialization::INITIALIZED)
147 Initialization cState = Initialization::UNINITIALIZED;
148 if(
fInit.compare_exchange_strong(cState, Initialization::INITIALIZING,
149 std::memory_order::memory_order_release, std::memory_order::memory_order_relaxed))
171 fInit = Initialization::INITIALIZED;
172 }
else while(cState != Initialization::INITIALIZED) {
174 cState =
fInit.load(std::memory_order::memory_order_relaxed);
185void Delaunay2D::DonormalizePoints() {
191 fNormalizedPoints.insert(std::make_pair(
p,
n));
197 fCGALdelaunay.insert(fNormalizedPoints.begin(), fNormalizedPoints.end());
199 std::transform(fCGALdelaunay.finite_faces_begin(),
200 fCGALdelaunay.finite_faces_end(), std::back_inserter(
fTriangles),
201 [] (
const Delaunay::Face face) -> Triangle {
205 auto transform = [&] (const unsigned int i) {
206 tri.x[i] = face.vertex(i)->point().x();
207 tri.y[i] = face.vertex(i)->point().y();
208 tri.idx[i] = face.vertex(i)->info();
221double Delaunay2D::DoInterpolateNormalized(
double xx,
double yy)
233 std::vector<std::pair<Point, Coord_type> > coords;
234 auto nn = CGAL::natural_neighbor_coordinates_2(fCGALdelaunay,
p,
235 std::back_inserter(coords));
244 Coord_type res = CGAL::linear_interpolation(coords.begin(), coords.end(),
245 nn.second, Value_access(fNormalizedPoints, fZ));
255void Delaunay2D::DoNormalizePoints() {
256 for (
Int_t n = 0;
n < fNpoints;
n++) {
257 fXN.push_back(Linear_transform(fX[
n], fOffsetX, fScaleFactorX));
258 fYN.push_back(Linear_transform(fY[
n], fOffsetY, fScaleFactorY));
262 fXCellStep = fNCells / (fXNmax - fXNmin);
263 fYCellStep = fNCells / (fYNmax - fYNmin);
267void Delaunay2D::DoFindTriangles() {
270 s.pointlist =
nullptr;
271 s.pointattributelist =
nullptr;
272 s.pointmarkerlist =
nullptr;
273 s.numberofpoints = 0;
274 s.numberofpointattributes = 0;
276 s.trianglelist =
nullptr;
277 s.triangleattributelist =
nullptr;
278 s.trianglearealist =
nullptr;
279 s.neighborlist =
nullptr;
280 s.numberoftriangles = 0;
281 s.numberofcorners = 0;
282 s.numberoftriangleattributes = 0;
284 s.segmentlist =
nullptr;
285 s.segmentmarkerlist =
nullptr;
286 s.numberofsegments = 0;
288 s.holelist =
nullptr;
291 s.regionlist =
nullptr;
292 s.numberofregions = 0;
294 s.edgelist =
nullptr;
295 s.edgemarkerlist =
nullptr;
296 s.normlist =
nullptr;
301 if(s.pointlist !=
nullptr)
free(s.pointlist);
302 if(s.pointattributelist !=
nullptr)
free(s.pointattributelist);
303 if(s.pointmarkerlist !=
nullptr)
free(s.pointmarkerlist);
305 if(s.trianglelist !=
nullptr)
free(s.trianglelist);
306 if(s.triangleattributelist !=
nullptr)
free(s.triangleattributelist);
307 if(s.trianglearealist !=
nullptr)
free(s.trianglearealist);
308 if(s.neighborlist !=
nullptr)
free(s.neighborlist);
310 if(s.segmentlist !=
nullptr)
free(s.segmentlist);
311 if(s.segmentmarkerlist !=
nullptr)
free(s.segmentmarkerlist);
313 if(s.holelist !=
nullptr)
free(s.holelist);
315 if(s.regionlist !=
nullptr)
free(s.regionlist);
317 if(s.edgelist !=
nullptr)
free(s.edgelist);
318 if(s.edgemarkerlist !=
nullptr)
free(s.edgemarkerlist);
319 if(s.normlist !=
nullptr)
free(s.normlist);
323 initStruct(in); initStruct(out);
330 for (
Int_t i = 0; i < fNpoints; ++i) {
341 auto transform = [&] (
const unsigned int v) {
362 tri.
invDenom = 1 / ( (tri.
y[1] - tri.
y[2])*(tri.
x[0] - tri.
x[2]) + (tri.
x[2] - tri.
x[1])*(tri.
y[0] - tri.
y[2]) );
366 auto bx = std::minmax({tri.
x[0], tri.
x[1], tri.
x[2]});
367 auto by = std::minmax({tri.
y[0], tri.
y[1], tri.
y[2]});
369 unsigned int cellXmin = CellX(bx.first);
370 unsigned int cellXmax = CellX(bx.second);
372 unsigned int cellYmin = CellY(by.first);
373 unsigned int cellYmax = CellY(by.second);
375 for(
unsigned int i = cellXmin; i <= cellXmax; ++i) {
376 for(
unsigned int j = cellYmin; j <= cellYmax; ++j) {
378 fCells[Cell(i,j)].insert(t);
383 freeStruct(in); freeStruct(out);
390double Delaunay2D::DoInterpolateNormalized(
double xx,
double yy)
397 auto bayCoords = [&] (
const unsigned int t) -> std::tuple<double, double, double> {
398 double la = ( (fTriangles[t].y[1] - fTriangles[t].y[2])*(xx - fTriangles[t].
x[2])
399 + (fTriangles[t].x[2] - fTriangles[t].x[1])*(yy - fTriangles[t].
y[2]) ) * fTriangles[t].invDenom;
400 double lb = ( (fTriangles[t].y[2] - fTriangles[t].y[0])*(xx - fTriangles[t].
x[2])
401 + (fTriangles[t].x[0] - fTriangles[t].x[2])*(yy - fTriangles[t].
y[2]) ) * fTriangles[t].invDenom;
403 return std::make_tuple(la, lb, (1 - la - lb));
406 auto inTriangle = [] (
const std::tuple<double, double, double> & coords) ->
bool {
407 return std::get<0>(coords) >= 0 && std::get<1>(coords) >= 0 && std::get<2>(coords) >= 0;
413 if(cX < 0 || cX > fNCells || cY < 0 || cY > fNCells)
416 for(
unsigned int t : fCells[Cell(cX, cY)]){
417 auto coords = bayCoords(t);
419 if(inTriangle(coords)){
421 return std::get<0>(coords) * fZ[fTriangles[t].idx[0]]
422 + std::get<1>(coords) * fZ[fTriangles[t].idx[1]]
423 + std::get<2>(coords) * fZ[fTriangles[t].idx[2]];
winID h TVirtualViewer3D TVirtualGLPainter p
double fXNmin
! Minimum value of fXN
double DoInterpolateNormalized(double x, double y)
internal method to compute the interpolation
double Interpolate(double x, double y)
Return the Interpolated z value corresponding to the given (x,y) point Note that in case no Delaunay ...
const double * fZ
! Pointer to Z array
double fXNmax
! Maximum value of fXN
double fZout
! Height for points lying outside the convex hull
double fOffsetY
! Normalization offset Y
Int_t fNdt
! Number of Delaunay triangles found
Triangles fTriangles
! Triangles of Triangulation
double Linear_transform(double x, double offset, double factor)
double fYCellStep
! inverse denominator to calculate X cell = fNCells / (fYNmax - fYNmin)
Delaunay2D(int n, const double *x, const double *y, const double *z, double xmin=0, double xmax=0, double ymin=0, double ymax=0)
class constructor from array of data points
void FindAllTriangles()
Find all triangles.
double fXCellStep
! inverse denominator to calculate X cell = fNCells / (fXNmax - fXNmin)
double fYNmin
! Minimum value of fYN
double fOffsetX
! Normalization offset X
Int_t fNpoints
! Number of data points
Bool_t fInit
! True if FindAllTriangles() has been performed
const double * fY
! Pointer to Y array
void SetInputPoints(int n, const double *x, const double *y, const double *z, double xmin=0, double xmax=0, double ymin=0, double ymax=0)
set the input points for building the graph
const double * fX
! Pointer to X array (managed externally)
void DoNormalizePoints()
internal function to normalize the points
double fYNmax
! Maximum value of fYN
double fScaleFactorY
! Normalization factor Y
double fScaleFactorX
! Normalization factor X
void DoFindTriangles()
internal function to find the triangle use Triangle or CGAL if flag is set
Namespace for new Math classes and functions.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
void triangulate(char *triswitches, struct triangulateio *in, struct triangulateio *out, struct triangulateio *vorout)