#include #include #include #include #define NDIMS 3 #define ARCSEGS45 2 /* # segs for a 45° arc */ #define ARCSCALE .1 #define ROOT2 .707106781186547524400844362104849039284835937688474036588339869 /* 8-bit binary values give octant fill maps. Order is --- +-- -+- ++- --+ +-+ -++ +++. */ typedef enum { /* not yet set */ JK_UNSET = 1, /* empty or full space, 00000000 or 11111111 */ JK_NIL, /* corner, 10000000 */ JK_CORNER, /* edge, 11000000 */ JK_EDGE, /* two corners sharing an edge, 10010000 */ JK_TWOCORNER_EDGE, /* elbow corner, 11100000 */ JK_ELBOW, /* flat surface, 11110000 */ JK_FLAT, /* three corners mutually edge-touching, 10010100 */ JK_THREECORNER, /* Soma piece 7, 11101000 */ JK_SOMA7, /* two corners touching point-on, 10000001 */ JK_TWOCORNER_POINT, /* edge with corner edge-touching half of it, 11000010 */ JK_EDGE_CORNER, /* Soma piece 5 (or 6), 11100100 */ JK_SOMA56_A, /* Soma piece 6 (or 5), 11100010 */ JK_SOMA56_B, /* corner edge-touching with elbow, 11100001 */ JK_EBLOW_CORNER, /* edge dead-ending at flat surface, 11111000 */ JK_EDGE_FLAT, /* two edges edge-touching, 11000011 */ JK_DUAL_EDGE, /* diagonal bridge complex corner, 11100110 */ JK_BRIDGE, /* concave edge, 11111100 */ JK_CONCAVE, /* checkerboard of corners 10010110 */ JK_CHECKERBOARD, /* Soma piece 7 with fill-in corner, 11101001 */ JK_SOMA7_FILL, /* two edge-touching edges dead-ending at flat surface, 11111001 */ JK_DUAL_EDGE_FLAT, /* diagonally-opposite corners missing, 11100111 */ JK_DUAL_VOID, /* single void, 11111110 */ JK_VOID } JCTKIND; typedef enum { ROT_NONE = 1, ROT_012345, ROT_014532, ROT_542301, ROT_231045, ROT_234501, ROT_541023, ROT_103245, ROT_540132, ROT_102354, ROT_013254, ROT_451032, ROT_453201, ROT_105432, ROT_015423, ROT_321054, ROT_452310, ROT_230154, ROT_543210, ROT_104523, ROT_320145, ROT_324510, ROT_450123, ROT_235410, ROT_325401 } ROT; #define ROT__N (1+(int)ROT_325401) typedef enum { PK_CORNER = 1, PK_SURFACE } PTKIND; #define ARCSEGS (ARCSEGS45 + ARCSEGS45) typedef struct xyi XYI; typedef struct xyf XYF; typedef struct xyzi XYZI; typedef struct xyzf XYZF; typedef struct tri TRI; typedef struct loc LOC; typedef struct pt PT; typedef struct cell CELL; typedef struct jct JCT; typedef struct syndrome SYNDROME; struct xyi { int x; int y; } ; struct xyf { double x; double y; } ; struct xyzi { int x; int y; int z; } ; struct xyzf { double x; double y; double z; } ; struct loc { LOC *link; XYZF p; int n; } ; struct pt { PT *link; LOC *l; PTKIND kind; XYZF sn; int n; } ; struct tri { TRI *link; PT *a; PT *b; PT *c; int n; } ; struct syndrome { JCTKIND kind; ROT rot; } ; struct jct { SYNDROME *syn; JCT *link[3][2]; } ; struct cell { char filled; unsigned char x; unsigned char y; unsigned char z; JCT j; } ; #define XHP ((XYZI){1,0,0}) #define YHP ((XYZI){0,1,0}) #define ZHP ((XYZI){0,0,1}) #define XHN ((XYZI){-1,0,0}) #define YHN ((XYZI){0,-1,0}) #define ZHN ((XYZI){0,0,-1}) /* while read a b; do echo $b | rotate | sed -e 's/\(.*\) \(.*\)/ ab \1 ba { '$a', ROT_\2 },/' | tr ab /\* done << EOF JK_CORNER 10000000 JK_EDGE 11000000 JK_TWOCORNER_EDGE 10010000 JK_ELBOW 11100000 JK_FLAT 11110000 JK_THREECORNER 10010100 JK_SOMA7 11101000 JK_TWOCORNER_POINT 10000001 JK_EDGE_CORNER 11000010 JK_SOMA56_A 11100100 JK_SOMA56_B 11100010 JK_EBLOW_CORNER 11100001 JK_EDGE_FLAT 11111000 JK_DUAL_EDGE 11000011 JK_BRIDGE 11100110 JK_CONCAVE 11111100 JK_CHECKERBOARD 10010110 JK_SOMA7_FILL 11101001 JK_DUAL_EDGE_FLAT 11111001 JK_DUAL_VOID 11100111 JK_VOID 11111110 */ static SYNDROME syndrome[256] = { /* 00000000 */ { JK_NIL, ROT_012345 }, /* 00000001 */ { JK_CORNER, ROT_105432 }, /* 00000010 */ { JK_CORNER, ROT_235410 }, /* 00000011 */ { JK_EDGE, ROT_013254 }, /* 00000100 */ { JK_CORNER, ROT_102354 }, /* 00000101 */ { JK_EDGE, ROT_540132 }, /* 00000110 */ { JK_TWOCORNER_EDGE, ROT_013254 }, /* 00000111 */ { JK_ELBOW, ROT_321054 }, /* 00001000 */ { JK_CORNER, ROT_452310 }, /* 00001001 */ { JK_TWOCORNER_EDGE, ROT_230154 }, /* 00001010 */ { JK_EDGE, ROT_230154 }, /* 00001011 */ { JK_ELBOW, ROT_013254 }, /* 00001100 */ { JK_EDGE, ROT_014532 }, /* 00001101 */ { JK_ELBOW, ROT_102354 }, /* 00001110 */ { JK_ELBOW, ROT_230154 }, /* 00001111 */ { JK_FLAT, ROT_230154 }, /* 00010000 */ { JK_CORNER, ROT_325401 }, /* 00010001 */ { JK_EDGE, ROT_543210 }, /* 00010010 */ { JK_TWOCORNER_EDGE, ROT_235410 }, /* 00010011 */ { JK_ELBOW, ROT_105432 }, /* 00010100 */ { JK_TWOCORNER_EDGE, ROT_540132 }, /* 00010101 */ { JK_ELBOW, ROT_543210 }, /* 00010110 */ { JK_THREECORNER, ROT_540132 }, /* 00010111 */ { JK_SOMA7, ROT_105432 }, /* 00011000 */ { JK_TWOCORNER_POINT, ROT_452310 }, /* 00011001 */ { JK_EDGE_CORNER, ROT_543210 }, /* 00011010 */ { JK_EDGE_CORNER, ROT_451032 }, /* 00011011 */ { JK_SOMA56_A, ROT_013254 }, /* 00011100 */ { JK_EDGE_CORNER, ROT_102354 }, /* 00011101 */ { JK_SOMA56_B, ROT_102354 }, /* 00011110 */ { JK_EBLOW_CORNER, ROT_230154 }, /* 00011111 */ { JK_EDGE_FLAT, ROT_321054 }, /* 00100000 */ { JK_CORNER, ROT_015423 }, /* 00100001 */ { JK_TWOCORNER_EDGE, ROT_015423 }, /* 00100010 */ { JK_EDGE, ROT_235410 }, /* 00100011 */ { JK_ELBOW, ROT_235410 }, /* 00100100 */ { JK_TWOCORNER_POINT, ROT_015423 }, /* 00100101 */ { JK_EDGE_CORNER, ROT_321054 }, /* 00100110 */ { JK_EDGE_CORNER, ROT_235410 }, /* 00100111 */ { JK_SOMA56_B, ROT_235410 }, /* 00101000 */ { JK_TWOCORNER_EDGE, ROT_452310 }, /* 00101001 */ { JK_THREECORNER, ROT_230154 }, /* 00101010 */ { JK_ELBOW, ROT_451032 }, /* 00101011 */ { JK_SOMA7, ROT_235410 }, /* 00101100 */ { JK_EDGE_CORNER, ROT_014532 }, /* 00101101 */ { JK_EBLOW_CORNER, ROT_102354 }, /* 00101110 */ { JK_SOMA56_A, ROT_230154 }, /* 00101111 */ { JK_EDGE_FLAT, ROT_013254 }, /* 00110000 */ { JK_EDGE, ROT_015423 }, /* 00110001 */ { JK_ELBOW, ROT_325401 }, /* 00110010 */ { JK_ELBOW, ROT_015423 }, /* 00110011 */ { JK_FLAT, ROT_235410 }, /* 00110100 */ { JK_EDGE_CORNER, ROT_103245 }, /* 00110101 */ { JK_SOMA56_A, ROT_543210 }, /* 00110110 */ { JK_EBLOW_CORNER, ROT_015423 }, /* 00110111 */ { JK_EDGE_FLAT, ROT_105432 }, /* 00111000 */ { JK_EDGE_CORNER, ROT_015423 }, /* 00111001 */ { JK_EBLOW_CORNER, ROT_325401 }, /* 00111010 */ { JK_SOMA56_B, ROT_015423 }, /* 00111011 */ { JK_EDGE_FLAT, ROT_235410 }, /* 00111100 */ { JK_DUAL_EDGE, ROT_015423 }, /* 00111101 */ { JK_BRIDGE, ROT_543210 }, /* 00111110 */ { JK_BRIDGE, ROT_451032 }, /* 00111111 */ { JK_CONCAVE, ROT_013254 }, /* 01000000 */ { JK_CORNER, ROT_320145 }, /* 01000001 */ { JK_TWOCORNER_EDGE, ROT_543210 }, /* 01000010 */ { JK_TWOCORNER_POINT, ROT_320145 }, /* 01000011 */ { JK_EDGE_CORNER, ROT_105432 }, /* 01000100 */ { JK_EDGE, ROT_324510 }, /* 01000101 */ { JK_ELBOW, ROT_540132 }, /* 01000110 */ { JK_EDGE_CORNER, ROT_324510 }, /* 01000111 */ { JK_SOMA56_A, ROT_540132 }, /* 01001000 */ { JK_TWOCORNER_EDGE, ROT_014532 }, /* 01001001 */ { JK_THREECORNER, ROT_542301 }, /* 01001010 */ { JK_EDGE_CORNER, ROT_230154 }, /* 01001011 */ { JK_EBLOW_CORNER, ROT_013254 }, /* 01001100 */ { JK_ELBOW, ROT_324510 }, /* 01001101 */ { JK_SOMA7, ROT_102354 }, /* 01001110 */ { JK_SOMA56_B, ROT_230154 }, /* 01001111 */ { JK_EDGE_FLAT, ROT_102354 }, /* 01010000 */ { JK_EDGE, ROT_320145 }, /* 01010001 */ { JK_ELBOW, ROT_541023 }, /* 01010010 */ { JK_EDGE_CORNER, ROT_541023 }, /* 01010011 */ { JK_SOMA56_B, ROT_105432 }, /* 01010100 */ { JK_ELBOW, ROT_542301 }, /* 01010101 */ { JK_FLAT, ROT_540132 }, /* 01010110 */ { JK_EBLOW_CORNER, ROT_542301 }, /* 01010111 */ { JK_EDGE_FLAT, ROT_543210 }, /* 01011000 */ { JK_EDGE_CORNER, ROT_320145 }, /* 01011001 */ { JK_EBLOW_CORNER, ROT_541023 }, /* 01011010 */ { JK_DUAL_EDGE, ROT_320145 }, /* 01011011 */ { JK_BRIDGE, ROT_105432 }, /* 01011100 */ { JK_SOMA56_A, ROT_324510 }, /* 01011101 */ { JK_EDGE_FLAT, ROT_540132 }, /* 01011110 */ { JK_BRIDGE, ROT_324510 }, /* 01011111 */ { JK_CONCAVE, ROT_540132 }, /* 01100000 */ { JK_TWOCORNER_EDGE, ROT_320145 }, /* 01100001 */ { JK_THREECORNER, ROT_320145 }, /* 01100010 */ { JK_EDGE_CORNER, ROT_453201 }, /* 01100011 */ { JK_EBLOW_CORNER, ROT_235410 }, /* 01100100 */ { JK_EDGE_CORNER, ROT_542301 }, /* 01100101 */ { JK_EBLOW_CORNER, ROT_540132 }, /* 01100110 */ { JK_DUAL_EDGE, ROT_235410 }, /* 01100111 */ { JK_BRIDGE, ROT_321054 }, /* 01101000 */ { JK_THREECORNER, ROT_452310 }, /* 01101001 */ { JK_CHECKERBOARD, ROT_320145 }, /* 01101010 */ { JK_EBLOW_CORNER, ROT_451032 }, /* 01101011 */ { JK_SOMA7_FILL, ROT_235410 }, /* 01101100 */ { JK_EBLOW_CORNER, ROT_324510 }, /* 01101101 */ { JK_SOMA7_FILL, ROT_102354 }, /* 01101110 */ { JK_BRIDGE, ROT_230154 }, /* 01101111 */ { JK_DUAL_EDGE_FLAT, ROT_013254 }, /* 01110000 */ { JK_ELBOW, ROT_103245 }, /* 01110001 */ { JK_SOMA7, ROT_325401 }, /* 01110010 */ { JK_SOMA56_A, ROT_015423 }, /* 01110011 */ { JK_EDGE_FLAT, ROT_325401 }, /* 01110100 */ { JK_SOMA56_B, ROT_542301 }, /* 01110101 */ { JK_EDGE_FLAT, ROT_541023 }, /* 01110110 */ { JK_BRIDGE, ROT_103245 }, /* 01110111 */ { JK_CONCAVE, ROT_543210 }, /* 01111000 */ { JK_EBLOW_CORNER, ROT_103245 }, /* 01111001 */ { JK_SOMA7_FILL, ROT_325401 }, /* 01111010 */ { JK_BRIDGE, ROT_015423 }, /* 01111011 */ { JK_DUAL_EDGE_FLAT, ROT_235410 }, /* 01111100 */ { JK_BRIDGE, ROT_542301 }, /* 01111101 */ { JK_DUAL_EDGE_FLAT, ROT_540132 }, /* 01111110 */ { JK_DUAL_VOID, ROT_015423 }, /* 01111111 */ { JK_VOID, ROT_105432 }, /* 10000000 */ { JK_CORNER, ROT_012345 }, /* 10000001 */ { JK_TWOCORNER_POINT, ROT_012345 }, /* 10000010 */ { JK_TWOCORNER_EDGE, ROT_450123 }, /* 10000011 */ { JK_EDGE_CORNER, ROT_013254 }, /* 10000100 */ { JK_TWOCORNER_EDGE, ROT_324510 }, /* 10000101 */ { JK_EDGE_CORNER, ROT_540132 }, /* 10000110 */ { JK_THREECORNER, ROT_102354 }, /* 10000111 */ { JK_EBLOW_CORNER, ROT_321054 }, /* 10001000 */ { JK_EDGE, ROT_452310 }, /* 10001001 */ { JK_EDGE_CORNER, ROT_452310 }, /* 10001010 */ { JK_ELBOW, ROT_452310 }, /* 10001011 */ { JK_SOMA56_B, ROT_452310 }, /* 10001100 */ { JK_ELBOW, ROT_014532 }, /* 10001101 */ { JK_SOMA56_A, ROT_014532 }, /* 10001110 */ { JK_SOMA7, ROT_452310 }, /* 10001111 */ { JK_EDGE_FLAT, ROT_230154 }, /* 10010000 */ { JK_TWOCORNER_EDGE, ROT_012345 }, /* 10010001 */ { JK_EDGE_CORNER, ROT_325401 }, /* 10010010 */ { JK_THREECORNER, ROT_450123 }, /* 10010011 */ { JK_EBLOW_CORNER, ROT_105432 }, /* 10010100 */ { JK_THREECORNER, ROT_012345 }, /* 10010101 */ { JK_EBLOW_CORNER, ROT_543210 }, /* 10010110 */ { JK_CHECKERBOARD, ROT_012345 }, /* 10010111 */ { JK_SOMA7_FILL, ROT_105432 }, /* 10011000 */ { JK_EDGE_CORNER, ROT_234501 }, /* 10011001 */ { JK_DUAL_EDGE, ROT_452310 }, /* 10011010 */ { JK_EBLOW_CORNER, ROT_452310 }, /* 10011011 */ { JK_BRIDGE, ROT_013254 }, /* 10011100 */ { JK_EBLOW_CORNER, ROT_014532 }, /* 10011101 */ { JK_BRIDGE, ROT_102354 }, /* 10011110 */ { JK_SOMA7_FILL, ROT_452310 }, /* 10011111 */ { JK_DUAL_EDGE_FLAT, ROT_230154 }, /* 10100000 */ { JK_EDGE, ROT_450123 }, /* 10100001 */ { JK_EDGE_CORNER, ROT_231045 }, /* 10100010 */ { JK_ELBOW, ROT_453201 }, /* 10100011 */ { JK_SOMA56_A, ROT_235410 }, /* 10100100 */ { JK_EDGE_CORNER, ROT_450123 }, /* 10100101 */ { JK_DUAL_EDGE, ROT_450123 }, /* 10100110 */ { JK_EBLOW_CORNER, ROT_453201 }, /* 10100111 */ { JK_BRIDGE, ROT_235410 }, /* 10101000 */ { JK_ELBOW, ROT_450123 }, /* 10101001 */ { JK_EBLOW_CORNER, ROT_450123 }, /* 10101010 */ { JK_FLAT, ROT_450123 }, /* 10101011 */ { JK_EDGE_FLAT, ROT_451032 }, /* 10101100 */ { JK_SOMA56_B, ROT_450123 }, /* 10101101 */ { JK_BRIDGE, ROT_014532 }, /* 10101110 */ { JK_EDGE_FLAT, ROT_452310 }, /* 10101111 */ { JK_CONCAVE, ROT_230154 }, /* 10110000 */ { JK_ELBOW, ROT_231045 }, /* 10110001 */ { JK_SOMA56_B, ROT_325401 }, /* 10110010 */ { JK_SOMA7, ROT_015423 }, /* 10110011 */ { JK_EDGE_FLAT, ROT_015423 }, /* 10110100 */ { JK_EBLOW_CORNER, ROT_231045 }, /* 10110101 */ { JK_BRIDGE, ROT_325401 }, /* 10110110 */ { JK_SOMA7_FILL, ROT_015423 }, /* 10110111 */ { JK_DUAL_EDGE_FLAT, ROT_015423 }, /* 10111000 */ { JK_SOMA56_A, ROT_450123 }, /* 10111001 */ { JK_BRIDGE, ROT_231045 }, /* 10111010 */ { JK_EDGE_FLAT, ROT_453201 }, /* 10111011 */ { JK_CONCAVE, ROT_235410 }, /* 10111100 */ { JK_BRIDGE, ROT_450123 }, /* 10111101 */ { JK_DUAL_VOID, ROT_450123 }, /* 10111110 */ { JK_DUAL_EDGE_FLAT, ROT_452310 }, /* 10111111 */ { JK_VOID, ROT_235410 }, /* 11000000 */ { JK_EDGE, ROT_012345 }, /* 11000001 */ { JK_EDGE_CORNER, ROT_104523 }, /* 11000010 */ { JK_EDGE_CORNER, ROT_012345 }, /* 11000011 */ { JK_DUAL_EDGE, ROT_012345 }, /* 11000100 */ { JK_ELBOW, ROT_104523 }, /* 11000101 */ { JK_SOMA56_B, ROT_540132 }, /* 11000110 */ { JK_EBLOW_CORNER, ROT_104523 }, /* 11000111 */ { JK_BRIDGE, ROT_540132 }, /* 11001000 */ { JK_ELBOW, ROT_234501 }, /* 11001001 */ { JK_EBLOW_CORNER, ROT_234501 }, /* 11001010 */ { JK_SOMA56_A, ROT_452310 }, /* 11001011 */ { JK_BRIDGE, ROT_452310 }, /* 11001100 */ { JK_FLAT, ROT_324510 }, /* 11001101 */ { JK_EDGE_FLAT, ROT_324510 }, /* 11001110 */ { JK_EDGE_FLAT, ROT_014532 }, /* 11001111 */ { JK_CONCAVE, ROT_014532 }, /* 11010000 */ { JK_ELBOW, ROT_320145 }, /* 11010001 */ { JK_SOMA56_A, ROT_320145 }, /* 11010010 */ { JK_EBLOW_CORNER, ROT_320145 }, /* 11010011 */ { JK_BRIDGE, ROT_541023 }, /* 11010100 */ { JK_SOMA7, ROT_320145 }, /* 11010101 */ { JK_EDGE_FLAT, ROT_542301 }, /* 11010110 */ { JK_SOMA7_FILL, ROT_320145 }, /* 11010111 */ { JK_DUAL_EDGE_FLAT, ROT_543210 }, /* 11011000 */ { JK_SOMA56_B, ROT_320145 }, /* 11011001 */ { JK_BRIDGE, ROT_320145 }, /* 11011010 */ { JK_BRIDGE, ROT_234501 }, /* 11011011 */ { JK_DUAL_VOID, ROT_320145 }, /* 11011100 */ { JK_EDGE_FLAT, ROT_104523 }, /* 11011101 */ { JK_CONCAVE, ROT_324510 }, /* 11011110 */ { JK_DUAL_EDGE_FLAT, ROT_014532 }, /* 11011111 */ { JK_VOID, ROT_102354 }, /* 11100000 */ { JK_ELBOW, ROT_012345 }, /* 11100001 */ { JK_EBLOW_CORNER, ROT_012345 }, /* 11100010 */ { JK_SOMA56_B, ROT_012345 }, /* 11100011 */ { JK_BRIDGE, ROT_453201 }, /* 11100100 */ { JK_SOMA56_A, ROT_012345 }, /* 11100101 */ { JK_BRIDGE, ROT_104523 }, /* 11100110 */ { JK_BRIDGE, ROT_012345 }, /* 11100111 */ { JK_DUAL_VOID, ROT_012345 }, /* 11101000 */ { JK_SOMA7, ROT_012345 }, /* 11101001 */ { JK_SOMA7_FILL, ROT_012345 }, /* 11101010 */ { JK_EDGE_FLAT, ROT_450123 }, /* 11101011 */ { JK_DUAL_EDGE_FLAT, ROT_450123 }, /* 11101100 */ { JK_EDGE_FLAT, ROT_234501 }, /* 11101101 */ { JK_DUAL_EDGE_FLAT, ROT_324510 }, /* 11101110 */ { JK_CONCAVE, ROT_452310 }, /* 11101111 */ { JK_VOID, ROT_452310 }, /* 11110000 */ { JK_FLAT, ROT_320145 }, /* 11110001 */ { JK_EDGE_FLAT, ROT_103245 }, /* 11110010 */ { JK_EDGE_FLAT, ROT_231045 }, /* 11110011 */ { JK_CONCAVE, ROT_015423 }, /* 11110100 */ { JK_EDGE_FLAT, ROT_320145 }, /* 11110101 */ { JK_CONCAVE, ROT_320145 }, /* 11110110 */ { JK_DUAL_EDGE_FLAT, ROT_320145 }, /* 11110111 */ { JK_VOID, ROT_325401 }, /* 11111000 */ { JK_EDGE_FLAT, ROT_012345 }, /* 11111001 */ { JK_DUAL_EDGE_FLAT, ROT_012345 }, /* 11111010 */ { JK_CONCAVE, ROT_450123 }, /* 11111011 */ { JK_VOID, ROT_015423 }, /* 11111100 */ { JK_CONCAVE, ROT_012345 }, /* 11111101 */ { JK_VOID, ROT_320145 }, /* 11111110 */ { JK_VOID, ROT_012345 }, /* 11111111 */ { JK_NIL, ROT_012345 } }; #if 0 static ROT inverse[] = { [ROT_012345] = ROT_012345, [ROT_014532] = ROT_015423, [ROT_542301] = ROT_452310, [ROT_231045] = ROT_320145, [ROT_234501] = ROT_450123, [ROT_541023] = ROT_324510, [ROT_103245] = ROT_103245, [ROT_540132] = ROT_235410, [ROT_102354] = ROT_102354, [ROT_013254] = ROT_013254, [ROT_451032] = ROT_325401, [ROT_453201] = ROT_453201, [ROT_105432] = ROT_105432, [ROT_015423] = ROT_014532, [ROT_321054] = ROT_321054, [ROT_452310] = ROT_542301, [ROT_230154] = ROT_230154, [ROT_543210] = ROT_543210, [ROT_104523] = ROT_104523, [ROT_320145] = ROT_231045, [ROT_324510] = ROT_541023, [ROT_450123] = ROT_234501, [ROT_235410] = ROT_540132, [ROT_325401] = ROT_451032 }; #endif #if 0 /* compose[a][b] corresponds to doing a then b */ static ROT compose[ROT__N][ROT__N] = { [ROT_012345] = { [ROT_012345] = ROT_012345, [ROT_014532] = ROT_014532, [ROT_542301] = ROT_542301, [ROT_231045] = ROT_231045, [ROT_234501] = ROT_234501, [ROT_541023] = ROT_541023, [ROT_103245] = ROT_103245, [ROT_540132] = ROT_540132, [ROT_102354] = ROT_102354, [ROT_013254] = ROT_013254, [ROT_451032] = ROT_451032, [ROT_453201] = ROT_453201, [ROT_105432] = ROT_105432, [ROT_015423] = ROT_015423, [ROT_321054] = ROT_321054, [ROT_452310] = ROT_452310, [ROT_230154] = ROT_230154, [ROT_543210] = ROT_543210, [ROT_104523] = ROT_104523, [ROT_320145] = ROT_320145, [ROT_324510] = ROT_324510, [ROT_450123] = ROT_450123, [ROT_235410] = ROT_235410, [ROT_325401] = ROT_325401 }, [ROT_014532] = { [ROT_012345] = ROT_014532, [ROT_014532] = ROT_013254, [ROT_542301] = ROT_234501, [ROT_231045] = ROT_451032, [ROT_234501] = ROT_453201, [ROT_541023] = ROT_231045, [ROT_103245] = ROT_105432, [ROT_540132] = ROT_230154, [ROT_102354] = ROT_104523, [ROT_013254] = ROT_015423, [ROT_451032] = ROT_321054, [ROT_453201] = ROT_325401, [ROT_105432] = ROT_102354, [ROT_015423] = ROT_012345, [ROT_321054] = ROT_541023, [ROT_452310] = ROT_324510, [ROT_230154] = ROT_450123, [ROT_543210] = ROT_235410, [ROT_104523] = ROT_103245, [ROT_320145] = ROT_540132, [ROT_324510] = ROT_543210, [ROT_450123] = ROT_320145, [ROT_235410] = ROT_452310, [ROT_325401] = ROT_542301 }, [ROT_542301] = { [ROT_012345] = ROT_542301, [ROT_014532] = ROT_540132, [ROT_542301] = ROT_102354, [ROT_231045] = ROT_234501, [ROT_234501] = ROT_230154, [ROT_541023] = ROT_104523, [ROT_103245] = ROT_453201, [ROT_540132] = ROT_105432, [ROT_102354] = ROT_452310, [ROT_013254] = ROT_543210, [ROT_451032] = ROT_014532, [ROT_453201] = ROT_013254, [ROT_105432] = ROT_451032, [ROT_015423] = ROT_541023, [ROT_321054] = ROT_324510, [ROT_452310] = ROT_012345, [ROT_230154] = ROT_235410, [ROT_543210] = ROT_103245, [ROT_104523] = ROT_450123, [ROT_320145] = ROT_325401, [ROT_324510] = ROT_320145, [ROT_450123] = ROT_015423, [ROT_235410] = ROT_231045, [ROT_325401] = ROT_321054 }, [ROT_231045] = { [ROT_012345] = ROT_231045, [ROT_014532] = ROT_234501, [ROT_542301] = ROT_541023, [ROT_231045] = ROT_103245, [ROT_234501] = ROT_104523, [ROT_541023] = ROT_543210, [ROT_103245] = ROT_320145, [ROT_540132] = ROT_542301, [ROT_102354] = ROT_321054, [ROT_013254] = ROT_230154, [ROT_451032] = ROT_453201, [ROT_453201] = ROT_450123, [ROT_105432] = ROT_325401, [ROT_015423] = ROT_235410, [ROT_321054] = ROT_013254, [ROT_452310] = ROT_451032, [ROT_230154] = ROT_102354, [ROT_543210] = ROT_540132, [ROT_104523] = ROT_324510, [ROT_320145] = ROT_012345, [ROT_324510] = ROT_014532, [ROT_450123] = ROT_452310, [ROT_235410] = ROT_105432, [ROT_325401] = ROT_015423 }, [ROT_234501] = { [ROT_012345] = ROT_234501, [ROT_014532] = ROT_230154, [ROT_542301] = ROT_104523, [ROT_231045] = ROT_453201, [ROT_234501] = ROT_450123, [ROT_541023] = ROT_103245, [ROT_103245] = ROT_325401, [ROT_540132] = ROT_102354, [ROT_102354] = ROT_324510, [ROT_013254] = ROT_235410, [ROT_451032] = ROT_013254, [ROT_453201] = ROT_015423, [ROT_105432] = ROT_321054, [ROT_015423] = ROT_231045, [ROT_321054] = ROT_543210, [ROT_452310] = ROT_014532, [ROT_230154] = ROT_452310, [ROT_543210] = ROT_105432, [ROT_104523] = ROT_320145, [ROT_320145] = ROT_542301, [ROT_324510] = ROT_540132, [ROT_450123] = ROT_012345, [ROT_235410] = ROT_451032, [ROT_325401] = ROT_541023 }, [ROT_541023] = { [ROT_012345] = ROT_541023, [ROT_014532] = ROT_542301, [ROT_542301] = ROT_321054, [ROT_231045] = ROT_104523, [ROT_234501] = ROT_102354, [ROT_541023] = ROT_324510, [ROT_103245] = ROT_450123, [ROT_540132] = ROT_325401, [ROT_102354] = ROT_451032, [ROT_013254] = ROT_540132, [ROT_451032] = ROT_234501, [ROT_453201] = ROT_230154, [ROT_105432] = ROT_453201, [ROT_015423] = ROT_543210, [ROT_321054] = ROT_014532, [ROT_452310] = ROT_231045, [ROT_230154] = ROT_105432, [ROT_543210] = ROT_320145, [ROT_104523] = ROT_452310, [ROT_320145] = ROT_015423, [ROT_324510] = ROT_012345, [ROT_450123] = ROT_235410, [ROT_235410] = ROT_103245, [ROT_325401] = ROT_013254 }, [ROT_103245] = { [ROT_012345] = ROT_103245, [ROT_014532] = ROT_104523, [ROT_542301] = ROT_543210, [ROT_231045] = ROT_320145, [ROT_234501] = ROT_324510, [ROT_541023] = ROT_540132, [ROT_103245] = ROT_012345, [ROT_540132] = ROT_541023, [ROT_102354] = ROT_013254, [ROT_013254] = ROT_102354, [ROT_451032] = ROT_450123, [ROT_453201] = ROT_452310, [ROT_105432] = ROT_015423, [ROT_015423] = ROT_105432, [ROT_321054] = ROT_230154, [ROT_452310] = ROT_453201, [ROT_230154] = ROT_321054, [ROT_543210] = ROT_542301, [ROT_104523] = ROT_014532, [ROT_320145] = ROT_231045, [ROT_324510] = ROT_234501, [ROT_450123] = ROT_451032, [ROT_235410] = ROT_325401, [ROT_325401] = ROT_235410 }, [ROT_540132] = { [ROT_012345] = ROT_540132, [ROT_014532] = ROT_543210, [ROT_542301] = ROT_230154, [ROT_231045] = ROT_014532, [ROT_234501] = ROT_013254, [ROT_541023] = ROT_234501, [ROT_103245] = ROT_451032, [ROT_540132] = ROT_235410, [ROT_102354] = ROT_450123, [ROT_013254] = ROT_541023, [ROT_451032] = ROT_324510, [ROT_453201] = ROT_321054, [ROT_105432] = ROT_452310, [ROT_015423] = ROT_542301, [ROT_321054] = ROT_104523, [ROT_452310] = ROT_320145, [ROT_230154] = ROT_015423, [ROT_543210] = ROT_231045, [ROT_104523] = ROT_453201, [ROT_320145] = ROT_105432, [ROT_324510] = ROT_103245, [ROT_450123] = ROT_325401, [ROT_235410] = ROT_012345, [ROT_325401] = ROT_102354 }, [ROT_102354] = { [ROT_012345] = ROT_102354, [ROT_014532] = ROT_105432, [ROT_542301] = ROT_452310, [ROT_231045] = ROT_230154, [ROT_234501] = ROT_235410, [ROT_541023] = ROT_450123, [ROT_103245] = ROT_013254, [ROT_540132] = ROT_451032, [ROT_102354] = ROT_012345, [ROT_013254] = ROT_103245, [ROT_451032] = ROT_540132, [ROT_453201] = ROT_543210, [ROT_105432] = ROT_014532, [ROT_015423] = ROT_104523, [ROT_321054] = ROT_320145, [ROT_452310] = ROT_542301, [ROT_230154] = ROT_231045, [ROT_543210] = ROT_453201, [ROT_104523] = ROT_015423, [ROT_320145] = ROT_321054, [ROT_324510] = ROT_325401, [ROT_450123] = ROT_541023, [ROT_235410] = ROT_234501, [ROT_325401] = ROT_324510 }, [ROT_013254] = { [ROT_012345] = ROT_013254, [ROT_014532] = ROT_015423, [ROT_542301] = ROT_453201, [ROT_231045] = ROT_321054, [ROT_234501] = ROT_325401, [ROT_541023] = ROT_451032, [ROT_103245] = ROT_102354, [ROT_540132] = ROT_450123, [ROT_102354] = ROT_103245, [ROT_013254] = ROT_012345, [ROT_451032] = ROT_541023, [ROT_453201] = ROT_542301, [ROT_105432] = ROT_104523, [ROT_015423] = ROT_014532, [ROT_321054] = ROT_231045, [ROT_452310] = ROT_543210, [ROT_230154] = ROT_320145, [ROT_543210] = ROT_452310, [ROT_104523] = ROT_105432, [ROT_320145] = ROT_230154, [ROT_324510] = ROT_235410, [ROT_450123] = ROT_540132, [ROT_235410] = ROT_324510, [ROT_325401] = ROT_234501 }, [ROT_451032] = { [ROT_012345] = ROT_451032, [ROT_014532] = ROT_453201, [ROT_542301] = ROT_231045, [ROT_231045] = ROT_105432, [ROT_234501] = ROT_103245, [ROT_541023] = ROT_235410, [ROT_103245] = ROT_540132, [ROT_540132] = ROT_234501, [ROT_102354] = ROT_541023, [ROT_013254] = ROT_450123, [ROT_451032] = ROT_325401, [ROT_453201] = ROT_320145, [ROT_105432] = ROT_542301, [ROT_015423] = ROT_452310, [ROT_321054] = ROT_015423, [ROT_452310] = ROT_321054, [ROT_230154] = ROT_104523, [ROT_543210] = ROT_230154, [ROT_104523] = ROT_543210, [ROT_320145] = ROT_014532, [ROT_324510] = ROT_013254, [ROT_450123] = ROT_324510, [ROT_235410] = ROT_102354, [ROT_325401] = ROT_012345 }, [ROT_453201] = { [ROT_012345] = ROT_453201, [ROT_014532] = ROT_450123, [ROT_542301] = ROT_103245, [ROT_231045] = ROT_325401, [ROT_234501] = ROT_320145, [ROT_541023] = ROT_105432, [ROT_103245] = ROT_542301, [ROT_540132] = ROT_104523, [ROT_102354] = ROT_543210, [ROT_013254] = ROT_452310, [ROT_451032] = ROT_015423, [ROT_453201] = ROT_012345, [ROT_105432] = ROT_541023, [ROT_015423] = ROT_451032, [ROT_321054] = ROT_235410, [ROT_452310] = ROT_013254, [ROT_230154] = ROT_324510, [ROT_543210] = ROT_102354, [ROT_104523] = ROT_540132, [ROT_320145] = ROT_234501, [ROT_324510] = ROT_230154, [ROT_450123] = ROT_014532, [ROT_235410] = ROT_321054, [ROT_325401] = ROT_231045 }, [ROT_105432] = { [ROT_012345] = ROT_105432, [ROT_014532] = ROT_103245, [ROT_542301] = ROT_235410, [ROT_231045] = ROT_540132, [ROT_234501] = ROT_543210, [ROT_541023] = ROT_230154, [ROT_103245] = ROT_014532, [ROT_540132] = ROT_231045, [ROT_102354] = ROT_015423, [ROT_013254] = ROT_104523, [ROT_451032] = ROT_320145, [ROT_453201] = ROT_324510, [ROT_105432] = ROT_012345, [ROT_015423] = ROT_102354, [ROT_321054] = ROT_450123, [ROT_452310] = ROT_325401, [ROT_230154] = ROT_541023, [ROT_543210] = ROT_234501, [ROT_104523] = ROT_013254, [ROT_320145] = ROT_451032, [ROT_324510] = ROT_453201, [ROT_450123] = ROT_321054, [ROT_235410] = ROT_542301, [ROT_325401] = ROT_452310 }, [ROT_015423] = { [ROT_012345] = ROT_015423, [ROT_014532] = ROT_012345, [ROT_542301] = ROT_325401, [ROT_231045] = ROT_541023, [ROT_234501] = ROT_542301, [ROT_541023] = ROT_321054, [ROT_103245] = ROT_104523, [ROT_540132] = ROT_320145, [ROT_102354] = ROT_105432, [ROT_013254] = ROT_014532, [ROT_451032] = ROT_231045, [ROT_453201] = ROT_234501, [ROT_105432] = ROT_103245, [ROT_015423] = ROT_013254, [ROT_321054] = ROT_451032, [ROT_452310] = ROT_235410, [ROT_230154] = ROT_540132, [ROT_543210] = ROT_324510, [ROT_104523] = ROT_102354, [ROT_320145] = ROT_450123, [ROT_324510] = ROT_452310, [ROT_450123] = ROT_230154, [ROT_235410] = ROT_543210, [ROT_325401] = ROT_453201 }, [ROT_321054] = { [ROT_012345] = ROT_321054, [ROT_014532] = ROT_325401, [ROT_542301] = ROT_451032, [ROT_231045] = ROT_102354, [ROT_234501] = ROT_105432, [ROT_541023] = ROT_452310, [ROT_103245] = ROT_230154, [ROT_540132] = ROT_453201, [ROT_102354] = ROT_231045, [ROT_013254] = ROT_320145, [ROT_451032] = ROT_542301, [ROT_453201] = ROT_540132, [ROT_105432] = ROT_234501, [ROT_015423] = ROT_324510, [ROT_321054] = ROT_012345, [ROT_452310] = ROT_541023, [ROT_230154] = ROT_103245, [ROT_543210] = ROT_450123, [ROT_104523] = ROT_235410, [ROT_320145] = ROT_013254, [ROT_324510] = ROT_015423, [ROT_450123] = ROT_543210, [ROT_235410] = ROT_104523, [ROT_325401] = ROT_014532 }, [ROT_452310] = { [ROT_012345] = ROT_452310, [ROT_014532] = ROT_451032, [ROT_542301] = ROT_012345, [ROT_231045] = ROT_235410, [ROT_234501] = ROT_231045, [ROT_541023] = ROT_015423, [ROT_103245] = ROT_543210, [ROT_540132] = ROT_014532, [ROT_102354] = ROT_542301, [ROT_013254] = ROT_453201, [ROT_451032] = ROT_105432, [ROT_453201] = ROT_103245, [ROT_105432] = ROT_540132, [ROT_015423] = ROT_450123, [ROT_321054] = ROT_325401, [ROT_452310] = ROT_102354, [ROT_230154] = ROT_234501, [ROT_543210] = ROT_013254, [ROT_104523] = ROT_541023, [ROT_320145] = ROT_324510, [ROT_324510] = ROT_321054, [ROT_450123] = ROT_104523, [ROT_235410] = ROT_230154, [ROT_325401] = ROT_320145 }, [ROT_230154] = { [ROT_012345] = ROT_230154, [ROT_014532] = ROT_235410, [ROT_542301] = ROT_450123, [ROT_231045] = ROT_013254, [ROT_234501] = ROT_015423, [ROT_541023] = ROT_453201, [ROT_103245] = ROT_321054, [ROT_540132] = ROT_452310, [ROT_102354] = ROT_320145, [ROT_013254] = ROT_231045, [ROT_451032] = ROT_543210, [ROT_453201] = ROT_541023, [ROT_105432] = ROT_324510, [ROT_015423] = ROT_234501, [ROT_321054] = ROT_103245, [ROT_452310] = ROT_540132, [ROT_230154] = ROT_012345, [ROT_543210] = ROT_451032, [ROT_104523] = ROT_325401, [ROT_320145] = ROT_102354, [ROT_324510] = ROT_105432, [ROT_450123] = ROT_542301, [ROT_235410] = ROT_014532, [ROT_325401] = ROT_104523 }, [ROT_543210] = { [ROT_012345] = ROT_543210, [ROT_014532] = ROT_541023, [ROT_542301] = ROT_013254, [ROT_231045] = ROT_324510, [ROT_234501] = ROT_321054, [ROT_541023] = ROT_014532, [ROT_103245] = ROT_452310, [ROT_540132] = ROT_015423, [ROT_102354] = ROT_453201, [ROT_013254] = ROT_542301, [ROT_451032] = ROT_104523, [ROT_453201] = ROT_102354, [ROT_105432] = ROT_450123, [ROT_015423] = ROT_540132, [ROT_321054] = ROT_234501, [ROT_452310] = ROT_103245, [ROT_230154] = ROT_325401, [ROT_543210] = ROT_012345, [ROT_104523] = ROT_451032, [ROT_320145] = ROT_235410, [ROT_324510] = ROT_231045, [ROT_450123] = ROT_105432, [ROT_235410] = ROT_320145, [ROT_325401] = ROT_230154 }, [ROT_104523] = { [ROT_012345] = ROT_104523, [ROT_014532] = ROT_102354, [ROT_542301] = ROT_324510, [ROT_231045] = ROT_450123, [ROT_234501] = ROT_452310, [ROT_541023] = ROT_320145, [ROT_103245] = ROT_015423, [ROT_540132] = ROT_321054, [ROT_102354] = ROT_014532, [ROT_013254] = ROT_105432, [ROT_451032] = ROT_230154, [ROT_453201] = ROT_235410, [ROT_105432] = ROT_013254, [ROT_015423] = ROT_103245, [ROT_321054] = ROT_540132, [ROT_452310] = ROT_234501, [ROT_230154] = ROT_451032, [ROT_543210] = ROT_325401, [ROT_104523] = ROT_012345, [ROT_320145] = ROT_541023, [ROT_324510] = ROT_542301, [ROT_450123] = ROT_231045, [ROT_235410] = ROT_453201, [ROT_325401] = ROT_543210 }, [ROT_320145] = { [ROT_012345] = ROT_320145, [ROT_014532] = ROT_324510, [ROT_542301] = ROT_540132, [ROT_231045] = ROT_012345, [ROT_234501] = ROT_014532, [ROT_541023] = ROT_542301, [ROT_103245] = ROT_231045, [ROT_540132] = ROT_543210, [ROT_102354] = ROT_230154, [ROT_013254] = ROT_321054, [ROT_451032] = ROT_452310, [ROT_453201] = ROT_451032, [ROT_105432] = ROT_235410, [ROT_015423] = ROT_325401, [ROT_321054] = ROT_102354, [ROT_452310] = ROT_450123, [ROT_230154] = ROT_013254, [ROT_543210] = ROT_541023, [ROT_104523] = ROT_234501, [ROT_320145] = ROT_103245, [ROT_324510] = ROT_104523, [ROT_450123] = ROT_453201, [ROT_235410] = ROT_015423, [ROT_325401] = ROT_105432 }, [ROT_324510] = { [ROT_012345] = ROT_324510, [ROT_014532] = ROT_321054, [ROT_542301] = ROT_014532, [ROT_231045] = ROT_452310, [ROT_234501] = ROT_451032, [ROT_541023] = ROT_012345, [ROT_103245] = ROT_235410, [ROT_540132] = ROT_013254, [ROT_102354] = ROT_234501, [ROT_013254] = ROT_325401, [ROT_451032] = ROT_102354, [ROT_453201] = ROT_105432, [ROT_105432] = ROT_230154, [ROT_015423] = ROT_320145, [ROT_321054] = ROT_542301, [ROT_452310] = ROT_104523, [ROT_230154] = ROT_453201, [ROT_543210] = ROT_015423, [ROT_104523] = ROT_231045, [ROT_320145] = ROT_543210, [ROT_324510] = ROT_541023, [ROT_450123] = ROT_103245, [ROT_235410] = ROT_450123, [ROT_325401] = ROT_540132 }, [ROT_450123] = { [ROT_012345] = ROT_450123, [ROT_014532] = ROT_452310, [ROT_542301] = ROT_320145, [ROT_231045] = ROT_015423, [ROT_234501] = ROT_012345, [ROT_541023] = ROT_325401, [ROT_103245] = ROT_541023, [ROT_540132] = ROT_324510, [ROT_102354] = ROT_540132, [ROT_013254] = ROT_451032, [ROT_451032] = ROT_235410, [ROT_453201] = ROT_231045, [ROT_105432] = ROT_543210, [ROT_015423] = ROT_453201, [ROT_321054] = ROT_105432, [ROT_452310] = ROT_230154, [ROT_230154] = ROT_014532, [ROT_543210] = ROT_321054, [ROT_104523] = ROT_542301, [ROT_320145] = ROT_104523, [ROT_324510] = ROT_102354, [ROT_450123] = ROT_234501, [ROT_235410] = ROT_013254, [ROT_325401] = ROT_103245 }, [ROT_235410] = { [ROT_012345] = ROT_235410, [ROT_014532] = ROT_231045, [ROT_542301] = ROT_015423, [ROT_231045] = ROT_543210, [ROT_234501] = ROT_541023, [ROT_541023] = ROT_013254, [ROT_103245] = ROT_324510, [ROT_540132] = ROT_012345, [ROT_102354] = ROT_325401, [ROT_013254] = ROT_234501, [ROT_451032] = ROT_103245, [ROT_453201] = ROT_104523, [ROT_105432] = ROT_320145, [ROT_015423] = ROT_230154, [ROT_321054] = ROT_453201, [ROT_452310] = ROT_105432, [ROT_230154] = ROT_542301, [ROT_543210] = ROT_014532, [ROT_104523] = ROT_321054, [ROT_320145] = ROT_452310, [ROT_324510] = ROT_451032, [ROT_450123] = ROT_102354, [ROT_235410] = ROT_540132, [ROT_325401] = ROT_450123 }, [ROT_325401] = { [ROT_012345] = ROT_325401, [ROT_014532] = ROT_320145, [ROT_542301] = ROT_105432, [ROT_231045] = ROT_542301, [ROT_234501] = ROT_540132, [ROT_541023] = ROT_102354, [ROT_103245] = ROT_234501, [ROT_540132] = ROT_103245, [ROT_102354] = ROT_235410, [ROT_013254] = ROT_324510, [ROT_451032] = ROT_012345, [ROT_453201] = ROT_014532, [ROT_105432] = ROT_231045, [ROT_015423] = ROT_321054, [ROT_321054] = ROT_452310, [ROT_452310] = ROT_015423, [ROT_230154] = ROT_543210, [ROT_543210] = ROT_104523, [ROT_104523] = ROT_230154, [ROT_320145] = ROT_453201, [ROT_324510] = ROT_450123, [ROT_450123] = ROT_013254, [ROT_235410] = ROT_541023, [ROT_325401] = ROT_451032 } }; #endif static XYF qc[ARCSEGS+1]; static int pcsz[NDIMS]; static int pcm[NDIMS]; static int pcnv; static CELL *pcv; #define pc(x,y,z) pcv[((x)*pcm[2])+((y)*pcm[1])+((z)*pcm[0])] static LOC *locs; static int nlocs; static PT *pts; static int npts; static TRI *tris; static int ntris; #if 0 static XYI xyi_add(XYI, XYI) __attribute__((__const__)); static XYI xyi_add(XYI a, XYI b) { return((XYI){a.x+b.x,a.y+b.y}); } #endif #if 0 static XYI xyi_sub(XYI, XYI) __attribute__((__const__)); static XYI xyi_sub(XYI a, XYI b) { return((XYI){a.x-b.x,a.y-b.y}); } #endif #if 0 static XYI xyi_rotcw(XYI) __attribute__((__const__)); static XYI xyi_rotcw(XYI a) { return((XYI){a.y,-a.x}); } #endif #if 0 static XYI xyi_rotccw(XYI) __attribute__((__const__)); static XYI xyi_rotccw(XYI a) { return((XYI){-a.y,a.x}); } #endif #if 0 static int xyi_zerop(XYI) __attribute__((__const__)); static int xyi_zerop(XYI a) { return((a.x == 0) && (a.y == 0)); } #endif #if 0 static int xyzi_zerop(XYZI) __attribute__((__const__)); static int xyzi_zerop(XYZI v) { return((v.x == 0) && (v.y == 0) && (v.z == 0)); } #endif #if 0 static int xyzi_dot(XYZI a, XYZI b) __attribute__((__const__)); static int xyzi_dot(XYZI a, XYZI b) { return((a.x * b.x) + (a.y * b.y) + (a.z * b.z)); } #endif #if 0 static XYZI xyzi_sub(XYZI, XYZI) __attribute__((__const__)); static XYZI xyzi_sub(XYZI a, XYZI b) { return( (XYZI) { .x = a.x - b.x, .y = a.y - b.y, .z = a.z - b.z } ); } #endif #if 0 static XYZI xyzi_cross(XYZI, XYZI) __attribute__((__const__)); static XYZI xyzi_cross(XYZI a, XYZI b) { return( (XYZI) { .x = (a.y * b.z) - (a.z * b.y), .y = (a.z * b.x) - (a.x * b.z), .z = (a.x * b.y) - (a.y * b.x) } ); } #endif static XYZF xyzf_add(XYZF, XYZF) __attribute__((__const__)); static XYZF xyzf_add(XYZF a, XYZF b) { return( (XYZF) { .x = a.x + b.x, .y = a.y + b.y, .z = a.z + b.z } ); } static XYZF xyzf_scale(XYZF, double) __attribute__((__const__)); static XYZF xyzf_scale(XYZF a, double s) { return( (XYZF) { .x = a.x * s, .y = a.y * s, .z = a.z * s } ); } static XYZF xyzf_unit(XYZF) __attribute__((__const__)); static XYZF xyzf_unit(XYZF v) { return(xyzf_scale(v,1/sqrt((v.x*v.x)+(v.y*v.y)+(v.z*v.z)))); } #if 0 static XYZF xyzi2f(XYZI) __attribute__((__const__)); static XYZF xyzi2f(XYZI v) { return( (XYZF) { .x = v.x, .y = v.y, .z = v.z } ); } #endif static void baddescr(const char *how) { fprintf(stderr,"Bad piece (%s)\n",how); exit(1); } static void read_pc(void) { int ch; int dims[NDIMS]; int lens[NDIMS]; int muls[NDIMS]; int x; int y; int z; char *bits; int bithave; int bitlen; int i; int depth; int m; CELL c; bits = 0; bitlen = 0; bithave = 0; for (i=NDIMS-1;i>=-0;i--) dims[i] = -1; depth = 0; lens[0] = 0; while <"readloop"> (1) { ch = getchar(); switch (ch) { default: baddescr("bad character in bitmap"); break; case EOF: break <"readloop">; break; case ' ': case '\t': case '\n': break; case '(': depth ++; if (depth >= NDIMS) baddescr("too many (s in bitmap"); lens[depth] = 0; break; case ')': if (dims[depth] < 0) { dims[depth] = lens[depth]; } else if (lens[depth] != dims[depth]) { baddescr("length mismatch in bitmap"); } depth --; if (depth < 0) baddescr("unmatched ) in bitmap"); lens[depth] ++; break; case '0': case '1': if (depth != NDIMS-1) baddescr("bit not deep enough"); lens[depth] ++; if (bitlen >= bithave) bits = realloc(bits,bithave=bitlen+64); bits[bitlen++] = ('1'==ch); break; } } if (depth != 0) baddescr("misbalanced ()s in bitmap"); dims[0] = lens[0]; m = 1; for (i=NDIMS-1;i>=0;i--) { muls[i] = m; m *= dims[i]; } m = 1; for (i=NDIMS-1;i>=0;i--) { pcsz[i] = dims[i] + 2; pcm[i] = m; m *= pcsz[i]; } pcnv = m; pcv = malloc(m*sizeof(CELL)); c.j.syn = 0; for (x=pcsz[2]-1;x>=0;x--) { c.x = x; for (y=pcsz[1]-1;y>=0;y--) { c.y = y; for (z=pcsz[0]-1;z>=0;z--) { c.z = z; if ( (x == 0) || (x == pcsz[2]-1) || (y == 0) || (y == pcsz[1]-1) || (z == 0) || (z == pcsz[0]-1) || !bits[((x-1)*muls[2])+((y-1)*muls[1])+((z-1)*muls[0])] ) { c.filled = 0; } else { c.filled = 1; } pc(x,y,z) = c; } } } free(bits); } static LOC *loc_cache(XYZF p) { LOC *rv; for (rv=locs;rv;rv=rv->link) { if ( (fabs(rv->p.x-p.x) < 1e-4) && (fabs(rv->p.y-p.y) < 1e-4) && (fabs(rv->p.z-p.z) < 1e-4) ) { return(rv); } } rv = malloc(sizeof(LOC)); rv->p = p; rv->link = locs; locs = rv; nlocs ++; return(rv); } #if 0 static PT *pt_c(LOC *l) { PT *rv; for (rv=pts;rv;rv=rv->link) { if ((rv->l == l) && (rv->kind == PK_CORNER)) return(rv); } rv = malloc(sizeof(PT)); rv->l = l; rv->kind = PK_CORNER; rv->link = pts; pts = rv; npts ++; return(rv); } #endif static PT *pt_s(LOC *l, XYZF n) { PT *rv; for (rv=pts;rv;rv=rv->link) { if ( (rv->l == l) && (rv->kind == PK_SURFACE) && (fabs(rv->sn.x-n.x) < 1e-4) && (fabs(rv->sn.y-n.y) < 1e-4) && (fabs(rv->sn.z-n.z) < 1e-4) ) return(rv); } rv = malloc(sizeof(PT)); rv->l = l; rv->kind = PK_SURFACE; rv->sn = xyzf_unit(n); rv->link = pts; pts = rv; npts ++; return(rv); } static void save_tri(PT *a, PT *b, PT *c) { TRI *t; printf("@ triangle (%g,%g,%g) - (%g,%g,%g) - (%g,%g,%g)\n", a->l->p.x, a->l->p.y, a->l->p.z, b->l->p.x, b->l->p.y, b->l->p.z, c->l->p.x, c->l->p.y, c->l->p.z ); if ((a == b) || (a == c) || (b == c)) abort(); t = malloc(sizeof(TRI)); t->a = a; t->b = b; t->c = c; t->link = tris; tris = t; ntris ++; } static void save_quad(PT *a, PT *b, PT *c, PT *d) { save_tri(a,b,c); save_tri(a,c,d); } #if 0 static int point_in_triangle(XYZI p, XYZI a, XYZI b, XYZI c) { XYZI ab; XYZI bc; XYZI ca; a = xyzi_sub(a,p); b = xyzi_sub(b,p); c = xyzi_sub(c,p); ab = xyzi_cross(a,b); bc = xyzi_cross(b,c); ca = xyzi_cross(c,a); return( (xyzi_dot(ab,bc) >= 0) && (xyzi_dot(bc,ca) >= 0) ); } #endif static const char *jctkind_str(JCTKIND k) { static char badbuf[64]; switch (k) { case JK_UNSET: return("UNSET"); break; case JK_NIL: return("NIL"); break; case JK_CORNER: return("CORNER"); break; case JK_EDGE: return("EDGE"); break; case JK_TWOCORNER_EDGE: return("TWOCORNER_EDGE"); break; case JK_ELBOW: return("ELBOW"); break; case JK_FLAT: return("FLAT"); break; case JK_THREECORNER: return("THREECORNER"); break; case JK_SOMA7: return("SOMA7"); break; case JK_TWOCORNER_POINT: return("TWOCORNER_POINT"); break; case JK_EDGE_CORNER: return("EDGE_CORNER"); break; case JK_SOMA56_A: return("SOMA56_A"); break; case JK_SOMA56_B: return("SOMA56_B"); break; case JK_EBLOW_CORNER: return("EBLOW_CORNER"); break; case JK_EDGE_FLAT: return("EDGE_FLAT"); break; case JK_DUAL_EDGE: return("DUAL_EDGE"); break; case JK_BRIDGE: return("BRIDGE"); break; case JK_CONCAVE: return("CONCAVE"); break; case JK_CHECKERBOARD: return("CHECKERBOARD"); break; case JK_SOMA7_FILL: return("SOMA7_FILL"); break; case JK_DUAL_EDGE_FLAT: return("DUAL_EDGE_FLAT"); break; case JK_DUAL_VOID: return("DUAL_VOID"); break; case JK_VOID: return("VOID"); break; } sprintf(&badbuf[0],"?%d",(int)k); return(&badbuf[0]); } static const char *rot_str(ROT r) { static char badbuf[64]; switch (r) { case ROT_NONE: return("NONE"); break; case ROT_012345: return("012345"); break; case ROT_014532: return("014532"); break; case ROT_542301: return("542301"); break; case ROT_231045: return("231045"); break; case ROT_234501: return("234501"); break; case ROT_541023: return("541023"); break; case ROT_103245: return("103245"); break; case ROT_540132: return("540132"); break; case ROT_102354: return("102354"); break; case ROT_013254: return("013254"); break; case ROT_451032: return("451032"); break; case ROT_453201: return("453201"); break; case ROT_105432: return("105432"); break; case ROT_015423: return("015423"); break; case ROT_321054: return("321054"); break; case ROT_452310: return("452310"); break; case ROT_230154: return("230154"); break; case ROT_543210: return("543210"); break; case ROT_104523: return("104523"); break; case ROT_320145: return("320145"); break; case ROT_324510: return("324510"); break; case ROT_450123: return("450123"); break; case ROT_235410: return("235410"); break; case ROT_325401: return("325401"); break; } sprintf(&badbuf[0],"?%d",(int)r); return(&badbuf[0]); } #if 0 static XYZI rot_delta_i(ROT r, XYZI d) { switch (r) { case ROT_012345: return((XYZI){ d.x, d.y, d.z}); break; case ROT_014532: return((XYZI){ d.x, d.z,-d.y}); break; case ROT_542301: return((XYZI){-d.z, d.y, d.x}); break; case ROT_231045: return((XYZI){ d.y,-d.x, d.z}); break; case ROT_234501: return((XYZI){ d.y, d.z, d.x}); break; case ROT_541023: return((XYZI){-d.z,-d.x, d.y}); break; case ROT_103245: return((XYZI){-d.x,-d.y, d.z}); break; case ROT_540132: return((XYZI){-d.z, d.x,-d.y}); break; case ROT_102354: return((XYZI){-d.x, d.y,-d.z}); break; case ROT_013254: return((XYZI){ d.x,-d.y,-d.z}); break; case ROT_451032: return((XYZI){ d.z,-d.x,-d.y}); break; case ROT_453201: return((XYZI){ d.z,-d.y, d.x}); break; case ROT_105432: return((XYZI){-d.x,-d.z,-d.y}); break; case ROT_015423: return((XYZI){ d.x,-d.z, d.y}); break; case ROT_321054: return((XYZI){-d.y,-d.x,-d.z}); break; case ROT_452310: return((XYZI){ d.z, d.y,-d.x}); break; case ROT_230154: return((XYZI){ d.y, d.x,-d.z}); break; case ROT_543210: return((XYZI){-d.z,-d.y,-d.x}); break; case ROT_104523: return((XYZI){-d.x, d.z, d.y}); break; case ROT_320145: return((XYZI){-d.y, d.x, d.z}); break; case ROT_324510: return((XYZI){-d.y, d.z,-d.x}); break; case ROT_450123: return((XYZI){ d.z, d.x, d.y}); break; case ROT_235410: return((XYZI){ d.y,-d.z,-d.x}); break; case ROT_325401: return((XYZI){-d.y,-d.z, d.x}); break; default: abort(); break; } } #endif #if 0 static XYZI irot_delta_i(ROT r, XYZI d) { switch (inverse[r]) { case ROT_012345: return((XYZI){ d.x, d.y, d.z}); break; case ROT_014532: return((XYZI){ d.x, d.z,-d.y}); break; case ROT_542301: return((XYZI){-d.z, d.y, d.x}); break; case ROT_231045: return((XYZI){ d.y,-d.x, d.z}); break; case ROT_234501: return((XYZI){ d.y, d.z, d.x}); break; case ROT_541023: return((XYZI){-d.z,-d.x, d.y}); break; case ROT_103245: return((XYZI){-d.x,-d.y, d.z}); break; case ROT_540132: return((XYZI){-d.z, d.x,-d.y}); break; case ROT_102354: return((XYZI){-d.x, d.y,-d.z}); break; case ROT_013254: return((XYZI){ d.x,-d.y,-d.z}); break; case ROT_451032: return((XYZI){ d.z,-d.x,-d.y}); break; case ROT_453201: return((XYZI){ d.z,-d.y, d.x}); break; case ROT_105432: return((XYZI){-d.x,-d.z,-d.y}); break; case ROT_015423: return((XYZI){ d.x,-d.z, d.y}); break; case ROT_321054: return((XYZI){-d.y,-d.x,-d.z}); break; case ROT_452310: return((XYZI){ d.z, d.y,-d.x}); break; case ROT_230154: return((XYZI){ d.y, d.x,-d.z}); break; case ROT_543210: return((XYZI){-d.z,-d.y,-d.x}); break; case ROT_104523: return((XYZI){-d.x, d.z, d.y}); break; case ROT_320145: return((XYZI){-d.y, d.x, d.z}); break; case ROT_324510: return((XYZI){-d.y, d.z,-d.x}); break; case ROT_450123: return((XYZI){ d.z, d.x, d.y}); break; case ROT_235410: return((XYZI){ d.y,-d.z,-d.x}); break; case ROT_325401: return((XYZI){-d.y,-d.z, d.x}); break; default: abort(); break; } } #endif static XYZF rot_delta_f(ROT r, XYZF d) { switch (r) { case ROT_012345: return((XYZF){ d.x, d.y, d.z}); break; case ROT_014532: return((XYZF){ d.x, d.z,-d.y}); break; case ROT_542301: return((XYZF){-d.z, d.y, d.x}); break; case ROT_231045: return((XYZF){ d.y,-d.x, d.z}); break; case ROT_234501: return((XYZF){ d.y, d.z, d.x}); break; case ROT_541023: return((XYZF){-d.z,-d.x, d.y}); break; case ROT_103245: return((XYZF){-d.x,-d.y, d.z}); break; case ROT_540132: return((XYZF){-d.z, d.x,-d.y}); break; case ROT_102354: return((XYZF){-d.x, d.y,-d.z}); break; case ROT_013254: return((XYZF){ d.x,-d.y,-d.z}); break; case ROT_451032: return((XYZF){ d.z,-d.x,-d.y}); break; case ROT_453201: return((XYZF){ d.z,-d.y, d.x}); break; case ROT_105432: return((XYZF){-d.x,-d.z,-d.y}); break; case ROT_015423: return((XYZF){ d.x,-d.z, d.y}); break; case ROT_321054: return((XYZF){-d.y,-d.x,-d.z}); break; case ROT_452310: return((XYZF){ d.z, d.y,-d.x}); break; case ROT_230154: return((XYZF){ d.y, d.x,-d.z}); break; case ROT_543210: return((XYZF){-d.z,-d.y,-d.x}); break; case ROT_104523: return((XYZF){-d.x, d.z, d.y}); break; case ROT_320145: return((XYZF){-d.y, d.x, d.z}); break; case ROT_324510: return((XYZF){-d.y, d.z,-d.x}); break; case ROT_450123: return((XYZF){ d.z, d.x, d.y}); break; case ROT_235410: return((XYZF){ d.y,-d.z,-d.x}); break; case ROT_325401: return((XYZF){-d.y,-d.z, d.x}); break; default: abort(); break; } } #if 0 static XYZF irot_delta_f(ROT r, XYZF d) { switch (inverse[r]) { case ROT_012345: return((XYZF){ d.x, d.y, d.z}); break; case ROT_014532: return((XYZF){ d.x, d.z,-d.y}); break; case ROT_542301: return((XYZF){-d.z, d.y, d.x}); break; case ROT_231045: return((XYZF){ d.y,-d.x, d.z}); break; case ROT_234501: return((XYZF){ d.y, d.z, d.x}); break; case ROT_541023: return((XYZF){-d.z,-d.x, d.y}); break; case ROT_103245: return((XYZF){-d.x,-d.y, d.z}); break; case ROT_540132: return((XYZF){-d.z, d.x,-d.y}); break; case ROT_102354: return((XYZF){-d.x, d.y,-d.z}); break; case ROT_013254: return((XYZF){ d.x,-d.y,-d.z}); break; case ROT_451032: return((XYZF){ d.z,-d.x,-d.y}); break; case ROT_453201: return((XYZF){ d.z,-d.y, d.x}); break; case ROT_105432: return((XYZF){-d.x,-d.z,-d.y}); break; case ROT_015423: return((XYZF){ d.x,-d.z, d.y}); break; case ROT_321054: return((XYZF){-d.y,-d.x,-d.z}); break; case ROT_452310: return((XYZF){ d.z, d.y,-d.x}); break; case ROT_230154: return((XYZF){ d.y, d.x,-d.z}); break; case ROT_543210: return((XYZF){-d.z,-d.y,-d.x}); break; case ROT_104523: return((XYZF){-d.x, d.z, d.y}); break; case ROT_320145: return((XYZF){-d.y, d.x, d.z}); break; case ROT_324510: return((XYZF){-d.y, d.z,-d.x}); break; case ROT_450123: return((XYZF){ d.z, d.x, d.y}); break; case ROT_235410: return((XYZF){ d.y,-d.z,-d.x}); break; case ROT_325401: return((XYZF){-d.y,-d.z, d.x}); break; default: abort(); break; } } #endif static void gen_jct(SYNDROME *syn, PT *(*p_s)(XYZF, XYZF)) { #define USE_OFFSET \ PT *p_s_offset(XYZF d, XYZF n) \ { return((*p_s)((XYZF){d.x-ARCSCALE,d.y-ARCSCALE,d.z-ARCSCALE},n)); \ } #define USE_013254 \ PT *p_s_013254(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.x,-d.y,-d.z},(XYZF){+n.x,-n.y,-n.z})); \ } #define USE_014532 \ PT *p_s_014532(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.x,+d.z,-d.y},(XYZF){+n.x,+n.z,-n.y})); \ } #define USE_015423 \ PT *p_s_015423(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.x,-d.z,+d.y},(XYZF){+n.x,-n.z,+n.y})); \ } #define USE_102354 \ PT *p_s_102354(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.x,+d.y,-d.z},(XYZF){-n.x,+n.y,-n.z})); \ } #define USE_103245 \ PT *p_s_103245(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.x,-d.y,+d.z},(XYZF){-n.x,-n.y,+n.z})); \ } #define USE_104523 \ PT *p_s_104523(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.x,+d.z,+d.y},(XYZF){-n.x,+n.z,+n.y})); \ } #define USE_105432 \ PT *p_s_105432(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.x,-d.z,-d.y},(XYZF){-n.x,-n.z,-n.y})); \ } #define USE_230154 \ PT *p_s_230154(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.y,+d.x,-d.z},(XYZF){+n.y,+n.x,-n.z})); \ } #define USE_231045 \ PT *p_s_231045(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.y,-d.x,+d.z},(XYZF){+n.y,-n.x,+n.z})); \ } #define USE_234501 \ PT *p_s_234501(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.y,+d.z,+d.x},(XYZF){+n.y,+n.z,+n.x})); \ } #define USE_235410 \ PT *p_s_235410(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.y,-d.z,-d.x},(XYZF){+n.y,-n.z,-n.x})); \ } #define USE_320145 \ PT *p_s_320145(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.y,+d.x,+d.z},(XYZF){-n.y,+n.x,+n.z})); \ } #define USE_321054 \ PT *p_s_321054(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.y,-d.x,-d.z},(XYZF){-n.y,-n.x,-n.z})); \ } #define USE_324510 \ PT *p_s_324510(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.y,+d.z,-d.x},(XYZF){-n.y,+n.z,-n.x})); \ } #define USE_325401 \ PT *p_s_325401(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.y,-d.z,+d.x},(XYZF){-n.y,-n.z,+n.x})); \ } #define USE_450123 \ PT *p_s_450123(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.z,+d.x,+d.y},(XYZF){+n.z,+n.x,+n.y})); \ } #define USE_451032 \ PT *p_s_451032(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.z,-d.x,-d.y},(XYZF){+n.z,-n.x,-n.y})); \ } #define USE_452310 \ PT *p_s_452310(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.z,+d.y,-d.x},(XYZF){+n.z,+n.y,-n.x})); \ } #define USE_453201 \ PT *p_s_453201(XYZF d, XYZF n) \ { return((*p_s)((XYZF){+d.z,-d.y,+d.x},(XYZF){+n.z,-n.y,+n.x})); \ } #define USE_540132 \ PT *p_s_540132(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.z,+d.x,-d.y},(XYZF){-n.z,+n.x,-n.y})); \ } #define USE_541023 \ PT *p_s_541023(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.z,-d.x,+d.y},(XYZF){-n.z,-n.x,+n.y})); \ } #define USE_542301 \ PT *p_s_542301(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.z,+d.y,+d.x},(XYZF){-n.z,+n.y,+n.x})); \ } #define USE_543210 \ PT *p_s_543210(XYZF d, XYZF n) \ { return((*p_s)((XYZF){-d.z,-d.y,-d.x},(XYZF){-n.z,-n.y,-n.x})); \ } void gen_edge(double cd, PT *(*p)(XYZF, XYZF)) { PT *e[ARCSEGS+1]; PT *n[ARCSEGS+1]; int i; for (i=ARCSEGS;i>=0;i--) { e[i] = (*p)((XYZF){-.5,qc[i].x-ARCSCALE,qc[i].y-ARCSCALE},(XYZF){0,qc[i].x,qc[i].y}); n[i] = (*p)((XYZF){-cd,qc[i].x-ARCSCALE,qc[i].y-ARCSCALE},(XYZF){0,qc[i].x,qc[i].y}); } for (i=ARCSEGS-1;i>=0;i--) save_quad(e[i+1],e[i],n[i],n[i+1]); } void gen_face(double dy, double dz, PT *(*p)(XYZF, XYZF)) { PT *f; PT *c; f = (*p)((XYZF){0,-.5,-.5},(XYZF){1,0,0}); c = (*p)((XYZF){0,-dy,-dz},(XYZF){1,0,0}); save_quad( f, (*p)((XYZF){0,-.5,-dz},(XYZF){1,0,0}), c, (*p)((XYZF){0,-dy,-.5},(XYZF){1,0,0}) ); } void gen_1_8_sphere(PT *(*p)(XYZF, XYZF)) { int i; int j; XYZF v; PT *pt[ARCSEGS][ARCSEGS+1]; PT *np; for (i=ARCSEGS-1;i>=0;i--) { for (j=ARCSEGS;j>=0;j--) { v = (XYZF) { qc[j].x * qc[i].x / ARCSCALE, qc[j].y * qc[i].x / ARCSCALE, qc[i].y }; pt[i][j] = (*p)(v,v); } } np = (*p)((XYZF){0,0,ARCSCALE},(XYZF){0,0,1}); for (j=ARCSEGS-1;j>=0;j--) { for (i=ARCSEGS-2;i>=0;i--) { save_quad(pt[i][j],pt[i+1][j],pt[i+1][j+1],pt[i][j+1]); } save_tri(np,pt[ARCSEGS-1][j+1],pt[ARCSEGS-1][j]); } } void gen_crotch(PT *(*p)(XYZF, XYZF)) { int i; int j; PT *pt[ARCSEGS][ARCSEGS+1]; PT *v[ARCSEGS]; PT *f; PT *f1; PT *f2; for (i=ARCSEGS-1;i>=0;i--) { for (j=ARCSEGS;j>=0;j--) { pt[i][j] = (*p)( (XYZF) { - qc[j].y * (ARCSCALE - qc[i].y) / ARCSCALE, - qc[j].x * (ARCSCALE - qc[i].y) / ARCSCALE, qc[i].x - ARCSCALE }, (XYZF) { qc[j].y * qc[i].y / ARCSCALE, qc[j].x * qc[i].y / ARCSCALE, qc[i].x } ); } } for (j=ARCSEGS-1;j>=0;j--) { v[j] = (*p)((XYZF){0,0,-ARCSCALE},(XYZF){qc[j].y+qc[j+1].y,qc[j].x+qc[j+1].x,0}); } for (j=ARCSEGS-1;j>=0;j--) { for (i=ARCSEGS-2;i>=0;i--) { save_quad(pt[i][j],pt[i][j+1],pt[i+1][j+1],pt[i+1][j]); } save_tri(v[j],pt[ARCSEGS-1][j],pt[ARCSEGS-1][j+1]); } f = (*p)((XYZF){-.5,-.5,0},(XYZF){0,0,1}); f1 = (*p)((XYZF){0,-.5,0},(XYZF){0,0,1}); f2 = (*p)((XYZF){-.5,0,0},(XYZF){0,0,1}); save_tri(f,f2,pt[0][ARCSEGS]); for (j=ARCSEGS-1;j>=0;j--) save_tri(f,pt[0][j+1],pt[0][j]); save_tri(f,pt[0][0],f1); } void gen_7crotch(PT *(*p)(XYZF, XYZF)) { int i; PT *cv[ARCSEGS+1][3]; PT *ev[ARCSEGS+1][3]; for (i=ARCSEGS;i>ARCSEGS45;i--) { ev[i][0] = (*p)((XYZF){.5,qc[i].x-ARCSCALE,qc[i].y-ARCSCALE},(XYZF){0,qc[i].x/ARCSCALE,qc[i].y/ARCSCALE}); cv[i][0] = (*p)((XYZF){qc[i].y-ARCSCALE,qc[i].x-ARCSCALE,qc[i].y-ARCSCALE},(XYZF){0,qc[i].x/ARCSCALE,qc[i].y/ARCSCALE}); ev[i][1] = (*p)((XYZF){qc[i].x-ARCSCALE,qc[i].y-ARCSCALE,.5},(XYZF){qc[i].x/ARCSCALE,qc[i].y/ARCSCALE,0}); cv[i][1] = (*p)((XYZF){qc[i].x-ARCSCALE,qc[i].y-ARCSCALE,qc[i].y-ARCSCALE},(XYZF){qc[i].x/ARCSCALE,qc[i].y/ARCSCALE,0}); ev[i][2] = (*p)((XYZF){qc[i].y-ARCSCALE,.5,qc[i].x-ARCSCALE},(XYZF){qc[i].y/ARCSCALE,0,qc[i].x/ARCSCALE}); cv[i][2] = (*p)((XYZF){qc[i].y-ARCSCALE,qc[i].y-ARCSCALE,qc[i].x-ARCSCALE},(XYZF){qc[i].y/ARCSCALE,0,qc[i].x/ARCSCALE}); } for (i=ARCSEGS45;i>=0;i--) { ev[i][0] = (*p)((XYZF){.5,qc[i].x-ARCSCALE,qc[i].y-ARCSCALE},(XYZF){0,qc[i].x/ARCSCALE,qc[i].y/ARCSCALE}); cv[i][0] = (*p)((XYZF){qc[i].x-ARCSCALE,qc[i].x-ARCSCALE,qc[i].y-ARCSCALE},(XYZF){0,qc[i].x/ARCSCALE,qc[i].y/ARCSCALE}); ev[i][1] = (*p)((XYZF){qc[i].x-ARCSCALE,qc[i].y-ARCSCALE,.5},(XYZF){qc[i].x/ARCSCALE,qc[i].y/ARCSCALE,0}); cv[i][1] = (*p)((XYZF){qc[i].x-ARCSCALE,qc[i].y-ARCSCALE,qc[i].x-ARCSCALE},(XYZF){qc[i].x/ARCSCALE,qc[i].y/ARCSCALE,0}); ev[i][2] = (*p)((XYZF){qc[i].y-ARCSCALE,.5,qc[i].x-ARCSCALE},(XYZF){qc[i].y/ARCSCALE,0,qc[i].x/ARCSCALE}); cv[i][2] = (*p)((XYZF){qc[i].y-ARCSCALE,qc[i].x-ARCSCALE,qc[i].x-ARCSCALE},(XYZF){qc[i].y/ARCSCALE,0,qc[i].x/ARCSCALE}); } for (i=ARCSEGS-1;i>=0;i--) { save_quad(ev[i][0],ev[i+1][0],cv[i+1][0],cv[i][0]); save_quad(ev[i][1],ev[i+1][1],cv[i+1][1],cv[i][1]); save_quad(ev[i][2],ev[i+1][2],cv[i+1][2],cv[i][2]); } } void gen_corner(PT *(*p_s)(XYZF, XYZF)) { USE_234501 USE_450123 USE_OFFSET gen_face(ARCSCALE,ARCSCALE,p_s); gen_face(ARCSCALE,ARCSCALE,&p_s_450123); gen_face(ARCSCALE,ARCSCALE,&p_s_234501); gen_edge(ARCSCALE,p_s); gen_edge(ARCSCALE,&p_s_450123); gen_edge(ARCSCALE,&p_s_234501); gen_1_8_sphere(&p_s_offset); } void gen_elbow(PT *(*p_s)(XYZF, XYZF)) { USE_015423 USE_104523 USE_231045 USE_320145 USE_453201 USE_542301 gen_face(ARCSCALE,0,&p_s_542301); gen_face(0,ARCSCALE,&p_s_320145); gen_face(ARCSCALE,0,&p_s_015423); gen_face(0,ARCSCALE,&p_s_453201); gen_edge(0,&p_s_104523); gen_edge(0,&p_s_231045); gen_crotch(p_s); } void gen_soma7(PT *(*p_s)(XYZF, XYZF)) { USE_014532 USE_015423 USE_104523 USE_230154 USE_231045 USE_320145 USE_452310 USE_453201 USE_542301 gen_face(ARCSCALE,0,&p_s_542301); gen_face(0,ARCSCALE,&p_s_320145); gen_face(ARCSCALE,0,&p_s_015423); gen_face(0,ARCSCALE,&p_s_453201); gen_face(ARCSCALE,0,&p_s_230154); gen_face(0,ARCSCALE,&p_s_014532); gen_7crotch(p_s); } USE_013254 USE_014532 USE_015423 USE_102354 USE_103245 USE_104523 USE_105432 USE_230154 USE_231045 USE_234501 USE_235410 USE_320145 USE_321054 USE_324510 USE_325401 USE_450123 USE_451032 USE_452310 USE_453201 USE_540132 USE_542301 USE_543210 switch (syn->kind) { default: abort(); break; case JK_NIL: break; case JK_CORNER: gen_corner(p_s); break; case JK_EDGE: gen_face(ARCSCALE,-.5,&p_s_450123); gen_face(-.5,ARCSCALE,&p_s_234501); gen_edge(-.5,p_s); break; case JK_TWOCORNER_EDGE: gen_corner(p_s); gen_corner(&p_s_103245); break; case JK_ELBOW: gen_elbow(p_s); break; case JK_FLAT: gen_face(-.5,-.5,&p_s_234501); break; case JK_THREECORNER: gen_corner(p_s); gen_corner(&p_s_103245); gen_corner(&p_s_102354); break; case JK_SOMA7: gen_soma7(p_s); break; case JK_TWOCORNER_POINT: gen_corner(p_s); gen_corner(&p_s_543210); break; case JK_EDGE_CORNER: gen_face(ARCSCALE,-.5,&p_s_450123); gen_face(-.5,ARCSCALE,&p_s_234501); gen_edge(-.5,p_s); gen_corner(&p_s_013254); break; case JK_SOMA56_A: gen_face(ARCSCALE,0,&p_s_102354); gen_face(0,ARCSCALE,&p_s_540132); gen_face(ARCSCALE,0,&p_s_015423); gen_face(0,ARCSCALE,&p_s_453201); gen_edge(0,&p_s_324510); gen_edge(0,&p_s_231045); gen_crotch(p_s); gen_crotch(&p_s_104523); break; case JK_SOMA56_B: gen_face(ARCSCALE,0,&p_s_013254); gen_face(0,ARCSCALE,&p_s_451032); gen_face(ARCSCALE,0,&p_s_542301); gen_face(0,ARCSCALE,&p_s_320145); gen_edge(0,&p_s_235410); gen_edge(0,&p_s_104523); gen_crotch(p_s); gen_crotch(&p_s_453201); break; case JK_EBLOW_CORNER: gen_elbow(p_s); gen_corner(&p_s_543210); break; case JK_EDGE_FLAT: gen_face(-.5,-.5,&p_s_234501); gen_face(ARCSCALE,0,&p_s_230154); gen_face(0,ARCSCALE,&p_s_014532); gen_edge(0,&p_s_452310); break; case JK_DUAL_EDGE: gen_face(ARCSCALE,-.5,&p_s_450123); gen_face(-.5,ARCSCALE,&p_s_234501); gen_face(ARCSCALE,-.5,&p_s_451032); gen_face(-.5,ARCSCALE,&p_s_235410); gen_edge(-.5,p_s); gen_edge(-.5,&p_s_013254); break; case JK_BRIDGE: gen_face(ARCSCALE,0,&p_s_102354); gen_face(0,ARCSCALE,&p_s_540132); gen_face(ARCSCALE,0,&p_s_013254); gen_face(0,ARCSCALE,&p_s_451032); gen_edge(0,&p_s_324510); gen_crotch(&p_s_104523); gen_crotch(p_s); gen_crotch(&p_s_453201); gen_edge(0,&p_s_235410); break; case JK_CONCAVE: /*gen_face(-.5,0,-y-z+x);*/ gen_face(0,-.5,&p_s_453201); /*gen_face(-.5,0,+y+x-z);fzr*/ gen_face(0,-.5,&p_s_540132); break; case JK_CHECKERBOARD: gen_corner(p_s); gen_corner(&p_s_013254); gen_corner(&p_s_102354); gen_corner(&p_s_103245); break; case JK_SOMA7_FILL: gen_soma7(p_s); gen_corner(&p_s_543210); break; case JK_DUAL_EDGE_FLAT: gen_face(-.5,-.5,&p_s_234501); gen_face(ARCSCALE,0,&p_s_230154); gen_face(0,ARCSCALE,&p_s_014532); gen_face(ARCSCALE,0,&p_s_321054); gen_face(0,ARCSCALE,&p_s_105432); gen_edge(0,&p_s_452310); gen_edge(0,&p_s_543210); break; case JK_DUAL_VOID: gen_face(0,0,&p_s_234501); gen_face(0,0,&p_s_451032); gen_face(0,0,&p_s_102354); gen_face(0,0,&p_s_543210); gen_face(0,0,&p_s_320145); gen_face(0,0,&p_s_015423); break; case JK_VOID: gen_face(0,0,&p_s_013254); gen_face(0,0,&p_s_540132); gen_face(0,0,&p_s_325401); break; } } static void setup_arc(void) { int i; for (i=ARCSEGS;i>=0;i--) { qc[i] = (XYF) { ARCSCALE * cos(i*M_PI/(2*ARCSEGS)), ARCSCALE * sin(i*M_PI/(2*ARCSEGS)) }; } } static void setup_mesh(void) { int x; int y; int z; int s; printf("@ size: (%d,%d,%d)\n",pcsz[2],pcsz[1],pcsz[0]); for (z=0;z0;x--) { for (y=pcsz[1]-1;y>0;y--) { for (z=pcsz[0]-1;z>0;z--) { s = (pc(x ,y ,z ).filled ? 1 : 0) | (pc(x-1,y ,z ).filled ? 2 : 0) | (pc(x ,y-1,z ).filled ? 4 : 0) | (pc(x-1,y-1,z ).filled ? 8 : 0) | (pc(x ,y ,z-1).filled ? 16 : 0) | (pc(x-1,y ,z-1).filled ? 32 : 0) | (pc(x ,y-1,z-1).filled ? 64 : 0) | (pc(x-1,y-1,z-1).filled ? 128 : 0); pc(x,y,z).j.syn = &syndrome[s]; printf("@ (%d,%d,%d) syndrome = %d%d%d%d%d%d%d%d (%s %s)\n", x,y,z, (s>>7)&1,(s>>6)&1,(s>>5)&1,(s>>4)&1, (s>>3)&1,(s>>2)&1,(s>>1)&1,s&1, jctkind_str(syndrome[s].kind),rot_str(syndrome[s].rot) ); } } } printf("@\n"); locs = 0; nlocs = 0; pts = 0; npts = 0; tris = 0; ntris = 0; for (x=pcsz[2]-1;x>0;x--) { for (y=pcsz[1]-1;y>0;y--) { for (z=pcsz[0]-1;z>0;z--) { SYNDROME *s; PT *p_s(XYZF d, XYZF n) { printf("@ ps: d=(%g,%g,%g) n=(%g,%g,%g) -> ", d.x,d.y,d.z,n.x,n.y,n.z); d = xyzf_add((XYZF){x,y,z},rot_delta_f(s->rot,d)); n = rot_delta_f(s->rot,n); printf("(%g,%g,%g) (%g,%g,%g)\n",d.x,d.y,d.z,n.x,n.y,n.z); return(pt_s(loc_cache(d),n)); } printf("@ calling gen_jct for (%d,%d,%d) (%s)\n",x,y,z,rot_str(pc(x,y,z).j.syn->rot)); s = pc(x,y,z).j.syn; gen_jct(s,&p_s); } } } } static void dump_output(void) { LOC *l; PT *p; TRI *t; int i; for (i=0,l=locs;l;l=l->link,i++) l->n = i; if (i != nlocs) abort(); for (i=0,p=pts;p;p=p->link,i++) p->n = i; if (i != npts) abort(); for (i=0,t=tris;t;t=t->link,i++) t->n = i; if (i != ntris) abort(); printf("@\nModelV1\n"); printf("1 %d %d %d\n",nlocs,npts,ntris); printf("White 0 0 0 .7 .7 .7 10 .5\n"); for (l=locs;l;l=l->link) printf("%g %g %g\n",l->p.x,l->p.y,l->p.z); for (p=pts;p;p=p->link) { switch (p->kind) { case PK_CORNER: printf("%d c\n",p->l->n); break; case PK_SURFACE: printf("%d s %g %g %g\n",p->l->n,p->sn.x,p->sn.y,p->sn.z); break; } } for (t=tris;t;t=t->link) printf("0 %d %d %d\n",t->a->n,t->b->n,t->c->n); } int main(void); int main(void) { read_pc(); setup_arc(); setup_mesh(); dump_output(); return(0); }