h3_baseCells.c (760 lines of code) (raw):
/*
* Copyright 2016-2020 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @file baseCells.c
* @brief Base cell related lookup tables and access functions.
*/
#include "h3_baseCells.h"
#include "h3_h3Index.h"
/** @struct BaseCellRotation
* @brief base cell at a given ijk and required rotations into its system
*/
typedef struct {
int baseCell; ///< base cell number
int ccwRot60; ///< number of ccw 60 degree rotations relative to current
/// face
} BaseCellRotation;
/** @brief Neighboring base cell ID in each IJK direction.
*
* For each base cell, for each direction, the neighboring base
* cell ID is given. 127 indicates there is no neighbor in that direction.
*/
const int baseCellNeighbors[NUM_BASE_CELLS][7] = {
{0, 1, 5, 2, 4, 3, 8}, // base cell 0
{1, 7, 6, 9, 0, 3, 2}, // base cell 1
{2, 6, 10, 11, 0, 1, 5}, // base cell 2
{3, 13, 1, 7, 4, 12, 0}, // base cell 3
{4, INVALID_BASE_CELL, 15, 8, 3, 0, 12}, // base cell 4 (pentagon)
{5, 2, 18, 10, 8, 0, 16}, // base cell 5
{6, 14, 11, 17, 1, 9, 2}, // base cell 6
{7, 21, 9, 19, 3, 13, 1}, // base cell 7
{8, 5, 22, 16, 4, 0, 15}, // base cell 8
{9, 19, 14, 20, 1, 7, 6}, // base cell 9
{10, 11, 24, 23, 5, 2, 18}, // base cell 10
{11, 17, 23, 25, 2, 6, 10}, // base cell 11
{12, 28, 13, 26, 4, 15, 3}, // base cell 12
{13, 26, 21, 29, 3, 12, 7}, // base cell 13
{14, INVALID_BASE_CELL, 17, 27, 9, 20, 6}, // base cell 14 (pentagon)
{15, 22, 28, 31, 4, 8, 12}, // base cell 15
{16, 18, 33, 30, 8, 5, 22}, // base cell 16
{17, 11, 14, 6, 35, 25, 27}, // base cell 17
{18, 24, 30, 32, 5, 10, 16}, // base cell 18
{19, 34, 20, 36, 7, 21, 9}, // base cell 19
{20, 14, 19, 9, 40, 27, 36}, // base cell 20
{21, 38, 19, 34, 13, 29, 7}, // base cell 21
{22, 16, 41, 33, 15, 8, 31}, // base cell 22
{23, 24, 11, 10, 39, 37, 25}, // base cell 23
{24, INVALID_BASE_CELL, 32, 37, 10, 23, 18}, // base cell 24 (pentagon)
{25, 23, 17, 11, 45, 39, 35}, // base cell 25
{26, 42, 29, 43, 12, 28, 13}, // base cell 26
{27, 40, 35, 46, 14, 20, 17}, // base cell 27
{28, 31, 42, 44, 12, 15, 26}, // base cell 28
{29, 43, 38, 47, 13, 26, 21}, // base cell 29
{30, 32, 48, 50, 16, 18, 33}, // base cell 30
{31, 41, 44, 53, 15, 22, 28}, // base cell 31
{32, 30, 24, 18, 52, 50, 37}, // base cell 32
{33, 30, 49, 48, 22, 16, 41}, // base cell 33
{34, 19, 38, 21, 54, 36, 51}, // base cell 34
{35, 46, 45, 56, 17, 27, 25}, // base cell 35
{36, 20, 34, 19, 55, 40, 54}, // base cell 36
{37, 39, 52, 57, 24, 23, 32}, // base cell 37
{38, INVALID_BASE_CELL, 34, 51, 29, 47, 21}, // base cell 38 (pentagon)
{39, 37, 25, 23, 59, 57, 45}, // base cell 39
{40, 27, 36, 20, 60, 46, 55}, // base cell 40
{41, 49, 53, 61, 22, 33, 31}, // base cell 41
{42, 58, 43, 62, 28, 44, 26}, // base cell 42
{43, 62, 47, 64, 26, 42, 29}, // base cell 43
{44, 53, 58, 65, 28, 31, 42}, // base cell 44
{45, 39, 35, 25, 63, 59, 56}, // base cell 45
{46, 60, 56, 68, 27, 40, 35}, // base cell 46
{47, 38, 43, 29, 69, 51, 64}, // base cell 47
{48, 49, 30, 33, 67, 66, 50}, // base cell 48
{49, INVALID_BASE_CELL, 61, 66, 33, 48, 41}, // base cell 49 (pentagon)
{50, 48, 32, 30, 70, 67, 52}, // base cell 50
{51, 69, 54, 71, 38, 47, 34}, // base cell 51
{52, 57, 70, 74, 32, 37, 50}, // base cell 52
{53, 61, 65, 75, 31, 41, 44}, // base cell 53
{54, 71, 55, 73, 34, 51, 36}, // base cell 54
{55, 40, 54, 36, 72, 60, 73}, // base cell 55
{56, 68, 63, 77, 35, 46, 45}, // base cell 56
{57, 59, 74, 78, 37, 39, 52}, // base cell 57
{58, INVALID_BASE_CELL, 62, 76, 44, 65, 42}, // base cell 58 (pentagon)
{59, 63, 78, 79, 39, 45, 57}, // base cell 59
{60, 72, 68, 80, 40, 55, 46}, // base cell 60
{61, 53, 49, 41, 81, 75, 66}, // base cell 61
{62, 43, 58, 42, 82, 64, 76}, // base cell 62
{63, INVALID_BASE_CELL, 56, 45, 79, 59, 77}, // base cell 63 (pentagon)
{64, 47, 62, 43, 84, 69, 82}, // base cell 64
{65, 58, 53, 44, 86, 76, 75}, // base cell 65
{66, 67, 81, 85, 49, 48, 61}, // base cell 66
{67, 66, 50, 48, 87, 85, 70}, // base cell 67
{68, 56, 60, 46, 90, 77, 80}, // base cell 68
{69, 51, 64, 47, 89, 71, 84}, // base cell 69
{70, 67, 52, 50, 83, 87, 74}, // base cell 70
{71, 89, 73, 91, 51, 69, 54}, // base cell 71
{72, INVALID_BASE_CELL, 73, 55, 80, 60, 88}, // base cell 72 (pentagon)
{73, 91, 72, 88, 54, 71, 55}, // base cell 73
{74, 78, 83, 92, 52, 57, 70}, // base cell 74
{75, 65, 61, 53, 94, 86, 81}, // base cell 75
{76, 86, 82, 96, 58, 65, 62}, // base cell 76
{77, 63, 68, 56, 93, 79, 90}, // base cell 77
{78, 74, 59, 57, 95, 92, 79}, // base cell 78
{79, 78, 63, 59, 93, 95, 77}, // base cell 79
{80, 68, 72, 60, 99, 90, 88}, // base cell 80
{81, 85, 94, 101, 61, 66, 75}, // base cell 81
{82, 96, 84, 98, 62, 76, 64}, // base cell 82
{83, INVALID_BASE_CELL, 74, 70, 100, 87, 92}, // base cell 83 (pentagon)
{84, 69, 82, 64, 97, 89, 98}, // base cell 84
{85, 87, 101, 102, 66, 67, 81}, // base cell 85
{86, 76, 75, 65, 104, 96, 94}, // base cell 86
{87, 83, 102, 100, 67, 70, 85}, // base cell 87
{88, 72, 91, 73, 99, 80, 105}, // base cell 88
{89, 97, 91, 103, 69, 84, 71}, // base cell 89
{90, 77, 80, 68, 106, 93, 99}, // base cell 90
{91, 73, 89, 71, 105, 88, 103}, // base cell 91
{92, 83, 78, 74, 108, 100, 95}, // base cell 92
{93, 79, 90, 77, 109, 95, 106}, // base cell 93
{94, 86, 81, 75, 107, 104, 101}, // base cell 94
{95, 92, 79, 78, 109, 108, 93}, // base cell 95
{96, 104, 98, 110, 76, 86, 82}, // base cell 96
{97, INVALID_BASE_CELL, 98, 84, 103, 89, 111}, // base cell 97 (pentagon)
{98, 110, 97, 111, 82, 96, 84}, // base cell 98
{99, 80, 105, 88, 106, 90, 113}, // base cell 99
{100, 102, 83, 87, 108, 114, 92}, // base cell 100
{101, 102, 107, 112, 81, 85, 94}, // base cell 101
{102, 101, 87, 85, 114, 112, 100}, // base cell 102
{103, 91, 97, 89, 116, 105, 111}, // base cell 103
{104, 107, 110, 115, 86, 94, 96}, // base cell 104
{105, 88, 103, 91, 113, 99, 116}, // base cell 105
{106, 93, 99, 90, 117, 109, 113}, // base cell 106
{107, INVALID_BASE_CELL, 101, 94, 115, 104,
112}, // base cell 107 (pentagon)
{108, 100, 95, 92, 118, 114, 109}, // base cell 108
{109, 108, 93, 95, 117, 118, 106}, // base cell 109
{110, 98, 104, 96, 119, 111, 115}, // base cell 110
{111, 97, 110, 98, 116, 103, 119}, // base cell 111
{112, 107, 102, 101, 120, 115, 114}, // base cell 112
{113, 99, 116, 105, 117, 106, 121}, // base cell 113
{114, 112, 100, 102, 118, 120, 108}, // base cell 114
{115, 110, 107, 104, 120, 119, 112}, // base cell 115
{116, 103, 119, 111, 113, 105, 121}, // base cell 116
{117, INVALID_BASE_CELL, 109, 118, 113, 121,
106}, // base cell 117 (pentagon)
{118, 120, 108, 114, 117, 121, 109}, // base cell 118
{119, 111, 115, 110, 121, 116, 120}, // base cell 119
{120, 115, 114, 112, 121, 119, 118}, // base cell 120
{121, 116, 120, 119, 117, 113, 118}, // base cell 121
};
/** @brief Neighboring base cell rotations in each IJK direction.
*
* For each base cell, for each direction, the number of 60 degree
* CCW rotations to the coordinate system of the neighbor is given.
* -1 indicates there is no neighbor in that direction.
*/
const int baseCellNeighbor60CCWRots[NUM_BASE_CELLS][7] = {
{0, 5, 0, 0, 1, 5, 1}, // base cell 0
{0, 0, 1, 0, 1, 0, 1}, // base cell 1
{0, 0, 0, 0, 0, 5, 0}, // base cell 2
{0, 5, 0, 0, 2, 5, 1}, // base cell 3
{0, -1, 1, 0, 3, 4, 2}, // base cell 4 (pentagon)
{0, 0, 1, 0, 1, 0, 1}, // base cell 5
{0, 0, 0, 3, 5, 5, 0}, // base cell 6
{0, 0, 0, 0, 0, 5, 0}, // base cell 7
{0, 5, 0, 0, 0, 5, 1}, // base cell 8
{0, 0, 1, 3, 0, 0, 1}, // base cell 9
{0, 0, 1, 3, 0, 0, 1}, // base cell 10
{0, 3, 3, 3, 0, 0, 0}, // base cell 11
{0, 5, 0, 0, 3, 5, 1}, // base cell 12
{0, 0, 1, 0, 1, 0, 1}, // base cell 13
{0, -1, 3, 0, 5, 2, 0}, // base cell 14 (pentagon)
{0, 5, 0, 0, 4, 5, 1}, // base cell 15
{0, 0, 0, 0, 0, 5, 0}, // base cell 16
{0, 3, 3, 3, 3, 0, 3}, // base cell 17
{0, 0, 0, 3, 5, 5, 0}, // base cell 18
{0, 3, 3, 3, 0, 0, 0}, // base cell 19
{0, 3, 3, 3, 0, 3, 0}, // base cell 20
{0, 0, 0, 3, 5, 5, 0}, // base cell 21
{0, 0, 1, 0, 1, 0, 1}, // base cell 22
{0, 3, 3, 3, 0, 3, 0}, // base cell 23
{0, -1, 3, 0, 5, 2, 0}, // base cell 24 (pentagon)
{0, 0, 0, 3, 0, 0, 3}, // base cell 25
{0, 0, 0, 0, 0, 5, 0}, // base cell 26
{0, 3, 0, 0, 0, 3, 3}, // base cell 27
{0, 0, 1, 0, 1, 0, 1}, // base cell 28
{0, 0, 1, 3, 0, 0, 1}, // base cell 29
{0, 3, 3, 3, 0, 0, 0}, // base cell 30
{0, 0, 0, 0, 0, 5, 0}, // base cell 31
{0, 3, 3, 3, 3, 0, 3}, // base cell 32
{0, 0, 1, 3, 0, 0, 1}, // base cell 33
{0, 3, 3, 3, 3, 0, 3}, // base cell 34
{0, 0, 3, 0, 3, 0, 3}, // base cell 35
{0, 0, 0, 3, 0, 0, 3}, // base cell 36
{0, 3, 0, 0, 0, 3, 3}, // base cell 37
{0, -1, 3, 0, 5, 2, 0}, // base cell 38 (pentagon)
{0, 3, 0, 0, 3, 3, 0}, // base cell 39
{0, 3, 0, 0, 3, 3, 0}, // base cell 40
{0, 0, 0, 3, 5, 5, 0}, // base cell 41
{0, 0, 0, 3, 5, 5, 0}, // base cell 42
{0, 3, 3, 3, 0, 0, 0}, // base cell 43
{0, 0, 1, 3, 0, 0, 1}, // base cell 44
{0, 0, 3, 0, 0, 3, 3}, // base cell 45
{0, 0, 0, 3, 0, 3, 0}, // base cell 46
{0, 3, 3, 3, 0, 3, 0}, // base cell 47
{0, 3, 3, 3, 0, 3, 0}, // base cell 48
{0, -1, 3, 0, 5, 2, 0}, // base cell 49 (pentagon)
{0, 0, 0, 3, 0, 0, 3}, // base cell 50
{0, 3, 0, 0, 0, 3, 3}, // base cell 51
{0, 0, 3, 0, 3, 0, 3}, // base cell 52
{0, 3, 3, 3, 0, 0, 0}, // base cell 53
{0, 0, 3, 0, 3, 0, 3}, // base cell 54
{0, 0, 3, 0, 0, 3, 3}, // base cell 55
{0, 3, 3, 3, 0, 0, 3}, // base cell 56
{0, 0, 0, 3, 0, 3, 0}, // base cell 57
{0, -1, 3, 0, 5, 2, 0}, // base cell 58 (pentagon)
{0, 3, 3, 3, 3, 3, 0}, // base cell 59
{0, 3, 3, 3, 3, 3, 0}, // base cell 60
{0, 3, 3, 3, 3, 0, 3}, // base cell 61
{0, 3, 3, 3, 3, 0, 3}, // base cell 62
{0, -1, 3, 0, 5, 2, 0}, // base cell 63 (pentagon)
{0, 0, 0, 3, 0, 0, 3}, // base cell 64
{0, 3, 3, 3, 0, 3, 0}, // base cell 65
{0, 3, 0, 0, 0, 3, 3}, // base cell 66
{0, 3, 0, 0, 3, 3, 0}, // base cell 67
{0, 3, 3, 3, 0, 0, 0}, // base cell 68
{0, 3, 0, 0, 3, 3, 0}, // base cell 69
{0, 0, 3, 0, 0, 3, 3}, // base cell 70
{0, 0, 0, 3, 0, 3, 0}, // base cell 71
{0, -1, 3, 0, 5, 2, 0}, // base cell 72 (pentagon)
{0, 3, 3, 3, 0, 0, 3}, // base cell 73
{0, 3, 3, 3, 0, 0, 3}, // base cell 74
{0, 0, 0, 3, 0, 0, 3}, // base cell 75
{0, 3, 0, 0, 0, 3, 3}, // base cell 76
{0, 0, 0, 3, 0, 5, 0}, // base cell 77
{0, 3, 3, 3, 0, 0, 0}, // base cell 78
{0, 0, 1, 3, 1, 0, 1}, // base cell 79
{0, 0, 1, 3, 1, 0, 1}, // base cell 80
{0, 0, 3, 0, 3, 0, 3}, // base cell 81
{0, 0, 3, 0, 3, 0, 3}, // base cell 82
{0, -1, 3, 0, 5, 2, 0}, // base cell 83 (pentagon)
{0, 0, 3, 0, 0, 3, 3}, // base cell 84
{0, 0, 0, 3, 0, 3, 0}, // base cell 85
{0, 3, 0, 0, 3, 3, 0}, // base cell 86
{0, 3, 3, 3, 3, 3, 0}, // base cell 87
{0, 0, 0, 3, 0, 5, 0}, // base cell 88
{0, 3, 3, 3, 3, 3, 0}, // base cell 89
{0, 0, 0, 0, 0, 0, 1}, // base cell 90
{0, 3, 3, 3, 0, 0, 0}, // base cell 91
{0, 0, 0, 3, 0, 5, 0}, // base cell 92
{0, 5, 0, 0, 5, 5, 0}, // base cell 93
{0, 0, 3, 0, 0, 3, 3}, // base cell 94
{0, 0, 0, 0, 0, 0, 1}, // base cell 95
{0, 0, 0, 3, 0, 3, 0}, // base cell 96
{0, -1, 3, 0, 5, 2, 0}, // base cell 97 (pentagon)
{0, 3, 3, 3, 0, 0, 3}, // base cell 98
{0, 5, 0, 0, 5, 5, 0}, // base cell 99
{0, 0, 1, 3, 1, 0, 1}, // base cell 100
{0, 3, 3, 3, 0, 0, 3}, // base cell 101
{0, 3, 3, 3, 0, 0, 0}, // base cell 102
{0, 0, 1, 3, 1, 0, 1}, // base cell 103
{0, 3, 3, 3, 3, 3, 0}, // base cell 104
{0, 0, 0, 0, 0, 0, 1}, // base cell 105
{0, 0, 1, 0, 3, 5, 1}, // base cell 106
{0, -1, 3, 0, 5, 2, 0}, // base cell 107 (pentagon)
{0, 5, 0, 0, 5, 5, 0}, // base cell 108
{0, 0, 1, 0, 4, 5, 1}, // base cell 109
{0, 3, 3, 3, 0, 0, 0}, // base cell 110
{0, 0, 0, 3, 0, 5, 0}, // base cell 111
{0, 0, 0, 3, 0, 5, 0}, // base cell 112
{0, 0, 1, 0, 2, 5, 1}, // base cell 113
{0, 0, 0, 0, 0, 0, 1}, // base cell 114
{0, 0, 1, 3, 1, 0, 1}, // base cell 115
{0, 5, 0, 0, 5, 5, 0}, // base cell 116
{0, -1, 1, 0, 3, 4, 2}, // base cell 117 (pentagon)
{0, 0, 1, 0, 0, 5, 1}, // base cell 118
{0, 0, 0, 0, 0, 0, 1}, // base cell 119
{0, 5, 0, 0, 5, 5, 0}, // base cell 120
{0, 0, 1, 0, 1, 5, 1}, // base cell 121
};
/** @brief Resolution 0 base cell lookup table for each face.
*
* Given the face number and a resolution 0 ijk+ coordinate in that face's
* face-centered ijk coordinate system, gives the base cell located at that
* coordinate and the number of 60 ccw rotations to rotate into that base
* cell's orientation.
*
* Valid lookup coordinates are from (0, 0, 0) to (2, 2, 2).
*
* This table can be accessed using the functions `_faceIjkToBaseCell` and
* `_faceIjkToBaseCellCCWrot60`
*/
static const BaseCellRotation faceIjkBaseCells[NUM_ICOSA_FACES][3][3][3] = {
{// face 0
{
// i 0
{{16, 0}, {18, 0}, {24, 0}}, // j 0
{{33, 0}, {30, 0}, {32, 3}}, // j 1
{{49, 1}, {48, 3}, {50, 3}} // j 2
},
{
// i 1
{{8, 0}, {5, 5}, {10, 5}}, // j 0
{{22, 0}, {16, 0}, {18, 0}}, // j 1
{{41, 1}, {33, 0}, {30, 0}} // j 2
},
{
// i 2
{{4, 0}, {0, 5}, {2, 5}}, // j 0
{{15, 1}, {8, 0}, {5, 5}}, // j 1
{{31, 1}, {22, 0}, {16, 0}} // j 2
}},
{// face 1
{
// i 0
{{2, 0}, {6, 0}, {14, 0}}, // j 0
{{10, 0}, {11, 0}, {17, 3}}, // j 1
{{24, 1}, {23, 3}, {25, 3}} // j 2
},
{
// i 1
{{0, 0}, {1, 5}, {9, 5}}, // j 0
{{5, 0}, {2, 0}, {6, 0}}, // j 1
{{18, 1}, {10, 0}, {11, 0}} // j 2
},
{
// i 2
{{4, 1}, {3, 5}, {7, 5}}, // j 0
{{8, 1}, {0, 0}, {1, 5}}, // j 1
{{16, 1}, {5, 0}, {2, 0}} // j 2
}},
{// face 2
{
// i 0
{{7, 0}, {21, 0}, {38, 0}}, // j 0
{{9, 0}, {19, 0}, {34, 3}}, // j 1
{{14, 1}, {20, 3}, {36, 3}} // j 2
},
{
// i 1
{{3, 0}, {13, 5}, {29, 5}}, // j 0
{{1, 0}, {7, 0}, {21, 0}}, // j 1
{{6, 1}, {9, 0}, {19, 0}} // j 2
},
{
// i 2
{{4, 2}, {12, 5}, {26, 5}}, // j 0
{{0, 1}, {3, 0}, {13, 5}}, // j 1
{{2, 1}, {1, 0}, {7, 0}} // j 2
}},
{// face 3
{
// i 0
{{26, 0}, {42, 0}, {58, 0}}, // j 0
{{29, 0}, {43, 0}, {62, 3}}, // j 1
{{38, 1}, {47, 3}, {64, 3}} // j 2
},
{
// i 1
{{12, 0}, {28, 5}, {44, 5}}, // j 0
{{13, 0}, {26, 0}, {42, 0}}, // j 1
{{21, 1}, {29, 0}, {43, 0}} // j 2
},
{
// i 2
{{4, 3}, {15, 5}, {31, 5}}, // j 0
{{3, 1}, {12, 0}, {28, 5}}, // j 1
{{7, 1}, {13, 0}, {26, 0}} // j 2
}},
{// face 4
{
// i 0
{{31, 0}, {41, 0}, {49, 0}}, // j 0
{{44, 0}, {53, 0}, {61, 3}}, // j 1
{{58, 1}, {65, 3}, {75, 3}} // j 2
},
{
// i 1
{{15, 0}, {22, 5}, {33, 5}}, // j 0
{{28, 0}, {31, 0}, {41, 0}}, // j 1
{{42, 1}, {44, 0}, {53, 0}} // j 2
},
{
// i 2
{{4, 4}, {8, 5}, {16, 5}}, // j 0
{{12, 1}, {15, 0}, {22, 5}}, // j 1
{{26, 1}, {28, 0}, {31, 0}} // j 2
}},
{// face 5
{
// i 0
{{50, 0}, {48, 0}, {49, 3}}, // j 0
{{32, 0}, {30, 3}, {33, 3}}, // j 1
{{24, 3}, {18, 3}, {16, 3}} // j 2
},
{
// i 1
{{70, 0}, {67, 0}, {66, 3}}, // j 0
{{52, 3}, {50, 0}, {48, 0}}, // j 1
{{37, 3}, {32, 0}, {30, 3}} // j 2
},
{
// i 2
{{83, 0}, {87, 3}, {85, 3}}, // j 0
{{74, 3}, {70, 0}, {67, 0}}, // j 1
{{57, 1}, {52, 3}, {50, 0}} // j 2
}},
{// face 6
{
// i 0
{{25, 0}, {23, 0}, {24, 3}}, // j 0
{{17, 0}, {11, 3}, {10, 3}}, // j 1
{{14, 3}, {6, 3}, {2, 3}} // j 2
},
{
// i 1
{{45, 0}, {39, 0}, {37, 3}}, // j 0
{{35, 3}, {25, 0}, {23, 0}}, // j 1
{{27, 3}, {17, 0}, {11, 3}} // j 2
},
{
// i 2
{{63, 0}, {59, 3}, {57, 3}}, // j 0
{{56, 3}, {45, 0}, {39, 0}}, // j 1
{{46, 3}, {35, 3}, {25, 0}} // j 2
}},
{// face 7
{
// i 0
{{36, 0}, {20, 0}, {14, 3}}, // j 0
{{34, 0}, {19, 3}, {9, 3}}, // j 1
{{38, 3}, {21, 3}, {7, 3}} // j 2
},
{
// i 1
{{55, 0}, {40, 0}, {27, 3}}, // j 0
{{54, 3}, {36, 0}, {20, 0}}, // j 1
{{51, 3}, {34, 0}, {19, 3}} // j 2
},
{
// i 2
{{72, 0}, {60, 3}, {46, 3}}, // j 0
{{73, 3}, {55, 0}, {40, 0}}, // j 1
{{71, 3}, {54, 3}, {36, 0}} // j 2
}},
{// face 8
{
// i 0
{{64, 0}, {47, 0}, {38, 3}}, // j 0
{{62, 0}, {43, 3}, {29, 3}}, // j 1
{{58, 3}, {42, 3}, {26, 3}} // j 2
},
{
// i 1
{{84, 0}, {69, 0}, {51, 3}}, // j 0
{{82, 3}, {64, 0}, {47, 0}}, // j 1
{{76, 3}, {62, 0}, {43, 3}} // j 2
},
{
// i 2
{{97, 0}, {89, 3}, {71, 3}}, // j 0
{{98, 3}, {84, 0}, {69, 0}}, // j 1
{{96, 3}, {82, 3}, {64, 0}} // j 2
}},
{// face 9
{
// i 0
{{75, 0}, {65, 0}, {58, 3}}, // j 0
{{61, 0}, {53, 3}, {44, 3}}, // j 1
{{49, 3}, {41, 3}, {31, 3}} // j 2
},
{
// i 1
{{94, 0}, {86, 0}, {76, 3}}, // j 0
{{81, 3}, {75, 0}, {65, 0}}, // j 1
{{66, 3}, {61, 0}, {53, 3}} // j 2
},
{
// i 2
{{107, 0}, {104, 3}, {96, 3}}, // j 0
{{101, 3}, {94, 0}, {86, 0}}, // j 1
{{85, 3}, {81, 3}, {75, 0}} // j 2
}},
{// face 10
{
// i 0
{{57, 0}, {59, 0}, {63, 3}}, // j 0
{{74, 0}, {78, 3}, {79, 3}}, // j 1
{{83, 3}, {92, 3}, {95, 3}} // j 2
},
{
// i 1
{{37, 0}, {39, 3}, {45, 3}}, // j 0
{{52, 0}, {57, 0}, {59, 0}}, // j 1
{{70, 3}, {74, 0}, {78, 3}} // j 2
},
{
// i 2
{{24, 0}, {23, 3}, {25, 3}}, // j 0
{{32, 3}, {37, 0}, {39, 3}}, // j 1
{{50, 3}, {52, 0}, {57, 0}} // j 2
}},
{// face 11
{
// i 0
{{46, 0}, {60, 0}, {72, 3}}, // j 0
{{56, 0}, {68, 3}, {80, 3}}, // j 1
{{63, 3}, {77, 3}, {90, 3}} // j 2
},
{
// i 1
{{27, 0}, {40, 3}, {55, 3}}, // j 0
{{35, 0}, {46, 0}, {60, 0}}, // j 1
{{45, 3}, {56, 0}, {68, 3}} // j 2
},
{
// i 2
{{14, 0}, {20, 3}, {36, 3}}, // j 0
{{17, 3}, {27, 0}, {40, 3}}, // j 1
{{25, 3}, {35, 0}, {46, 0}} // j 2
}},
{// face 12
{
// i 0
{{71, 0}, {89, 0}, {97, 3}}, // j 0
{{73, 0}, {91, 3}, {103, 3}}, // j 1
{{72, 3}, {88, 3}, {105, 3}} // j 2
},
{
// i 1
{{51, 0}, {69, 3}, {84, 3}}, // j 0
{{54, 0}, {71, 0}, {89, 0}}, // j 1
{{55, 3}, {73, 0}, {91, 3}} // j 2
},
{
// i 2
{{38, 0}, {47, 3}, {64, 3}}, // j 0
{{34, 3}, {51, 0}, {69, 3}}, // j 1
{{36, 3}, {54, 0}, {71, 0}} // j 2
}},
{// face 13
{
// i 0
{{96, 0}, {104, 0}, {107, 3}}, // j 0
{{98, 0}, {110, 3}, {115, 3}}, // j 1
{{97, 3}, {111, 3}, {119, 3}} // j 2
},
{
// i 1
{{76, 0}, {86, 3}, {94, 3}}, // j 0
{{82, 0}, {96, 0}, {104, 0}}, // j 1
{{84, 3}, {98, 0}, {110, 3}} // j 2
},
{
// i 2
{{58, 0}, {65, 3}, {75, 3}}, // j 0
{{62, 3}, {76, 0}, {86, 3}}, // j 1
{{64, 3}, {82, 0}, {96, 0}} // j 2
}},
{// face 14
{
// i 0
{{85, 0}, {87, 0}, {83, 3}}, // j 0
{{101, 0}, {102, 3}, {100, 3}}, // j 1
{{107, 3}, {112, 3}, {114, 3}} // j 2
},
{
// i 1
{{66, 0}, {67, 3}, {70, 3}}, // j 0
{{81, 0}, {85, 0}, {87, 0}}, // j 1
{{94, 3}, {101, 0}, {102, 3}} // j 2
},
{
// i 2
{{49, 0}, {48, 3}, {50, 3}}, // j 0
{{61, 3}, {66, 0}, {67, 3}}, // j 1
{{75, 3}, {81, 0}, {85, 0}} // j 2
}},
{// face 15
{
// i 0
{{95, 0}, {92, 0}, {83, 0}}, // j 0
{{79, 0}, {78, 0}, {74, 3}}, // j 1
{{63, 1}, {59, 3}, {57, 3}} // j 2
},
{
// i 1
{{109, 0}, {108, 0}, {100, 5}}, // j 0
{{93, 1}, {95, 0}, {92, 0}}, // j 1
{{77, 1}, {79, 0}, {78, 0}} // j 2
},
{
// i 2
{{117, 4}, {118, 5}, {114, 5}}, // j 0
{{106, 1}, {109, 0}, {108, 0}}, // j 1
{{90, 1}, {93, 1}, {95, 0}} // j 2
}},
{// face 16
{
// i 0
{{90, 0}, {77, 0}, {63, 0}}, // j 0
{{80, 0}, {68, 0}, {56, 3}}, // j 1
{{72, 1}, {60, 3}, {46, 3}} // j 2
},
{
// i 1
{{106, 0}, {93, 0}, {79, 5}}, // j 0
{{99, 1}, {90, 0}, {77, 0}}, // j 1
{{88, 1}, {80, 0}, {68, 0}} // j 2
},
{
// i 2
{{117, 3}, {109, 5}, {95, 5}}, // j 0
{{113, 1}, {106, 0}, {93, 0}}, // j 1
{{105, 1}, {99, 1}, {90, 0}} // j 2
}},
{// face 17
{
// i 0
{{105, 0}, {88, 0}, {72, 0}}, // j 0
{{103, 0}, {91, 0}, {73, 3}}, // j 1
{{97, 1}, {89, 3}, {71, 3}} // j 2
},
{
// i 1
{{113, 0}, {99, 0}, {80, 5}}, // j 0
{{116, 1}, {105, 0}, {88, 0}}, // j 1
{{111, 1}, {103, 0}, {91, 0}} // j 2
},
{
// i 2
{{117, 2}, {106, 5}, {90, 5}}, // j 0
{{121, 1}, {113, 0}, {99, 0}}, // j 1
{{119, 1}, {116, 1}, {105, 0}} // j 2
}},
{// face 18
{
// i 0
{{119, 0}, {111, 0}, {97, 0}}, // j 0
{{115, 0}, {110, 0}, {98, 3}}, // j 1
{{107, 1}, {104, 3}, {96, 3}} // j 2
},
{
// i 1
{{121, 0}, {116, 0}, {103, 5}}, // j 0
{{120, 1}, {119, 0}, {111, 0}}, // j 1
{{112, 1}, {115, 0}, {110, 0}} // j 2
},
{
// i 2
{{117, 1}, {113, 5}, {105, 5}}, // j 0
{{118, 1}, {121, 0}, {116, 0}}, // j 1
{{114, 1}, {120, 1}, {119, 0}} // j 2
}},
{// face 19
{
// i 0
{{114, 0}, {112, 0}, {107, 0}}, // j 0
{{100, 0}, {102, 0}, {101, 3}}, // j 1
{{83, 1}, {87, 3}, {85, 3}} // j 2
},
{
// i 1
{{118, 0}, {120, 0}, {115, 5}}, // j 0
{{108, 1}, {114, 0}, {112, 0}}, // j 1
{{92, 1}, {100, 0}, {102, 0}} // j 2
},
{
// i 2
{{117, 0}, {121, 5}, {119, 5}}, // j 0
{{109, 1}, {118, 0}, {120, 0}}, // j 1
{{95, 1}, {108, 1}, {114, 0}} // j 2
}}};
/** @brief Resolution 0 base cell data table.
*
* For each base cell, gives the "home" face and ijk+ coordinates on that face,
* whether or not the base cell is a pentagon. Additionally, if the base cell
* is a pentagon, the two cw offset rotation adjacent faces are given (-1
* indicates that no cw offset rotation faces exist for this base cell).
*/
const BaseCellData baseCellData[NUM_BASE_CELLS] = {
{{1, {1, 0, 0}}, 0, {0, 0}}, // base cell 0
{{2, {1, 1, 0}}, 0, {0, 0}}, // base cell 1
{{1, {0, 0, 0}}, 0, {0, 0}}, // base cell 2
{{2, {1, 0, 0}}, 0, {0, 0}}, // base cell 3
{{0, {2, 0, 0}}, 1, {-1, -1}}, // base cell 4
{{1, {1, 1, 0}}, 0, {0, 0}}, // base cell 5
{{1, {0, 0, 1}}, 0, {0, 0}}, // base cell 6
{{2, {0, 0, 0}}, 0, {0, 0}}, // base cell 7
{{0, {1, 0, 0}}, 0, {0, 0}}, // base cell 8
{{2, {0, 1, 0}}, 0, {0, 0}}, // base cell 9
{{1, {0, 1, 0}}, 0, {0, 0}}, // base cell 10
{{1, {0, 1, 1}}, 0, {0, 0}}, // base cell 11
{{3, {1, 0, 0}}, 0, {0, 0}}, // base cell 12
{{3, {1, 1, 0}}, 0, {0, 0}}, // base cell 13
{{11, {2, 0, 0}}, 1, {2, 6}}, // base cell 14
{{4, {1, 0, 0}}, 0, {0, 0}}, // base cell 15
{{0, {0, 0, 0}}, 0, {0, 0}}, // base cell 16
{{6, {0, 1, 0}}, 0, {0, 0}}, // base cell 17
{{0, {0, 0, 1}}, 0, {0, 0}}, // base cell 18
{{2, {0, 1, 1}}, 0, {0, 0}}, // base cell 19
{{7, {0, 0, 1}}, 0, {0, 0}}, // base cell 20
{{2, {0, 0, 1}}, 0, {0, 0}}, // base cell 21
{{0, {1, 1, 0}}, 0, {0, 0}}, // base cell 22
{{6, {0, 0, 1}}, 0, {0, 0}}, // base cell 23
{{10, {2, 0, 0}}, 1, {1, 5}}, // base cell 24
{{6, {0, 0, 0}}, 0, {0, 0}}, // base cell 25
{{3, {0, 0, 0}}, 0, {0, 0}}, // base cell 26
{{11, {1, 0, 0}}, 0, {0, 0}}, // base cell 27
{{4, {1, 1, 0}}, 0, {0, 0}}, // base cell 28
{{3, {0, 1, 0}}, 0, {0, 0}}, // base cell 29
{{0, {0, 1, 1}}, 0, {0, 0}}, // base cell 30
{{4, {0, 0, 0}}, 0, {0, 0}}, // base cell 31
{{5, {0, 1, 0}}, 0, {0, 0}}, // base cell 32
{{0, {0, 1, 0}}, 0, {0, 0}}, // base cell 33
{{7, {0, 1, 0}}, 0, {0, 0}}, // base cell 34
{{11, {1, 1, 0}}, 0, {0, 0}}, // base cell 35
{{7, {0, 0, 0}}, 0, {0, 0}}, // base cell 36
{{10, {1, 0, 0}}, 0, {0, 0}}, // base cell 37
{{12, {2, 0, 0}}, 1, {3, 7}}, // base cell 38
{{6, {1, 0, 1}}, 0, {0, 0}}, // base cell 39
{{7, {1, 0, 1}}, 0, {0, 0}}, // base cell 40
{{4, {0, 0, 1}}, 0, {0, 0}}, // base cell 41
{{3, {0, 0, 1}}, 0, {0, 0}}, // base cell 42
{{3, {0, 1, 1}}, 0, {0, 0}}, // base cell 43
{{4, {0, 1, 0}}, 0, {0, 0}}, // base cell 44
{{6, {1, 0, 0}}, 0, {0, 0}}, // base cell 45
{{11, {0, 0, 0}}, 0, {0, 0}}, // base cell 46
{{8, {0, 0, 1}}, 0, {0, 0}}, // base cell 47
{{5, {0, 0, 1}}, 0, {0, 0}}, // base cell 48
{{14, {2, 0, 0}}, 1, {0, 9}}, // base cell 49
{{5, {0, 0, 0}}, 0, {0, 0}}, // base cell 50
{{12, {1, 0, 0}}, 0, {0, 0}}, // base cell 51
{{10, {1, 1, 0}}, 0, {0, 0}}, // base cell 52
{{4, {0, 1, 1}}, 0, {0, 0}}, // base cell 53
{{12, {1, 1, 0}}, 0, {0, 0}}, // base cell 54
{{7, {1, 0, 0}}, 0, {0, 0}}, // base cell 55
{{11, {0, 1, 0}}, 0, {0, 0}}, // base cell 56
{{10, {0, 0, 0}}, 0, {0, 0}}, // base cell 57
{{13, {2, 0, 0}}, 1, {4, 8}}, // base cell 58
{{10, {0, 0, 1}}, 0, {0, 0}}, // base cell 59
{{11, {0, 0, 1}}, 0, {0, 0}}, // base cell 60
{{9, {0, 1, 0}}, 0, {0, 0}}, // base cell 61
{{8, {0, 1, 0}}, 0, {0, 0}}, // base cell 62
{{6, {2, 0, 0}}, 1, {11, 15}}, // base cell 63
{{8, {0, 0, 0}}, 0, {0, 0}}, // base cell 64
{{9, {0, 0, 1}}, 0, {0, 0}}, // base cell 65
{{14, {1, 0, 0}}, 0, {0, 0}}, // base cell 66
{{5, {1, 0, 1}}, 0, {0, 0}}, // base cell 67
{{16, {0, 1, 1}}, 0, {0, 0}}, // base cell 68
{{8, {1, 0, 1}}, 0, {0, 0}}, // base cell 69
{{5, {1, 0, 0}}, 0, {0, 0}}, // base cell 70
{{12, {0, 0, 0}}, 0, {0, 0}}, // base cell 71
{{7, {2, 0, 0}}, 1, {12, 16}}, // base cell 72
{{12, {0, 1, 0}}, 0, {0, 0}}, // base cell 73
{{10, {0, 1, 0}}, 0, {0, 0}}, // base cell 74
{{9, {0, 0, 0}}, 0, {0, 0}}, // base cell 75
{{13, {1, 0, 0}}, 0, {0, 0}}, // base cell 76
{{16, {0, 0, 1}}, 0, {0, 0}}, // base cell 77
{{15, {0, 1, 1}}, 0, {0, 0}}, // base cell 78
{{15, {0, 1, 0}}, 0, {0, 0}}, // base cell 79
{{16, {0, 1, 0}}, 0, {0, 0}}, // base cell 80
{{14, {1, 1, 0}}, 0, {0, 0}}, // base cell 81
{{13, {1, 1, 0}}, 0, {0, 0}}, // base cell 82
{{5, {2, 0, 0}}, 1, {10, 19}}, // base cell 83
{{8, {1, 0, 0}}, 0, {0, 0}}, // base cell 84
{{14, {0, 0, 0}}, 0, {0, 0}}, // base cell 85
{{9, {1, 0, 1}}, 0, {0, 0}}, // base cell 86
{{14, {0, 0, 1}}, 0, {0, 0}}, // base cell 87
{{17, {0, 0, 1}}, 0, {0, 0}}, // base cell 88
{{12, {0, 0, 1}}, 0, {0, 0}}, // base cell 89
{{16, {0, 0, 0}}, 0, {0, 0}}, // base cell 90
{{17, {0, 1, 1}}, 0, {0, 0}}, // base cell 91
{{15, {0, 0, 1}}, 0, {0, 0}}, // base cell 92
{{16, {1, 0, 1}}, 0, {0, 0}}, // base cell 93
{{9, {1, 0, 0}}, 0, {0, 0}}, // base cell 94
{{15, {0, 0, 0}}, 0, {0, 0}}, // base cell 95
{{13, {0, 0, 0}}, 0, {0, 0}}, // base cell 96
{{8, {2, 0, 0}}, 1, {13, 17}}, // base cell 97
{{13, {0, 1, 0}}, 0, {0, 0}}, // base cell 98
{{17, {1, 0, 1}}, 0, {0, 0}}, // base cell 99
{{19, {0, 1, 0}}, 0, {0, 0}}, // base cell 100
{{14, {0, 1, 0}}, 0, {0, 0}}, // base cell 101
{{19, {0, 1, 1}}, 0, {0, 0}}, // base cell 102
{{17, {0, 1, 0}}, 0, {0, 0}}, // base cell 103
{{13, {0, 0, 1}}, 0, {0, 0}}, // base cell 104
{{17, {0, 0, 0}}, 0, {0, 0}}, // base cell 105
{{16, {1, 0, 0}}, 0, {0, 0}}, // base cell 106
{{9, {2, 0, 0}}, 1, {14, 18}}, // base cell 107
{{15, {1, 0, 1}}, 0, {0, 0}}, // base cell 108
{{15, {1, 0, 0}}, 0, {0, 0}}, // base cell 109
{{18, {0, 1, 1}}, 0, {0, 0}}, // base cell 110
{{18, {0, 0, 1}}, 0, {0, 0}}, // base cell 111
{{19, {0, 0, 1}}, 0, {0, 0}}, // base cell 112
{{17, {1, 0, 0}}, 0, {0, 0}}, // base cell 113
{{19, {0, 0, 0}}, 0, {0, 0}}, // base cell 114
{{18, {0, 1, 0}}, 0, {0, 0}}, // base cell 115
{{18, {1, 0, 1}}, 0, {0, 0}}, // base cell 116
{{19, {2, 0, 0}}, 1, {-1, -1}}, // base cell 117
{{19, {1, 0, 0}}, 0, {0, 0}}, // base cell 118
{{18, {0, 0, 0}}, 0, {0, 0}}, // base cell 119
{{19, {1, 0, 1}}, 0, {0, 0}}, // base cell 120
{{18, {1, 0, 0}}, 0, {0, 0}} // base cell 121
};
/** @brief Return whether or not the indicated base cell is a pentagon. */
int _isBaseCellPentagon(int baseCell) {
if (baseCell < 0 || baseCell >= NUM_BASE_CELLS) {
// Base cells less than zero can not be represented in an index
return false;
}
return baseCellData[baseCell].isPentagon;
}
/** @brief Return whether the indicated base cell is a pentagon where all
* neighbors are oriented towards it. */
bool _isBaseCellPolarPentagon(int baseCell) {
return baseCell == 4 || baseCell == 117;
}
/** @brief Find base cell given FaceIJK.
*
* Given the face number and a resolution 0 ijk+ coordinate in that face's
* face-centered ijk coordinate system, return the base cell located at that
* coordinate.
*
* Valid ijk+ lookup coordinates are from (0, 0, 0) to (2, 2, 2).
*/
int _faceIjkToBaseCell(const FaceIJK *h) {
return faceIjkBaseCells[h->face][h->coord.i][h->coord.j][h->coord.k]
.baseCell;
}
/** @brief Find base cell given FaceIJK.
*
* Given the face number and a resolution 0 ijk+ coordinate in that face's
* face-centered ijk coordinate system, return the number of 60' ccw rotations
* to rotate into the coordinate system of the base cell at that coordinates.
*
* Valid ijk+ lookup coordinates are from (0, 0, 0) to (2, 2, 2).
*/
int _faceIjkToBaseCellCCWrot60(const FaceIJK *h) {
return faceIjkBaseCells[h->face][h->coord.i][h->coord.j][h->coord.k]
.ccwRot60;
}
/** @brief Find the FaceIJK given a base cell.
*/
void _baseCellToFaceIjk(int baseCell, FaceIJK *h) {
*h = baseCellData[baseCell].homeFijk;
}
/**
* @brief Given a base cell and the face it appears on, return
* the number of 60' ccw rotations for that base cell's
* coordinate system.
* @returns The number of rotations, or INVALID_ROTATIONS if the base
* cell is not found on the given face
*/
int _baseCellToCCWrot60(int baseCell, int face) {
if (face < 0 || face > NUM_ICOSA_FACES) return INVALID_ROTATIONS;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
if (faceIjkBaseCells[face][i][j][k].baseCell == baseCell) {
return faceIjkBaseCells[face][i][j][k].ccwRot60;
}
}
}
}
return INVALID_ROTATIONS;
}
/** @brief Return whether or not the tested face is a cw offset face.
*/
bool _baseCellIsCwOffset(int baseCell, int testFace) {
return baseCellData[baseCell].cwOffsetPent[0] == testFace ||
baseCellData[baseCell].cwOffsetPent[1] == testFace;
}
/** @brief Return the neighboring base cell in the given direction.
*/
int _getBaseCellNeighbor(int baseCell, Direction dir) {
return baseCellNeighbors[baseCell][dir];
}
/** @brief Return the direction from the origin base cell to the neighbor.
* Returns INVALID_DIGIT if the base cells are not neighbors.
*/
Direction _getBaseCellDirection(int originBaseCell, int neighboringBaseCell) {
for (Direction dir = CENTER_DIGIT; dir < NUM_DIGITS; dir++) {
int testBaseCell = _getBaseCellNeighbor(originBaseCell, dir);
if (testBaseCell == neighboringBaseCell) {
return dir;
}
}
return INVALID_DIGIT;
}
/**
* res0CellCount returns the number of resolution 0 cells
*
* @return int count of resolution 0 cells
*/
int H3_EXPORT(res0CellCount)(void) { return NUM_BASE_CELLS; }
/**
* getRes0Cells generates all base cells storing them into the provided
* memory pointer. Buffer must be of size NUM_BASE_CELLS * sizeof(H3Index).
*
* @param out H3Index* the memory to store the resulting base cells in
* @returns E_SUCCESS.
*/
H3Error H3_EXPORT(getRes0Cells)(H3Index *out) {
for (int bc = 0; bc < NUM_BASE_CELLS; bc++) {
H3Index baseCell = H3_INIT;
H3_SET_MODE(baseCell, H3_CELL_MODE);
H3_SET_BASE_CELL(baseCell, bc);
out[bc] = baseCell;
}
return E_SUCCESS;
}