/*************************************************************************************************************************************/
/* */
/* G E N E R A T I O N D E S I C O S A E D R E S R E G U L I E R E T T R O N Q U E */
/* E T G E N E R A T I O N D U F U L L E R E N E C 6 0 : */
/* */
/* */
/* Author of '$xtc/Fullerene_C60.01$vv$c' : */
/* */
/* ChatGPT.5 et Jean-Francois COLONNA (LACTAMME, 20260916104826). */
/* */
/*************************************************************************************************************************************/
#define NSOMMETS 12
#define NARETES 60
#include "Polyedres.01.vv.I"
#define POND1 1
#define POND2 2
double pond1=POND1;
double pond2=POND2;
#define SCALE (pond1+pond2)
/* Dans le cas ou l'on essaye autre chose que les ponderations {1,2}, on se retrouve avec */
/* des liaisons qui n'ont pas toutes la meme longueur, or pour la visualisation, on */
/* selectionne celles qui ont la longueur mnimale ('dmin') et donc ainsi, on perd celles */
/* qui sont plus grandes. Cela parait donc impossible de vusaliser l'icosaedre lui-meme */
/* en jouant sur {POND1,POND2}... */
/* */
/* Le 20261001111650 fut introduit la possibilite de faire varier {pond1,pond2}... */
static POINT c60[NARETES];
/*************************************************************************************************************************************/
/* */
/* C A L C U L D E L A D I S T A N C E M I N I M A L E E N T R E */
/* D E U X E N S E M B L E S D E P O I N T S : */
/* */
/*************************************************************************************************************************************/
#define DISTANCE_MINIMALE(dmin) \
{ \
int i,j; \
\
for (i=0; i<NSOMMETS; i++) \
{ \
for (j=i+1; j<NSOMMETS; j++) \
{ \
double d=dist2(p[i],p[j]); \
if ((d<dmin) && (d>epsilon2)) \
{ \
dmin=d; \
/* Toutes les aretes de l'icosaedre ont la meme longueur. */ \
} \
else \
{ \
} \
} \
} \
}
/*************************************************************************************************************************************/
/* */
/* G E N E R A T I O N D E S S O M M E T S D E L ' I C O S A E D R E : */
/* */
/*************************************************************************************************************************************/
double phi;
/* Nombre d'or... */
double Xmin_Icosaedre=+INFINI,Ymin_Icosaedre=+INFINI,Zmin_Icosaedre=+INFINI;
double Xmax_Icosaedre=-INFINI,Ymax_Icosaedre=-INFINI,Zmax_Icosaedre=-INFINI;
/* Extrema de l'icosaedre. */
static void icosahedron(void)
{
int n=0;
int s1,s2;
for (s1=-1; s1<=1; s1+=2)
{
for (s2=-1; s2<=1; s2+=2)
{
p[n++] = (POINT){0,s1,s2*phi};
/* Generation de 4 sommets {0,+/-1,+/-Phi}. */
}
}
for (s1=-1; s1<=1; s1+=2)
{
for (s2=-1; s2<=1; s2+=2)
{
p[n++] = (POINT){s1,s2*phi,0};
/* Generation de 4 sommets {+/-1,+/-Phi,0}. */
}
}
for (s1=-1; s1<=1; s1+=2)
{
for (s2=-1; s2<=1; s2+=2)
{
p[n++] = (POINT){s2*phi,0,s1};
/* Generation de 4 sommets {+/-1,0,+/-Phi}. */
}
}
double dmin_Icosaedre=+INFINI;
DISTANCE_MINIMALE(dmin_Icosaedre);
int nb=0;
int i,j;
for (i=0; i<NSOMMETS; i++)
{
for (j=i+1; j<NSOMMETS; j++)
{
if (fabs(dist2(p[i],p[j])-dmin_Icosaedre)<epsilon1)
{
printf("AreteIcosaedre={%02d,%02d} ",i,j);
printf("X1=%+.12f Y1=%+.12f Z1=%+.12f",p[i].x,p[i].y,p[i].z);
printf(" ");
printf("X2=%+.12f Y2=%+.12f Z2=%+.12f",p[j].x,p[j].y,p[j].z);
printf("\n");
nb++;
}
else
{
}
}
}
printf("\nNombre de cotes de l'icosaedre = %d\n",nb);
EXTREMA_SOMMETS(Xmin_Icosaedre,Ymin_Icosaedre,Zmin_Icosaedre,Xmax_Icosaedre,Ymax_Icosaedre,Zmax_Icosaedre);
}
/*************************************************************************************************************************************/
/* */
/* C O N S T R U C T I O N D U C 6 0 P A R T R O N C A T I O N D E L ' I C O S A E D R E : */
/* */
/*************************************************************************************************************************************/
double Xmin_IcosaedreTronque=+INFINI,Ymin_IcosaedreTronque=+INFINI,Zmin_IcosaedreTronque=+INFINI;
double Xmax_IcosaedreTronque=-INFINI,Ymax_IcosaedreTronque=-INFINI,Zmax_IcosaedreTronque=-INFINI;
/* Extrema de l'icosaedre tronque. */
static void make_c60(void)
{
double dmin_IcosaedreTronque=+INFINI;
DISTANCE_MINIMALE(dmin_IcosaedreTronque);
int i,j;
int n=0;
for (i=0; i<NSOMMETS; i++)
{
for (j=i+1; j<NSOMMETS; j++)
{
if (fabs(dist2(p[i],p[j])-dmin_IcosaedreTronque)<epsilon1)
{
/* Cas ou l'on est en presence d'une arete de l'icosaedre : */
c60[n++] = (POINT){((pond2*p[i].x)+(pond1*p[j].x))/SCALE
,((pond2*p[i].y)+(pond1*p[j].y))/SCALE
,((pond2*p[i].z)+(pond1*p[j].z))/SCALE
};
c60[n++] = (POINT){((pond1*p[i].x)+(pond2*p[j].x))/SCALE
,((pond1*p[i].y)+(pond2*p[j].y))/SCALE
,((pond1*p[i].z)+(pond2*p[j].z))/SCALE
};
/* Chaque arete AB donne 2 sommets du polyedre : (2A+B)/3 et (A+2B)/3 (c'est la troncation). */
/* */
/* Je note le 20260929082318 que l'ordre entre 2 sommets n'a rien de logique et qu'il ne */
/* permet donc pas de reconstituer facilement les 12 pentagones et les 20 hexagones... */
}
else
{
}
}
}
printf("Nombre de sommets C60 = %d\n",n);
int m=0;
for (m=0; m<n; m++)
{
Xmin_IcosaedreTronque = MIN2(p[m].x,Xmin_IcosaedreTronque);
Ymin_IcosaedreTronque = MIN2(p[m].y,Ymin_IcosaedreTronque);
Zmin_IcosaedreTronque = MIN2(p[m].z,Zmin_IcosaedreTronque);
Xmax_IcosaedreTronque = MAX2(p[m].x,Xmax_IcosaedreTronque);
Ymax_IcosaedreTronque = MAX2(p[m].y,Ymax_IcosaedreTronque);
Zmax_IcosaedreTronque = MAX2(p[m].z,Zmax_IcosaedreTronque);
}
}
/*************************************************************************************************************************************/
/* */
/* R E C H E R C H E D E S A R E T E S : */
/* */
/*************************************************************************************************************************************/
static void bonds_special(void)
{
double dmin=+INFINI;
int i,j;
for (i=0; i<NARETES; i++)
{
for (j=i+1; j<NARETES; j++)
{
double d=dist2(c60[i],c60[j]);
if ((d<dmin) && (d>epsilon2))
{
dmin=d;
/* Distance minimale entre 2 des sommets. */
}
else
{
}
}
}
printf("Distance au carre = %.15g\n\n",dmin);
int nb=0;
for (i=0; i<NARETES; i++)
{
for (j=i+1; j<NARETES; j++)
{
if (fabs(dist2(c60[i],c60[j])-dmin)<epsilon1)
{
printf("AreteIcosaedreTronque={%02d,%02d} ",i,j);
printf("X1=%+.12f Y1=%+.12f Z1=%+.12f",c60[i].x,c60[i].y,c60[i].z);
printf(" ");
printf("X2=%+.12f Y2=%+.12f Z2=%+.12f",c60[j].x,c60[j].y,c60[j].z);
printf("\n");
nb++;
}
else
{
}
}
}
printf("\nNombre d'aretes = %d\n",nb);
}
/*************************************************************************************************************************************/
/* */
/* P R O G R A M M E P R I N C I P A L : */
/* */
/*************************************************************************************************************************************/
void main(int argc,char *argv[])
{
phi = (1.0+sqrt(5.0))/2.0;
/* Valeur par defaut... */
if (argc >= 2)
{
GET_ARGUMENT(1,futur_phi,phi);
if (argc >= 3)
{
GET_ARGUMENT(2,futur_pond1,pond1);
if (argc >= 4)
{
GET_ARGUMENT(3,futur_pond2,pond2);
if (argc >= 5)
{
GET_ARGUMENT(4,futur_epsilon1,epsilon1);
if (argc >= 6)
{
GET_ARGUMENT(5,futur_epsilon2,epsilon2);
if (argc >= 7)
{
printf("Les arguments en sur-nombre sont ignores.\n");
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
icosahedron();
printf("\n");
printf("ExtremaIcosaedre :");
printf(" Xmin_Icosaedre=%+.12f Ymin_Icosaedre=%+.12f Zmin_Icosaedre=%+.12f",Xmin_Icosaedre,Ymin_Icosaedre,Zmin_Icosaedre);
printf(" Xmax_Icosaedre=%+.12f Ymax_Icosaedre=%+.12f Zmax_Icosaedre=%+.12f",Xmax_Icosaedre,Ymax_Icosaedre,Zmax_Icosaedre);
printf("\n");
printf("\n");
make_c60();
EDITIONS_FINALES("IcosaedreTronque"
,Xmin_IcosaedreTronque,Ymin_IcosaedreTronque,Zmin_IcosaedreTronque
,Xmax_IcosaedreTronque,Ymax_IcosaedreTronque,Zmax_IcosaedreTronque
);
bonds_special();
return;
}