// Espace projectif de dimension 3 sur le corps Z/2Z

#include "colors.inc"
#include "textures.inc"
#include "shapes.inc"
#include "metals.inc"
//#include "stones.inc"
//#include "woods.inc"                                                
#include "glass.inc"

// ***************************
// Installation de la caméra *
// ***************************
// On installe la caméra et on définit son orientation.
// L'axe des x est vers la droite, l'axe des y vers le haut, l'axe des z vers le fond.


#declare cc=75; // =clock; pour une animation de 200 images

camera {
#declare DistanceObservateur = 3;
#declare HauteurObservateur = 2;
#declare Angle = -2;  // < 0 pour l'oeil gauche (G.POV) . L'image devra être placée à DROITE en vision croisée
                     // > 0 pour l'oeil droit (D.POV) (en degré), l'image devra être placée à GAUCHE. 
                     // En général 3 à 5° degré d'écart entre les deux yeux. Angle est en degré. 

//Définir l'angle pour choisir l'oeil
location  <DistanceObservateur*cos(Angle/180*pi), HauteurObservateur, DistanceObservateur*sin(Angle/180*pi)> 
look_at  <0, 0, 0>
}

// On définit le fond (par défaut noir)
background { color Black}  

// ********
// Objets *
// ********

#declare Rayon = 0.1;
#declare RayonCyl = 0.015;
#declare Cote = 2;
#declare Epsilon = 0.005;

#declare A = <-Cote*sqrt(3)/6,-Cote*sqrt(6)/12,Cote/2>;
#declare B = <-Cote*sqrt(3)/6,-Cote*sqrt(6)/12,-Cote/2>;    
#declare C = <0,Cote*sqrt(6)/4,0>;
#declare D = <Cote*sqrt(3)/3,-Cote*sqrt(6)/12,0>;


#declare CouleurSphere=Yellow;
#declare AutreCouleurSphere=Red; //=Yellow;  // permet de visualiser un sous-espace affine si = Red, 
#declare TextureSphere=Gold_Metal;

#declare CouleurTige=White;    
#declare TextureTige=Silver_Metal;


// Il y a 15 points, à savoir :
// A = 1000    B = 0100    C = 0010    D = 0001
// AB = 1100   AC = 1010   AD = 1001   BC = 0110   BD = 0101   CD = 0011
// ABC = 1110  ABD = 1101  ACD = 1011  BCD = 0111
// ABCD = 1111
union{
sphere {A Rayon texture{TextureSphere} pigment{color CouleurSphere}}
sphere {B Rayon texture{TextureSphere} pigment{color CouleurSphere}}
sphere {C Rayon texture{TextureSphere} pigment{color CouleurSphere}} 
sphere {D Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}

sphere {(A+B)/2 Rayon texture{TextureSphere} pigment{color CouleurSphere}}
sphere {(A+C)/2 Rayon texture{TextureSphere} pigment{color CouleurSphere}}    
sphere {(A+D)/2 Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}    
sphere {(B+C)/2 Rayon texture{TextureSphere} pigment{color CouleurSphere}}    
sphere {(B+D)/2 Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}        
sphere {(C+D)/2 Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}    

sphere {(A+B+C)/3 Rayon texture{TextureSphere} pigment{color CouleurSphere}}        
sphere {(A+B+D)/3 Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}
sphere {(A+C+D)/3 Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}        
sphere {(B+C+D)/3 Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}    

sphere {(B+A+D+C)/4 Rayon texture{TextureSphere} pigment{color AutreCouleurSphere}}      

//Il y a 35 droites, chacune portant 3 points. Par chaque point passe 7 droites.

//6 contenant (sommet, milieu, sommet) d'un côté du tétraèdre
// par exemple D = 0001, AD = 1001, A = 1000 d'équation y=z=0
// ou          D = 0001, CD = 0011, C = 0010  d'équation x=y=0
cylinder { A B RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { A C RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { A D RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { B C RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { B D RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { C D RayonCyl texture{TextureTige} pigment{color CouleurTige}}
                                                                        
//+12 = 18 contenant (sommet, centre d'une face, milieu du côté opposé) d'une même face
//par exemple D = 0001, ACD = 1011, AC =1010 d'équation y=0, x+z=0 
cylinder { A (B+C)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { A (B+D)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { A (C+D)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { B (A+C)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { B (A+D)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { B (C+D)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { C (A+B)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { C (A+D)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { C (B+D)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { D (A+B)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { D (A+C)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { D (B+C)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}

//+4 = 22 contenant (sommet, centre du tétraèdre, centre de la face opposée au sommet)
//par exemple D = 0001, ABCD = 1111, ABC = 1110 d'équation x+y=0 y+z=0
cylinder { A (B+C+D)/3 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { B (A+C+D)/3 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { C (A+B+D)/3 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { D (A+B+C)/3 RayonCyl texture{TextureTige} pigment{color CouleurTige}}

//+4 = 26 contenant les trois milieux des côtés d'une même face
//par exemple CD = 0011, AD = 1001, AC = 1010 d'équation y=0, x+z+t=0
torus {Cote*sqrt(3)/6 RayonCyl texture{TextureTige} pigment{color CouleurTige} translate (B+A+D)/3}

#declare V=vnormalize(vcross(B,A)+vcross(A,C)+vcross(C,B));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*sqrt(3)/6 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate -phi*180/3.14*y
        translate (B+A+C)/3}

#declare V=vnormalize(vcross(B,D)+vcross(D,C)+vcross(C,B));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*sqrt(3)/6 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate -phi*180/3.14*y
        translate (B+D+C)/3}

#declare V=vnormalize(vcross(A,D)+vcross(D,C)+vcross(C,A));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*sqrt(3)/6 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate -phi*180/3.14*y
        translate (A+D+C)/3}

//+3 = 29 contenant (milieu d'un côté, centre du tétraèdre, milieu du côté opposé)
//par exemple CD = 0011, ABCD = 1111, AB = 1100 d'équation x+y=0, z+t=0
cylinder { (B+A)/2 (D+C)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { (B+D)/2 (A+C)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}
cylinder { (B+C)/2 (A+D)/2 RayonCyl texture{TextureTige} pigment{color CouleurTige}}

//+6 = 35 contenant (milieu d'un côté, centres des faces ne contenant pas ce côté)
//par exemple CD = 0011, ABD = 1101, ABC = 1110 d'équation x+y=0, y+z+t=0
//Le rayon du cercle est de Cote*3*sqrt(2)/16
#declare V=vnormalize(vcross((A+B)/2,(A+C+D)/3)+vcross((A+C+D)/3,(B+C+D)/3)+vcross((B+C+D)/3,(A+B)/2));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*3*sqrt(2)/16 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate -phi*180/3.14*y
        translate (A+B)/2+9/16*(C+D-A-B)/3}

#declare V=vnormalize(vcross((A+C)/2,(A+B+D)/3)+vcross((A+B+D)/3,(B+C+D)/3)+vcross((B+C+D)/3,(A+C)/2));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*3*sqrt(2)/16 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate -phi*180/3.14*y
        translate (A+C)/2+9/16*(D+B-A-C)/3}
 
#declare V=vnormalize(vcross((A+D)/2,(A+C+B)/3)+vcross((A+C+B)/3,(B+C+D)/3)+vcross((B+C+D)/3,(A+D)/2));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*3*sqrt(2)/16 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate phi*180/3.14*y
        translate (A+D)/2+9/16*(C+B-A-D)/3}

#declare V=vnormalize(vcross((C+B)/2,(A+C+D)/3)+vcross((A+C+D)/3,(B+A+D)/3)+vcross((B+A+D)/3,(C+B)/2));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*3*sqrt(2)/16 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate phi*180/3.14*y
        translate (C+B)/2+9/16*(A+D-C-B)/3}

#declare V=vnormalize(vcross((D+B)/2,(A+C+D)/3)+vcross((A+C+D)/3,(B+C+A)/3)+vcross((B+C+A)/3,(D+B)/2));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*3*sqrt(2)/16 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate -phi*180/3.14*y
        translate (D+B)/2+9/16*(C+A-D-B)/3}

#declare V=vnormalize(vcross((C+D)/2,(A+B+D)/3)+vcross((A+B+D)/3,(B+C+A)/3)+vcross((B+C+A)/3,(C+D)/2));
#declare theta=acos(V.y);
#declare phi=acos(V.x/sin(theta));
torus {Cote*3*sqrt(2)/16 RayonCyl texture{TextureTige} pigment{color CouleurTige} 
        rotate -theta*180/3.14*z
        rotate -phi*180/3.14*y
        translate (C+D)/2+9/16*(A+B-C-D)/3}

rotate y*cc*3/10
} // fin union        

// *********
// Lumière *
// *********

light_source { <0, 10, 0> color White shadowless}
light_source { <10, 0, 0> color White shadowless}
light_source { <0, 0, 10> color White shadowless}
