/*************************************************************************************************************************************/ /* */ /* C A L C U L D ' U N E F O N C T I O N D E D E N S I T E D E F I N I E P A R */ /* U N E N S E M B L E D E P O I N T S { X , Y , Z } : */ /* */ /* */ /* Author of '$xrv/densite.01$I' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20111213102502). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L D E L A D E N S I T E : */ /* */ /*************************************************************************************************************************************/ #define RENORMALISER_XYZ(coordonnee,minimum,maximum,minimum_par_defaut,maximum_par_defaut) \ EGAL(coordonnee \ ,COND(IFET(IFEQ(minimum,minimum_par_defaut),IFEQ(maximum,maximum_par_defaut)) \ ,coordonnee \ ,HOMO(coordonnee,minimum_par_defaut,maximum_par_defaut,minimum,maximum) \ ) \ ); \ /* Renormalisation des coordonnees (introduite le 20100827205253). */ \ /* */ \ /* On notera qu'a priori le 'COND(...)' est inutile parce que par definition 'HOMO(...)' */ \ /* doit etre neutre lorsque les extrema sont egaux a leur valeur par defaut. Mais afin */ \ /* d'etre sur de garantir la compatibilite anterieure, il est plus prudent de mettre le */ \ /* 'COND(...)'. */ #define CALCUL_DE_LA_DENSITE(tranche_Z) \ Bblock \ DEFV(Float,INIT(coordonnee_XI,AXPB(facteur_AXI,TRANSFORMATION_COORDONNEEE_X(X),facteur_BXI))); \ DEFV(Float,INIT(coordonnee_YI,AXPB(facteur_AYI,TRANSFORMATION_COORDONNEEE_Y(Y),facteur_BYI))); \ DEFV(Float,INIT(coordonnee_ZI,AXPB(facteur_AZI,tranche_Z,facteur_BZI))); \ /* Recuperation des coordonnees {X,Y,Z} courantes de l'image. */ \ \ DEFV(Float,INIT(increment_de_la_densite_courante,FZERO)); \ /* Definition l'increment de la densite courante au point {X,Y,Z} de l'image. */ \ \ RENORMALISER_XYZ(coordonnee_XI,X_minimum,X_maximum,X_MINIMUM,X_MAXIMUM); \ RENORMALISER_XYZ(coordonnee_YI,Y_minimum,Y_maximum,Y_MINIMUM,Y_MAXIMUM); \ RENORMALISER_XYZ(coordonnee_ZI,Z_minimum,Z_maximum,Z_MINIMUM,Z_MAXIMUM); \ /* Renormalisation eventuelle des coordonnees (introduite le 20100827205253). */ \ \ CLIR(densite_courante); \ /* Initialisation de la densite courante au point {X,Y,Z} de l'image. */ \ \ DoIn(index \ ,PREMIER_ELEMENT_D_UN_FICHIER \ ,DERNIER_ELEMENT_D_UN_FICHIER \ ,I \ ) \ Bblock \ DEFV(Float,INIT(coordonnee_XF,AXPB(facteur_AXF,ELEMENT_DU_FICHIER_LISTE_X(index),facteur_BXF))); \ DEFV(Float,INIT(coordonnee_YF,AXPB(facteur_AYF,ELEMENT_DU_FICHIER_LISTE_Y(index),facteur_BYF))); \ DEFV(Float,INIT(coordonnee_ZF,AXPB(facteur_AZF,ELEMENT_DU_FICHIER_LISTE_Z(index),facteur_BZF))); \ /* Recuperation des coordonnees {X,Y,Z} courantes dans les fichiers. */ \ DEFV(Float,INIT(translation_de_XF,FLOT__UNDEF)); \ DEFV(Float,INIT(translation_de_YF,FLOT__UNDEF)); \ DEFV(Float,INIT(translation_de_ZF,FLOT__UNDEF)); \ /* Translations des coordonnees {X,Y,Z} nulles si 'EST_FAUX(l_espace_est_torique)' et */ \ /* valant {-1,0,+1} dans le cas contraire. */ \ \ DoIn(translation_de_XF \ ,TRANSLATION_NEGATIVE_DES_COORDONNEES(l_espace_est_torique_en_X) \ ,TRANSLATION_POSITIVE_DES_COORDONNEES(l_espace_est_torique_en_X) \ ,LONGUEUR_DES_TROIS_DIMENSIONS \ ) \ Bblock \ DoIn(translation_de_YF \ ,TRANSLATION_NEGATIVE_DES_COORDONNEES(l_espace_est_torique_en_Y) \ ,TRANSLATION_POSITIVE_DES_COORDONNEES(l_espace_est_torique_en_Y) \ ,LONGUEUR_DES_TROIS_DIMENSIONS \ ) \ Bblock \ DoIn(translation_de_ZF \ ,TRANSLATION_NEGATIVE_DES_COORDONNEES(l_espace_est_torique_en_Z) \ ,TRANSLATION_POSITIVE_DES_COORDONNEES(l_espace_est_torique_en_Z) \ ,LONGUEUR_DES_TROIS_DIMENSIONS \ ) \ Bblock \ DEFV(Float,INIT(distance_courante,FLOT__UNDEF)); \ DEFV(Float,INIT(distance_courante_transformee,FLOT__UNDEF)); \ /* Distance entre le point courant de l'Image et le point courant du Fichier, avant et */ \ /* apres transformation ('distance_courante_transformee' fut introduite le 20030228091429). */ \ DEFV(Float,INIT(fonction_de_la_distance_courante,FLOT__UNDEF)); \ /* Pour alleger le travail du compilateur et eventuellement optimisee le code genere au */ \ /* cas ou 'BUG_SYSTEME_SG_C_pow' existe... */ \ DEFV(Float,INIT(modulation_de_l_exponentielle,facteur_de_l_exponentielle)); \ /* Modulation courante de l'exponentielle a priori "neutre"... */ \ \ USs_GooF______CONDITIONNEL \ (calculer_des_distances_etendues \ ,BLOC( \ Bblock \ EGAL(distance_courante \ ,UdisF3D(NEUT(coordonnee_XI) \ ,NEUT(coordonnee_YI) \ ,NEUT(coordonnee_ZI) \ ,ADD2(coordonnee_XF,translation_de_XF) \ ,ADD2(coordonnee_YF,translation_de_YF) \ ,ADD2(coordonnee_ZF,translation_de_ZF) \ ,ponderation_de_la_distance_euclidienne \ ,ponderation_de_la_distance_du_chauffeur_de_taxi_inferieure \ ,ponderation_de_la_distance_du_chauffeur_de_taxi_superieure \ ,ponderation_de_la_distance_du_chauffeur_de_taxi_cumulee \ ,ponderation_de_la_distance_du_chauffeur_de_taxi_multipliee \ ) \ ); \ /* Le 20071026091245, tout cela fut simplifie en introduisant 'UdisF3D(...)'... */ \ Eblock \ ) \ ); \ /* L'appel a 'USs_GooF______CONDITIONNEL(...)' fut introduit le 20071103134743... */ \ \ Test(IFET(IL_FAUT(ignorer_les_grandes_distances) \ ,IFGE(distance_courante,seuil_de_definition_des_grandes_distances) \ ) \ ) \ /* Possibilite introduite le 20070514102133 pour accelerer les calculs... */ \ Bblock \ Eblock \ ATes \ Bblock \ EGAL(distance_courante_transformee \ ,xTRON(distance_courante \ ,minimum_de_la_distance \ ,maximum_de_la_distance \ ,valeur_de_la_distance_au_minimum_de_la_distance \ ,MUL2(facteur_de_la_distance,distance_courante) \ ,valeur_de_la_distance_au_maximum_de_la_distance \ ,IFINff \ ) \ ); \ /* Distance entre le point courant de l'Image et le point courant du Fichier avec seuillage. */ \ /* */ \ /* Le 20070506183223 'IFLE(distance_courante,seuil_de_la_distance)' a ete donc remplace */ \ /* par le 'IFINff(...)', les valeurs par defaut garantissant la compatibilite anterieure... */ \ \ EGAL(fonction_de_la_distance_courante \ ,NEGA(MUL2(MUL2(ELEMENT_DU_FICHIER_LISTE_MODULATION_DU_FACTEUR_DE_LA_DISTANCE(index) \ ,facteur_de_la_distance_dans_l_exponentielle \ ) \ ,PUIX(distance_courante_transformee \ ,exposant_de_la_distance_dans_l_exponentielle \ ) \ ) \ ) \ ); \ \ Test(IL_FAUT(moduler_l_exponentielle)) \ Bblock \ EGAL(modulation_de_l_exponentielle \ ,LIZ2(facteur_du_monome \ ,PUIX(distance_courante_transformee \ ,exposant_de_la_distance_dans_le_monome \ ) \ ,facteur_du_cosinus \ ,COSX(AXPB(MUL2(ELEMENT_DU_FICHIER_LISTE_MODULATION_DE_OMEGA(index) \ ,omega_du_cosinus \ ) \ ,PUIX(distance_courante_transformee \ ,exposant_de_la_distance_dans_le_cosinus \ ) \ ,MUL2(ELEMENT_DU_FICHIER_LISTE_MODULATION_DE_PHI(index) \ ,phi_du_cosinus \ ) \ ) \ ) \ ) \ ); \ /* La modulation est composee d'un premier terme polynomial puis d'un second terme */ \ /* trigonometrique. */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ EGAL(increment_de_la_densite_courante \ ,MUL2(modulation_de_l_exponentielle,EXEX(fonction_de_la_distance_courante)) \ ); \ \ EGAL(densite_courante \ ,OPC2(IL_FAUT(calculer_la_densite_par_sommation) \ ,ADD2 \ ,MAX2 \ ,densite_courante,increment_de_la_densite_courante \ ) \ ); \ /* Cumul des distances du point courant de l'Image a l'ensemble des points du Fichier. */ \ /* */ \ /* Soit donc 'PI' le point courant de l'Image et 'PF' le point courant du Fichier. La */ \ /* densite courante en 'PI' est definie par : */ \ /* */ \ /* ______ */ \ /* \ Ee */ \ /* \ Me Ce -Ek.d (PI,PF) */ \ /* densite(PI) = / [Mk.d (PI,PF) + Ck.cos(OMEGA.d (PI,PF) + PHI)].e */ \ /* /_____ */ \ /* */ \ /* {PF} \____________________________________________/ */ \ /* facteur conditionnel */ \ /* */ \ /* ou 'k' et 'E' designent 'facteur_de_la_distance_dans_l_exponentielle' et */ \ /* 'exposant_de_la_distance_dans_l_exponentielle' respectivement. La fonction 'd(...)' */ \ /* quant a elle correspond a la distance entre 'PI' et 'PF' (eventuellement seuillee */ \ /* par 'seuil_de_la_distance' et modulee par 'facteur_de_la_distance' ; on notera que */ \ /* le 20070506183223 le seuillage par 'seuil_de_la_distance' fut remplace par un filtrage */ \ /* dans [minimum_de_la_distance,maximum_de_la_distance]...). */ \ /* */ \ /* On notera le 20070714214628 que cette possibilite de moduler l'exponentielle par un */ \ /* cosinus introduit en quelques sorte une longueur d'onde pour les particules qui peuvent */ \ /* alors interferer entre-elles puisque cette modulation est signee et que le cumul qui */ \ /* est effectue est en fait une interference constructive et destructive suivant les cas... */ \ /* */ \ /* Evidemment, dans une utilisation de type "interpolation", il conviendra de ne pas */ \ /* "moduler" l'exponentielle et de s'en tenir donc a : */ \ /* */ \ /* ______ */ \ /* \ Ee */ \ /* \ -Ek.d (PI,PF) */ \ /* densite(PI) = / e */ \ /* /_____ */ \ /* */ \ /* {PF} */ \ /* */ \ /* qui est, au passage, le mode par defaut, soit plus explicitement : */ \ /* */ \ /* ______ */ \ /* \ 2 */ \ /* \ -16.d (PI,PF) */ \ /* densite(PI) = / e */ \ /* /_____ */ \ /* */ \ /* {PF} */ \ /* */ \ /* avec les valeurs par defaut... */ \ /* */ \ /* ATTENTION, 'EXPX(...)' a ete remplace par 'EXEX(...)' le 20000918133324 a cause du */ \ /* probleme decrit dans 'v $Dbugs/SGO200A2$D/IRIX$D/CC$D/exp.01$c'. */ \ /* */ \ /* On notera une utilisation interessante decouverte le 20030228091429 en faisant : */ \ /* */ \ /* moduler=VRAI */ \ /* */ \ /* Mk=1 Me=1 */ \ /* Ck=0 */ \ /* Ek=0 */ \ /* */ \ /* qui calcule donc (en "modulant" l'exponentielle par "moduler=VRAI") : */ \ /* */ \ /* ______ */ \ /* \ */ \ /* \ */ \ /* densite(PI) = / d(PI,PF) */ \ /* /_____ */ \ /* */ \ /* et qui, avec deux points redonne evidemment des ellipses concentriques dont ces deux */ \ /* points sont les foyers et ce en visualisant les lignes de niveau... */ \ /* */ \ /* Le choix entre 'ADD2(...)' et 'MAX2(...)' fut introduit le 20070517103803... */ \ Eblock \ ETes \ Eblock \ EDoI \ Eblock \ EDoI \ Eblock \ EDoI \ Eblock \ EDoI \ \ EGAL(minimum_des_densites,MIN2(densite_courante,minimum_des_densites)); \ EGAL(maximum_des_densites,MAX2(densite_courante,maximum_des_densites)); \ /* Extrema des exponentielles en vue d'une eventuelle renormalisation... */ \ Eblock \ /* Procedure introduite le 20100504103350... */