8 #define NUMBER_OF_SHAPES 24 9 #define MAX_ROTATION_LENGTH 5 63 size_t Hilbert3D_xyz2d(
Vector3D const & rvPoint,
int numOfIterations);
67 void RotateShape(
int iShapeIndex, vector<int> vAxes);
76 int GetRotation(
int * piRotation,
int iRotationIndex);
80 void BuildRecursionRule();
82 void BuildShapeOrder();
85 vector<HilbertCurve3D_shape> m_vRotatedShapes;
87 vector < vector<int> > m_vRotations;
90 vector< vector<int> > m_vShapeRecursion;
94 int m_mShapeOrder[NUMBER_OF_SHAPES][2][2][2];
103 m_vRotatedShapes.resize(NUMBER_OF_SHAPES);
104 m_vRotations.resize(NUMBER_OF_SHAPES);
105 m_vShapeRecursion.resize(NUMBER_OF_SHAPES);
106 for(
size_t i=0;i<NUMBER_OF_SHAPES;++i)
107 m_vShapeRecursion[i].resize(8);
108 int rot[MAX_ROTATION_LENGTH];
109 for (
int iRotIndex = 1; iRotIndex < NUMBER_OF_SHAPES; ++iRotIndex)
111 const int iRotLength = GetRotation(rot, iRotIndex);
112 m_vRotations[
static_cast<size_t>(iRotIndex)].assign(rot, rot + iRotLength);
115 for (
int ii = 1; ii < NUMBER_OF_SHAPES; ++ii)
117 RotateShape(ii, m_vRotations[static_cast<size_t>(ii)]);
120 BuildRecursionRule();
127 for (
int ii = 0; ii < NUMBER_OF_SHAPES; ++ii)
129 if (roShape == m_vRotatedShapes[static_cast<size_t>(ii)])
138 void HilbertCurve3D::BuildRecursionRule()
141 m_vShapeRecursion[0][0] = 12;
142 m_vShapeRecursion[0][1] = 16;
143 m_vShapeRecursion[0][2] = 16;
144 m_vShapeRecursion[0][3] = 2;
145 m_vShapeRecursion[0][4] = 2;
146 m_vShapeRecursion[0][5] = 14;
147 m_vShapeRecursion[0][6] = 14;
148 m_vShapeRecursion[0][7] = 10;
152 for (
int ii = 0; ii < NUMBER_OF_SHAPES; ++ii)
154 for (
int jj = 0; jj < 8; ++jj)
157 RotateShape(m_vRotatedShapes[static_cast<size_t>(m_vShapeRecursion[0][static_cast<size_t>(jj)])], oTempShape, ii);
159 m_vShapeRecursion[
static_cast<size_t>(ii)][static_cast<size_t>(jj)] = FindShapeIndex(oTempShape);
167 int HilbertCurve3D::GetRotation(
int * piRotation,
int iRotationIndex)
169 switch (iRotationIndex)
292 void HilbertCurve3D::RotateShape(
int iShapeIndex, vector<int> vAxes)
296 for (
size_t ii = 0; ii < 7; ++ii)
298 for (
size_t iAx = 0; iAx < vAxes.size(); ++iAx)
301 iSign = (vAxes[iAx] > 0) - (vAxes[iAx] < 0);
303 switch (
abs(vAxes[iAx]))
306 m_vRotatedShapes[
static_cast<size_t>(iShapeIndex)].m_vShapePoints[ii].
RotateX( iSign * PI / 2 );
309 m_vRotatedShapes[
static_cast<size_t>(iShapeIndex)].m_vShapePoints[ii].
RotateY( iSign * PI / 2 );
312 m_vRotatedShapes[
static_cast<size_t>(iShapeIndex)].m_vShapePoints[ii].
RotateZ( iSign * PI / 2 );
319 m_vRotatedShapes[
static_cast<size_t>(iShapeIndex)].m_vShapePoints[ii].Round();
327 vector<int> vAxes = m_vRotations[
static_cast<size_t>(iRotationIndex)];
328 roShapeOut = roShape;
330 for (
int ii = 0; ii < 7; ++ii)
332 for (
size_t iAx = 0; iAx < vAxes.size(); ++iAx)
335 iSign = (vAxes[iAx] > 0) - (vAxes[iAx] < 0);
337 switch (
abs(vAxes[iAx]))
343 roShapeOut.m_vShapePoints[
static_cast<size_t>(ii)].
RotateY(iSign * PI / 2);
346 roShapeOut.m_vShapePoints[
static_cast<size_t>(ii)].
RotateZ(iSign * PI / 2);
353 roShapeOut.m_vShapePoints[
static_cast<size_t>(ii)].Round();
359 void HilbertCurve3D::BuildShapeOrder()
361 vector<int> vShapeVerticesX(8);
362 vector<int> vShapeVerticesY(8);
363 vector<int> vShapeVerticesZ(8);
365 vShapeVerticesX[0] = 0;
366 vShapeVerticesY[0] = 0;
367 vShapeVerticesZ[0] = 0;
369 for (
size_t iShapeInd = 0; iShapeInd < NUMBER_OF_SHAPES; ++iShapeInd)
371 for (
size_t ii = 0; ii < m_vRotatedShapes[iShapeInd].m_vShapePoints.size(); ++ii)
373 vShapeVerticesX[ii + 1] =
static_cast<int>(vShapeVerticesX[ii] + m_vRotatedShapes[iShapeInd].m_vShapePoints[ii].x);
374 vShapeVerticesY[ii + 1] =
static_cast<int>(vShapeVerticesY[ii] + m_vRotatedShapes[iShapeInd].m_vShapePoints[ii].y);
375 vShapeVerticesZ[ii + 1] =
static_cast<int>(vShapeVerticesZ[ii] + m_vRotatedShapes[iShapeInd].m_vShapePoints[ii].z);
378 int iMinX = *min_element(vShapeVerticesX.begin(), vShapeVerticesX.end());
379 int iMinY = *min_element(vShapeVerticesY.begin(), vShapeVerticesY.end());
380 int iMinZ = *min_element(vShapeVerticesZ.begin(), vShapeVerticesZ.end());
382 for (
size_t jj = 0; jj < vShapeVerticesX.size(); ++jj)
384 vShapeVerticesX[jj] -= iMinX;
385 vShapeVerticesY[jj] -= iMinY;
386 vShapeVerticesZ[jj] -= iMinZ;
389 for (
size_t kk = 0; kk < vShapeVerticesX.size(); ++kk)
391 m_mShapeOrder[iShapeInd][vShapeVerticesX[kk]][vShapeVerticesY[kk]][vShapeVerticesZ[kk]] =
static_cast<int>(kk);
401 double x = rvPoint.
x;
402 double y = rvPoint.
y;
403 double z = rvPoint.
z;
409 int iCurrentShape = 0;
410 for (
int iN = 1; iN <= numOfIterations; ++iN)
413 const double dbPow2 = (
static_cast<double>(1)) / (1 << iN);
414 const bool bX = x > dbPow2;
415 const bool bY = y > dbPow2;
416 const bool bZ = z > dbPow2;
424 const int iOctantNum = m_mShapeOrder[iCurrentShape][bX][bY][bZ];
425 d = d +
static_cast<size_t>(iOctantNum);
426 iCurrentShape = m_vShapeRecursion[
static_cast<size_t>(iCurrentShape)][static_cast<size_t>(iOctantNum)];
436 if ( 2 >= cor.size() )
438 vector<size_t> vIndSort( cor.size() );
439 for (
size_t ii = 0; ii < cor.size(); ++ii)
449 int N =
static_cast<int>(cor.size());
451 vOut.reserve(cor.size());
456 vector<Vector3D> vAdjustedPoints;
462 for (
int ii = 0; ii < N; ++ii)
464 vOut.push_back(oHilbert.
Hilbert3D_xyz2d(vAdjustedPoints[static_cast<size_t>(ii)], numOfIterations+6));
468 vector<size_t> vIndSort;
474 vector<vector<size_t> > vEqualIndices;
478 if (vEqualIndices.empty())
484 for (
size_t ii = 0; ii < vEqualIndices.size(); ++ii)
486 vector<Vector3D> vPointsInner(vEqualIndices[ii].size() );
487 vector<size_t> vIndInner(vEqualIndices[ii].size());
488 vector<size_t> vIndSortInner(vEqualIndices[ii].size());
489 vector<size_t> vIndSortInner_cpy(vEqualIndices[ii].size());
492 for (
size_t jj = 0; jj < vEqualIndices[ii].size() ; ++jj)
494 vIndInner[jj] = vIndSort[vEqualIndices[ii][jj]];
495 vPointsInner[jj] = cor[vIndInner[jj]];
496 vIndSortInner_cpy[jj] = vIndSort[vIndInner[jj]];
502 for (
size_t kk = 0; kk < vIndSortInner.size(); ++kk)
504 vIndSort[vIndInner[kk]] = vIndSortInner_cpy[vIndSortInner[kk]];
Vector3D RotateZ(Vector3D const &v, double a)
Rotates a 3D-vector around the Z axis.
void sort_index(const vector< T > &arr, vector< int > &res)
Returns the indeces of a sort.
double z
Component in the z direction.
void FindEqualIndices(vector< size_t > const &vD_sorted, vector< vector< size_t > > &vOut)
Scale a vector of 3D points to the unit-cube.
Vector3D RotateX(Vector3D const &v, double a)
Rotates a 3D-vector around the X axis.
void AdjustPoints(vector< Vector3D > const &vPointsIn, vector< Vector3D > &vPointsOut)
Scale a vector of 3D points to the unit-cube.
Hilbert 3D-space filling curve.
Hilbert 3D Order - Utility functions.
Vector3D RotateY(Vector3D const &v, double a)
Rotates a 3D-vector around the Y axis.
size_t Hilbert3D_xyz2d(Vector3D const &rvPoint, int numOfIterations)
Calculate the Hilbert curve distance of a given point, given a required number of iterations...
vector< size_t > HilbertOrder3D(vector< Vector3D > const &cor)
Returns the 3D-Hilbert curve ordering.
vector< Vector3D > m_vShapePoints
An array of the 7 unit vector steps defining the shape.
HilbertCurve3D(void)
Constructor.
double y
Component in the y direction.
void reorder(vector< T > &v, vector< size_t > const &order)
Reorder a vector according to an index vector (obtained from the 'ordered' function) ...
The elementary Hilbert Curve shape.
double abs(Vector3D const &v)
Norm of a vector.
int EstimateHilbertIterationNum(vector< Vector3D > const &cor)
Estimate the number of iterations required in the Hilbert Curve, according to the number of points...
bool operator==(HilbertCurve3D_shape &shape)
Comparison.
double x
Component in the x direction.
HilbertCurve3D_shape()
Class constructor.