OmniSciDB  6686921089
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
faceijk.h File Reference

FaceIJK functions including conversion to/from lat/lon. More...

+ Include dependency graph for faceijk.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define FACE_INDEX   3
 
#define FaceIJK(variable_name)   int variable_name[4]
 
#define FaceIJK_clone(fijk)   { fijk[I_INDEX], fijk[J_INDEX], fijk[K_INDEX], fijk[FACE_INDEX] }
 
#define FaceIJK_copy(dest_ijk, src_ijk)
 
#define CCWROT_60_INDEX   4
 
#define FaceOrientIJK(variable_name)   int variable_name[5]
 
#define FaceOrientIJK2DArray(variable_name, size1, size2)   int variable_name[size1][size2][5]
 
#define IJ   1
 
#define KI   2
 
#define JK   3
 

Enumerations

enum  Overage { NO_OVERAGE = 0, FACE_EDGE = 1, NEW_FACE = 2 }
 

Functions

EXTENSION_INLINE int isResClassIII (int res)
 
EXTENSION_NOINLINE bool _geoToFaceIjk (const GeoCoord(g), int res, FaceIJK(h))
 
EXTENSION_NOINLINE bool _geoToHex2d (const GeoCoord(g), int res, int *face, Vec2d(v))
 
EXTENSION_NOINLINE bool _faceIjkToGeo (const FaceIJK(h), int res, GeoCoord(g))
 
EXTENSION_NOINLINE bool _hex2dToGeo (const Vec2d(v), int face, int res, int substrate, GeoCoord(g))
 
EXTENSION_NOINLINE int _adjustOverageClassII (FaceIJK(fijk), int res, int pentLeading4, int substrate)
 

Detailed Description

FaceIJK functions including conversion to/from lat/lon.

References the Vec2d cartesian coordinate systems hex2d: local face-centered coordinate system scaled a specific H3 grid resolution unit length and with x-axes aligned with the local i-axes

Definition in file faceijk.h.

Macro Definition Documentation

#define CCWROT_60_INDEX   4

Definition at line 53 of file faceijk.h.

Referenced by _adjustOverageClassII().

#define FACE_INDEX   3
#define FaceIJK (   variable_name)    int variable_name[4]

Definition at line 36 of file faceijk.h.

Referenced by _faceIjkToH3(), _h3ToGeo(), and geoToH3().

#define FaceIJK_clone (   fijk)    { fijk[I_INDEX], fijk[J_INDEX], fijk[K_INDEX], fijk[FACE_INDEX] }

Definition at line 37 of file faceijk.h.

Referenced by _faceIjkToH3().

#define FaceIJK_copy (   dest_ijk,
  src_ijk 
)
Value:
dest_ijk[I_INDEX] = src_ijk[I_INDEX]; \
dest_ijk[J_INDEX] = src_ijk[J_INDEX]; \
dest_ijk[K_INDEX] = src_ijk[K_INDEX]; \
dest_ijk[FACE_INDEX] = src_ijk[FACE_INDEX];
#define J_INDEX
Definition: coordijk.h:43
#define I_INDEX
Definition: coordijk.h:42
#define FACE_INDEX
Definition: faceijk.h:35
#define K_INDEX
Definition: coordijk.h:44

Definition at line 39 of file faceijk.h.

Referenced by _h3ToFaceIjk().

#define FaceOrientIJK (   variable_name)    int variable_name[5]

Definition at line 54 of file faceijk.h.

#define FaceOrientIJK2DArray (   variable_name,
  size1,
  size2 
)    int variable_name[size1][size2][5]

Definition at line 55 of file faceijk.h.

#define IJ   1

IJ quadrant faceNeighbors table direction

Definition at line 68 of file faceijk.h.

Referenced by _adjustOverageClassII().

#define JK   3

JK quadrant faceNeighbors table direction

Definition at line 72 of file faceijk.h.

Referenced by _adjustOverageClassII().

#define KI   2

KI quadrant faceNeighbors table direction

Definition at line 70 of file faceijk.h.

Referenced by _adjustOverageClassII().

Enumeration Type Documentation

enum Overage

Invalid face index Digit representing overage type

Enumerator
NO_OVERAGE 

No overage (on original face)

FACE_EDGE 

On face edge (only occurs on substrate grids)

NEW_FACE 

Overage on new face interior

Definition at line 78 of file faceijk.h.

