001: /* ct_puzzle_common.c

002:  * by Arnold Wendl, Fürth, anno Domini 2003

003:  */
004: /* eventuell bei UNIX-Compiler noetig:

005:  * #define __int64  long long

006:  */
007: 
008: #define BAUSTEINZAHL      12
009: #define MAX_TEILWUERFEL    6
010: 
011: typedef struct TP_KOORD {
012:   GrInt KOORD[3];
013: } KOORD;
014: static KOORD KOORD_NULLPUNKT = { 0,0,0 };
015: 
016: typedef struct TP_MATRIX {
017:   GrInt MATRIX[12];
018: } MATRIX;
019: 
020: typedef struct TP_BAUSTEIN {
021:   GrInt Teilwuerfelzahl, Beschriftet;
022:   /*@ Alle Beschriftungen vom 1. Teilwürfel - immer auf (0,0,0) - aus in z-Richtung */
023:   KOORD Min, Max, Einzelelemente[MAX_TEILWUERFEL];
024: } BAUSTEIN;
025: 
026: const BAUSTEIN Baustein[BAUSTEINZAHL] = {
027: /*  1 */ { 5, 1, { 0, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 2, 0}, { 1, 2, 0}, { 0, 0, 0} } },
028: /*  2 */ { 5, 1, { 0,-1,-2 }, { 0, 1, 0 }, { { 0, 0, 0}, { 0, 1, 0}, { 0, 0,-1}, { 0, 0,-2}, { 0,-1,-2}, { 0, 0, 0} } },
029: /*  3 */ { 5, 0, { 0, 0, 0 }, { 1, 3, 0 }, { { 0, 0, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 3, 0}, { 0, 0, 0} } },
030: /*  4 */ { 5, 0, { 0, 0, 0 }, { 1, 3, 0 }, { { 0, 0, 0}, { 1, 2, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 3, 0}, { 0, 0, 0} } },
031: /*  5 */ { 5, 1, { 0, 0,-1 }, { 1, 1, 0 }, { { 0, 0, 0}, { 1, 0,-1}, { 0, 1, 0}, { 0, 1,-1}, { 0, 0,-1}, { 0, 0, 0} } },
032: /*  6 */ { 5, 0, {-1, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, {-1, 2, 0}, { 1, 2, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 0, 0} } },
033: /*  7 */ { 5, 0, { 0, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, { 0, 2, 0}, { 1, 1, 0}, { 0, 1, 0}, { 1, 0, 0}, { 0, 0, 0} } },
034: /*  8 */ { 5, 0, {-1, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, {-1, 2, 0}, {-1, 1, 0}, { 0, 1, 0}, { 1, 0, 0}, { 0, 0, 0} } },
035: /*  9 */ { 4, 1, { 0, 0,-1 }, { 1, 1, 0 }, { { 0, 0, 0}, { 1, 1,-1}, { 0, 1, 0}, { 0, 1,-1}, { 0, 0, 0}, { 0, 0, 0} } },
036: /* 10 */ { 5, 0, {-1, 0, 0 }, { 1, 2, 0 }, { { 0, 0, 0}, { 1, 2, 0}, {-1, 1, 0}, { 0, 1, 0}, { 0, 2, 0}, { 0, 0, 0} } },
037: /* 11 */ { 5, 0, {-1,-1, 0 }, { 1, 1, 0 }, { { 0, 0, 0}, {-1, 0, 0}, { 0,-1, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 0, 0} } },
038: /* 12 */ { 6, 1, { 0, 0, 0 }, { 1, 3, 0 }, { { 0, 0, 0}, { 0, 3, 0}, { 1, 2, 0}, { 1, 0, 0}, { 0, 1, 0}, { 0, 2, 0} } }
039: };
040: 
041: MATRIX MatMul(MATRIX m1, MATRIX m2)
042: { MATRIX erg;
043:   memset(&erg, 0, sizeof(MATRIX));
044:   erg.MATRIX[0] = m1.MATRIX[0] * m2.MATRIX[0] + m1.MATRIX[3] * m2.MATRIX[1] + m1.MATRIX[6] * m2.MATRIX[2];
045:   erg.MATRIX[1] = m1.MATRIX[1] * m2.MATRIX[0] + m1.MATRIX[4] * m2.MATRIX[1] + m1.MATRIX[7] * m2.MATRIX[2];
046:   erg.MATRIX[2] = m1.MATRIX[2] * m2.MATRIX[0] + m1.MATRIX[5] * m2.MATRIX[1] + m1.MATRIX[8] * m2.MATRIX[2];
047:   erg.MATRIX[3] = m1.MATRIX[0] * m2.MATRIX[3] + m1.MATRIX[3] * m2.MATRIX[4] + m1.MATRIX[6] * m2.MATRIX[5];
048:   erg.MATRIX[4] = m1.MATRIX[1] * m2.MATRIX[3] + m1.MATRIX[4] * m2.MATRIX[4] + m1.MATRIX[7] * m2.MATRIX[5];
049:   erg.MATRIX[5] = m1.MATRIX[2] * m2.MATRIX[3] + m1.MATRIX[5] * m2.MATRIX[4] + m1.MATRIX[8] * m2.MATRIX[5];
050:   erg.MATRIX[6] = m1.MATRIX[0] * m2.MATRIX[6] + m1.MATRIX[3] * m2.MATRIX[7] + m1.MATRIX[6] * m2.MATRIX[8];
051:   erg.MATRIX[7] = m1.MATRIX[1] * m2.MATRIX[6] + m1.MATRIX[4] * m2.MATRIX[7] + m1.MATRIX[7] * m2.MATRIX[8];
052:   erg.MATRIX[8] = m1.MATRIX[2] * m2.MATRIX[6] + m1.MATRIX[5] * m2.MATRIX[7] + m1.MATRIX[8] * m2.MATRIX[8];
053:   erg.MATRIX[ 9] = m1.MATRIX[0] * m2.MATRIX[9] + m1.MATRIX[3] * m2.MATRIX[10] + m1.MATRIX[6] * m2.MATRIX[11] + m1.MATRIX[ 9];
054:   erg.MATRIX[10] = m1.MATRIX[1] * m2.MATRIX[9] + m1.MATRIX[4] * m2.MATRIX[10] + m1.MATRIX[7] * m2.MATRIX[11] + m1.MATRIX[10];
055:   erg.MATRIX[11] = m1.MATRIX[2] * m2.MATRIX[9] + m1.MATRIX[5] * m2.MATRIX[10] + m1.MATRIX[8] * m2.MATRIX[11] + m1.MATRIX[11];
056:   /* DUMP_MAT(erg) */ return erg;
057: }
058: 
059: KOORD PosTransKoord(MATRIX m, KOORD v)
060: { KOORD erg;
061:   erg.KOORD[0] = m.MATRIX[0] * v.KOORD[0] + m.MATRIX[3] * v.KOORD[1] + m.MATRIX[6] * v.KOORD[2] + m.MATRIX[ 9];
062:   erg.KOORD[1] = m.MATRIX[1] * v.KOORD[0] + m.MATRIX[4] * v.KOORD[1] + m.MATRIX[7] * v.KOORD[2] + m.MATRIX[10];
063:   erg.KOORD[2] = m.MATRIX[2] * v.KOORD[0] + m.MATRIX[5] * v.KOORD[1] + m.MATRIX[8] * v.KOORD[2] + m.MATRIX[11];
064:   return erg;
065: }
066: 
067: KOORD PosTrans3i(MATRIX m, int x, int y, int z)
068: { KOORD erg;
069:   erg.KOORD[0] = m.MATRIX[0] * x + m.MATRIX[3] * y + m.MATRIX[6] * z + m.MATRIX[ 9];
070:   erg.KOORD[1] = m.MATRIX[1] * x + m.MATRIX[4] * y + m.MATRIX[7] * z + m.MATRIX[10];
071:   erg.KOORD[2] = m.MATRIX[2] * x + m.MATRIX[5] * y + m.MATRIX[8] * z + m.MATRIX[11];
072:   return erg;
073: }
074: 
075: void GetBausteinExtends(BAUSTEIN *bs)
076: { int ct, xmin, ymin, zmin, xmax, ymax, zmax, w;
077:   // printf("GetBausteinExtends() ...\n");

078:   // DumpBS(stdout, *bs);

079:   xmin = xmax = bs->Einzelelemente[0].KOORD[0];
080:   ymin = ymax = bs->Einzelelemente[0].KOORD[1];
081:   zmin = zmax = bs->Einzelelemente[0].KOORD[2];
082:   for (ct = 1; ct < bs->Teilwuerfelzahl; ct++) {
083:     if ((w = bs->Einzelelemente[ct].KOORD[0]) > xmax) xmax = w;
084:     else if (w < xmin) xmin = w;
085:     if ((w = bs->Einzelelemente[ct].KOORD[1]) > ymax) ymax = w;
086:     else if (w < ymin) ymin = w;
087:     if ((w = bs->Einzelelemente[ct].KOORD[2]) > zmax) zmax = w;
088:     else if (w < zmin) zmin = w;
089:   }
090:   bs->Min.KOORD[0] = xmin; bs->Min.KOORD[1] = ymin; bs->Min.KOORD[2] = zmin;
091:   bs->Max.KOORD[0] = xmax; bs->Max.KOORD[1] = ymax; bs->Max.KOORD[2] = zmax;
092:   // DumpBS(stdout, *bs);

093: }
094: 
095: BAUSTEIN BewegterBaustein(BAUSTEIN bs, MATRIX m)
096: { BAUSTEIN erg;
097:   int ct;
098:   memset(&erg, 0, sizeof(BAUSTEIN));
099:   erg.Teilwuerfelzahl = bs.Teilwuerfelzahl;
100:   erg.Beschriftet = bs.Beschriftet;
101:   for (ct = 0; ct < bs.Teilwuerfelzahl; ct++) {
102:     erg.Einzelelemente[ct] = PosTransKoord(m, bs.Einzelelemente[ct]);
103:   }
104:   GetBausteinExtends(&erg);
105:   return erg;
106: }
107: