132001f49Smrg
232001f49Smrg/*-
332001f49Smrg * morph3d.c - Shows 3D morphing objects
432001f49Smrg *
532001f49Smrg * Converted to GLUT by brianp on 1/1/98
632001f49Smrg *
732001f49Smrg * This program was inspired on a WindowsNT(R)'s screen saver. It was written
832001f49Smrg * from scratch and it was not based on any other source code.
932001f49Smrg *
1032001f49Smrg * Porting it to xlock (the final objective of this code since the moment I
1132001f49Smrg * decided to create it) was possible by comparing the original Mesa's gear
1232001f49Smrg * demo with it's ported version, so thanks for Danny Sung for his indirect
1332001f49Smrg * help (look at gear.c in xlock source tree). NOTE: At the moment this code
1432001f49Smrg * was sent to Brian Paul for package inclusion, the XLock Version was not
1532001f49Smrg * available. In fact, I'll wait it to appear on the next Mesa release (If you
1632001f49Smrg * are reading this, it means THIS release) to send it for xlock package
1732001f49Smrg * inclusion). It will probably there be a GLUT version too.
1832001f49Smrg *
1932001f49Smrg * Thanks goes also to Brian Paul for making it possible and inexpensive
2032001f49Smrg * to use OpenGL at home.
2132001f49Smrg *
2232001f49Smrg * Since I'm not a native english speaker, my apologies for any gramatical
2332001f49Smrg * mistake.
2432001f49Smrg *
2532001f49Smrg * My e-mail addresses are
2632001f49Smrg *
2732001f49Smrg * vianna@cat.cbpf.br
2832001f49Smrg *         and
2932001f49Smrg * marcelo@venus.rdc.puc-rio.br
3032001f49Smrg *
3132001f49Smrg * Marcelo F. Vianna (Feb-13-1997)
3232001f49Smrg */
3332001f49Smrg
3432001f49Smrg/*
3532001f49SmrgThis document is VERY incomplete, but tries to describe the mathematics used
3632001f49Smrgin the program. At this moment it just describes how the polyhedra are
3732001f49Smrggenerated. On futhurer versions, this document will be probabbly improved.
3832001f49Smrg
3932001f49SmrgSince I'm not a native english speaker, my apologies for any gramatical
4032001f49Smrgmistake.
4132001f49Smrg
4232001f49SmrgMarcelo Fernandes Vianna
4332001f49Smrg- Undergraduate in Computer Engeneering at Catholic Pontifical University
4432001f49Smrg- of Rio de Janeiro (PUC-Rio) Brasil.
4532001f49Smrg- e-mail: vianna@cat.cbpf.br or marcelo@venus.rdc.puc-rio.br
4632001f49Smrg- Feb-13-1997
4732001f49Smrg
4832001f49SmrgPOLYHEDRA GENERATION
4932001f49Smrg
5032001f49SmrgFor the purpose of this program it's not sufficient to know the polyhedra
5132001f49Smrgvertexes coordinates. Since the morphing algorithm applies a nonlinear
5232001f49Smrgtransformation over the surfaces (faces) of the polyhedron, each face has
5332001f49Smrgto be divided into smaller ones. The morphing algorithm needs to transform
5432001f49Smrgeach vertex of these smaller faces individually. It's a very time consoming
5532001f49Smrgtask.
5632001f49Smrg
5732001f49SmrgIn order to reduce calculation overload, and since all the macro faces of
5832001f49Smrgthe polyhedron are transformed by the same way, the generation is made by
5932001f49Smrgcreating only one face of the polyhedron, morphing it and then rotating it
6032001f49Smrgaround the polyhedron center.
6132001f49Smrg
6232001f49SmrgWhat we need to know is the face radius of the polyhedron (the radius of
6332001f49Smrgthe inscribed sphere) and the angle between the center of two adjacent
6432001f49Smrgfaces using the center of the sphere as the angle's vertex.
6532001f49Smrg
6632001f49SmrgThe face radius of the regular polyhedra are known values which I decided
6732001f49Smrgto not waste my time calculating. Following is a table of face radius for
6832001f49Smrgthe regular polyhedra with edge length = 1:
6932001f49Smrg
7032001f49Smrg    TETRAHEDRON  : 1/(2*sqrt(2))/sqrt(3)
7132001f49Smrg    CUBE	 : 1/2
7232001f49Smrg    OCTAHEDRON   : 1/sqrt(6)
7332001f49Smrg    DODECAHEDRON : T^2 * sqrt((T+2)/5) / 2     -> where T=(sqrt(5)+1)/2
7432001f49Smrg    ICOSAHEDRON  : (3*sqrt(3)+sqrt(15))/12
7532001f49Smrg
7632001f49SmrgI've not found any reference about the mentioned angles, so I needed to
7732001f49Smrgcalculate them, not a trivial task until I figured out how :)
7832001f49SmrgCuriously these angles are the same for the tetrahedron and octahedron.
7932001f49SmrgA way to obtain this value is inscribing the tetrahedron inside the cube
8032001f49Smrgby matching their vertexes. So you'll notice that the remaining unmatched
8132001f49Smrgvertexes are in the same straight line starting in the cube/tetrahedron
8232001f49Smrgcenter and crossing the center of each tetrahedron's face. At this point
8332001f49Smrgit's easy to obtain the bigger angle of the isosceles triangle formed by
8432001f49Smrgthe center of the cube and two opposite vertexes on the same cube face.
8532001f49SmrgThe edges of this triangle have the following lenghts: sqrt(2) for the base
8632001f49Smrgand sqrt(3)/2 for the other two other edges. So the angle we want is:
8732001f49Smrg     +-----------------------------------------------------------+
8832001f49Smrg     | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees |
8932001f49Smrg     +-----------------------------------------------------------+
9032001f49SmrgFor the cube this angle is obvious, but just for formality it can be
9132001f49Smrgeasily obtained because we also know it's isosceles edge lenghts:
9232001f49Smrgsqrt(2)/2 for the base and 1/2 for the other two edges. So the angle we
9332001f49Smrgwant is:
9432001f49Smrg     +-----------------------------------------------------------+
9532001f49Smrg     | 2*ARCSIN((sqrt(2)/2)/1)   = 90.000000000000000000 degrees |
9632001f49Smrg     +-----------------------------------------------------------+
9732001f49SmrgFor the octahedron we use the same idea used for the tetrahedron, but now
9832001f49Smrgwe inscribe the cube inside the octahedron so that all cubes's vertexes
9932001f49Smrgmatches excatly the center of each octahedron's face. It's now clear that
10032001f49Smrgthis angle is the same of the thetrahedron one:
10132001f49Smrg     +-----------------------------------------------------------+
10232001f49Smrg     | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees |
10332001f49Smrg     +-----------------------------------------------------------+
10432001f49SmrgFor the dodecahedron it's a little bit harder because it's only relationship
10532001f49Smrgwith the cube is useless to us. So we need to solve the problem by another
10632001f49Smrgway. The concept of Face radius also exists on 2D polygons with the name
10732001f49SmrgEdge radius:
10832001f49Smrg  Edge Radius For Pentagon (ERp)
10932001f49Smrg  ERp = (1/2)/TAN(36 degrees) * VRp = 0.6881909602355867905
11032001f49Smrg  (VRp is the pentagon's vertex radio).
11132001f49Smrg  Face Radius For Dodecahedron
11232001f49Smrg  FRd = T^2 * sqrt((T+2)/5) / 2 = 1.1135163644116068404
11332001f49SmrgWhy we need ERp? Well, ERp and FRd segments forms a 90 degrees angle,
11432001f49Smrgcompleting this triangle, the lesser angle is a half of the angle we are
11532001f49Smrglooking for, so this angle is:
11632001f49Smrg     +-----------------------------------------------------------+
11732001f49Smrg     | 2*ARCTAN(ERp/FRd)	 = 63.434948822922009981 degrees |
11832001f49Smrg     +-----------------------------------------------------------+
11932001f49SmrgFor the icosahedron we can use the same method used for dodecahedron (well
12032001f49Smrgthe method used for dodecahedron may be used for all regular polyhedra)
12132001f49Smrg  Edge Radius For Triangle (this one is well known: 1/3 of the triangle height)
12232001f49Smrg  ERt = sin(60)/3 = sqrt(3)/6 = 0.2886751345948128655
12332001f49Smrg  Face Radius For Icosahedron
12432001f49Smrg  FRi= (3*sqrt(3)+sqrt(15))/12 = 0.7557613140761707538
12532001f49SmrgSo the angle is:
12632001f49Smrg     +-----------------------------------------------------------+
12732001f49Smrg     | 2*ARCTAN(ERt/FRi)	 = 41.810314895778596167 degrees |
12832001f49Smrg     +-----------------------------------------------------------+
12932001f49Smrg
13032001f49Smrg*/
13132001f49Smrg
13232001f49Smrg
13332001f49Smrg#include <stdio.h>
13432001f49Smrg#include <stdlib.h>
13532001f49Smrg#ifndef _WIN32
13632001f49Smrg#include <unistd.h>
13732001f49Smrg#endif
13832001f49Smrg#include "glut_wrap.h"
13932001f49Smrg#include <math.h>
14032001f49Smrg
14132001f49Smrg#define Scale                      0.3
14232001f49Smrg
14332001f49Smrg#define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2)
14432001f49Smrg#define sqr(A)                     ((A)*(A))
14532001f49Smrg
14632001f49Smrg/* Increasing this values produces better image quality, the price is speed. */
14732001f49Smrg/* Very low values produces erroneous/incorrect plotting */
14832001f49Smrg#define tetradivisions             23
14932001f49Smrg#define cubedivisions              20
15032001f49Smrg#define octadivisions              21
15132001f49Smrg#define dodecadivisions            10
15232001f49Smrg#define icodivisions               15
15332001f49Smrg
15432001f49Smrg#define tetraangle                 109.47122063449069174
15532001f49Smrg#define cubeangle                  90.000000000000000000
15632001f49Smrg#define octaangle                  109.47122063449069174
15732001f49Smrg#define dodecaangle                63.434948822922009981
15832001f49Smrg#define icoangle                   41.810314895778596167
15932001f49Smrg
16032001f49Smrg#ifndef Pi
16132001f49Smrg#define Pi                         3.1415926535897932385
16232001f49Smrg#endif
16332001f49Smrg#define SQRT2                      1.4142135623730951455
16432001f49Smrg#define SQRT3                      1.7320508075688771932
16532001f49Smrg#define SQRT5                      2.2360679774997898051
16632001f49Smrg#define SQRT6                      2.4494897427831778813
16732001f49Smrg#define SQRT15                     3.8729833462074170214
16832001f49Smrg#define cossec36_2                 0.8506508083520399322
16932001f49Smrg#define cos72                      0.3090169943749474241
17032001f49Smrg#define sin72                      0.9510565162951535721
17132001f49Smrg#define cos36                      0.8090169943749474241
17232001f49Smrg#define sin36                      0.5877852522924731292
17332001f49Smrg
17432001f49Smrg/*************************************************************************/
17532001f49Smrg
17632001f49Smrgstatic int       mono=0;
17732001f49Smrgstatic int       smooth=1;
17832001f49Smrgstatic int       anim=1;
17932001f49Smrgstatic GLint     WindH, WindW;
18032001f49Smrgstatic GLfloat   step=0;
18132001f49Smrgstatic GLfloat   seno;
18232001f49Smrgstatic int       object;
18332001f49Smrgstatic int       edgedivisions;
18432001f49Smrgstatic void      (*draw_object)( void );
18532001f49Smrgstatic float     Magnitude;
18632001f49Smrgstatic float     *MaterialColor[20];
18732001f49Smrg
18832001f49Smrgstatic float front_shininess[] =   {60.0};
18932001f49Smrgstatic float front_specular[]  =   { 0.7, 0.7, 0.7, 1.0 };
19032001f49Smrgstatic float ambient[]         =   { 0.0, 0.0, 0.0, 1.0 };
19132001f49Smrgstatic float diffuse[]         =   { 1.0, 1.0, 1.0, 1.0 };
19232001f49Smrgstatic float position0[]       =   { 1.0, 1.0, 1.0, 0.0 };
19332001f49Smrgstatic float position1[]       =   {-1.0,-1.0, 1.0, 0.0 };
19432001f49Smrgstatic float lmodel_ambient[]  =   { 0.5, 0.5, 0.5, 1.0 };
19532001f49Smrgstatic float lmodel_twoside[]  =   {GL_TRUE};
19632001f49Smrg
19732001f49Smrgstatic float MaterialRed[]     =   { 0.7, 0.0, 0.0, 1.0 };
19832001f49Smrgstatic float MaterialGreen[]   =   { 0.1, 0.5, 0.2, 1.0 };
19932001f49Smrgstatic float MaterialBlue[]    =   { 0.0, 0.0, 0.7, 1.0 };
20032001f49Smrgstatic float MaterialCyan[]    =   { 0.2, 0.5, 0.7, 1.0 };
20132001f49Smrgstatic float MaterialYellow[]  =   { 0.7, 0.7, 0.0, 1.0 };
20232001f49Smrgstatic float MaterialMagenta[] =   { 0.6, 0.2, 0.5, 1.0 };
20332001f49Smrgstatic float MaterialWhite[]   =   { 0.7, 0.7, 0.7, 1.0 };
20432001f49Smrgstatic float MaterialGray[]    =   { 0.2, 0.2, 0.2, 1.0 };
20532001f49Smrg
20632001f49Smrg#define TRIANGLE(Edge, Amp, Divisions, Z)                                                                        \
20732001f49Smrg{                                                                                                                \
20832001f49Smrg  GLfloat   Xf,Yf,Xa,Yb,Xf2,Yf2;                                                                                 \
20932001f49Smrg  GLfloat   Factor,Factor1,Factor2;                                                                              \
21032001f49Smrg  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
21132001f49Smrg  GLfloat   Ax,Ay,Bx;                                                                                            \
21232001f49Smrg  int       Ri,Ti;                                                                                               \
21332001f49Smrg  GLfloat   Vr=(Edge)*SQRT3/3;                                                                                   \
21432001f49Smrg  GLfloat   AmpVr2=(Amp)/sqr(Vr);                                                                                \
21532001f49Smrg  GLfloat   Zf=(Edge)*(Z);                                                                                       \
21632001f49Smrg                                                                                                                 \
21732001f49Smrg  Ax=(Edge)*(+0.5/(Divisions)), Ay=(Edge)*(-SQRT3/(2*Divisions));                                                \
21832001f49Smrg  Bx=(Edge)*(-0.5/(Divisions));                                                                                  \
21932001f49Smrg                                                                                                                 \
22032001f49Smrg  for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \
22132001f49Smrg    glBegin(GL_TRIANGLE_STRIP);                                                                                  \
22232001f49Smrg    for (Ti=0; Ti<Ri; Ti++) {                                                                                    \
22332001f49Smrg      Xf=(float)(Ri-Ti)*Ax + (float)Ti*Bx;                                                                       \
22432001f49Smrg      Yf=Vr+(float)(Ri-Ti)*Ay + (float)Ti*Ay;                                                                    \
22532001f49Smrg      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
22632001f49Smrg      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \
22732001f49Smrg      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
22832001f49Smrg      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
22932001f49Smrg      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
23032001f49Smrg      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
23132001f49Smrg      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
23232001f49Smrg      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
23332001f49Smrg      glVertex3f(VertX, VertY, VertZ);                                                                           \
23432001f49Smrg                                                                                                                 \
23532001f49Smrg      Xf=(float)(Ri-Ti-1)*Ax + (float)Ti*Bx;                                                                     \
23632001f49Smrg      Yf=Vr+(float)(Ri-Ti-1)*Ay + (float)Ti*Ay;                                                                  \
23732001f49Smrg      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
23832001f49Smrg      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \
23932001f49Smrg      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
24032001f49Smrg      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
24132001f49Smrg      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
24232001f49Smrg      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
24332001f49Smrg      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
24432001f49Smrg      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
24532001f49Smrg      glVertex3f(VertX, VertY, VertZ);                                                                           \
24632001f49Smrg                                                                                                                 \
24732001f49Smrg    }                                                                                                            \
24832001f49Smrg    Xf=(float)Ri*Bx;                                                                                             \
24932001f49Smrg    Yf=Vr+(float)Ri*Ay;                                                                                          \
25032001f49Smrg    Xa=Xf+0.001; Yb=Yf+0.001;                                                                                    \
25132001f49Smrg    Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                             \
25232001f49Smrg    Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                            \
25332001f49Smrg    Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                            \
25432001f49Smrg    VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                             \
25532001f49Smrg    NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                      \
25632001f49Smrg    NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                      \
25732001f49Smrg    glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                               \
25832001f49Smrg    glVertex3f(VertX, VertY, VertZ);                                                                             \
25932001f49Smrg    glEnd();                                                                                                     \
26032001f49Smrg  }                                                                                                              \
26132001f49Smrg}
26232001f49Smrg
26332001f49Smrg#define SQUARE(Edge, Amp, Divisions, Z)                                                                          \
26432001f49Smrg{                                                                                                                \
26532001f49Smrg  int       Xi,Yi;                                                                                               \
26632001f49Smrg  GLfloat   Xf,Yf,Y,Xf2,Yf2,Y2,Xa,Yb;                                                                            \
26732001f49Smrg  GLfloat   Factor,Factor1,Factor2;                                                                              \
26832001f49Smrg  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
26932001f49Smrg  GLfloat   Zf=(Edge)*(Z);                                                                                       \
27032001f49Smrg  GLfloat   AmpVr2=(Amp)/sqr((Edge)*SQRT2/2);                                                                    \
27132001f49Smrg                                                                                                                 \
27232001f49Smrg  for (Yi=0; Yi<(Divisions); Yi++) {                                                                             \
27332001f49Smrg    Yf=-((Edge)/2.0) + ((float)Yi)/(Divisions)*(Edge);                                                           \
27432001f49Smrg    Yf2=sqr(Yf);                                                                                                 \
27532001f49Smrg    Y=Yf+1.0/(Divisions)*(Edge);                                                                                 \
27632001f49Smrg    Y2=sqr(Y);                                                                                                   \
27732001f49Smrg    glBegin(GL_QUAD_STRIP);                                                                                      \
27832001f49Smrg    for (Xi=0; Xi<=(Divisions); Xi++) {                                                                          \
27932001f49Smrg      Xf=-((Edge)/2.0) + ((float)Xi)/(Divisions)*(Edge);                                                         \
28032001f49Smrg      Xf2=sqr(Xf);                                                                                               \
28132001f49Smrg                                                                                                                 \
28232001f49Smrg      Xa=Xf+0.001; Yb=Y+0.001;                                                                                   \
28332001f49Smrg      Factor=1-((Xf2+Y2)*AmpVr2);                                                                                \
28432001f49Smrg      Factor1=1-((sqr(Xa)+Y2)*AmpVr2);                                                                           \
28532001f49Smrg      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
28632001f49Smrg      VertX=Factor*Xf;        VertY=Factor*Y;         VertZ=Factor*Zf;                                           \
28732001f49Smrg      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Y-VertY;  NeiAZ=Factor1*Zf-VertZ;                                    \
28832001f49Smrg      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
28932001f49Smrg      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
29032001f49Smrg      glVertex3f(VertX, VertY, VertZ);                                                                           \
29132001f49Smrg                                                                                                                 \
29232001f49Smrg      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
29332001f49Smrg      Factor=1-((Xf2+Yf2)*AmpVr2);                                                                               \
29432001f49Smrg      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
29532001f49Smrg      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
29632001f49Smrg      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
29732001f49Smrg      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
29832001f49Smrg      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
29932001f49Smrg      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
30032001f49Smrg      glVertex3f(VertX, VertY, VertZ);                                                                           \
30132001f49Smrg    }                                                                                                            \
30232001f49Smrg    glEnd();                                                                                                     \
30332001f49Smrg  }                                                                                                              \
30432001f49Smrg}
30532001f49Smrg
30632001f49Smrg#define PENTAGON(Edge, Amp, Divisions, Z)                                                                        \
30732001f49Smrg{                                                                                                                \
30832001f49Smrg  int       Ri,Ti,Fi;                                                                                            \
30932001f49Smrg  GLfloat   Xf,Yf,Xa,Yb,Xf2,Yf2;                                                                                 \
31032001f49Smrg  GLfloat   x[6],y[6];                                                                                           \
31132001f49Smrg  GLfloat   Factor,Factor1,Factor2;                                                                              \
31232001f49Smrg  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
31332001f49Smrg  GLfloat   Zf=(Edge)*(Z);                                                                                       \
31432001f49Smrg  GLfloat   AmpVr2=(Amp)/sqr((Edge)*cossec36_2);                                                                 \
31532001f49Smrg                                                                                                                 \
31632001f49Smrg  for(Fi=0;Fi<6;Fi++) {                                                                                          \
31732001f49Smrg    x[Fi]=-cos( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                                \
31832001f49Smrg    y[Fi]=sin( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                                \
31932001f49Smrg  }                                                                                                              \
32032001f49Smrg                                                                                                                 \
32132001f49Smrg  for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \
32232001f49Smrg    for (Fi=0; Fi<5; Fi++) {                                                                                     \
32332001f49Smrg      glBegin(GL_TRIANGLE_STRIP);                                                                                \
32432001f49Smrg      for (Ti=0; Ti<Ri; Ti++) {                                                                                  \
32532001f49Smrg        Xf=(float)(Ri-Ti)*x[Fi] + (float)Ti*x[Fi+1];                                                             \
32632001f49Smrg        Yf=(float)(Ri-Ti)*y[Fi] + (float)Ti*y[Fi+1];                                                             \
32732001f49Smrg        Xa=Xf+0.001; Yb=Yf+0.001;                                                                                \
32832001f49Smrg	Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \
32932001f49Smrg	Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \
33032001f49Smrg	Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \
33132001f49Smrg        VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \
33232001f49Smrg        NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \
33332001f49Smrg        NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \
33432001f49Smrg        glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \
33532001f49Smrg	glVertex3f(VertX, VertY, VertZ);                                                                         \
33632001f49Smrg                                                                                                                 \
33732001f49Smrg        Xf=(float)(Ri-Ti-1)*x[Fi] + (float)Ti*x[Fi+1];                                                           \
33832001f49Smrg        Yf=(float)(Ri-Ti-1)*y[Fi] + (float)Ti*y[Fi+1];                                                           \
33932001f49Smrg        Xa=Xf+0.001; Yb=Yf+0.001;                                                                                \
34032001f49Smrg	Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \
34132001f49Smrg	Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \
34232001f49Smrg	Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \
34332001f49Smrg        VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \
34432001f49Smrg        NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \
34532001f49Smrg        NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \
34632001f49Smrg        glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \
34732001f49Smrg	glVertex3f(VertX, VertY, VertZ);                                                                         \
34832001f49Smrg                                                                                                                 \
34932001f49Smrg      }                                                                                                          \
35032001f49Smrg      Xf=(float)Ri*x[Fi+1];                                                                                      \
35132001f49Smrg      Yf=(float)Ri*y[Fi+1];                                                                                      \
35232001f49Smrg      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
35332001f49Smrg      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \
35432001f49Smrg      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
35532001f49Smrg      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
35632001f49Smrg      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
35732001f49Smrg      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
35832001f49Smrg      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
35932001f49Smrg      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
36032001f49Smrg      glVertex3f(VertX, VertY, VertZ);                                                                           \
36132001f49Smrg      glEnd();                                                                                                   \
36232001f49Smrg    }                                                                                                            \
36332001f49Smrg  }                                                                                                              \
36432001f49Smrg}
36532001f49Smrg
36632001f49Smrgstatic void draw_tetra( void )
36732001f49Smrg{
36832001f49Smrg  GLuint list;
36932001f49Smrg
37032001f49Smrg  list = glGenLists( 1 );
37132001f49Smrg  glNewList( list, GL_COMPILE );
37232001f49Smrg  TRIANGLE(2,seno,edgedivisions,0.5/SQRT6);
37332001f49Smrg  glEndList();
37432001f49Smrg
37532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
37632001f49Smrg  glCallList(list);
37732001f49Smrg  glPushMatrix();
37832001f49Smrg  glRotatef(180,0,0,1);
37932001f49Smrg  glRotatef(-tetraangle,1,0,0);
38032001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
38132001f49Smrg  glCallList(list);
38232001f49Smrg  glPopMatrix();
38332001f49Smrg  glPushMatrix();
38432001f49Smrg  glRotatef(180,0,1,0);
38532001f49Smrg  glRotatef(-180+tetraangle,0.5,SQRT3/2,0);
38632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
38732001f49Smrg  glCallList(list);
38832001f49Smrg  glPopMatrix();
38932001f49Smrg  glRotatef(180,0,1,0);
39032001f49Smrg  glRotatef(-180+tetraangle,0.5,-SQRT3/2,0);
39132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
39232001f49Smrg  glCallList(list);
39332001f49Smrg
39432001f49Smrg  glDeleteLists(list,1);
39532001f49Smrg}
39632001f49Smrg
39732001f49Smrgstatic void draw_cube( void )
39832001f49Smrg{
39932001f49Smrg  GLuint list;
40032001f49Smrg
40132001f49Smrg  list = glGenLists( 1 );
40232001f49Smrg  glNewList( list, GL_COMPILE );
40332001f49Smrg  SQUARE(2, seno, edgedivisions, 0.5)
40432001f49Smrg  glEndList();
40532001f49Smrg
40632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
40732001f49Smrg  glCallList(list);
40832001f49Smrg  glRotatef(cubeangle,1,0,0);
40932001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
41032001f49Smrg  glCallList(list);
41132001f49Smrg  glRotatef(cubeangle,1,0,0);
41232001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
41332001f49Smrg  glCallList(list);
41432001f49Smrg  glRotatef(cubeangle,1,0,0);
41532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
41632001f49Smrg  glCallList(list);
41732001f49Smrg  glRotatef(cubeangle,0,1,0);
41832001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
41932001f49Smrg  glCallList(list);
42032001f49Smrg  glRotatef(2*cubeangle,0,1,0);
42132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
42232001f49Smrg  glCallList(list);
42332001f49Smrg
42432001f49Smrg  glDeleteLists(list,1);
42532001f49Smrg}
42632001f49Smrg
42732001f49Smrgstatic void draw_octa( void )
42832001f49Smrg{
42932001f49Smrg  GLuint list;
43032001f49Smrg
43132001f49Smrg  list = glGenLists( 1 );
43232001f49Smrg  glNewList( list, GL_COMPILE );
43332001f49Smrg  TRIANGLE(2,seno,edgedivisions,1/SQRT6);
43432001f49Smrg  glEndList();
43532001f49Smrg
43632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
43732001f49Smrg  glCallList(list);
43832001f49Smrg  glPushMatrix();
43932001f49Smrg  glRotatef(180,0,0,1);
44032001f49Smrg  glRotatef(-180+octaangle,1,0,0);
44132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
44232001f49Smrg  glCallList(list);
44332001f49Smrg  glPopMatrix();
44432001f49Smrg  glPushMatrix();
44532001f49Smrg  glRotatef(180,0,1,0);
44632001f49Smrg  glRotatef(-octaangle,0.5,SQRT3/2,0);
44732001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
44832001f49Smrg  glCallList(list);
44932001f49Smrg  glPopMatrix();
45032001f49Smrg  glPushMatrix();
45132001f49Smrg  glRotatef(180,0,1,0);
45232001f49Smrg  glRotatef(-octaangle,0.5,-SQRT3/2,0);
45332001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
45432001f49Smrg  glCallList(list);
45532001f49Smrg  glPopMatrix();
45632001f49Smrg  glRotatef(180,1,0,0);
45732001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
45832001f49Smrg  glCallList(list);
45932001f49Smrg  glPushMatrix();
46032001f49Smrg  glRotatef(180,0,0,1);
46132001f49Smrg  glRotatef(-180+octaangle,1,0,0);
46232001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
46332001f49Smrg  glCallList(list);
46432001f49Smrg  glPopMatrix();
46532001f49Smrg  glPushMatrix();
46632001f49Smrg  glRotatef(180,0,1,0);
46732001f49Smrg  glRotatef(-octaangle,0.5,SQRT3/2,0);
46832001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
46932001f49Smrg  glCallList(list);
47032001f49Smrg  glPopMatrix();
47132001f49Smrg  glRotatef(180,0,1,0);
47232001f49Smrg  glRotatef(-octaangle,0.5,-SQRT3/2,0);
47332001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
47432001f49Smrg  glCallList(list);
47532001f49Smrg
47632001f49Smrg  glDeleteLists(list,1);
47732001f49Smrg}
47832001f49Smrg
47932001f49Smrgstatic void draw_dodeca( void )
48032001f49Smrg{
48132001f49Smrg  GLuint list;
48232001f49Smrg
48332001f49Smrg#define TAU ((SQRT5+1)/2)
48432001f49Smrg
48532001f49Smrg  list = glGenLists( 1 );
48632001f49Smrg  glNewList( list, GL_COMPILE );
48732001f49Smrg  PENTAGON(1,seno,edgedivisions,sqr(TAU) * sqrt((TAU+2)/5) / 2);
48832001f49Smrg  glEndList();
48932001f49Smrg
49032001f49Smrg  glPushMatrix();
49132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
49232001f49Smrg  glCallList(list);
49332001f49Smrg  glRotatef(180,0,0,1);
49432001f49Smrg  glPushMatrix();
49532001f49Smrg  glRotatef(-dodecaangle,1,0,0);
49632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
49732001f49Smrg  glCallList(list);
49832001f49Smrg  glPopMatrix();
49932001f49Smrg  glPushMatrix();
50032001f49Smrg  glRotatef(-dodecaangle,cos72,sin72,0);
50132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
50232001f49Smrg  glCallList(list);
50332001f49Smrg  glPopMatrix();
50432001f49Smrg  glPushMatrix();
50532001f49Smrg  glRotatef(-dodecaangle,cos72,-sin72,0);
50632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
50732001f49Smrg  glCallList(list);
50832001f49Smrg  glPopMatrix();
50932001f49Smrg  glPushMatrix();
51032001f49Smrg  glRotatef(dodecaangle,cos36,-sin36,0);
51132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
51232001f49Smrg  glCallList(list);
51332001f49Smrg  glPopMatrix();
51432001f49Smrg  glRotatef(dodecaangle,cos36,sin36,0);
51532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
51632001f49Smrg  glCallList(list);
51732001f49Smrg  glPopMatrix();
51832001f49Smrg  glRotatef(180,1,0,0);
51932001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
52032001f49Smrg  glCallList(list);
52132001f49Smrg  glRotatef(180,0,0,1);
52232001f49Smrg  glPushMatrix();
52332001f49Smrg  glRotatef(-dodecaangle,1,0,0);
52432001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
52532001f49Smrg  glCallList(list);
52632001f49Smrg  glPopMatrix();
52732001f49Smrg  glPushMatrix();
52832001f49Smrg  glRotatef(-dodecaangle,cos72,sin72,0);
52932001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]);
53032001f49Smrg  glCallList(list);
53132001f49Smrg  glPopMatrix();
53232001f49Smrg  glPushMatrix();
53332001f49Smrg  glRotatef(-dodecaangle,cos72,-sin72,0);
53432001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]);
53532001f49Smrg  glCallList(list);
53632001f49Smrg  glPopMatrix();
53732001f49Smrg  glPushMatrix();
53832001f49Smrg  glRotatef(dodecaangle,cos36,-sin36,0);
53932001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]);
54032001f49Smrg  glCallList(list);
54132001f49Smrg  glPopMatrix();
54232001f49Smrg  glRotatef(dodecaangle,cos36,sin36,0);
54332001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]);
54432001f49Smrg  glCallList(list);
54532001f49Smrg
54632001f49Smrg  glDeleteLists(list,1);
54732001f49Smrg}
54832001f49Smrg
54932001f49Smrgstatic void draw_ico( void )
55032001f49Smrg{
55132001f49Smrg  GLuint list;
55232001f49Smrg
55332001f49Smrg  list = glGenLists( 1 );
55432001f49Smrg  glNewList( list, GL_COMPILE );
55532001f49Smrg  TRIANGLE(1.5,seno,edgedivisions,(3*SQRT3+SQRT15)/12);
55632001f49Smrg  glEndList();
55732001f49Smrg
55832001f49Smrg  glPushMatrix();
55932001f49Smrg
56032001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
56132001f49Smrg  glCallList(list);
56232001f49Smrg  glPushMatrix();
56332001f49Smrg  glRotatef(180,0,0,1);
56432001f49Smrg  glRotatef(-icoangle,1,0,0);
56532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
56632001f49Smrg  glCallList(list);
56732001f49Smrg  glPushMatrix();
56832001f49Smrg  glRotatef(180,0,1,0);
56932001f49Smrg  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
57032001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
57132001f49Smrg  glCallList(list);
57232001f49Smrg  glPopMatrix();
57332001f49Smrg  glRotatef(180,0,1,0);
57432001f49Smrg  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
57532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
57632001f49Smrg  glCallList(list);
57732001f49Smrg  glPopMatrix();
57832001f49Smrg  glPushMatrix();
57932001f49Smrg  glRotatef(180,0,1,0);
58032001f49Smrg  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
58132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
58232001f49Smrg  glCallList(list);
58332001f49Smrg  glPushMatrix();
58432001f49Smrg  glRotatef(180,0,1,0);
58532001f49Smrg  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
58632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
58732001f49Smrg  glCallList(list);
58832001f49Smrg  glPopMatrix();
58932001f49Smrg  glRotatef(180,0,0,1);
59032001f49Smrg  glRotatef(-icoangle,1,0,0);
59132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
59232001f49Smrg  glCallList(list);
59332001f49Smrg  glPopMatrix();
59432001f49Smrg  glRotatef(180,0,1,0);
59532001f49Smrg  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
59632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
59732001f49Smrg  glCallList(list);
59832001f49Smrg  glPushMatrix();
59932001f49Smrg  glRotatef(180,0,1,0);
60032001f49Smrg  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
60132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]);
60232001f49Smrg  glCallList(list);
60332001f49Smrg  glPopMatrix();
60432001f49Smrg  glRotatef(180,0,0,1);
60532001f49Smrg  glRotatef(-icoangle,1,0,0);
60632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]);
60732001f49Smrg  glCallList(list);
60832001f49Smrg  glPopMatrix();
60932001f49Smrg  glRotatef(180,1,0,0);
61032001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]);
61132001f49Smrg  glCallList(list);
61232001f49Smrg  glPushMatrix();
61332001f49Smrg  glRotatef(180,0,0,1);
61432001f49Smrg  glRotatef(-icoangle,1,0,0);
61532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]);
61632001f49Smrg  glCallList(list);
61732001f49Smrg  glPushMatrix();
61832001f49Smrg  glRotatef(180,0,1,0);
61932001f49Smrg  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
62032001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[12]);
62132001f49Smrg  glCallList(list);
62232001f49Smrg  glPopMatrix();
62332001f49Smrg  glRotatef(180,0,1,0);
62432001f49Smrg  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
62532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[13]);
62632001f49Smrg  glCallList(list);
62732001f49Smrg  glPopMatrix();
62832001f49Smrg  glPushMatrix();
62932001f49Smrg  glRotatef(180,0,1,0);
63032001f49Smrg  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
63132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[14]);
63232001f49Smrg  glCallList(list);
63332001f49Smrg  glPushMatrix();
63432001f49Smrg  glRotatef(180,0,1,0);
63532001f49Smrg  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
63632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[15]);
63732001f49Smrg  glCallList(list);
63832001f49Smrg  glPopMatrix();
63932001f49Smrg  glRotatef(180,0,0,1);
64032001f49Smrg  glRotatef(-icoangle,1,0,0);
64132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[16]);
64232001f49Smrg  glCallList(list);
64332001f49Smrg  glPopMatrix();
64432001f49Smrg  glRotatef(180,0,1,0);
64532001f49Smrg  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
64632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[17]);
64732001f49Smrg  glCallList(list);
64832001f49Smrg  glPushMatrix();
64932001f49Smrg  glRotatef(180,0,1,0);
65032001f49Smrg  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
65132001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[18]);
65232001f49Smrg  glCallList(list);
65332001f49Smrg  glPopMatrix();
65432001f49Smrg  glRotatef(180,0,0,1);
65532001f49Smrg  glRotatef(-icoangle,1,0,0);
65632001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[19]);
65732001f49Smrg  glCallList(list);
65832001f49Smrg
65932001f49Smrg  glDeleteLists(list,1);
66032001f49Smrg}
66132001f49Smrg
66232001f49Smrgstatic void draw ( void ) {
66332001f49Smrg  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
66432001f49Smrg
66532001f49Smrg  glPushMatrix();
66632001f49Smrg
66732001f49Smrg    glTranslatef( 0.0, 0.0, -10.0 );
66832001f49Smrg    glScalef( Scale*WindH/WindW, Scale, Scale );
66932001f49Smrg    glTranslatef(2.5*WindW/WindH*sin(step*1.11),2.5*cos(step*1.25*1.11),0);
67032001f49Smrg    glRotatef(step*100,1,0,0);
67132001f49Smrg    glRotatef(step*95,0,1,0);
67232001f49Smrg    glRotatef(step*90,0,0,1);
67332001f49Smrg
67432001f49Smrg  seno=(sin(step)+1.0/3.0)*(4.0/5.0)*Magnitude;
67532001f49Smrg
67632001f49Smrg  draw_object();
67732001f49Smrg
67832001f49Smrg  glPopMatrix();
67932001f49Smrg
68032001f49Smrg  glFlush();
68132001f49Smrg
68232001f49Smrg  glutSwapBuffers();
68332001f49Smrg
68432001f49Smrg}
68532001f49Smrg
68632001f49Smrgstatic void idle_( void )
68732001f49Smrg{
68832001f49Smrg  static double t0 = -1.;
68932001f49Smrg  double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
69032001f49Smrg  if (t0 < 0.0)
69132001f49Smrg     t0 = t;
69232001f49Smrg  dt = t - t0;
69332001f49Smrg  t0 = t;
69432001f49Smrg
69532001f49Smrg  step += dt;
69632001f49Smrg
69732001f49Smrg   glutPostRedisplay();
69832001f49Smrg}
69932001f49Smrg
70032001f49Smrgstatic void reshape( int width, int height )
70132001f49Smrg{
70232001f49Smrg  glViewport(0, 0, WindW=(GLint)width, WindH=(GLint)height);
70332001f49Smrg  glMatrixMode(GL_PROJECTION);
70432001f49Smrg  glLoadIdentity();
70532001f49Smrg  glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
70632001f49Smrg  glMatrixMode(GL_MODELVIEW);
70732001f49Smrg}
70832001f49Smrg
70932001f49Smrgstatic void pinit(void);
71032001f49Smrg
71132001f49Smrgstatic void key( unsigned char k, int x, int y )
71232001f49Smrg{
71332001f49Smrg  (void) x;
71432001f49Smrg  (void) y;
71532001f49Smrg  switch (k) {
71632001f49Smrg    case '1': object=1; break;
71732001f49Smrg    case '2': object=2; break;
71832001f49Smrg    case '3': object=3; break;
71932001f49Smrg    case '4': object=4; break;
72032001f49Smrg    case '5': object=5; break;
72132001f49Smrg    case ' ': mono^=1; break;
72232001f49Smrg    case 's': smooth^=1; break;
72332001f49Smrg    case 'a':
72432001f49Smrg       anim^=1;
72532001f49Smrg       if (anim)
72632001f49Smrg          glutIdleFunc( idle_ );
72732001f49Smrg       else
72832001f49Smrg          glutIdleFunc(NULL);
72932001f49Smrg       break;
73032001f49Smrg    case 27:
73132001f49Smrg       exit(0);
73232001f49Smrg  }
73332001f49Smrg  pinit();
73432001f49Smrg  glutPostRedisplay();
73532001f49Smrg}
73632001f49Smrg
73732001f49Smrgstatic void pinit(void)
73832001f49Smrg{
73932001f49Smrg  switch(object) {
74032001f49Smrg    case 1:
74132001f49Smrg      draw_object=draw_tetra;
74232001f49Smrg      MaterialColor[0]=MaterialRed;
74332001f49Smrg      MaterialColor[1]=MaterialGreen;
74432001f49Smrg      MaterialColor[2]=MaterialBlue;
74532001f49Smrg      MaterialColor[3]=MaterialWhite;
74632001f49Smrg      edgedivisions=tetradivisions;
74732001f49Smrg      Magnitude=2.5;
74832001f49Smrg      break;
74932001f49Smrg    case 2:
75032001f49Smrg      draw_object=draw_cube;
75132001f49Smrg      MaterialColor[0]=MaterialRed;
75232001f49Smrg      MaterialColor[1]=MaterialGreen;
75332001f49Smrg      MaterialColor[2]=MaterialCyan;
75432001f49Smrg      MaterialColor[3]=MaterialMagenta;
75532001f49Smrg      MaterialColor[4]=MaterialYellow;
75632001f49Smrg      MaterialColor[5]=MaterialBlue;
75732001f49Smrg      edgedivisions=cubedivisions;
75832001f49Smrg      Magnitude=2.0;
75932001f49Smrg      break;
76032001f49Smrg    case 3:
76132001f49Smrg      draw_object=draw_octa;
76232001f49Smrg      MaterialColor[0]=MaterialRed;
76332001f49Smrg      MaterialColor[1]=MaterialGreen;
76432001f49Smrg      MaterialColor[2]=MaterialBlue;
76532001f49Smrg      MaterialColor[3]=MaterialWhite;
76632001f49Smrg      MaterialColor[4]=MaterialCyan;
76732001f49Smrg      MaterialColor[5]=MaterialMagenta;
76832001f49Smrg      MaterialColor[6]=MaterialGray;
76932001f49Smrg      MaterialColor[7]=MaterialYellow;
77032001f49Smrg      edgedivisions=octadivisions;
77132001f49Smrg      Magnitude=2.5;
77232001f49Smrg      break;
77332001f49Smrg    case 4:
77432001f49Smrg      draw_object=draw_dodeca;
77532001f49Smrg      MaterialColor[ 0]=MaterialRed;
77632001f49Smrg      MaterialColor[ 1]=MaterialGreen;
77732001f49Smrg      MaterialColor[ 2]=MaterialCyan;
77832001f49Smrg      MaterialColor[ 3]=MaterialBlue;
77932001f49Smrg      MaterialColor[ 4]=MaterialMagenta;
78032001f49Smrg      MaterialColor[ 5]=MaterialYellow;
78132001f49Smrg      MaterialColor[ 6]=MaterialGreen;
78232001f49Smrg      MaterialColor[ 7]=MaterialCyan;
78332001f49Smrg      MaterialColor[ 8]=MaterialRed;
78432001f49Smrg      MaterialColor[ 9]=MaterialMagenta;
78532001f49Smrg      MaterialColor[10]=MaterialBlue;
78632001f49Smrg      MaterialColor[11]=MaterialYellow;
78732001f49Smrg      edgedivisions=dodecadivisions;
78832001f49Smrg      Magnitude=2.0;
78932001f49Smrg      break;
79032001f49Smrg    case 5:
79132001f49Smrg      draw_object=draw_ico;
79232001f49Smrg      MaterialColor[ 0]=MaterialRed;
79332001f49Smrg      MaterialColor[ 1]=MaterialGreen;
79432001f49Smrg      MaterialColor[ 2]=MaterialBlue;
79532001f49Smrg      MaterialColor[ 3]=MaterialCyan;
79632001f49Smrg      MaterialColor[ 4]=MaterialYellow;
79732001f49Smrg      MaterialColor[ 5]=MaterialMagenta;
79832001f49Smrg      MaterialColor[ 6]=MaterialRed;
79932001f49Smrg      MaterialColor[ 7]=MaterialGreen;
80032001f49Smrg      MaterialColor[ 8]=MaterialBlue;
80132001f49Smrg      MaterialColor[ 9]=MaterialWhite;
80232001f49Smrg      MaterialColor[10]=MaterialCyan;
80332001f49Smrg      MaterialColor[11]=MaterialYellow;
80432001f49Smrg      MaterialColor[12]=MaterialMagenta;
80532001f49Smrg      MaterialColor[13]=MaterialRed;
80632001f49Smrg      MaterialColor[14]=MaterialGreen;
80732001f49Smrg      MaterialColor[15]=MaterialBlue;
80832001f49Smrg      MaterialColor[16]=MaterialCyan;
80932001f49Smrg      MaterialColor[17]=MaterialYellow;
81032001f49Smrg      MaterialColor[18]=MaterialMagenta;
81132001f49Smrg      MaterialColor[19]=MaterialGray;
81232001f49Smrg      edgedivisions=icodivisions;
81332001f49Smrg      Magnitude=2.5;
81432001f49Smrg      break;
81532001f49Smrg  }
81632001f49Smrg  if (mono) {
81732001f49Smrg    int loop;
81832001f49Smrg    for (loop=0; loop<20; loop++) MaterialColor[loop]=MaterialGray;
81932001f49Smrg  }
82032001f49Smrg  if (smooth) {
82132001f49Smrg    glShadeModel( GL_SMOOTH );
82232001f49Smrg  } else {
82332001f49Smrg    glShadeModel( GL_FLAT );
82432001f49Smrg  }
82532001f49Smrg
82632001f49Smrg}
82732001f49Smrg
82832001f49Smrgint main(int argc, char **argv)
82932001f49Smrg{
83032001f49Smrg  printf("Morph 3D - Shows morphing platonic polyhedra\n");
83132001f49Smrg  printf("Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n\n");
83232001f49Smrg  printf("  [1]    - Tetrahedron\n");
83332001f49Smrg  printf("  [2]    - Hexahedron (Cube)\n");
83432001f49Smrg  printf("  [3]    - Octahedron\n");
83532001f49Smrg  printf("  [4]    - Dodecahedron\n");
83632001f49Smrg  printf("  [5]    - Icosahedron\n");
83732001f49Smrg  printf("[SPACE]  - Toggle colored faces\n");
83832001f49Smrg  printf("[RETURN] - Toggle smooth/flat shading\n");
83932001f49Smrg  printf(" [ESC]   - Quit\n");
84032001f49Smrg
84132001f49Smrg  object=1;
84232001f49Smrg
84332001f49Smrg  glutInitWindowSize(640,480);
84432001f49Smrg  glutInit(&argc, argv);
84532001f49Smrg
84632001f49Smrg  glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
84732001f49Smrg
84832001f49Smrg  if (glutCreateWindow("Morph 3D - Shows morphing platonic polyhedra") <= 0) {
84932001f49Smrg     exit(0);
85032001f49Smrg  }
85132001f49Smrg
85232001f49Smrg  glClearDepth(1.0);
85332001f49Smrg  glClearColor( 0.0, 0.0, 0.0, 1.0 );
85432001f49Smrg  glColor3f( 1.0, 1.0, 1.0 );
85532001f49Smrg
85632001f49Smrg  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
85732001f49Smrg  glFlush();
85832001f49Smrg  glutSwapBuffers();
85932001f49Smrg
86032001f49Smrg  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
86132001f49Smrg  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
86232001f49Smrg  glLightfv(GL_LIGHT0, GL_POSITION, position0);
86332001f49Smrg  glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
86432001f49Smrg  glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
86532001f49Smrg  glLightfv(GL_LIGHT1, GL_POSITION, position1);
86632001f49Smrg  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
86732001f49Smrg  glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
86832001f49Smrg  glEnable(GL_LIGHTING);
86932001f49Smrg  glEnable(GL_LIGHT0);
87032001f49Smrg  glEnable(GL_LIGHT1);
87132001f49Smrg  glEnable(GL_DEPTH_TEST);
87232001f49Smrg  glEnable(GL_NORMALIZE);
87332001f49Smrg
87432001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
87532001f49Smrg  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
87632001f49Smrg
87732001f49Smrg  glHint(GL_FOG_HINT, GL_FASTEST);
87832001f49Smrg  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
87932001f49Smrg  glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
88032001f49Smrg
88132001f49Smrg  pinit();
88232001f49Smrg
88332001f49Smrg  glutReshapeFunc( reshape );
88432001f49Smrg  glutKeyboardFunc( key );
88532001f49Smrg  glutIdleFunc( idle_ );
88632001f49Smrg  glutDisplayFunc( draw );
88732001f49Smrg  glutMainLoop();
88832001f49Smrg
88932001f49Smrg  return 0;
89032001f49Smrg}
891