78  {
80  NO_OVERAGE = 0,
82  FACE_EDGE = 1,
84  NEW_FACE = 2
85 } Overage;
Overage
Definition: faceijk.h:78

Function Documentation

EXTENSION_NOINLINE int _adjustOverageClassII ( FaceIJK(fijk)  ,
int  res,
int  pentLeading4,
int  substrate 
)

Generates the cell boundary in spherical coordinates for a pentagonal cell given by a FaceIJK address at a specified resolution.

Parameters
hThe FaceIJK address of the pentagonal cell.
resThe H3 resolution of the cell.
startThe first topological vertex to return.
lengthThe number of topological vertexes to return.
gThe spherical coordinates of the cell boundary. Get the vertices of a pentagon cell as substrate FaceIJK addresses
fijkThe FaceIJK address of the cell.
resThe H3 resolution of the cell. This may be adjusted if necessary for the substrate grid resolution.
fijkVertsOutput array for the vertices Generates the cell boundary in spherical coordinates for a cell given by a FaceIJK address at a specified resolution.
hThe FaceIJK address of the cell.
resThe H3 resolution of the cell.
startThe first topological vertex to return.
lengthThe number of topological vertexes to return.
gThe spherical coordinates of the cell boundary. Get the vertices of a cell as substrate FaceIJK addresses
fijkThe FaceIJK address of the cell.
resThe H3 resolution of the cell. This may be adjusted if necessary for the substrate grid resolution.
fijkVertsOutput array for the vertices Adjusts a FaceIJK address in place so that the resulting cell address is relative to the correct icosahedral face.
fijkThe FaceIJK address of the cell.
resThe H3 resolution of the cell.
pentLeading4Whether or not the cell is a pentagon with a leading digit 4.
substrateWhether or not the cell is in a substrate grid.
Returns
0 if on original face (no overage); 1 if on face edge (only occurs on substrate grids); 2 if overage on new face interior

Definition at line 864 of file faceijk.hpp.

References _ijkAdd(), _ijkNormalize(), _ijkRotate60ccw(), _ijkRotate60cw(), _ijkScale(), _ijkSub(), _setIJK(), CCWROT_60_INDEX, CoordIJK, CoordIJK_clone, CoordIJK_ptr, FACE_EDGE, FACE_INDEX, i, I_INDEX, IJ, J_INDEX, JK, K_INDEX, KI, maxDimByCIIres, NEW_FACE, NO_OVERAGE, run_benchmark_import::res, and unitScaleByCIIres.

Referenced by _h3ToFaceIjk().

