/*************************************************************************************************************************************/
/* */
/* C A L C U L D E T O U T E S L E S D I S T A N C E S 2 A 2 D A N S */
/* U N E N S E M B L E D E P O I N T S { X , Y , Z } : */
/* */
/* */
/* Author of '$xrv/distance.02$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20000522115636). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* I N T E R F A C E ' listG ' : */
/* */
/* */
/* :Debut_listG: */
/* :Fin_listG: */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */
/* */
/*************************************************************************************************************************************/
/* Le 20080311163442, fut supprime : */
/* */
/* @define PRAGMA_CL_____MODULE_NON_OPTIMISABLE */
/* */
/* qui semblait inutile... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_BASE
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* V A L E U R S I M P L I C I T E S D E S P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define EDITER_LES_N_PREMIERS_VOISINS \
FAUX
#define NOMBRE_DE_PREMIERS_VOISINS \
TROIS
#define TRIER_LES_INDEX_DES_PREMIERS_VOISINS \
VRAI
#define EDITER_LES_COORDONNEES_DES_POINTS_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS \
FAUX
#define METTRE_LES_POINTS_DANS_LE_BON_ORDRE_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS \
FAUX
/* Doit-on n'editer que les 'N' premiers voisins ('VRAI') ou bien editer quasiment tous */
/* couples {I,J} ('FAUX') suivant 'IL_FAUT(editer_tous_les_couples_IJ)' ? D'autre part, */
/* doit-on editer les couples {I,J} des premiers voisins quel que soit leur ordre ('FAUX') */
/* ou bien en respectant le critere de tri I<J ('VRAI') ? On notera au passage que cette */
/* option ('TRIER_LES_INDEX_DES_PREMIERS_VOISINS') a ete introduite le 20011014091311 */
/* afin d'optimiser 'v $xiirs/.PSPH.21.1.$U 20011014091311' et eliminer la redondance */
/* des couples... */
/* */
/* Le 20051201133356 a ete introduit la possibilite d'editer (en plus des index) les */
/* coordonnees des points lorsque 'IL_FAUT(editer_les_N_premiers_voisins)'... */
/* */
/* Le 20051203100941,la possibilite de lister les points {I,J} dans le bon ordre, lorsque */
/* 'IL_FAUT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins)', a */
/* a ete introduite... */
#define EDITER_TOUS_LES_COUPLES_IJ \
VRAI \
/* Doit-on editer tous les couples {I,J} ('VRAI') ou bien n'editer ceux pour lesquels */ \
/* I<J strictement ('FAUX') ? */
#define FILTRER_LES_DISTANCES \
FAUX
#define BORNE_INFERIEURE_DES_DISTANCES \
FZERO
#define BORNE_SUPERIEURE_DES_DISTANCES \
F_INFINI
/* Doit-on filtrer dans [inf,sup] les distances ('VRAI') ou pas ('FAUX') ? Les valeurs par */
/* defaut garantissent la compatibilite anterieure. Cela fut introduit le 20161109083817 */
#define AMPLITUDE_DE_LA_TRANSLATION_DES_INDEX_DES_POINTS \
PREMIER_ELEMENT_D_UN_FICHIER \
/* Translation des index des points lors de leur edition. Ceci a ete introduit le */ \
/* 20011011112017 car, en effet, '$xrv/distance.02$K' utilise : */ \
/* */ \
/* 1-'gELEMENT_DU_FICHIER(...)', pour lequel le premier element vaut : */ \
/* */ \
/* PREMIER_ELEMENT_D_UN_FICHIER = INDEX0 = ZERO */ \
/* */ \
/* qui ne peut utiliser 'Komp(...)' et demande donc une gestion de type 'DoIn(...)' en */ \
/* precisant le premier element en tant qu'argument du 'DoIn(...)' (et valant donc 'ZERO'). */ \
/* Alors que de nombreux programmes gerant des points ('v $xrv/particule.10$K ACCES_LISTE' */ \
/* par exemple) utilisent : */ \
/* */ \
/* 2-'ACCES_LISTE(...)', pour lequel le premier element vaut : */ \
/* */ \
/* PREMIER_POINT_DES_LISTES = PREMIER_POINT = PREMIERE_ITERATION_D_UN_Komp = UN */ \
/* */ \
/* qui est donc adapte a une gestion de type 'Komp(...)' ou le premier element est defini */ \
/* implicitement (et vaut donc 'UN')... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S F I C H I E R S : */
/* */
/*************************************************************************************************************************************/
#define NOMBRE_MAXIMAL_D_ELEMENTS_DANS_LE_FICHIER \
GRO1(MILLE) \
/* En prevision d'une matrice memorisant les distances 2 a 2... */
#include xrv/ARITHMET.1d.I"
/* Passage a l'allocation dynamique le 20060214190521... */
#include xrv/ARITHMET.21.I"
#include xrk/attractor.12.I"
#include xrv/champs_5.11.I"
#define X_IMPLICITE \
FZERO
#define Y_IMPLICITE \
FZERO
#define Z_IMPLICITE \
FZERO
gGENERATION_D_UN_FICHIER(fichier_LISTE_X,liste_initiale_des_X);
gGENERATION_D_UN_FICHIER(fichier_LISTE_Y,liste_initiale_des_Y);
gGENERATION_D_UN_FICHIER(fichier_LISTE_Z,liste_initiale_des_Z);
/* Definition en memoire des fichiers de coordonnees cartesiennes. */
#define ELEMENT_DU_FICHIER_LISTE_X(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_X,index)
#define ELEMENT_DU_FICHIER_LISTE_Y(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_Y,index)
#define ELEMENT_DU_FICHIER_LISTE_Z(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_Z,index)
/* Acces a un element courant des fichiers de coordonnees cartesiennes. */
#define VOISIN_IMPLICITE \
FLOT(AUTORISE)
gGENERATION_D_UN_FICHIER(fichier_LISTE_VOISIN,liste_initiale_des_VOISIN);
/* Definition en memoire des fichiers des "autorisations" de voisinnage (ceci fut */
/* introduit le 20051206093616). Pour chaque point 'I', on va disposer (si cela est */
/* demande via 'IL_FAUT(editer_les_N_premiers_voisins)') de la liste triee par distances */
/* croissantes des voisins {J} du point 'I'. La liste 'liste_initiale_des_VOISIN' */
/* permet de selectionner les voisins a editer dans cette liste. On notera que le */
/* point 'J' d'index 0 est le point 'I' lui-meme et donc la premiere entree du fichier */
/* 'liste_initiale_des_VOISIN' n'est pas utilisee ; on verra a ce propos le test : */
/* */
/* Test(IFNE(indexI,index_J_trie)) */
/* */
/* ci-apres qui fait que les couples de type {I,I} sont ignores lors de l'edition des */
/* premiers voisins... */
#define ELEMENT_DU_FICHIER_LISTE_VOISIN(index) \
LOGI(gELEMENT_DU_FICHIER(liste_initiale_des_VOISIN,index))
/* Acces a un element courant des fichiers des "autorisations" de voisinnage. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#define TRANSLATION_DES_INDEX_DES_POINTS(index) \
CONX(index,PREMIER_ELEMENT_D_UN_FICHIER,amplitude_de_la_translation_des_index_des_points) \
/* Translation des index des points lors de leur edition. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C A L C U L D E T O U T E S L E S D I S T A N C E S 2 A 2 D A N S */
/* U N E N S E M B L E D E P O I N T S { X , Y , Z } : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
#include xrv/ARITHMET.22.I"
DEFV(Logical,INIT(editer_les_N_premiers_voisins,EDITER_LES_N_PREMIERS_VOISINS));
DEFV(Positive,INIT(nombre_de_premiers_voisins,NOMBRE_DE_PREMIERS_VOISINS));
DEFV(Logical,INIT(trier_les_index_des_premiers_voisins,TRIER_LES_INDEX_DES_PREMIERS_VOISINS));
DEFV(Logical,INIT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins
,EDITER_LES_COORDONNEES_DES_POINTS_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS
)
);
DEFV(Logical,INIT(mettre_les_points_dans_le_bon_ordre_lorsqu_il_y_a_tri_des_premiers_voisins
,METTRE_LES_POINTS_DANS_LE_BON_ORDRE_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS
)
);
/* Doit-on n'editer que les 'N' premiers voisins ('VRAI') ou bien editer quasiment tous */
/* couples {I,J} ('FAUX') suivant 'IL_FAUT(editer_tous_les_couples_IJ)' ? D'autre part, */
/* doit-on editer les couples {I,J} des premiers voisins quel que soit leur ordre ('FAUX') */
/* ou bien en respectant le critere de tri I<J ('VRAI') ? On notera au passage que cette */
/* option ('TRIER_LES_INDEX_DES_PREMIERS_VOISINS') a ete introduite le 20011014091311 */
/* afin d'optimiser 'v $xiirs/.PSPH.21.1.$U 20011014091311' et eliminer la redondance */
/* des couples... */
/* */
/* Le 20051201133356 a ete introduit la possibilite d'editer (en plus des index) les */
/* coordonnees des points lorsque 'IL_FAUT(editer_les_N_premiers_voisins)'... */
/* */
/* Le 20051203100941,la possibilite de lister les points {I,J} dans le bon ordre, lorsque */
/* 'IL_FAUT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins)', a */
/* a ete introduite... */
DEFV(Logical,INIT(editer_tous_les_couples_IJ,EDITER_TOUS_LES_COUPLES_IJ));
/* Doit-on editer tous les couples {I,J} ('VRAI') ou bien n'editer ceux pour lesquels */
/* I<J strictement ('FAUX') ? */
DEFV(Logical,INIT(filtrer_les_distances,FILTRER_LES_DISTANCES));
DEFV(Float,INIT(borne_inferieure_des_distances,BORNE_INFERIEURE_DES_DISTANCES));
DEFV(Float,INIT(borne_superieure_des_distances,BORNE_SUPERIEURE_DES_DISTANCES));
/* Doit-on filtrer dans [inf,sup] les distances ('VRAI') ou pas ('FAUX') ? Les valeurs par */
/* defaut garantissent la compatibilite anterieure. Cela fut introduit le 20161109083817 */
DEFV(Int,INIT(amplitude_de_la_translation_des_index_des_points,AMPLITUDE_DE_LA_TRANSLATION_DES_INDEX_DES_POINTS));
/* Translation des index des points lors de leur edition. Ceci a ete introduit le */
/* 20011011112017 car, en effet, '$xrv/distance.02$K' utilise : */
/* */
/* 1-'gELEMENT_DU_FICHIER(...)', pour lequel le premier element vaut : */
/* */
/* PREMIER_ELEMENT_D_UN_FICHIER=INDEX0=ZERO */
/* */
/* qui ne peut utiliser 'Komp(...)' et demande donc une gestion de type 'DoIn(...)' en */
/* precisant le premier element en tant qu'argument du 'DoIn(...)' (et valant donc 'ZERO'). */
/* Alors que de nombreux programmes gerant des points ('v $xrv/particule.10$K ACCES_LISTE' */
/* par exemple) utilisent : */
/* */
/* 2-'ACCES_LISTE(...)', pour lequel le premier element vaut : */
/* */
/* PREMIER_POINT_DES_LISTES=PREMIER_POINT=PREMIERE_ITERATION_D_UN_Komp=UN */
/* */
/* qui est donc adapte a une gestion de type 'Komp(...)' ou le premier element est defini */
/* implicitement (et vaut donc 'UN')... */
DEFV(Int,INIT(indexI,UNDEF));
DEFV(Int,INIT(indexJ,UNDEF));
/* Index des elements courants dans les fichiers pour calculer les distances {I,J}. */
DEFV(Int,INIT(compteur_des_distances,ZERO));
/* Compteur des distances destine a editer eventuellement un message d'avertissement */
/* (introduit le 20161109120606)... */
/*..............................................................................................................................*/
GET_ARGUMENTS_(nombre_d_arguments
,BLOC(PROCESS_ARGUMENT_I("nombre_elements=""ne=",nombre_d_elements
,BLOC(VIDE;)
,BLOC(Bblock
PRINT_AVERTISSEMENT("'ne=' doit etre defini avant toute entree de fichiers");
Eblock
)
);
PROCESS_ARGUMENTS_DE_DEFINITION_DES_FICHIERS_01;
PROKESF_ARGUMENT_FICHIER("LISTE_X="
,fichier_LISTE_X
,liste_initiale_des_X
,X_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_Y="
,fichier_LISTE_Y
,liste_initiale_des_Y
,Y_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_Z="
,fichier_LISTE_Z
,liste_initiale_des_Z
,Z_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_VOISIN="
,fichier_LISTE_VOISIN
,liste_initiale_des_VOISIN
,VOISIN_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
GET_ARGUMENT_L("pv=""premiers_voisins=",editer_les_N_premiers_voisins);
GET_ARGUMENT_I("N=",nombre_de_premiers_voisins);
GET_ARGUMENT_L("tri=",trier_les_index_des_premiers_voisins);
GET_ARGUMENT_L("editer_coordonnees_si_tri=""ecst=""coordonnees="
,editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins
);
GET_ARGUMENT_L("bost=""bon_ordre_des_points_si_tri=""bon_ordre="
,mettre_les_points_dans_le_bon_ordre_lorsqu_il_y_a_tri_des_premiers_voisins
);
GET_ARGUMENT_L("tri_N2=""N_carre=""N_au_carre=""N_AU_CARRE=""N2="
,utiliser_le_tri_d_une_liste_quelconque_VERSION_N_AU_CARRE
);
GET_ARGUMENT_N("tri_NlogN=""NlN=""N_log_N=""N1=",utiliser_le_tri_d_une_liste_quelconque_VERSION_N_AU_CARRE);
/* Les parametres "N_log_N=", "N_log_N",... ont ete introduits le 20111028201026... */
GET_ARGUMENT_L("IFGT_N_carre=""IFGT_N_au_carre=""IFGT_N_AU_CARRE=""IFGT_N2="
,TRI_D_UNE_LISTE_QUELCONQUE_VERSION_N_AU_CARRE_____faire_un_IFGT
);
GET_ARGUMENT_L("message_N_carre=""message_N_au_carre=""message_N_AU_CARRE=""mN2="
,TRI_D_UNE_LISTE_QUELCONQUE_VERSION_N_AU_CARRE_____editer_le_message_de_duree_excessive
);
/* Arguments introduits le 20120509095215... */
GET_ARGUMENT_L("tousIJ=""tous=""IJ=",editer_tous_les_couples_IJ);
GET_ARGUMENT_L("filtrer_distances=""fd=",filtrer_les_distances);
GET_ARGUMENT_F("borne_inferieure_distances=""bid=",borne_inferieure_des_distances);
GET_ARGUMENT_F("borne_superieure_distances=""bsd=",borne_superieure_des_distances);
/* Arguments introduits le 20161109083817... */
GET_ARGUMENT_I("translation=""t=",amplitude_de_la_translation_des_index_des_points);
)
);
Test(IFGE(nombre_de_premiers_voisins,nombre_d_elements))
Bblock
EGAL(nombre_de_premiers_voisins,PRED(nombre_d_elements));
/* Introduit le 20051206101606 car, en effet, cela manquait par erreur... */
PRINT_ATTENTION("le nombre de premiers voisins est trop grand par rapport au nombre de points");
CAL1(Prer1("(la valeur maximale (%d) va donc etre utilisee)\n",nombre_de_premiers_voisins));
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(editer_les_N_premiers_voisins))
Bblock
DEFV(Logical,INIT(au_moins_un_voisin_est_autorise,FAUX));
/* Ce test de validation de 'liste_initiale_des_VOISIN' a ete introduit le 20051206101606. */
DoIn(indexI
,SUCC(PREMIER_ELEMENT_D_UN_FICHIER)
,DERNIER_ELEMENT_D_UN_FICHIER
,I
)
/* Le 'SUCC(...)' est destine a prendre en compte le fait que le premier point (d'index 0) */
/* de la liste 'liste_initiale_des_VOISIN' correspond aux couples de type {I,I} lors du */
/* calcul des distances 2 a 2 ... */
Bblock
Test(EST_AUTORISE(ELEMENT_DU_FICHIER_LISTE_VOISIN(indexI)))
Bblock
EGAL(au_moins_un_voisin_est_autorise,VRAI);
Eblock
ATes
Bblock
Eblock
ETes
Eblock
EDoI
Test(EST_FAUX(au_moins_un_voisin_est_autorise))
Bblock
PRINT_ATTENTION("aucun voisin n'est autorise (le premier element etant ignore), on les autorise donc tous");
iGENERATION_D_UN_FICHIER(liste_initiale_des_VOISIN,VOISIN_IMPLICITE);
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
DoIn(indexI
,PREMIER_ELEMENT_D_UN_FICHIER
,DERNIER_ELEMENT_D_UN_FICHIER
,I
)
Bblock
DEFV(Float,INIT(coordonnee_XI,ELEMENT_DU_FICHIER_LISTE_X(indexI)));
DEFV(Float,INIT(coordonnee_YI,ELEMENT_DU_FICHIER_LISTE_Y(indexI)));
DEFV(Float,INIT(coordonnee_ZI,ELEMENT_DU_FICHIER_LISTE_Z(indexI)));
/* Recuperation des coordonnees {X,Y,Z} courantes du point 'I' dans les fichiers. */
gGENERATION_D_UN_FICHIER_liste(liste_des_points);
gGENERATION_D_UN_FICHIER_liste(liste_des_distances_du_point_I_aux_points_J);
/* Liste des distances du point 'I' (fixe) aux points 'J' variables. */
iGENERATION_D_UN_FICHIER(liste_des_points,FLOT__UNDEF);
iGENERATION_D_UN_FICHIER(liste_des_distances_du_point_I_aux_points_J,FLOT__UNDEF);
/* Ceci est rendu obligatoire par l'allocation dynamique de la memoire (le 20060214190521). */
/* Dans la boucle 'DoIn(...)' qui suit on va rechercher les 'nombre_de_premiers_voisins' */
/* d'index 'indexJ' du point courant d'index 'indexI'. On notera que cela ne donne pas */
/* toujours le resultat "global" que l'on attend comme cela s'est vu aux environs du */
/* 20180828152255. Ainsi, lors de la generation de l'image 'v $xiirs/PSPH.B5.1.20' en */
/* choisissant '_____NPoints=3', le point d'index 4 (en tant que 'indexI' ou 'indexJ') */
/* se retrouve plus de 3 fois : */
/* */
/* */
/* indexJ=4 */
/* couple={0,4} distance=+0.792554635397115126 */
/* */
/* indexJ=4 */
/* couple={1,4} distance=+0.794813519138595659 */
/* */
/* indexJ=4 */
/* couple={2,4} distance=+0.798600008488370872 */
/* */
/* indexI=4 */
/* couple={4,0} distance=+0.792554635397115126 */
/* couple={4,1} distance=+0.794813519138595659 */
/* couple={4,13} distance=+0.796233061158463595 */
/* */
/* indexJ=4 */
/* couple={11,4} distance=+0.816106796257996314 */
/* */
/* indexJ=4 */
/* couple={13,4} distance=+0.796233061158463595 */
/* */
/* */
/* et ainsi, le point d'index 4 semble avoir 5 plus proches voisins, soit : */
/* */
/* couple ={0,4} = {4,0} 0 vrai 3-proche voisin */
/* couple ={1,4} = {4,1} 1 vrai 3-proche voisin */
/* couple ={2,4} 2 */
/* couple ={11,4} 11 */
/* couple ={4,13} = {13,4} 13 vrai 3-proche voisin */
/* */
/* et non pas 3 (=$_____NPoints) ! Et c'est cela qui fait que l'on voit certains points */
/* connectes a plus de 3 autres (dont le point 4 qui est donc connecte a 5 autres...). */
/* */
/* Que faire ? Je crois qu'il n'y a pas de solution pour le moment car, en effet, pour */
/* reprendre le cas precedent, on ne peut pas eliminer le couple {2,4} car, en effet, le */
/* point 4 est bien un 3-proche voisin du point 2, alors que le point 2 n'est pas un */
/* un 3-proche voisin du point 4... */
/* */
/* Moralite : la notion de "N-proche voisin" ne "commute" pas... */
DoIn(indexJ
,PREMIER_ELEMENT_D_UN_FICHIER
,DERNIER_ELEMENT_D_UN_FICHIER
,I
)
Bblock
/* Les donnees qui suivent pourraient etre evidemment apres le 'Test(...)' relatif a */
/* 'editer_tous_les_couples_IJ', mais en fait cette localisation peu optimisee a priori */
/* est en prevision d'une matrice memorisant les distances 2 a 2... */
DEFV(Float,INIT(coordonnee_XJ,ELEMENT_DU_FICHIER_LISTE_X(indexJ)));
DEFV(Float,INIT(coordonnee_YJ,ELEMENT_DU_FICHIER_LISTE_Y(indexJ)));
DEFV(Float,INIT(coordonnee_ZJ,ELEMENT_DU_FICHIER_LISTE_Z(indexJ)));
/* Recuperation des coordonnees {X,Y,Z} courantes du point 'J' dans les fichiers. */
DEFV(Float,INIT(distance_IJ
,RdisF3D(coordonnee_XI,coordonnee_YI,coordonnee_ZI
,coordonnee_XJ,coordonnee_YJ,coordonnee_ZJ
)
)
);
/* Calcul de la distance des points {I,J}. */
Test(IL_FAUT(editer_les_N_premiers_voisins))
Bblock
EGAL(gELEMENT_DU_FICHIER(liste_des_points,indexJ),FLOT(indexJ));
EGAL(gELEMENT_DU_FICHIER(liste_des_distances_du_point_I_aux_points_J,indexJ),distance_IJ);
Eblock
ATes
Bblock
Test(IFOU(IL_FAUT(editer_tous_les_couples_IJ)
,IFET(IL_NE_FAUT_PAS(editer_tous_les_couples_IJ)
,IFLT(indexI,indexJ)
)
)
)
Bblock
Test(IFOU(IL_NE_FAUT_PAS(filtrer_les_distances)
,IFET(IL_FAUT(filtrer_les_distances)
,IFINff(distance_IJ,borne_inferieure_des_distances,borne_superieure_des_distances)
)
)
)
/* Possibilite introduite le 20161109083817... */
Bblock
CAL2(Prin2(" couple={%d,%d}"
,TRANSLATION_DES_INDEX_DES_POINTS(indexI)
,TRANSLATION_DES_INDEX_DES_POINTS(indexJ)
)
);
/* On notera (le 20040128142430) que lorsque 'IL_FAUT(trier_les_index_des_premiers_voisins)' */
/* l'index du premier element d'un couple est inferieur a celui du second element. D'autre */
/* part, il est tout a fait logique dans ces memes circonstances de trouver en double */
/* certaines lignes ; elles correspondent alors que fait que : */
/* */
/* DISTANCE(i,j) = DISTANCE(j,i) */
/* */
/* et que faisant un tri des {i,j} et en supposant que i<j, on sort donc deux fois la */
/* ligne 'couple={i,j}' (mais pas la ligne 'couple={j,i}'). Cela ne se produira evidemment */
/* pas si 'IL_FAUT(editer_les_N_premiers_voisins)' et que l'une ou les deux de ce lignes */
/* sont alors eliminees... */
CAL2(Prin3(" pointI={%+.^^^,%+.^^^,%+.^^^}",coordonnee_XI,coordonnee_YI,coordonnee_ZI));
CAL2(Prin3(" pointJ={%+.^^^,%+.^^^,%+.^^^}",coordonnee_XJ,coordonnee_YJ,coordonnee_ZJ));
CAL2(Prin1(" distance=%+.^^^",distance_IJ));
CAL2(Prin0("\n"));
/* Edition de la distance des points {I,J}. */
/* */
/* Le 20060105152121, le format "16g" est passe a "^^g" pour plus de souplesse... */
/* */
/* Le 20091123123539, le format "^^g" est passe a "^^^" pour plus de souplesse... */
INCR(compteur_des_distances,I);
/* Introduit le 20161109120606... */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Eblock
EDoI
Test(IL_FAUT(editer_les_N_premiers_voisins))
Bblock
TRI_D_UNE_LISTE_QUELCONQUE(liste_des_distances_du_point_I_aux_points_J
,liste_des_points
,PREMIER_ELEMENT_D_UN_FICHIER
,NEUT(DERNIER_ELEMENT_D_UN_FICHIER)
,EST_CE_LE_TRI_AUTOMATIQUE_D_UNE_LISTE_QUELCONQUE
,utiliser_le_tri_d_une_liste_quelconque_VERSION_N_AU_CARRE
,gELEMENT_DU_FICHIER
);
/* Tri des distances du point 'I' (fixe) aux points 'J' variables. */
/* */
/* Le 20020828170851 j'ai fait en sorte que l'argument '????_dernier_element' des */
/* procedures de tri pointe bien sur le dernier element de la liste et non pas sur son */
/* successeur, d'ou le remplacement des operateurs 'SUCC(...)' par des 'NEUT(...)' (voir */
/* a ce propos 'v $ximd/operator.1$FON 20020828170851'). */
/* */
/* L'argument 'EST_CE_LE_TRI_AUTOMATIQUE_D_UNE_LISTE_QUELCONQUE' a ete introduit le */
/* 20170608103553... */
DoIn(indexJ
,PREMIER_ELEMENT_D_UN_FICHIER
,LSTX(PREMIER_ELEMENT_D_UN_FICHIER,MIN2(SUCC(nombre_de_premiers_voisins),nombre_d_elements))
,I
)
/* Le 'SUCC(...)' est destine a prendre en compte le couple {I,I} pour lequel la distance */
/* est minimale (nulle...). */
Bblock
DEFV(Int,INIT(index_J_trie,INTE(gELEMENT_DU_FICHIER(liste_des_points,indexJ))));
Test(EST_AUTORISE(ELEMENT_DU_FICHIER_LISTE_VOISIN(indexJ)))
Bblock
/* Test introduit le 20051206093616 afin de pouvoir selectionner de facon individuelle */
/* les voisins a editer. ATTENTION : c'est 'indexJ' et non point 'index_J_trie' qu'il */
/* faut utiliser ici car, en effet, on cherche a tester les couples {I,J} par distances */
/* croissantes... */
Test(IFNE(indexI,index_J_trie))
Bblock
DEFV(Int,INIT(premier_index
,COND(IL_FAUT(trier_les_index_des_premiers_voisins)
,MIN2(indexI,index_J_trie)
,indexI
)
)
);
DEFV(Int,INIT(second_index
,COND(IL_FAUT(trier_les_index_des_premiers_voisins)
,MAX2(indexI,index_J_trie)
,index_J_trie
)
)
);
CAL2(Prin2(" couple={%d,%d}"
,TRANSLATION_DES_INDEX_DES_POINTS(premier_index)
,TRANSLATION_DES_INDEX_DES_POINTS(second_index)
)
);
/* On rappelle le 20080224180559 que si 'IL_FAUT(trier_les_index_des_premiers_voisins)', */
/* il y a alors frequemment des couples qui sortent en double (par exemple {I,J} et {I,J} */
/* avec I<J, provenant donc de {I,J} et {J,I}). Cela justifie donc les '$SOR -u's faits */
/* ulterieurement apres ces sorties ('v $xiirs/.PSPH.21.1.$U ListeCouples' par exemple...). */
Test(IL_FAUT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins))
Bblock
DEFV(Float,INIT(coordonnee_XJ,ELEMENT_DU_FICHIER_LISTE_X(index_J_trie)));
DEFV(Float,INIT(coordonnee_YJ,ELEMENT_DU_FICHIER_LISTE_Y(index_J_trie)));
DEFV(Float,INIT(coordonnee_ZJ,ELEMENT_DU_FICHIER_LISTE_Z(index_J_trie)));
/* Recuperation des coordonnees {X,Y,Z} courantes du point 'J' dans les fichiers. */
DEFV(Float,INIT(coordonnee_X1,FLOT__UNDEF));
DEFV(Float,INIT(coordonnee_Y1,FLOT__UNDEF));
DEFV(Float,INIT(coordonnee_Z1,FLOT__UNDEF));
DEFV(Float,INIT(coordonnee_X2,FLOT__UNDEF));
DEFV(Float,INIT(coordonnee_Y2,FLOT__UNDEF));
DEFV(Float,INIT(coordonnee_Z2,FLOT__UNDEF));
/* Afin de pouvoir changer l'ordre des 2 points {I,J} (introduit le 20051203100941)... */
EGAL(coordonnee_X1,coordonnee_XI);
EGAL(coordonnee_Y1,coordonnee_YI);
EGAL(coordonnee_Z1,coordonnee_ZI);
EGAL(coordonnee_X2,coordonnee_XJ);
EGAL(coordonnee_Y2,coordonnee_YJ);
EGAL(coordonnee_Z2,coordonnee_ZJ);
/* Choix de l'ordre {I,J} pour les deux points. */
Test(IFET(IL_FAUT(mettre_les_points_dans_le_bon_ordre_lorsqu_il_y_a_tri_des_premiers_voisins)
,IFET(IFEQ(premier_index,index_J_trie)
,IFEQ(second_index,indexI)
)
)
)
/* Ce test a ete introduit le 20051203100941... */
Bblock
fSWAP(coordonnee_X1,coordonnee_X2);
fSWAP(coordonnee_Y1,coordonnee_Y2);
fSWAP(coordonnee_Z1,coordonnee_Z2);
/* Choix de l'ordre {J,I} pour les deux points (l'utilisation de la procedure 'fSWAP(...)' */
/* fut introduite le 20051206093039...). */
Eblock
ATes
Bblock
Eblock
ETes
CAL2(Prin3(" pointI={%+.^^^,%+.^^^,%+.^^^}",coordonnee_X1,coordonnee_Y1,coordonnee_Z1));
CAL2(Prin3(" pointJ={%+.^^^,%+.^^^,%+.^^^}",coordonnee_X2,coordonnee_Y2,coordonnee_Z2));
/* Le 20060105152121, le format "16g" est passe a "^^g" pour plus de souplesse... */
/* */
/* Le 20091123123539, le format "^^g" est passe a "^^^" pour plus de souplesse... */
Eblock
ATes
Bblock
Eblock
ETes
CAL2(Prin1(" distance=%+.^^^"
,gELEMENT_DU_FICHIER(liste_des_distances_du_point_I_aux_points_J,index_J_trie)
)
);
CAL2(Prin0("\n"));
/* Edition de la distance du point 'I' (fixe) a ses N premiers voisins 'J'. */
/* */
/* Le 20060105152121, le format "16g" est passe a "^^g" pour plus de souplesse... */
/* */
/* Le 20091123123539, le format "^^g" est passe a "^^^" pour plus de souplesse... */
INCR(compteur_des_distances,I);
/* Introduit le 20161109120606... */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
EDoI
Eblock
ATes
Bblock
Eblock
ETes
lGENERATION_D_UN_FICHIER(liste_des_distances_du_point_I_aux_points_J,FLOT__UNDEF);
lGENERATION_D_UN_FICHIER(liste_des_points,FLOT__UNDEF);
Eblock
EDoI
Test(IZEQ(compteur_des_distances))
/* Test introduit le 20161109120606... */
Bblock
PRINT_ATTENTION("aucune distance n'a ete editee");
Test(IL_FAUT(filtrer_les_distances))
Bblock
PRINT_ATTENTION("il y a filtrage et les bornes sont certainement 'insuffisantes'");
CAL1(Prer2("(les bornes inferieure et superieure valent respectivement %f et %f)\n"
,borne_inferieure_des_distances
,borne_superieure_des_distances
)
);
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
lGENERATION_D_UN_FICHIER(liste_initiale_des_VOISIN,VOISIN_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_VOISIN,VOISIN_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_Z,Z_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_Y,Y_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_X,X_IMPLICITE);
RETU_Commande;
Eblock
ECommande