Povray code-ike-sym.inc

```
/\* This program is free software: you can redistribute it and/or modify it
 \* under the terms of the GNU General Public License as published by the Free
 \* Software Foundation, either version 3 of the License, or (at your option)
 \* any later version.
 \*
 \* This program is distributed in the hope that it will be useful, but WITHOUT
 \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 \* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 \* more details.
 \*
 \* You should have received a copy of the GNU General Public License along with
 \* this program. If not, see <http://www.gnu.org/licenses/>
 \*/

/\* Details for icosahedral symmetry \*/

#declare Phi = (1 + sqrt(5)) / 2;

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 \* \*
 \* Dodecahedron \*
 \* \*
 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
#declare NumDoeVertices = 20;
#declare DoeVertices = array[NumDoeVertices] {
 <0, 1, Phi \* Phi>,
 <0, 1, -Phi \* Phi>,
 <0, -1, Phi \* Phi>,
 <0, -1, -Phi \* Phi>,
 <1, Phi \* Phi, 0>,
 <1, -Phi \* Phi, 0>,
 <-1, Phi \* Phi, 0>,
 <-1, -Phi \* Phi, 0>,
 <Phi \* Phi, 0, 1>,
 <-Phi \* Phi, 0, 1>,
 <Phi \* Phi, 0, -1>,
 <-Phi \* Phi, 0, -1>,
 <Phi, Phi, Phi>,
 <Phi, Phi, -Phi>,
 <Phi, -Phi, Phi>,
 <Phi, -Phi, -Phi>,
 <-Phi, Phi, Phi>,
 <-Phi, Phi, -Phi>,
 <-Phi, -Phi, Phi>,
 <-Phi, -Phi, -Phi>
};

#declare DoeCircumradius = Phi \* sqrt(3);

#declare NumDoeEdges = 30;
#declare DoeEdges = array[NumDoeEdges][2] {
 { 0, 2}, { 0, 12}, { 0, 16},
 { 1, 3}, { 1, 13}, { 1, 17},
 { 2, 14}, { 2, 18}, { 3, 15},
 { 3, 19}, { 4, 6}, { 4, 12},
 { 4, 13}, { 5, 7}, { 5, 14},
 { 5, 15}, { 6, 16}, { 6, 17},
 { 7, 18}, { 7, 19}, { 8, 10},
 { 8, 12}, { 8, 14}, { 9, 11},
 { 9, 16}, { 9, 18}, {10, 13},
 {10, 15}, {11, 17}, {11, 19}
};

#declare DoeDoubleEdges = array[2 \* NumDoeEdges][2];
#for (E, 0, NumDoeEdges - 1, 1)
 #declare DoeDoubleEdges[E][0] = DoeEdges[E][0];
 #declare DoeDoubleEdges[E][1] = DoeEdges[E][1];
 #declare DoeDoubleEdges[E + NumDoeEdges][0] = DoeEdges[E][1];
 #declare DoeDoubleEdges[E + NumDoeEdges][1] = DoeEdges[E][0];
#end

#declare NumDoeFullFaces = 12;
#declare DoeFullFaces = array[NumDoeFullFaces][5] {
 { 4, 12, 8, 10, 13},
 { 5, 15, 10, 8, 14},
 { 6, 17, 11, 9, 16},
 { 7, 18, 9, 11, 19},
 { 0, 2, 14, 8, 12},
 { 0, 16, 9, 18, 2},
 { 1, 13, 10, 15, 3},
 { 1, 3, 19, 11, 17},
 { 0, 12, 4, 6, 16},
 { 1, 17, 6, 4, 13},
 { 2, 18, 7, 5, 14},
 { 3, 15, 5, 7, 19}
};

#declare DoeFaceEdges = array[NumDoeFullFaces][5];
#for (F, 0, NumDoeFullFaces - 1, 1)
 #for (DE, 0, 4, 1)
 #local V1 = DoeFullFaces[F][DE];
 #local V2 = DoeFullFaces[F][mod(DE + 1, 5)];
 #for (E, 0, 2 \* NumDoeEdges - 1, 1)
 #if (V1 = DoeDoubleEdges[E][0] & V2 = DoeDoubleEdges[E][1])
 #declare DoeFaceEdges[F][DE] = E;
 #end
 #end
 #end
#end

#declare DoeFullFaceSizes = array[NumDoeFullFaces][2];
#for (F, 0, NumDoeFullFaces - 1, 1)
 #declare DoeFullFaceSizes[F][0] = 5; // i.e. Pentagon = {5} = {5 / 1}
 #declare DoeFullFaceSizes[F][1] = 1;
#end

#declare NumDoeSplitFaces = NumDoeFullFaces \* 3;
#declare DoeSplitFaces = array[NumDoeSplitFaces][3];
#for (F, 0, NumDoeFullFaces - 1, 1)
 #declare DoeSplitFaces[3 \* F ][0] = DoeFullFaces[F][0];
 #declare DoeSplitFaces[3 \* F ][1] = DoeFullFaces[F][1];
 #declare DoeSplitFaces[3 \* F ][2] = DoeFullFaces[F][2];
 #declare DoeSplitFaces[3 \* F + 1][0] = DoeFullFaces[F][0];
 #declare DoeSplitFaces[3 \* F + 1][1] = DoeFullFaces[F][2];
 #declare DoeSplitFaces[3 \* F + 1][2] = DoeFullFaces[F][3];
 #declare DoeSplitFaces[3 \* F + 2][0] = DoeFullFaces[F][0];
 #declare DoeSplitFaces[3 \* F + 2][1] = DoeFullFaces[F][3];
 #declare DoeSplitFaces[3 \* F + 2][2] = DoeFullFaces[F][4];
#end

#declare DoeVertexOpposites = array[NumDoeVertices] {
 3, 2, 1, 0, 7, 6, 5, 4, 11, 10,
 9, 8, 19, 18, 17, 16, 15, 14, 13, 12
};

#declare DoeVertexVertex = array[NumDoeVertices][3] {
 { 2, 12, 16}, { 3, 13, 17}, { 0, 14, 18}, { 1, 15, 19}, { 6, 12, 13},
 { 7, 14, 15}, { 4, 16, 17}, { 5, 18, 19}, {10, 12, 14}, {11, 16, 18},
 { 8, 13, 15}, { 9, 17, 19}, { 0, 4, 8}, { 1, 4, 10}, { 2, 5, 8},
 { 3, 5, 10}, { 0, 6, 9}, { 1, 6, 11}, { 2, 7, 9}, { 3, 7, 11}
};

#declare NumGissidEdges = 30;
#declare GissidEdges = array[NumGissidEdges][2] {
 { 0, 1}, { 0, 15}, { 0, 19}, { 1, 14}, { 1, 18},
 { 2, 3}, { 2, 13}, { 2, 17}, { 3, 12}, { 3, 16},
 { 4, 5}, { 4, 18}, { 4, 19}, { 5, 16}, { 5, 17},
 { 6, 7}, { 6, 14}, { 6, 15}, { 7, 12}, { 7, 13},
 { 8, 9}, { 8, 17}, { 8, 19}, { 9, 13}, { 9, 15},
 {10, 11}, {10, 16}, {10, 18}, {11, 12}, {11, 14}
};
#declare GissidScale = 1 / Phi / Phi;

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 \* \*
 \* Icosahedron \*
 \* \*
 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
 // Ensure IkeVertices in same order as DoeFullFaces
#declare NumIkeVertices = 12;
#declare IkeVertices = array[NumIkeVertices] {
 <Phi, 1, 0>, <Phi, -1, 0>, <-Phi, 1, 0>, <-Phi, -1, 0>,
 <1, 0, Phi>, <-1, 0, Phi>, <1, 0, -Phi>, <-1, 0, -Phi>,
 <0, Phi, 1>, <0, Phi, -1>, <0, -Phi, 1>, <0, -Phi, -1>
};

#declare IkeCircumradius = sqrt(Phi \* sqrt(5));

#declare NumIkeEdges = 30;
#declare IkeEdges = array[NumIkeEdges][2] {
 { 4, 5}, { 8, 4}, { 5, 8}, { 7, 6}, { 6, 9},
 { 9, 7}, { 4, 10}, {10, 5}, {11, 6}, { 7, 11},
 { 8, 9}, { 0, 8}, { 9, 0}, {11, 10}, {10, 1},
 { 1, 11}, { 8, 2}, { 2, 9}, { 3, 10}, {11, 3},
 { 0, 1}, { 4, 0}, { 1, 4}, { 3, 2}, { 2, 5},
 { 5, 3}, { 0, 6}, { 6, 1}, { 7, 2}, { 3, 7}
};

#declare IkeDoubleEdges = array[2 \* NumIkeEdges][2];
#for (E, 0, NumIkeEdges - 1, 1)
 #declare IkeDoubleEdges[E ][0] = IkeEdges[E][0];
 #declare IkeDoubleEdges[E ][1] = IkeEdges[E][1];
 #declare IkeDoubleEdges[E + NumIkeEdges][0] = IkeEdges[E][1];
 #declare IkeDoubleEdges[E + NumIkeEdges][1] = IkeEdges[E][0];
#end

// Ensure IkeFaces in same order as DoeVertices
#declare NumIkeFaces = 20;
#declare IkeFaces = array[NumIkeFaces][3] {
 { 4, 5, 8}, { 6, 9, 7}, { 4, 10, 5}, { 6, 7, 11},
 { 0, 8, 9}, { 1, 11, 10}, { 2, 9, 8}, { 3, 10, 11},
 { 0, 1, 4}, { 2, 5, 3}, { 0, 6, 1}, { 2, 3, 7},
 { 0, 4, 8}, { 0, 9, 6}, { 1, 10, 4}, { 1, 6, 11},
 { 2, 8, 5}, { 2, 7, 9}, { 3, 5, 10}, { 3, 11, 7}
};

#declare IkeFaceEdges = array[NumIkeFaces][3];
#for (F, 0, NumIkeFaces - 1, 1)
 #for (IE, 0, 2, 1)
 #local V1 = IkeFaces[F][IE];
 #local V2 = IkeFaces[F][mod(IE + 1, 3)];
 #for (E, 0, 2 \* NumIkeEdges - 1, 1)
 #if (V1 = IkeDoubleEdges[E][0] & V2 = IkeDoubleEdges[E][1])
 #declare IkeFaceEdges[F][IE] = E;
 #end
 #end
 #end
#end

#declare IkeVertexVertex = array[NumIkeVertices][5] {
 { 9, 8, 4, 1, 6}, {10, 11, 6, 0, 4},
 { 8, 9, 7, 3, 5}, {11, 10, 5, 2, 7},
 { 8, 5, 10, 1, 0}, { 4, 8, 2, 3, 10},
 { 7, 9, 0, 1, 11}, { 9, 6, 11, 3, 2},
 { 5, 4, 0, 9, 2}, { 6, 7, 2, 8, 0},
 { 4, 5, 3, 11, 1}, { 7, 6, 1, 10, 3}
};

```