867  {
868  Overage overage = NO_OVERAGE;
869 
870  CoordIJK_ptr(ijk) = fijk;
871 
872  // get the maximum dimension value; scale if a substrate grid
873  int maxDim = maxDimByCIIres[res];
874  if (substrate)
875  maxDim *= 3;
876 
877  // check for overage
878  if (substrate && ijk[I_INDEX] + ijk[J_INDEX] + ijk[K_INDEX] == maxDim) // on edge
879  overage = FACE_EDGE;
880  else if (ijk[I_INDEX] + ijk[J_INDEX] + ijk[K_INDEX] > maxDim) // overage
881  {
882  overage = NEW_FACE;
883 
884  const int* fijkOrient;
885  if (ijk[K_INDEX] > 0) {
886  if (ijk[J_INDEX] > 0) // jk "quadrant"
887  fijkOrient = faceNeighbors[fijk[FACE_INDEX]][JK];
888  else // ik "quadrant"
889  {
890  fijkOrient = faceNeighbors[fijk[FACE_INDEX]][KI];
891 
892  // adjust for the pentagonal missing sequence
893  if (pentLeading4) {
894  // translate origin to center of pentagon
895  CoordIJK(origin);
896  _setIJK(origin, maxDim, 0, 0);
897  CoordIJK(tmp);
898  _ijkSub(ijk, origin, tmp);
899  // rotate to adjust for the missing sequence
900  _ijkRotate60cw(tmp);
901  // translate the origin back to the center of the triangle
902  _ijkAdd(tmp, origin, ijk);
903  }
904  }
905  } else // ij "quadrant"
906  fijkOrient = faceNeighbors[fijk[FACE_INDEX]][IJ];
907 
908  fijk[FACE_INDEX] = fijkOrient[FACE_INDEX];
909 
910  // rotate and translate for adjacent face
911  for (int i = 0; i < fijkOrient[CCWROT_60_INDEX]; i++)
912  _ijkRotate60ccw(ijk);
913 
914  CoordIJK(transVec) = CoordIJK_clone(fijkOrient);
915  int unitScale = unitScaleByCIIres[res];
916  if (substrate)
917  unitScale *= 3;
918  _ijkScale(transVec, unitScale);
919  _ijkAdd(ijk, transVec, ijk);
920  _ijkNormalize(ijk);
921 
922  // overage points on pentagon boundaries can end up on edges
923  if (substrate && ijk[I_INDEX] + ijk[J_INDEX] + ijk[K_INDEX] == maxDim) // on edge
924  overage = FACE_EDGE;
925  }
926 
927  return overage;
928 }
Overage
Definition: faceijk.h:78
#define CCWROT_60_INDEX
Definition: faceijk.h:53
static DEVICE const int unitScaleByCIIres[]
unit scale distance table
Definition: faceijk.hpp:323
EXTENSION_INLINE bool _ijkSub(const CoordIJK(h1), const CoordIJK(h2), CoordIJK(diff))
Definition: coordijk.hpp:198
#define J_INDEX
Definition: coordijk.h:43
EXTENSION_NOINLINE bool _ijkRotate60ccw(CoordIJK(ijk))
Definition: coordijk.hpp:385
#define IJ
Definition: faceijk.h:68
EXTENSION_NOINLINE bool _ijkRotate60cw(CoordIJK(ijk))
Definition: coordijk.hpp:407
EXTENSION_INLINE bool _ijkScale(CoordIJK(c), int factor)
Definition: coordijk.hpp:211
#define CoordIJK_clone(ijk)
Definition: coordijk.h:47
#define KI
Definition: faceijk.h:70
EXTENSION_INLINE bool _ijkAdd(const CoordIJK(h1), const CoordIJK(h2), CoordIJK(sum))
Definition: coordijk.hpp:184
#define I_INDEX
Definition: coordijk.h:42
#define CoordIJK_ptr(variable_name)
Definition: coordijk.h:46
#define CoordIJK(variable_name)
Definition: coordijk.h:45
#define JK
Definition: faceijk.h:72
#define FACE_INDEX
Definition: faceijk.h:35
static DEVICE const int maxDimByCIIres[]
direction from the origin face to the destination face, relative to the origin face&#39;s coordinate syst...
Definition: faceijk.hpp:302
#define K_INDEX
Definition: coordijk.h:44
EXTENSION_INLINE bool _setIJK(CoordIJK(ijk), int i, int j, int k)
Definition: coordijk.hpp:40
EXTENSION_NOINLINE bool _ijkNormalize(CoordIJK(c))
Definition: coordijk.hpp:224

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

EXTENSION_NOINLINE bool _faceIjkToGeo ( const   FaceIJKh,
int  res,
GeoCoord(g)   
)

Determines the center point in spherical coordinates of a cell given by a FaceIJK address at a specified resolution.

Parameters
hThe FaceIJK address of the cell.
resThe H3 resolution of the cell.
gThe spherical coordinates of the cell center point.

Definition at line 495 of file faceijk.hpp.

References _hex2dToGeo(), _ijkToHex2d(), FACE_INDEX, and Vec2d.

Referenced by _h3ToGeo().

495  {
496  Vec2d(v);
497  _ijkToHex2d(h, v);
498  _hex2dToGeo(v, h[FACE_INDEX], res, 0, g);
499  return true;
500 }
EXTENSION_NOINLINE bool _hex2dToGeo(const Vec2d(v), int face, int res, int substrate, GeoCoord(g))
Definition: faceijk.hpp:442
#define Vec2d(variable_name)
Definition: vec2d.h:28
EXTENSION_INLINE bool _ijkToHex2d(const CoordIJK(h), Vec2d(v))
Definition: coordijk.hpp:155
#define FACE_INDEX
Definition: faceijk.h:35

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

EXTENSION_NOINLINE bool _geoToFaceIjk ( const   GeoCoordg,
int  res,
FaceIJK(h)   
)

Encodes a coordinate on the sphere to the FaceIJK address of the containing cell at the specified resolution.

Parameters
gThe spherical coordinates to encode.
resThe desired H3 resolution for the encoding.
hThe FaceIJK address of the containing cell at resolution res.

Definition at line 362 of file faceijk.hpp.

References _geoToHex2d(), _hex2dToCoordIJK(), FACE_INDEX, and Vec2d.

Referenced by geoToH3().

362  {
363  // first convert to hex2d
364  Vec2d(v);
365  _geoToHex2d(g, res, &h[FACE_INDEX], v);
366 
367  // then convert to ijk+
368  _hex2dToCoordIJK(v, h);
369 
370  return true;
371 }
EXTENSION_NOINLINE bool _hex2dToCoordIJK(const Vec2d(v), CoordIJK(h))
Definition: coordijk.hpp:54
EXTENSION_NOINLINE bool _geoToHex2d(const GeoCoord(g), int res, int *face, Vec2d(v))
Definition: faceijk.hpp:382
#define Vec2d(variable_name)
Definition: vec2d.h:28
#define FACE_INDEX
Definition: faceijk.h:35

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

EXTENSION_NOINLINE bool _geoToHex2d ( const   GeoCoordg,
int  res,
int *  face,
Vec2d(v)   
)

Encodes a coordinate on the sphere to the corresponding icosahedral face and containing 2D hex coordinates relative to that face center.

Parameters
gThe spherical coordinates to encode.
resThe desired H3 resolution for the encoding.
faceThe icosahedral face containing the spherical coordinates.
vThe 2D hex coordinates of the cell containing the point.

Definition at line 382 of file faceijk.hpp.

References _geoAzimuthRads(), _geoToVec3d(), _pointSquareDist(), _posAngleRads(), EPSILON, f, faceAxesAzRadsCII, i, isResClassIII(), M_AP7_ROT_RADS, M_SQRT7, NUM_ICOSA_FACES, run_benchmark_import::res, RES0_U_GNOMONIC, Vec3d, X_INDEX, and Y_INDEX.

Referenced by _geoToFaceIjk().

382  {
383  Vec3d(v3d);
384  _geoToVec3d(g, v3d);
385 
386  // determine the icosahedron face
387  *face = 0;
388  double sqd = _pointSquareDist(faceCenterPoint[0], v3d);
389  for (int f = 1; f < NUM_ICOSA_FACES; f++) {
390  double sqdT = _pointSquareDist(faceCenterPoint[f], v3d);
391  if (sqdT < sqd) {
392  *face = f;
393  sqd = sqdT;
394  }
395  }
396 
397  // cos(r) = 1 - 2 * sin^2(r/2) = 1 - 2 * (sqd / 4) = 1 - sqd/2
398  double r = acos(1 - sqd / 2);
399 
400  if (r < EPSILON) {
401  v[X_INDEX] = v[Y_INDEX] = 0.0;
402  return true;
403  }
404 
405  // now have face and r, now find CCW theta from CII i-axis
406  double theta = _posAngleRads(faceAxesAzRadsCII[*face][0] -
407  _posAngleRads(_geoAzimuthRads(faceCenterGeo[*face], g)));
408 
409  // adjust theta for Class III (odd resolutions)
410  if (isResClassIII(res))
411  theta = _posAngleRads(theta - M_AP7_ROT_RADS);
412 
413  // perform gnomonic scaling of r
414  r = tan(r);
415 
416  // scale for current resolution length u
417  r /= RES0_U_GNOMONIC;
418  for (int i = 0; i < res; i++)
419  r *= M_SQRT7;
420 
421  // we now have (r, theta) in hex2d with theta ccw from x-axes
422 
423  // convert to local x,y
424  v[X_INDEX] = r * cos(theta);
425  v[Y_INDEX] = r * sin(theta);
426 
427  return true;
428 }
EXTENSION_INLINE int isResClassIII(int res)
Definition: faceijk.hpp:350
#define M_AP7_ROT_RADS
Definition: constants.h:51
static DEVICE const double faceAxesAzRadsCII[NUM_ICOSA_FACES][3]
icosahedron face ijk axes as azimuth in radians from face center to vertex 0/1/2 respectively ...
Definition: faceijk.hpp:89
#define NUM_ICOSA_FACES
Definition: constants.h:71
#define M_SQRT7
Definition: faceijk.hpp:36
EXTENSION_NOINLINE double _posAngleRads(double rads)
Definition: geoCoord.hpp:35
#define X_INDEX
Definition: vec2d.h:26
#define Vec3d(variable_name)
Definition: vec3d.h:29
#define EPSILON
Definition: constants.h:42
EXTENSION_NOINLINE bool _geoToVec3d(const GeoCoord(geo), Vec3d(v))
Definition: vec3d.hpp:52
#define RES0_U_GNOMONIC
Definition: constants.h:65
EXTENSION_NOINLINE double _geoAzimuthRads(const GeoCoord(p1), const GeoCoord(p2))
Definition: geoCoord.hpp:187
#define Y_INDEX
Definition: vec2d.h:27
char * f
EXTENSION_NOINLINE double _pointSquareDist(const Vec3d(v1), const Vec3d(v2))
Definition: vec3d.hpp:41

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

