in src/apps/miscapps/generateBaseCellNeighbors.c [84:251]
static void generate() {
int baseCellNeighbors[NUM_BASE_CELLS][7];
int baseCellRotations[NUM_BASE_CELLS][7];
for (int i = 0; i < NUM_BASE_CELLS; i++) {
if (!_isBaseCellPentagon(i)) {
for (int dir = CENTER_DIGIT; dir <= NUM_DIRS; dir++) {
FaceIJK fijk;
_baseCellToFaceIjk(i, &fijk);
_neighbor(&fijk.coord, dir);
// Should never happen, but just in case :)
if (fijk.coord.i < 3 && fijk.coord.j < 3 && fijk.coord.k < 3) {
baseCellNeighbors[i][dir] = _faceIjkToBaseCell(&fijk);
baseCellRotations[i][dir] =
_faceIjkToBaseCellCCWrot60(&fijk);
} else {
printf("UH OH: Went out of bounds\n");
}
}
} else {
baseCellNeighbors[i][0] = i;
baseCellRotations[i][0] = 0;
for (int dir = 1; dir <= NUM_DIRS; dir++) {
baseCellNeighbors[i][dir] = INVALID_BASE_CELL;
baseCellRotations[i][dir] = -1;
}
for (int f = 0; f < NUM_ICOSA_FACES; f++) {
for (int axis = 0; axis < 3; axis++) {
FaceIJK fijk = {f, {0, 0, 0}};
switch (axis) {
case 0:
fijk.coord.k = 2;
break;
case 1:
fijk.coord.j = 2;
break;
case 2:
fijk.coord.i = 2;
break;
}
// Determine if we found a face that can traverse to the
// pentagon
if (_faceIjkToBaseCell(&fijk) == i) {
// fijk of the neighboring base cell
FaceIJK neighborFijk = {
fijk.face,
{fijk.coord.i / 2, fijk.coord.j / 2,
fijk.coord.k / 2}};
// number of rotations from the neighboring base cell
// into the pentagon
int rotations = _faceIjkToBaseCellCCWrot60(&fijk);
// direction from the neighboring base cell to the
// pentagon
CoordIJK ijk = neighborFijk.coord;
// turn that into the direction within the pentagon
// (direction for continuing straight inside the
// pentagon)
for (int currRot = 0; currRot < rotations; currRot++) {
_ijkRotate60ccw(&ijk);
}
// invert that
for (int currRot = 0; currRot < 3; currRot++) {
_ijkRotate60ccw(&ijk);
}
// direction from the pentagon towards the neighboring
// base cell
Direction dir = _unitIjkToDigit(&ijk);
// the direction was detected as being the i direction,
// but this can't be because i is deleted from the
// pentagon. We need to choose a different direction.
if (dir == K_AXES_DIGIT) {
// 4 and 117 are 'polar' type pentagons, which have
// some different behavior.
if (_isBaseCellPentagon(i)) {
_ijkRotate60cw(&ijk);
_ijkRotate60cw(&ijk);
} else {
_ijkRotate60ccw(&ijk);
}
dir = _unitIjkToDigit(&ijk);
}
// Adjust for the deleted k-subsequence distortion
int rotAdj = 0;
if (_isBaseCellPolarPentagon(i)) {
// 'polar' type pentagon with all faces pointing
// towards i
if (dir == IK_AXES_DIGIT) {
rotAdj = 2;
} else if (dir == IJ_AXES_DIGIT) {
rotAdj = 4;
}
} else {
// the deleted k subsequence causes 4 and 5 to
// 'warp', need to adjust for that.
if (dir == I_AXES_DIGIT || dir == IK_AXES_DIGIT) {
rotAdj = dir;
}
}
rotations = (rotations + rotAdj) % 6;
int neighborBc = _faceIjkToBaseCell(&neighborFijk);
// The poles are totally different, although the
// rotations are correctly generated, so only overwrite
// the neighbor information. It was easier to manually
// derive the neighbors than to write the generation
// program.
if (i == 4) {
int realNeighbors[] = {
4, INVALID_BASE_CELL, 15, 8, 3, 0, 12};
neighborBc = realNeighbors[dir];
} else if (i == 117) {
int realNeighbors[] = {
117, INVALID_BASE_CELL, 109, 118, 113, 121,
106};
neighborBc = realNeighbors[dir];
}
// the actual neighboring base cell
baseCellNeighbors[i][dir] = neighborBc;
// rotations from the pentagon into the neighboring base
// cell
baseCellRotations[i][dir] = rotations;
}
}
}
}
}
auditBaseCellNeighbors(baseCellNeighbors, baseCellRotations);
printf("const int baseCellNeighbors[NUM_BASE_CELLS][7] = {\n");
for (int i = 0; i < NUM_BASE_CELLS; i++) {
printf(" {");
for (int j = 0; j < 7; j++) {
if (j > 0) {
printf(", ");
}
if (baseCellNeighbors[i][j] != INVALID_BASE_CELL) {
printf("%d", baseCellNeighbors[i][j]);
} else {
printf("INVALID_BASE_CELL");
}
}
printf("}, // base cell %d%s\n", i,
_isBaseCellPentagon(i) ? " (pentagon)" : "");
}
printf("};\n");
printf("\n");
printf("const int baseCellNeighbor60CCWRots[NUM_BASE_CELLS][7] = {\n");
for (int i = 0; i < NUM_BASE_CELLS; i++) {
printf(" {%d, %d, %d, %d, %d, %d, %d}, // base cell %d%s\n",
baseCellRotations[i][0], baseCellRotations[i][1],
baseCellRotations[i][2], baseCellRotations[i][3],
baseCellRotations[i][4], baseCellRotations[i][5],
baseCellRotations[i][6], i,
_isBaseCellPentagon(i) ? " (pentagon)" : "");
}
printf("};\n");
}