/*************************************************************************************************************************************/ /* */ /* A R R A N G E M E N T H A R M O N I E U X D E P O I N T S S U R L A S P H E R E */ /* A V E C T E S T D E P L U S I E U R S C O N D I T I O N S I N I T I A L E S D I F F E R E N T E S : */ /* */ /* */ /* Nota : */ /* */ /* Ce programme a ete construit a partir */ /* de 'v $xtc/PtsSphere.02$c'... */ /* */ /* */ /* Author of '$xtc/PtsSphere.12$c' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20080316101146). */ /* */ /*************************************************************************************************************************************/ /*************************************************************************************************************************************/ /* */ /* I N T E R F A C E ' listG ' : */ /* */ /* */ /* :Debut_listG: */ /* */ /* $Z alias distances 'set NuMeRo=\!* ; \\ */ /* $Z set FiChIeR=$xTG/XYZ ; \\ */ /* $Z $DELETE $FiChIeR.$NuMeRo* >& $nul ; \\ */ /* $Z (listMN $FiChIeR :Debut_listG_XYZ_$NuMeRo"": :Fin_listG_XYZ_$NuMeRo"":) \\ */ /* $Z > $FiChIeR.$NuMeRo ; \\ */ /* $Z $CA $FiChIeR.$NuMeRo | $AW '"'"'{ print $1 }'"'"' > $FiChIeR.$NuMeRo$COORD_X ; \\ */ /* $Z $CA $FiChIeR.$NuMeRo | $AW '"'"'{ print $2 }'"'"' > $FiChIeR.$NuMeRo$COORD_Y ; \\ */ /* $Z $CA $FiChIeR.$NuMeRo | $AW '"'"'{ print $3 }'"'"' > $FiChIeR.$NuMeRo$COORD_Z ; \\ */ /* $Z $xrv/optimise.02$X ne=0 cartesiennesA=VRAI uniquement_matrice_distances=VRAI \\ */ /* $Z Valider_noms_relatifs=FAUX \\ */ /* $Z LISTE_X=$FiChIeR.$NuMeRo$COORD_X \\ */ /* $Z LISTE_Y=$FiChIeR.$NuMeRo$COORD_Y \\ */ /* $Z LISTE_Z=$FiChIeR.$NuMeRo$COORD_Z >& $FiChIeR.$NuMeRo.dist ; \\ */ /* $Z echo "=================== $NuMeRo" ; \\ */ /* $Z $CA $FiChIeR.$NuMeRo $FiChIeR.$NuMeRo.dist ; \\ */ /* $Z unset NuMeRo FiChIeR' */ /* */ /* :Fin_listG: */ /* */ /* */ /* Nota : */ /* */ /* L'usage sera ensuite le suivant. */ /* On fera : */ /* */ /* $xtc/$aPout >& $xTG/XYZ */ /* */ /* listG $xtc/PtsSphere.12$c :Debut_listG: :Fin_listG: */ /* */ /* puis un "copier-coller" de la sortie du */ /* 'listG' ci-dessus... */ /* */ /*************************************************************************************************************************************/ #include "INCLUDES.01.I" extern double drand48(); extern double srand48(); #define NOMBRE_DE_POINTS \ 26 #define NOMBRE_D_ENSEMBLES_A_GENERER \ 1 #define NOMBRE_D_ITERATIONS \ 1000000 #define RAYON_DE_LA_SPHERE_UNITE \ 1.0 /* Definition de la sphere unite. */ #define PONDERATION_0 \ 0.010 #define PONDERATION_N \ (1.0*(1/(double)NOMBRE_D_ITERATIONS)) /* Definition de l'interpolation... */ #define RANDOM(inf,sup) \ ((((sup)-(inf))*drand48())+(inf)) #define DISTANCE_1(dx,dy,dz) \ sqrt(EXP2(dx)+EXP2(dy)+EXP2(dz)) #define DISTANCE_2(dx,dy,dz) \ (EXP2(dx)+EXP2(dy)+EXP2(dz)) /* On notera que l'usage 'sqrt(...)' n'est utile que pour 'normalisation(...)', par contre */ /* losrqu'il s'agit uniquement de rechercher les distances extremales, on peut s'en passer */ /* et ainsi, aller deux fois plus vite... */ typedef struct { double x,y,z; } points; void normalisation(point) points *point; { double module=DISTANCE_1(point->x,point->y,point->z); point->x = RAYON_DE_LA_SPHERE_UNITE*((point->x)/module); point->y = RAYON_DE_LA_SPHERE_UNITE*((point->y)/module); point->z = RAYON_DE_LA_SPHERE_UNITE*((point->z)/module); } #define TROUVER(chercher_la_distance_extremale,distance_extremale,OPERATEUR,indice_i,indice_j,distance_extremale_trouvee) \ { \ if (chercher_la_distance_extremale == VRAI) \ { \ if (distance OPERATEUR distance_extremale) \ { \ distance_extremale = distance; \ \ indice_i = i; \ indice_j = j; \ \ distance_extremale_trouvee = VRAI; \ /* Recherche de la distance extremale. */ \ } \ else \ { \ } \ } \ else \ { \ } \ } #define AUGMENTATION(distance_extremale_trouvee,indice_i,indice_j) \ { \ if (distance_extremale_trouvee == VRAI) \ { \ double dX=ponderation*(ListePoints[indice_j].x - ListePoints[indice_i].x); \ double dY=ponderation*(ListePoints[indice_j].y - ListePoints[indice_i].y); \ double dZ=ponderation*(ListePoints[indice_j].z - ListePoints[indice_i].z); \ \ ListePoints[indice_j].x = ListePoints[indice_j].x + dX; \ ListePoints[indice_j].y = ListePoints[indice_j].y + dY; \ ListePoints[indice_j].z = ListePoints[indice_j].z + dZ; \ normalisation(&ListePoints[indice_j]); \ /* Augmentation de la distance {indice_i,indice_j}. */ \ \ ListePoints[indice_i].x = ListePoints[indice_i].x - dX; \ ListePoints[indice_i].y = ListePoints[indice_i].y - dY; \ ListePoints[indice_i].z = ListePoints[indice_i].z - dZ; \ normalisation(&ListePoints[indice_i]); \ /* Augmentation de la distance {indice_i,indice_j}. */ \ } \ else \ { \ } \ } main() { int compatibilite_20080319100918=0; int chercher_la_distance_minimale=VRAI; int chercher_la_distance_maximale=VRAI; /* Indicateurs de controle divers... */ int g,n,p; /* Index divers... */ points ListePoints[NOMBRE_DE_POINTS]; if (compatibilite_20080319100918 == 1) { } else { long int graine=1; /* Il semblerait qu'utiliser une graine nulle soit une mauvaise idee comme cela se voit */ /* avec N=19... */ srand48(graine); /* Introduit le 20080319100918 car, en effet, manquait... */ } for (p=0 ; p<NOMBRE_DE_POINTS ; p++) { ListePoints[p].x = RANDOM(-RAYON_DE_LA_SPHERE_UNITE,+RAYON_DE_LA_SPHERE_UNITE); ListePoints[p].y = RANDOM(-RAYON_DE_LA_SPHERE_UNITE,+RAYON_DE_LA_SPHERE_UNITE); ListePoints[p].z = RANDOM(-RAYON_DE_LA_SPHERE_UNITE,+RAYON_DE_LA_SPHERE_UNITE); /* Initialisation aleatoire du nuage de points a l'interieur du cube dans lequel la sphere */ /* unite est inscrite. */ normalisation(&ListePoints[p]); /* Mise du nuage de points sur la surface de la sphere unite. */ } for (g=1 ; g<=NOMBRE_D_ENSEMBLES_A_GENERER ; g++) { for (n=1 ; n<=NOMBRE_D_ITERATIONS ; n++) { int i,j; int distance_minimale_trouvee=FAUX; double distance_minimale=+1000; int min_i,min_j; int distance_maximale_trouvee=FAUX; double distance_maximale=-1000; int max_i,max_j; double ponderation=((double)((PONDERATION_0*(NOMBRE_D_ITERATIONS-n))+(PONDERATION_N*(n-1)))) /((double)(NOMBRE_D_ITERATIONS-1) ); for (i=0 ; i<NOMBRE_DE_POINTS ; i++) { for (j=i+1 ; j<NOMBRE_DE_POINTS ; j++) { double distance=DISTANCE_2(ListePoints[i].x-ListePoints[j].x ,ListePoints[i].y-ListePoints[j].y ,ListePoints[i].z-ListePoints[j].z ); TROUVER(chercher_la_distance_minimale ,distance_minimale ,< ,min_i,min_j ,distance_minimale_trouvee ); TROUVER(chercher_la_distance_maximale ,distance_maximale ,> ,max_i,max_j ,distance_maximale_trouvee ); } } AUGMENTATION(distance_minimale_trouvee,min_i,min_j); /* Augmentation de la distance minimale. */ AUGMENTATION(distance_maximale_trouvee,max_i,max_j); /* Augmentation (et non pas diminution !) de la distance maximale. */ } printf(":Debut_listG_XYZ_%08d:\n",g); for (p=0 ; p<NOMBRE_DE_POINTS ; p++) { printf("%+.16f %+.16f %+.16f\n",ListePoints[p].x,ListePoints[p].y,ListePoints[p].z); /* Edition des coordonees {X,Y,Z} resultantes... */ } printf(":Fin_listG_XYZ_%08d:\n",g); } for (g=1 ; g<=NOMBRE_D_ENSEMBLES_A_GENERER ; g++) { printf("distances %08d\n",g); } }