EXTENSION_NOINLINE bool _hex2dToGeo ( const   Vec2dv,
int  face,
int  res,
int  substrate,
GeoCoord(g)   
)

Determines the center point in spherical coordinates of a cell given by 2D hex coordinates on a particular icosahedral face.

Parameters
vThe 2D hex coordinates of the cell.
faceThe icosahedral face upon which the 2D hex coordinate system is centered.
resThe H3 resolution of the cell.
substrateIndicates whether or not this grid is actually a substrate grid relative to the specified resolution.
gThe spherical coordinates of the cell center point.

Definition at line 442 of file faceijk.hpp.

References _geoAzDistanceRads(), _posAngleRads(), _v2dMag(), EPSILON, faceAxesAzRadsCII, GeoCoordCopy, i, isResClassIII(), M_AP7_ROT_RADS, M_SQRT7, run_benchmark_import::res, RES0_U_GNOMONIC, X_INDEX, and Y_INDEX.

Referenced by _faceIjkToGeo().

446  {
447  // calculate (r, theta) in hex2d
448  double r = _v2dMag(v);
449 
450  if (r < EPSILON) {
451  GeoCoordCopy(g, faceCenterGeo[face]);
452  return true;
453  }
454 
455  double theta = atan2(v[Y_INDEX], v[X_INDEX]);
456 
457  // scale for current resolution length u
458  for (int i = 0; i < res; i++)
459  r /= M_SQRT7;
460 
461  // scale accordingly if this is a substrate grid
462  if (substrate) {
463  r /= 3.0;
464  if (isResClassIII(res))
465  r /= M_SQRT7;
466  }
467 
468  r *= RES0_U_GNOMONIC;
469 
470  // perform inverse gnomonic scaling of r
471  r = atan(r);
472 
473  // adjust theta for Class III
474  // if a substrate grid, then it's already been adjusted for Class III
475  if (!substrate && isResClassIII(res))
476  theta = _posAngleRads(theta + M_AP7_ROT_RADS);
477 
478  // find theta as an azimuth
479  theta = _posAngleRads(faceAxesAzRadsCII[face][0] - theta);
480 
481  // now find the point at (r,theta) from the face center
482  _geoAzDistanceRads(faceCenterGeo[face], theta, r, g);
483 
484  return true;
485 }
EXTENSION_INLINE int isResClassIII(int res)
Definition: faceijk.hpp:350
#define M_AP7_ROT_RADS
Definition: constants.h:51
static DEVICE const double faceAxesAzRadsCII[NUM_ICOSA_FACES][3]
icosahedron face ijk axes as azimuth in radians from face center to vertex 0/1/2 respectively ...
Definition: faceijk.hpp:89
#define M_SQRT7
Definition: faceijk.hpp:36
EXTENSION_NOINLINE double _posAngleRads(double rads)
Definition: geoCoord.hpp:35
EXTENSION_NOINLINE bool _geoAzDistanceRads(const GeoCoord(p1), double az, double distance, GeoCoord(p2))
Definition: geoCoord.hpp:204
#define X_INDEX
Definition: vec2d.h:26
#define EPSILON
Definition: constants.h:42
#define RES0_U_GNOMONIC
Definition: constants.h:65
#define Y_INDEX
Definition: vec2d.h:27
EXTENSION_INLINE double _v2dMag(const Vec2d(v))
Definition: vec2d.hpp:30
#define GeoCoordCopy(dest_coord, src_coord)
Definition: h3api.h:96

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

EXTENSION_INLINE int isResClassIII ( int  res)

Returns whether or not a resolution is a Class III grid. Note that odd resolutions are Class III and even resolutions are Class II.

Parameters
resThe H3 resolution.
Returns
1 if the resolution is a Class III grid, and 0 if the resolution is a Class II grid.

Definition at line 350 of file faceijk.hpp.

Referenced by _faceIjkToH3(), _geoToHex2d(), _h3ToFaceIjk(), _h3ToFaceIjkWithInitializedFijk(), and _hex2dToGeo().

350  {
351  return res % 2;
352 }

+ Here is the caller graph for this function: