/*************************************************************************************************************************************/ /* */ /* V I S U A L I S A T I O N D E L A L I S T E D E S P O I N T S : */ /* */ /* */ /* Author of '$xrv/champs_5.12$I' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 1992??????????). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E S T I O N D E S O M B R E S P O R T E E S : */ /* */ /*************************************************************************************************************************************/ #define GERER_LES_OMBRES_PORTEES \ FAUX DEFV(Local,DEFV(Logical,INIT(gerer_les_ombres_portees,GERER_LES_OMBRES_PORTEES))); /* Faut-il gerer les ombres portees ? Cette possibilite fut introduite le 20220508102801. */ /* La valeur par defaut assure la compatibilite anterieure... */ #TestADef GESTION_DES_OMBRES_PORTEES_____COMPATIBILITE_20220522 \ FAUX DEFV(Local,DEFV(Logical,INIT(gestion_des_ombres_portees_____compatibilite_20220522 ,GESTION_DES_OMBRES_PORTEES_____COMPATIBILITE_20220522 ) ) ); /* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */ /* du 20220522135138... */ #TestADef GESTION_DES_OMBRES_PORTEES_____COMPATIBILITE_2022060711 \ FAUX DEFV(Local,DEFV(Logical,INIT(gestion_des_ombres_portees_____compatibilite_2022060711 ,GESTION_DES_OMBRES_PORTEES_____COMPATIBILITE_2022060711 ) ) ); /* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */ /* du 20220607115736... */ #TestADef GESTION_DES_OMBRES_PORTEES_____COMPATIBILITE_2022060712 \ FAUX DEFV(Local,DEFV(Logical,INIT(gestion_des_ombres_portees_____compatibilite_2022060712 ,GESTION_DES_OMBRES_PORTEES_____COMPATIBILITE_2022060712 ) ) ); /* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */ /* du 20220607123914... */ #define SEUIL_ANGULAIRE_DE_DECLENCHEMENT_DE_L_OMBRAGE \ GRO2(FRA10(FRA10(FU))) #define ANGLE_D_INFLEXION_DE_L_OMBRAGE \ FRA2(SEUIL_ANGULAIRE_DE_DECLENCHEMENT_DE_L_OMBRAGE) DEFV(Local,DEFV(Float,INIT(seuil_angulaire_de_declenchement_de_l_ombrage,SEUIL_ANGULAIRE_DE_DECLENCHEMENT_DE_L_OMBRAGE))); DEFV(Local,DEFV(Float,INIT(angle_d_inflexion_de_l_ombrage,ANGLE_D_INFLEXION_DE_L_OMBRAGE))); /* Seuil en deca duquel on declare que le point est a l'ombre et angle d'inflexion de */ /* 'TAHX01(...)'. */ #define FACTEUR_DE_L_ANGLE_D_OMBRAGE \ FLOT(CENT) #define NIVEAU_D_OMBRAGE__ \ GRO1(FRA2(FU)) #define NIVEAU_D_ECLAIRAGE \ GRO1(FRA1(FU)) DEFV(Local,DEFV(Float,INIT(facteur_de_l_angle_d_ombrage,FACTEUR_DE_L_ANGLE_D_OMBRAGE))); DEFV(Local,DEFV(Float,INIT(niveau_d_ombrage__,NIVEAU_D_OMBRAGE__))); DEFV(Local,DEFV(Float,INIT(niveau_d_eclairage,NIVEAU_D_ECLAIRAGE))); /* Definition de l'ombre et de la zone de penombre... */ /* */ /* Ainsi la zone de penombre varie de 'niveau_d_ombrage__' a 'niveau_d_eclairage' */ /* suivant une tangente hyperbolique dans [0,1]... */ /* */ /* Voir 'v $xtc/TANH.01$c' pour regler les trois parametres... */ #define FACTEUR1_DU_RAPPORT_DES_RAYONS_D_OMBRAGE \ FU DEFV(Local,DEFV(Float,INIT(facteur1_du_rapport_des_rayons_d_ombrage,FACTEUR1_DU_RAPPORT_DES_RAYONS_D_OMBRAGE))); /* Facteur 1 du rapport des rayons d'ombrage. */ #define BORNE_INFERIEURE_DU_RAPPORT_DES_RAYONS_D_OMBRAGE \ FDU #define BORNE_SUPERIEURE_DU_RAPPORT_DES_RAYONS_D_OMBRAGE \ FDEUX DEFV(Local,DEFV(Float,INIT(borne_inferieure_du_rapport_des_rayons_d_ombrage,BORNE_INFERIEURE_DU_RAPPORT_DES_RAYONS_D_OMBRAGE))); DEFV(Local,DEFV(Float,INIT(borne_superieure_du_rapport_des_rayons_d_ombrage,BORNE_SUPERIEURE_DU_RAPPORT_DES_RAYONS_D_OMBRAGE))); /* Introduit le 20220607133039 afin de limiter les effets de la modulation de l'attenuation */ /* avec le rapport des rayons... */ #define FACTEUR2_DU_RAPPORT_DES_RAYONS_D_OMBRAGE \ GRO4(FRA10(FU)) DEFV(Local,DEFV(Float,INIT(facteur2_du_rapport_des_rayons_d_ombrage,FACTEUR2_DU_RAPPORT_DES_RAYONS_D_OMBRAGE))); /* Facteur 2 du rapport des rayons d'ombrage, une valeur nulle inhibant cet effet... */ gDEFINITION_LISTE(liste_des_ANGLES_D_OMBRAGE,NOMBRE_MAXIMAL_DE_POINTS_VISUALISABLES); gDEFINITION_LISTE(liste_des_RAYONS_D_OMBRAGE,NOMBRE_MAXIMAL_DE_POINTS_VISUALISABLES); /* Ces listes ne sont utiles que si les ombres portees sont gerees... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N D E V I S U A L I S A T I O N D U P O I N T C O U R A N T : */ /* */ /*************************************************************************************************************************************/ #define ATTENUATION_AU_BORD_D_UN_DISQUE \ GRO1(FRA8(FU)) \ /* Valeur implicite du facteur d'attenuation au bord des disques materialisant les */ \ /* spheres. */ DEFV(Local,DEFV(Float,INIT(attenuation_au_bord_d_un_disque,ATTENUATION_AU_BORD_D_UN_DISQUE))); /* Facteur d'attenuation au bord des disques materialisant les spheres. */ /* */ /* ATTENTION, ce parametre 'attenuation_au_bord_d_un_disque' ("attenuation_au_bord=") */ /* associe au parametre 'epaisseur_de_la_couronne_d_anti_aliasing' ("couronne=") peut, */ /* comme cela s'est vu en generant la sequence : */ /* */ /* xivPdf 9 2 / 026783_027294 */ /* */ /* avoir des effets visuels genants en ce qui concerne le rayon apparent des spheres */ /* (c'est-a-dire tel qu'elles sont vues). Il peut etre alors necessaire de "tricher" en */ /* augmentant le rayon (d'ou le parametre '$_____FacteurPsI' inferieur a 1 dans la dite */ /* sequence...). */ #define NIVEAU_AU_BORD_D_UN_DISQUE(niveau) \ NIVA(INTE(MUL2(attenuation_au_bord_d_un_disque,FLOT(NIVR(niveau))))) \ /* Niveau au bord d'un disque visualisant une sphere en vraies couleurs... */ BFonctionI DEFV(Local,DEFV(FonctionI,visualisation_d_un_point(Xf,Yf,Zf ,rayon_reel_absolu ,rayon_reel_de_visualisation ,niveau_ROUGE_normalise,niveau_VERTE_normalise,niveau_BLEUE_normalise ) ) ) DEFV(Argument,DEFV(Float,Xf)); DEFV(Argument,DEFV(Float,Yf)); DEFV(Argument,DEFV(Float,Zf)); /* Definition de la position {x,y,z} du point courant dans l'espace de visualisation, */ DEFV(Argument,DEFV(Float,rayon_reel_absolu)); DEFV(Argument,DEFV(Float,rayon_reel_de_visualisation)); /* Du rayon de sa sphere de materialisation (Absolu et de Visualisation). */ DEFV(Argument,DEFV(Float,niveau_ROUGE_normalise)); DEFV(Argument,DEFV(Float,niveau_VERTE_normalise)); DEFV(Argument,DEFV(Float,niveau_BLEUE_normalise)); /* Et de sa couleur... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /*..............................................................................................................................*/ store_sphere(NIVEAU_AU_BORD_D_UN_DISQUE(niveau_ROUGE_normalise) ,NIVEAU_AU_BORD_D_UN_DISQUE(niveau_VERTE_normalise) ,NIVEAU_AU_BORD_D_UN_DISQUE(niveau_BLEUE_normalise) ,niveau_ROUGE_normalise ,niveau_VERTE_normalise ,niveau_BLEUE_normalise ,Image_ROUGE ,Image_VERTE ,Image_BLEUE ,Xf ,Yf ,Zf ,rayon_reel_absolu ,rayon_reel_de_visualisation ); /* Et visualisation du point courant... */ RETU_ERROR; Eblock EFonctionI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* V I S U A L I S A T I O N D ' U N E L I S T E D E P O I N T S S A N S R E N O R M A L I S A T I O N : */ /* */ /*************************************************************************************************************************************/ #define NO_RENORMALISATION \ FU \ /* Valeur a donner au couple de facteurs de renormalisation si l'on souhaite que cette */ \ /* derniere operation soit neutre... */ #define VISUALISATION_D_UNE_LISTE_DE_POINTS(numero_image) \ Bblock \ VISUALISATION_D_UNE_LISTE_DE_POINTS_AVEC_RENORMALISATION(NO_RENORMALISATION,NO_RENORMALISATION \ ,NO_RENORMALISATION,NO_RENORMALISATION \ ,NO_RENORMALISATION,NO_RENORMALISATION \ ,numero_image \ ); \ /* Visualisation de la liste de points avec une renormalisation "neutre" (1/1)... */ \ Eblock \ /* Visualisation d'une liste de points sans renormalisation finale des niveaux. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* V I S U A L I S A T I O N D ' U N E L I S T E D E P O I N T S A V E C R E N O R M A L I S A T I O N : */ /* */ /*************************************************************************************************************************************/ #define EDITER_LE_NOMBRE_DE_POINTS_A_VISUALISER \ FAUX DEFV(Local,DEFV(Logical,INIT(editer_le_nombre_de_points_a_visualiser,EDITER_LE_NOMBRE_DE_POINTS_A_VISUALISER))); /* Faut-il editer le nombre de points a visualiser (introduit le 20050619182851). */ #define mTRONCATION_NORMALISATION(niveau,seuil_inferieur,seuil_superieur) \ TRON(__DENORMALISE_NIVEAU(niveau) \ ,seuil_inferieur \ ,seuil_superieur \ ) \ /* Normalisation, puis troncation des niveaux... */ BFonctionF DEFV(Local,DEFV(FonctionF,troncation_normalisation(niveau,seuil_inferieur,seuil_superieur))) /* ATTENTION, cette fonction a ete introduite afin de reduire la complexite des programmes */ /* '$c' generes, en particulier sur les SYSTEMEs 'SYSTEME_NWS3000_NEWSOS_2CC' et */ /* 'SYSTEME_VAX9000_ULTRIX_GCC'. */ DEFV(Argument,DEFV(Float,niveau)); /* Definition du niveau a normaliser puis a tronquer... */ DEFV(Argument,DEFV(genere_p,seuil_inferieur)); DEFV(Argument,DEFV(genere_p,seuil_superieur)); /* Definition des seuils inferieur et superieur du niveau a normaliser puis a tronquer... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ RETU(mTRONCATION_NORMALISATION(niveau,seuil_inferieur,seuil_superieur)); Eblock EFonctionF #define TRONCATION_NORMALISATION(niveau,seuil_inferieur,seuil_superieur) \ troncation_normalisation(FLOT(niveau),GENP(seuil_inferieur),GENP(seuil_superieur)) \ /* Normalisation, puis troncation des niveaux... */ #define DEPTH_CUEING_DES_POINTS(niveau,aCOULEUR,nCOULEUR,seuil_inferieur,seuil_superieur) \ SCAL(ATTENUATION_DE_DEPTH_CUEING(ATTENUATION(TRONCATION_NORMALISATION(niveau,seuil_inferieur,seuil_superieur) \ ,ACCES_LISTE(liste_des_numeros,index_de_visualisation) \ ) \ ,ACCES_LISTE(liste_des_Z,index_de_visualisation) \ ) \ ,aCOULEUR \ ,nCOULEUR \ ) \ /* Prise en compte de l'eventuel effet de "depth-cueing" et de toutes les operations de */ \ /* normalisation, de seuillage,... */ \ /* */ \ /* En resume, et en notant : */ \ /* */ \ /* pm = profondeur_minimale */ \ /* pM = profondeur_maximale */ \ /* */ \ /* pmT = profondeur_minimale_de_troncation */ \ /* pMT = profondeur_maximale_de_troncation */ \ /* */ \ /* la formule "simplifiee" de transformation d'un niveau 'N' est : */ \ /* */ \ /* N*TRON[z*(pM-pm)+pm,pmT,pMT] */ \ /* */ \ /* Note sur l'absence de "depth-cueing" : celle-ci est obtenu simplement en faisant : */ \ /* */ \ /* profondeur_minimale = COORDONNEE_BARYCENTRIQUE_MAXIMALE */ \ /* profondeur_maximale = COORDONNEE_BARYCENTRIQUE_MAXIMALE */ \ /* */ \ /* profondeur_minimale_de_troncation = COORDONNEE_BARYCENTRIQUE_MAXIMALE */ \ /* profondeur_maximale_de_troncation = COORDONNEE_BARYCENTRIQUE_MAXIMALE */ \ /* */ \ /* soit : */ \ /* */ \ /* minimum=Zminimum=1.0 */ \ /* maximum=Zmaximum=1.0 */ \ /* */ \ /* minimumT=ZminimumT=1.0 */ \ /* maximumT=ZmaximumT=1.0 */ \ /* */ \ /* */ \ /* Note sur le "depth-cueing" maximal : celle-ci est obtenu simplement en faisant : */ \ /* */ \ /* profondeur_minimale = COORDONNEE_BARYCENTRIQUE_MINIMALE */ \ /* profondeur_maximale = COORDONNEE_BARYCENTRIQUE_MAXIMALE */ \ /* */ \ /* profondeur_minimale_de_troncation = COORDONNEE_BARYCENTRIQUE_MINIMALE */ \ /* profondeur_maximale_de_troncation = COORDONNEE_BARYCENTRIQUE_MAXIMALE */ \ /* */ \ /* soit : */ \ /* */ \ /* minimum=Zminimum=0.0 */ \ /* maximum=Zmaximum=1.0 */ \ /* */ \ /* minimumT=ZminimumT=0.0 */ \ /* maximumT=ZmaximumT=1.0 */ \ /* */ \ /* ATTENTION, on notera bien que les valeurs {profondeur_minimale,profondeur_maximale} */ \ /* et {profondeur_minimale_de_troncation,profondeur_maximale_de_troncation} ne sont donc */ \ /* absolument pas synonymes. On pourra donc pour jouer sur le "depth-cueing" utiliser */ \ /* systematiquement les arguments suivants : */ \ /* */ \ /* Zmaximum=1.0 */ \ /* ZmaximumT=1.0 */ \ /* */ \ /* et a "moduler" : */ \ /* */ \ /* Zminimum=VALEUR */ \ /* ZminimumT=VALEUR */ \ /* */ \ /* ou 'VALEUR' est une valeur dans [0,1] pour laquelle '1.0' est l'absence de "depth-cueing" */ \ /* et '0.0' donne le "depth-cueing" maximal... */ #ifdef __VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND /* Le nom 'PERMETTRE_L_UTILISATION_D_UN_FOND' a ete change le 20030313151843 en */ /* '__VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND' afin de permettre sa recuperation */ /* dans 'v $xcc/cpp$Z _VERSION_'. */ # define INITIALISATION_DU_Z_BUFFER_D_UNE_IMAGE(numero_image) \ Bblock \ Test(EST_FAUX(le_fond_a_un_Z_Buffer)) \ Bblock \ CALi(IFinitialisation(Z_Buffer,valeur_d_initialisation_du_Z_Buffer)); \ /* Initialisation du 'Z-Buffer' ; cette initialisation est faite de facon a ce que la */ \ /* renormalisation du 'Z-Buffer', faite si un effet de brume est demande, soit correcte */ \ /* et homogene d'une image a l'autre. C'est aussi la raison pour laquelle les fonctions */ \ /* 'Iinit_Z_Buffer(...)' et 'Ifloat_std_du_Z_Buffer(...)' ne sont pas utilisees... */ \ Eblock \ ATes \ Bblock \ DEFV(CHAR,INIT(POINTERc(nom_temporaire_du_Z_Buffer_a_charger) \ ,COND(EST_VRAI(le_fond_est_dynamique) \ ,chain_Aconcaten2_sauf_nom_pipe(nom_imageZF,NUMERO_IMAGE(numero_image)) \ ,nom_imageZF \ ) \ ) \ ); \ CALi(IloadF_image(Z_Buffer,nom_temporaire_du_Z_Buffer_a_charger)); \ CALZ_FreCC(nom_temporaire_du_Z_Buffer_a_charger); \ /* Chargement du 'Z-Buffer' lorsque le fond en possede un... */ \ Eblock \ ETes \ Eblock \ /* Initialisation du 'Z-Buffer' de l'image a generer... */ #Aifdef __VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND # define INITIALISATION_DU_Z_BUFFER_D_UNE_IMAGE(numero_image) \ Bblock \ CALi(IFinitialisation(Z_Buffer,valeur_d_initialisation_du_Z_Buffer)); \ /* Initialisation du 'Z-Buffer' ; cette initialisation est faite de facon a ce que la */ \ /* renormalisation du 'Z-Buffer', faite si un effet de brume est demande, soit correcte */ \ /* et homogene d'une image a l'autre. C'est aussi la raison pour laquelle les fonctions */ \ /* 'Iinit_Z_Buffer(...)' et 'Ifloat_std_du_Z_Buffer(...)' ne sont pas utilisees... */ \ Eblock \ /* Initialisation du 'Z-Buffer' de l'image a generer... */ #Eifdef __VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND #define MODULER_LE_RAYON_DE_VISUALISATION_AVEC_LA_PROFONDEUR \ FAUX DEFV(Local,DEFV(Logical,INIT(moduler_le_rayon_de_visualisation_avec_la_profondeur ,MODULER_LE_RAYON_DE_VISUALISATION_AVEC_LA_PROFONDEUR ) ) ); #define PARAM_A_MODULATION_DU_RAYON_DE_VISUALISATION_AVEC_LA_PROFONDEUR \ FU DEFV(Local,DEFV(Float,INIT(param_A_modulation_du_rayon_de_visualisation_avec_la_profondeur ,PARAM_A_MODULATION_DU_RAYON_DE_VISUALISATION_AVEC_LA_PROFONDEUR ) ) ); #define PARAM_B_MODULATION_DU_RAYON_DE_VISUALISATION_AVEC_LA_PROFONDEUR \ FU DEFV(Local,DEFV(Float,INIT(param_B_modulation_du_rayon_de_visualisation_avec_la_profondeur ,PARAM_B_MODULATION_DU_RAYON_DE_VISUALISATION_AVEC_LA_PROFONDEUR ) ) ); /* Introduit le 20050419141720 afin de moduler 'rayon_reel_de_visualisation' avec 'Zf'... */ /* Les parametres {A,B} sont choisis de facon a ce que pour un 'Zf' nul, le rayon ne change */ /* pas et qu'il augmente ensuite avec 'Zf"... */ #ifndef CENTRER_AUTOMATIQUEMENT_LES_COORDONNEES # include xrk/attractor.51.I" /* Introduit le 20061110084827 a cause, en particulier, des '$K' de '$xrq'. */ #Aifndef CENTRER_AUTOMATIQUEMENT_LES_COORDONNEES #Eifndef CENTRER_AUTOMATIQUEMENT_LES_COORDONNEES #TestADef OPTIMISATION_DU_TRI_DES_POINTS_____COMPATIBILITE_2008030911 \ FAUX DEFV(Local,DEFV(Logical,INIT(optimisation_du_tri_des_points_____compatibilite_2008030911 ,OPTIMISATION_DU_TRI_DES_POINTS_____COMPATIBILITE_2008030911 ) ) ); /* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */ /* du 20080309112355... */ #include xrv/champs_5.1E.I" /* Mis sous cette forme le 20180823191034... */ #define VISUALISATION_D_UNE_LISTE_DE_POINTS_AVEC_RENORMALISATION(aROUGE,nROUGE,aVERTE,nVERTE,aBLEUE,nBLEUE,numero_image) \ Bblock \ DEFV(Float,INIT(translation_de_centrage_des_coordonnees_X,FZERO)); \ DEFV(Float,INIT(translation_de_centrage_des_coordonnees_Y,FZERO)); \ DEFV(Float,INIT(translation_de_centrage_des_coordonnees_Z,FZERO)); \ /* Translations des coordonnees {X,Y,Z}, nulles par defaut... */ \ \ DEFV(Float,INIT(coordonnee_X__du_point_precedent,FLOT__UNDEF)); \ DEFV(Float,INIT(coordonnee_Y__du_point_precedent,FLOT__UNDEF)); \ DEFV(Float,INIT(coordonnee_Z__du_point_precedent,FLOT__UNDEF)); \ DEFV(Float,INIT(rayon_________du_point_precedent,FLOT__UNDEF)); \ DEFV(Float,INIT(couleur_ROUGE_du_point_precedent,FLOT__UNDEF)); \ DEFV(Float,INIT(couleur_VERTE_du_point_precedent,FLOT__UNDEF)); \ DEFV(Float,INIT(couleur_BLEUE_du_point_precedent,FLOT__UNDEF)); \ /* Definition du point precedent (introduit le 20080309112355). */ \ \ Test(IL_FAUT(editer_le_nombre_de_points_a_visualiser)) \ Bblock \ CAL2(Prin1("nombre de points a visualiser=%d\n" \ ,NBRE(PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste) \ ) \ ); \ /* Edition introduite le 20050619182851 car cela peut-etre utile... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IL_FAUT(centrer_automatiquement_les_coordonnees)) \ /* Possibilite introduite le 20060922134949... */ \ Bblock \ DEFV(Float,INIT(minimum_des_coordonnees_X,F_INFINI)); \ DEFV(Float,INIT(minimum_des_coordonnees_Y,F_INFINI)); \ DEFV(Float,INIT(minimum_des_coordonnees_Z,F_INFINI)); \ /* Minima des coordonnees {X,Y,Z}... */ \ DEFV(Float,INIT(maximum_des_coordonnees_X,F_MOINS_L_INFINI)); \ DEFV(Float,INIT(maximum_des_coordonnees_Y,F_MOINS_L_INFINI)); \ DEFV(Float,INIT(maximum_des_coordonnees_Z,F_MOINS_L_INFINI)); \ /* Maxima des coordonnees {X,Y,Z}... */ \ \ DoIn(index_d_extraction_de_la_liste,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ Bblock \ /* On notera que l'on utilise pas {minimum_de_cx,minimum_de_cy,minimum_de_cz} car, en */ \ /* effet, les coordonnees {X,Y,Z} manipulees ici sont dans [0,1] et non plus dans */ \ /* l'espace physique... */ \ EGAL(minimum_des_coordonnees_X \ ,MIN2(minimum_des_coordonnees_X,ACCES_LISTE(liste_des_X,index_d_extraction_de_la_liste)) \ ); \ EGAL(maximum_des_coordonnees_X \ ,MAX2(maximum_des_coordonnees_X,ACCES_LISTE(liste_des_X,index_d_extraction_de_la_liste)) \ ); \ /* Extrema des coordonnees 'X'... */ \ EGAL(minimum_des_coordonnees_Y \ ,MIN2(minimum_des_coordonnees_Y,ACCES_LISTE(liste_des_Y,index_d_extraction_de_la_liste)) \ ); \ EGAL(maximum_des_coordonnees_Y \ ,MAX2(maximum_des_coordonnees_Y,ACCES_LISTE(liste_des_Y,index_d_extraction_de_la_liste)) \ ); \ /* Extrema des coordonnees 'Y'... */ \ EGAL(minimum_des_coordonnees_Z \ ,MIN2(minimum_des_coordonnees_Z,ACCES_LISTE(liste_des_Z,index_d_extraction_de_la_liste)) \ ); \ EGAL(maximum_des_coordonnees_Z \ ,MAX2(maximum_des_coordonnees_Z,ACCES_LISTE(liste_des_Z,index_d_extraction_de_la_liste)) \ ); \ /* Extrema des coordonnees 'Z'... */ \ Eblock \ EDoI \ \ Test(IL_FAUT(centrer_automatiquement_la_coordonnee_X)) \ Bblock \ /* Test introduit le 20131121075654... */ \ EGAL(translation_de_centrage_des_coordonnees_X \ ,ADD2(COORDONNEE_BARYCENTRIQUE_CENTRALE \ ,NEGA(MOYE(minimum_des_coordonnees_X,maximum_des_coordonnees_X)) \ ) \ ); \ /* Translations des coordonnees 'X' a utiliser... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IL_FAUT(centrer_automatiquement_la_coordonnee_Y)) \ Bblock \ /* Test introduit le 20131121075654... */ \ EGAL(translation_de_centrage_des_coordonnees_Y \ ,ADD2(COORDONNEE_BARYCENTRIQUE_CENTRALE \ ,NEGA(MOYE(minimum_des_coordonnees_Y,maximum_des_coordonnees_Y)) \ ) \ ); \ /* Translations des coordonnees 'Y' a utiliser... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IL_FAUT(centrer_automatiquement_la_coordonnee_Z)) \ Bblock \ /* Test introduit le 20131121075654... */ \ EGAL(translation_de_centrage_des_coordonnees_Z \ ,ADD2(COORDONNEE_BARYCENTRIQUE_CENTRALE \ ,NEGA(MOYE(minimum_des_coordonnees_Z,maximum_des_coordonnees_Z)) \ ) \ ); \ /* Translations des coordonnees 'Z' a utiliser... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ INITIALISATION_DU_Z_BUFFER_D_UNE_IMAGE(numero_image); \ /* Initialisation du 'Z-Buffer'. */ \ \ CLIR(compteur_des_spheres_dans_l_image); \ /* Afin de compter les spheres dans l'image (eventuellement "clippee" et/ou cachee par */ \ /* d'autres...). */ \ \ Test(IL_FAUT(gerer_les_ombres_portees)) \ Bblock \ /* Possibilite introduite le 20220508102801... */ \ /* */ \ /* Je note le 20220522133100 que cette gestion est evidemment simpliste et peut donner */ \ /* des resultats parfois absurdes : c'est par exemple le cas d'un Grosse sphere 'gS' a */ \ /* l'ombre d'une plus Petite 'pS'. C'est alors l'integralite de la surface de 'gS' qui */ \ /* sera ombragee alors qu'en realite seule une petite partie devrait l'etre. Malheureusement */ \ /* cela ne peut etre corrige puisque le traitement qui va suivre ne prende en compte que */ \ /* coordonnees {X,Y,Z} du centre de chaque sphere, en ignorant le rayon. Une petite */ \ /* amelioration pourrait etre de faire que 'attenuation_a_l_ombre' devienne de plus soit */ \ /* une fonction croissante du rayon de la sphere qui fait de l'ombre, soit une fonction */ \ /* decroissante du rayon de la sphere a l'ombre... */ \ /* */ \ /* Les defauts mentionnes ci-dessus ont ete corriges partiellement le 20220522135138 en */ \ /* prenant en compte le rapport entre le rayon de la particule faisant de l'ombre et le */ \ /* rayon de celle qui est a l'ombre... */ \ \ DEFV(Int,INIT(index1,UNDEF)); \ \ DoIn(index1,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ Bblock \ EGAL(ACCES_LISTE(liste_des_ANGLES_D_OMBRAGE,index1),F_INFINI); \ Eblock \ EDoI \ \ DoIn(index1,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ /* Parcours de la liste des 'Point1's (qui seront joints a la source lumineuse)... */ \ Bblock \ DEFV(Float,INIT(Point1_X,ACCES_LISTE(liste_des_X,index1))); \ DEFV(Float,INIT(Point1_Y,ACCES_LISTE(liste_des_Y,index1))); \ DEFV(Float,INIT(Point1_Z,ACCES_LISTE(liste_des_Z,index1))); \ \ DEFV(Float,INIT(distance_Point1_SourceLumineuse,FLOT__UNDEF)); \ \ EGAL(distance_Point1_SourceLumineuse \ ,RdisF3D(Point1_X \ ,Point1_Y \ ,Point1_Z \ ,ASD1(Lsource,x) \ ,ASD1(Lsource,y) \ ,ASD1(Lsource,z) \ ) \ ); \ Test(IZEQ(distance_Point1_SourceLumineuse)) \ Bblock \ /* Cas ou le 'Point1' est confondu avec la source lumineuse... */ \ Eblock \ ATes \ Bblock \ DEFV(Int,INIT(index2,UNDEF)); \ \ DEFV(vectorF_3D,Vecteur_SourceLumineuse_Point1); \ \ INITIALISATION_VECTEUR_3D(Vecteur_SourceLumineuse_Point1 \ ,ASD1(Lsource,x) \ ,ASD1(Lsource,y) \ ,ASD1(Lsource,z) \ ,Point1_X \ ,Point1_Y \ ,Point1_Z \ ); \ /* Definition du rayon lumineux passant par le point 'Point1'... */ \ \ DoIn(index2,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ /* Parcours de la liste des 'Point2's (qui seront joints au point 'Point1')... */ \ Bblock \ DEFV(Float,INIT(Point2_X,ACCES_LISTE(liste_des_X,index2))); \ DEFV(Float,INIT(Point2_Y,ACCES_LISTE(liste_des_Y,index2))); \ DEFV(Float,INIT(Point2_Z,ACCES_LISTE(liste_des_Z,index2))); \ \ Test(I3ET(IFEQ(Point2_X,Point1_X) \ ,IFEQ(Point2_Y,Point1_Y) \ ,IFEQ(Point2_Z,Point1_Z) \ ) \ ) \ Bblock \ /* Cas ou les 'Point1' et 'Point2' sont confondus... */ \ Eblock \ ATes \ Bblock \ DEFV(Float,INIT(distance_Point2_SourceLumineuse,FLOT__UNDEF)); \ \ EGAL(distance_Point2_SourceLumineuse \ ,RdisF3D(Point2_X \ ,Point2_Y \ ,Point2_Z \ ,ASD1(Lsource,x) \ ,ASD1(Lsource,y) \ ,ASD1(Lsource,z) \ ) \ ); \ /* Distance entre le point 'Point2' (different du point 'Point1' a la source lumineuses. */ \ \ Test(IZEQ(distance_Point2_SourceLumineuse)) \ Bblock \ /* Cas ou le 'Point2' est confondu avec la source lumineuse... */ \ Eblock \ ATes \ Bblock \ Test(IFGT(distance_Point2_SourceLumineuse,distance_Point1_SourceLumineuse)) \ Bblock \ /* Cas ou le point 'Point2' est plus loin que le point 'Point1' de la source lumineuse. */ \ /* Le point 'Point2' peut etre a l'ombre du point 'Point1' : */ \ DEFV(vectorF_3D,Vecteur_Point1_Point2); \ DEFV(Float,INIT(angle_d_ombrage,FLOT__UNDEF)); \ \ INITIALISATION_VECTEUR_3D(Vecteur_Point1_Point2 \ ,Point1_X \ ,Point1_Y \ ,Point1_Z \ ,Point2_X \ ,Point2_Y \ ,Point2_Z \ ); \ /* Definition du vecteur allant de 'Point1' a 'Point2'... */ \ \ EGAL(angle_d_ombrage \ ,ACOX(DIVI(prsF3D(Vecteur_SourceLumineuse_Point1,Vecteur_Point1_Point2) \ ,MUL2(normF3D(Vecteur_SourceLumineuse_Point1) \ ,normF3D(Vecteur_Point1_Point2) \ ) \ ) \ ) \ ); \ \ Test(IFLT(angle_d_ombrage,ACCES_LISTE(liste_des_ANGLES_D_OMBRAGE,index2))) \ Bblock \ EGAL(ACCES_LISTE(liste_des_ANGLES_D_OMBRAGE,index2),angle_d_ombrage); \ EGAL(ACCES_LISTE(liste_des_RAYONS_D_OMBRAGE,index2) \ ,ACCES_LISTE(liste_des_vRAYON,index1) \ ); \ /* Ainsi, on ne conserve que l'angle le plus faible correspondant donc au meilleur */ \ /* alignement entre 'Point1', 'Point2' et la source lumineuse.... */ \ Eblock \ ATes \ Bblock \ Test(IFEQ(angle_d_ombrage,ACCES_LISTE(liste_des_ANGLES_D_OMBRAGE,index2))) \ /* Test introduit le 20220607123914... */ \ Bblock \ Test(IL_FAUT(gestion_des_ombres_portees_____compatibilite_2022060712)) \ Bblock \ Eblock \ ATes \ Bblock \ EGAL(ACCES_LISTE(liste_des_RAYONS_D_OMBRAGE,index2) \ ,MAX2(ACCES_LISTE(liste_des_RAYONS_D_OMBRAGE,index2) \ ,ACCES_LISTE(liste_des_vRAYON,index1) \ ) \ ); \ /* Ainsi, c'est la plus grosse particule qui fait de l'ombre en cas d'egalite de */ \ /* 'angle_d_ombrage' (introduit le 20220607123914)... */ \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ EDoI \ Eblock \ ETes \ Eblock \ EDoI \ \ DoIn(index1,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ Bblock \ DEFV(Float,INIT(angle_d_ombrage,ACCES_LISTE(liste_des_ANGLES_D_OMBRAGE,index1))); \ DEFV(Float,INIT(rapport_des_rayons_d_ombrage,FLOT__UNDEF)); \ \ EGAL(rapport_des_rayons_d_ombrage \ ,DIVI(ACCES_LISTE(liste_des_RAYONS_D_OMBRAGE,index1) \ ,ACCES_LISTE(liste_des_vRAYON,index1) \ ) \ ); \ /* Calcul du rapport entre le rayon de la particule faisant de l'ombre a celui de celle */ \ /* qui est a l'ombre... */ \ \ Test(IFOU(IFET(IL_FAUT(gestion_des_ombres_portees_____compatibilite_2022060711) \ ,IFLE(angle_d_ombrage \ ,seuil_angulaire_de_declenchement_de_l_ombrage \ ) \ ) \ ,IFET(IL_NE_FAUT_PAS(gestion_des_ombres_portees_____compatibilite_2022060711) \ ,IFLE(angle_d_ombrage \ ,MUL2(TRON(MUL2(facteur1_du_rapport_des_rayons_d_ombrage \ ,rapport_des_rayons_d_ombrage \ ) \ ,borne_inferieure_du_rapport_des_rayons_d_ombrage \ ,borne_superieure_du_rapport_des_rayons_d_ombrage \ ) \ ,seuil_angulaire_de_declenchement_de_l_ombrage \ ) \ ) \ ) \ ) \ ) \ /* Le 20220607115555 a ete introduit la possibilite que le seuil de declenchement de */ \ /* l'ombrage depende du rapport des rayons... */ \ Bblock \ DEFV(Float,INIT(attenuation_a_l_ombre \ ,AXPB(SOUS(niveau_d_eclairage,niveau_d_ombrage__) \ ,TAHX01(MUL2(facteur_de_l_angle_d_ombrage \ ,SOUS(angle_d_ombrage,angle_d_inflexion_de_l_ombrage) \ ) \ ) \ ,niveau_d_ombrage__ \ ) \ ) \ ); \ /* Ainsi la zone de penombre varie de 'niveau_d_ombrage__' a 'niveau_d_eclairage' */ \ /* suivant une tangente hyperbolique dans [0,1]... */ \ \ Test(IL_FAUT(gestion_des_ombres_portees_____compatibilite_20220522)) \ Bblock \ Eblock \ ATes \ Bblock \ EGAL(attenuation_a_l_ombre \ ,MUL2(EXPX(NEGA(MUL2(facteur2_du_rapport_des_rayons_d_ombrage \ ,rapport_des_rayons_d_ombrage \ ) \ ) \ ) \ ,attenuation_a_l_ombre \ ) \ ); \ /* Ainsi l'attenuation devient une fonction decroissante du rayon de la particule qui est */ \ /* a l'ombre d'autres particules (introduit le 20220522135138)... */ \ /* */ \ /* Ceci a ete valide grace a 'v $xtc/OmbresPortees.01$c'... */ \ Eblock \ ETes \ \ EGAL(ACCES_LISTE(liste_des_ROUGE,index1) \ ,MUL2(attenuation_a_l_ombre,ACCES_LISTE(liste_des_ROUGE,index1)) \ ); \ EGAL(ACCES_LISTE(liste_des_VERTE,index1) \ ,MUL2(attenuation_a_l_ombre,ACCES_LISTE(liste_des_VERTE,index1)) \ ); \ EGAL(ACCES_LISTE(liste_des_BLEUE,index1) \ ,MUL2(attenuation_a_l_ombre,ACCES_LISTE(liste_des_BLEUE,index1)) \ ); \ /* Gestion de l'ombre et de la penombre... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ EDoI \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ DoIn(index_d_extraction_de_la_liste,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ Bblock \ DEFV(Int,INIT(index_de_visualisation,INTE(ACCES_LISTE(liste_des_index,index_d_extraction_de_la_liste)))); \ /* Index de visualisation destine au tri des points... */ \ \ DEFV(Float,INIT(coordonnee_X__du_point_courant,ACCES_LISTE(liste_des_X,index_de_visualisation))); \ DEFV(Float,INIT(coordonnee_Y__du_point_courant,ACCES_LISTE(liste_des_Y,index_de_visualisation))); \ DEFV(Float,INIT(coordonnee_Z__du_point_courant,ACCES_LISTE(liste_des_Z,index_de_visualisation))); \ DEFV(Float,INIT(rayon_________du_point_courant,ACCES_LISTE(liste_des_aRAYON,index_de_visualisation))); \ DEFV(Float,INIT(couleur_ROUGE_du_point_courant,ACCES_LISTE(liste_des_ROUGE,index_de_visualisation))); \ DEFV(Float,INIT(couleur_VERTE_du_point_courant,ACCES_LISTE(liste_des_VERTE,index_de_visualisation))); \ DEFV(Float,INIT(couleur_BLEUE_du_point_courant,ACCES_LISTE(liste_des_BLEUE,index_de_visualisation))); \ /* Definition du point courant (introduit le 20080309112355). */ \ \ Test(I3OU(IL_FAUT(optimisation_du_tri_des_points_____compatibilite_2008030911) \ ,IFEQ(index_d_extraction_de_la_liste,PREMIER_POINT_DES_LISTES) \ ,I3OU(I3OU(IFNE(coordonnee_X__du_point_courant,coordonnee_X__du_point_precedent) \ ,IFNE(coordonnee_Y__du_point_courant,coordonnee_Y__du_point_precedent) \ ,IFNE(coordonnee_Z__du_point_courant,coordonnee_Z__du_point_precedent) \ ) \ ,IFNE(rayon_________du_point_courant,rayon_________du_point_precedent) \ ,I3OU(IFNE(couleur_ROUGE_du_point_courant,couleur_ROUGE_du_point_precedent) \ ,IFNE(couleur_VERTE_du_point_courant,couleur_VERTE_du_point_precedent) \ ,IFNE(couleur_BLEUE_du_point_courant,couleur_BLEUE_du_point_precedent) \ ) \ ) \ ) \ ) \ /* L'optimisation precedente concernant a voir si le point courant n'est pas strictement */ \ /* identique au point precedent (s'il existe) a ete introduit le 20080309112355... */ \ Bblock \ DEFV(Float,INIT(niveau_ROUGE_normalise,FLOT__UNDEF)); \ DEFV(Float,INIT(niveau_VERTE_normalise,FLOT__UNDEF)); \ DEFV(Float,INIT(niveau_BLEUE_normalise,FLOT__UNDEF)); \ /* Niveaux chromatiques normalises, */ \ \ DEFV(Float,INIT(modulation_eventuelle_des_rayons \ ,COND(IL_NE_FAUT_PAS(moduler_le_rayon_de_visualisation_avec_la_profondeur) \ ,FU \ ,AXPB(param_A_modulation_du_rayon_de_visualisation_avec_la_profondeur \ ,COMP(NORM(coordonnee_Z__du_point_courant \ ,minimum_de_la_coordonnee_Z \ ,maximum_de_la_coordonnee_Z \ ) \ ) \ ,param_B_modulation_du_rayon_de_visualisation_avec_la_profondeur \ ) \ ) \ ) \ ); \ /* Modulation eventuelle des rayons en fonction du 'Z'... */ \ /* */ \ /* Il convient de rappeler au passage que l'axe 'Z' est dirige vers l'observateur, d'ou */ \ /* l'inversion de la coordonnee 'Z' de modulation du rayon via un 'COMP(....)'... */ \ \ EGAL(niveau_ROUGE_normalise \ ,AXPB(facteur_du_ROUGE \ ,couleur_ROUGE_du_point_courant \ ,translation_du_ROUGE \ ) \ ); \ EGAL(niveau_VERTE_normalise \ ,AXPB(facteur_du_VERTE \ ,couleur_VERTE_du_point_courant \ ,translation_du_VERTE \ ) \ ); \ EGAL(niveau_BLEUE_normalise \ ,AXPB(facteur_du_BLEUE \ ,couleur_BLEUE_du_point_courant \ ,translation_du_BLEUE \ ) \ ); \ /* Et calcul de leurs valeurs. Cette operation n'est pas faite lors de la declaration */ \ /* des variables 'Float' correspondantes afin de garantir que 'index_de_visualisation' */ \ /* a une valeur correcte. D'autre part, le passage par ces variables intermediaires est */ \ /* destine a alleger la traduction des 'DEPTH_CUEING_DES_POINTS(...)' ci-apres... */ \ \ CALi(visualisation_d_un_point(ADD2(coordonnee_X__du_point_courant \ ,translation_de_centrage_des_coordonnees_X \ ) \ ,ADD2(coordonnee_Y__du_point_courant \ ,translation_de_centrage_des_coordonnees_Y \ ) \ ,ADD2(coordonnee_Z__du_point_courant \ ,translation_de_centrage_des_coordonnees_Z \ ) \ ,MUL2(modulation_eventuelle_des_rayons \ ,rayon_________du_point_courant \ ) \ ,MUL2(modulation_eventuelle_des_rayons \ ,ACCES_LISTE(liste_des_vRAYON,index_de_visualisation) \ ) \ ,DEPTH_CUEING_DES_POINTS(niveau_ROUGE_normalise \ ,nROUGE \ ,aROUGE \ ,seuil_inferieur_du_ROUGE \ ,seuil_superieur_du_ROUGE \ ) \ ,DEPTH_CUEING_DES_POINTS(niveau_VERTE_normalise \ ,nVERTE \ ,aVERTE \ ,seuil_inferieur_du_VERTE \ ,seuil_superieur_du_VERTE \ ) \ ,DEPTH_CUEING_DES_POINTS(niveau_BLEUE_normalise \ ,nBLEUE \ ,aBLEUE \ ,seuil_inferieur_du_BLEUE \ ,seuil_superieur_du_BLEUE \ ) \ ) \ ); \ /* Visualisation du point courant. Grace au tri precedent, on visualise en premier le point */ \ /* le plus eloigne, et en dernier le plus proche. Cela permet d'utiliser efficacement la */ \ /* methode d'anti-aliasing qui interpole (au bord des spheres) avec ce qui etait present */ \ /* anterieurement. Il est donc necessaire que l'on trace par profondeur 'Z' decroissante, */ \ /* car ainsi, les spheres se superposent, et jamais une nouvelle sphere ne sera tracee */ \ /* derriere une autre, ce qui ferait que le contour de cette derniere aurait ete interpole */ \ /* par rapport au noir (dans le cas ou il y avait le fond derriere), et non pas par rapport */ \ /* a cette nouvelle sphere, puisqu'elle n'etait pas encore la. ATTENTION, on notera bien */ \ /* que l'on utilise l'ordre inverse dans : */ \ /* */ \ /* SCAL(ACCES_LISTE(...) */ \ /* ,n... */ \ /* ,a... */ \ /* ) */ \ /* */ \ /* On peut "moduler" le 'rayon_reel_de_visualisation' avec la profondeur 'Zf'. Cela a ete */ \ /* introduit le 20050419105308 afin, par exemple, d'augmenter le rayon des spheres en */ \ /* fonction de leur profondeur. Ainsi, si l'on souhaite appliquer 'v $xci/DepthFiel.11$Z' */ \ /* a un ensemble de sphere, il faudra : */ \ /* */ \ /* 1-Generer comme d'habitude l'image 'IMAGE', */ \ /* 2-La generer une seconde fois en modulant le 'rayon_reel_de_visualisation' avec */ \ /* 'Zf' afin de generer un 'Z-Buffer' dans lesquels les spheres eloignees de */ \ /* l'observateur occupe plus de place que les spheres proches de ce meme observateur. */ \ /* 3-Appliquer ensuite 'v $xci/DepthFiel.11$Z' a 'IMAGE' avec 'Z-Buffer'... */ \ /* */ \ /* Ainsi, les spheres eloignees de l'observateur seront plus convoluees que les spheres */ \ /* proches de ce meme observateur, mais surtout le fond autour de ces memes spheres sera */ \ /* lui-aussi convolue puisque celles-ci occuperont plus de place dans le 'Z-Buffer'... */ \ \ EGAL(coordonnee_X__du_point_precedent,coordonnee_X__du_point_courant); \ EGAL(coordonnee_Y__du_point_precedent,coordonnee_Y__du_point_courant); \ EGAL(coordonnee_Z__du_point_precedent,coordonnee_Z__du_point_courant); \ EGAL(rayon_________du_point_precedent,rayon_________du_point_courant); \ EGAL(couleur_ROUGE_du_point_precedent,couleur_ROUGE_du_point_courant); \ EGAL(couleur_VERTE_du_point_precedent,couleur_VERTE_du_point_courant); \ EGAL(couleur_BLEUE_du_point_precedent,couleur_BLEUE_du_point_courant); \ /* Gestion de l'optimisation (introduite le 20080309112355)... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ EDoI \ \ Test(IL_FAUT(editer_les_extrema_des_coordonnees_x_et_y_projetees)) \ Bblock \ DEFV(Int,INIT(dimension_des_coordonnees_X_projetees \ ,DIMENSION(minimum_des_coordonnees_X_projetees,maximum_des_coordonnees_X_projetees) \ ) \ ); \ DEFV(Int,INIT(dimension_des_coordonnees_Y_projetees \ ,DIMENSION(minimum_des_coordonnees_Y_projetees,maximum_des_coordonnees_Y_projetees) \ ) \ ); \ \ DEFV(Int,INIT(centre_des_coordonnees_X_projetees \ ,COXA(INTE(MOYE(minimum_des_coordonnees_X_projetees,maximum_des_coordonnees_X_projetees))) \ ) \ ); \ DEFV(Int,INIT(centre_des_coordonnees_Y_projetees \ ,COYA(INTE(MOYE(minimum_des_coordonnees_Y_projetees,maximum_des_coordonnees_Y_projetees))) \ ) \ ); \ \ CAL2(Prin2("les coordonnees X projetees sont dans [%+.^^^,%+.^^^]\n" \ ,minimum_des_coordonnees_X_projetees \ ,maximum_des_coordonnees_X_projetees \ ) \ ); \ CAL2(Prin2("les coordonnees Y projetees sont dans [%+.^^^,%+.^^^]\n" \ ,minimum_des_coordonnees_Y_projetees \ ,maximum_des_coordonnees_Y_projetees \ ) \ ); \ /* Introduit le 20180531101315 pour aider au cadrage bi-dimensionnel... */ \ \ CAL2(Prin2("definition d'une translation de centrage en X : %s%+.^^^\n" \ ,TRANSLATION_OX_PROJETEE \ ,_____lNORMALISE_OX(SOUS(Xcentre,centre_des_coordonnees_X_projetees)) \ ) \ ); \ CAL2(Prin2("definition d'une translation de centrage en Y : %s%+.^^^\n" \ ,TRANSLATION_OY_PROJETEE \ ,_____lNORMALISE_OY(SOUS(Ycentre,centre_des_coordonnees_Y_projetees)) \ ) \ ); \ \ Test(TOUJOURS_FAUX) \ /* Aux environs du 20180601111611 ('v $xrv/particule.10$Z 20180601111130') les experiences */ \ /* faites montrent que le rapport de zoom courant (utilise pour les mesures ci-dessus) */ \ /* doit etre CONSERVE lors de la generation utilisant les translations proposees ci-dessus */ \ /* pour les coordonnees 'X' et 'Y' projetees... */ \ Bblock \ CAL2(Prin1("definition d'un rapport de zoom optimal : ZOOM=%+.^^^\n" \ ,MUL2(rapport_courant_du_zoom \ ,DIVI(FLOT(MdimXY) \ ,FLOT(MAX2(dimension_des_coordonnees_X_projetees \ ,dimension_des_coordonnees_Y_projetees \ ) \ ) \ ) \ ) \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Visualisation d'une liste de points avec renormalisation finale des niveaux. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* R E N O R M A L I S A T I O N D ' U N E L I S T E D E P O I N T S : */ /* */ /*************************************************************************************************************************************/ #TestADef RENORMALISATION_D_UNE_LISTE_DE_POINTS_____COMPATIBILITE_20221224 \ FAUX DEFV(Local,DEFV(Logical,INIT(renormalisation_d_une_liste_de_points_____compatibilite_20221224 ,RENORMALISATION_D_UNE_LISTE_DE_POINTS_____COMPATIBILITE_20221224 ) ) ); /* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */ /* du 20221224121736... */ #define EPSILON_D_EQUIVALENCE_DES_MINIMA_ET_DES_MAXIMA \ igEPSILON DEFV(Local,DEFV(Float,INIT(epsilon_d_equivalence_des_minima_et_des_maxima,EPSILON_D_EQUIVALENCE_DES_MINIMA_ET_DES_MAXIMA))); /* Afin de pouvoir decreter que le minimum et le maximum sont equvalents. Cela a ete */ /* introduits le 20221224121736 lors de la mise au point de 'v $xrs/hyper_plan.11$K', alors */ /* qu'il utilisait l'option "u_v_w_arbitraires=VRAI" avec 'v $xci/valeurs_Hilbert3D$K. */ /* A priori, les composantes {ROUGE,VERTE,BLEUE} devaient etre toutes egales a 1, mais en */ /* fait elles s'etalaient dans [0.9999999999999998,1.0000000000000002]... */ #define NIVEAU_NORMALISE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ COORDONNEE_BARYCENTRIQUE_CENTRALE \ /* Valeur a donner a un niveau normalise lorsque les extrema correspondants sont egaux... */ #define NIVEAU_NORMALISE_DE_RVB_SI_MINIMUM_EGALE_LE_MAXIMUM(niveau_normalise_lorsque_le_minimum_egale_le_maximum) \ COND(IL_FAUT(niveau_normalise_lorsque_le_minimum_egale_le_maximum_____compatibilite_20120209) \ ,NIVEAU_NORMALISE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ ,niveau_normalise_lorsque_le_minimum_egale_le_maximum \ ) #define NIVEAU_NORMALISE_DE_ROUGE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ NIVEAU_NORMALISE_DE_RVB_SI_MINIMUM_EGALE_LE_MAXIMUM(niveau_normalise_de_ROUGE_lorsque_le_minimum_egale_le_maximum) #define NIVEAU_NORMALISE_DE_VERTE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ NIVEAU_NORMALISE_DE_RVB_SI_MINIMUM_EGALE_LE_MAXIMUM(niveau_normalise_de_VERTE_lorsque_le_minimum_egale_le_maximum) #define NIVEAU_NORMALISE_DE_BLEUE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ NIVEAU_NORMALISE_DE_RVB_SI_MINIMUM_EGALE_LE_MAXIMUM(niveau_normalise_de_BLEUE_lorsque_le_minimum_egale_le_maximum) /* Introduits le 20120209110935... */ #TestADef NIVEAU_NORMALISE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM_____COMPATIBILITE_20120209 \ FAUX \ /* Introduit le 20140822184625... */ DEFV(Local,DEFV(Logical,INIT(niveau_normalise_lorsque_le_minimum_egale_le_maximum_____compatibilite_20120209 ,NIVEAU_NORMALISE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM_____COMPATIBILITE_20120209 ) ) ); DEFV(Local,DEFV(genere_Float,INIT(niveau_normalise_de_ROUGE_lorsque_le_minimum_egale_le_maximum ,NIVEAU_NORMALISE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM ) ) ); DEFV(Local,DEFV(genere_Float,INIT(niveau_normalise_de_VERTE_lorsque_le_minimum_egale_le_maximum ,NIVEAU_NORMALISE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM ) ) ); DEFV(Local,DEFV(genere_Float,INIT(niveau_normalise_de_BLEUE_lorsque_le_minimum_egale_le_maximum ,NIVEAU_NORMALISE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM ) ) ); /* Introduits le 20120209110935... */ #define RENORMALISATION_D_UNE_LISTE_DE_POINTS \ Bblock \ Test(I3ET(IL_FAUT(visualiser_en_RVB) \ ,IL_NE_FAUT_PAS(renormaliser_arbitrairement_les_differentielles) \ ,IL_FAUT(faire_la_renormalisation_des_differentielles) \ ) \ ) \ /* Ce test est destine a eviter des divisions par 0 dans 'NORM(...)' ci-dessous, car */ \ /* en effet, dans le cas ou l'on ne visualise pas en couleurs, les extrema des trois */ \ /* composantes sont egales... */ \ /* */ \ /* Le 20221005144141, le test de 'faire_la_renormalisation_des_differentielles' a ete */ \ /* introduit pour generer correctement 'v $xiirv/NFRI.F1'... */ \ Bblock \ DEFV(Float,INIT(minimum_des_ROUGE,F_INFINI)); \ DEFV(Float,INIT(maximum_des_ROUGE,F_MOINS_L_INFINI)); \ /* Recherche des extrema du ROUGE. */ \ DEFV(Float,INIT(minimum_des_VERTE,F_INFINI)); \ DEFV(Float,INIT(maximum_des_VERTE,F_MOINS_L_INFINI)); \ /* Recherche des extrema du VERTE. */ \ DEFV(Float,INIT(minimum_des_BLEUE,F_INFINI)); \ DEFV(Float,INIT(maximum_des_BLEUE,F_MOINS_L_INFINI)); \ /* Recherche des extrema du BLEUE. */ \ \ DoIn(index_d_extraction_de_la_liste,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ Bblock \ EGAL(minimum_des_ROUGE \ ,MIN2(minimum_des_ROUGE,ACCES_LISTE(liste_des_ROUGE,index_d_extraction_de_la_liste)) \ ); \ EGAL(maximum_des_ROUGE \ ,MAX2(maximum_des_ROUGE,ACCES_LISTE(liste_des_ROUGE,index_d_extraction_de_la_liste)) \ ); \ /* Recherche des extrema du ROUGE. */ \ EGAL(minimum_des_VERTE \ ,MIN2(minimum_des_VERTE,ACCES_LISTE(liste_des_VERTE,index_d_extraction_de_la_liste)) \ ); \ EGAL(maximum_des_VERTE \ ,MAX2(maximum_des_VERTE,ACCES_LISTE(liste_des_VERTE,index_d_extraction_de_la_liste)) \ ); \ /* Recherche des extrema du VERTE. */ \ EGAL(minimum_des_BLEUE \ ,MIN2(minimum_des_BLEUE,ACCES_LISTE(liste_des_BLEUE,index_d_extraction_de_la_liste)) \ ); \ EGAL(maximum_des_BLEUE \ ,MAX2(maximum_des_BLEUE,ACCES_LISTE(liste_des_BLEUE,index_d_extraction_de_la_liste)) \ ); \ /* Recherche des extrema du BLEUE. */ \ Eblock \ EDoI \ \ Test(IL_FAUT(renormalisation_d_une_liste_de_points_____compatibilite_20221224)) \ Bblock \ Eblock \ ATes \ Bblock \ /* Introduit le 20221224121736 lors de la mise au point de 'v $xrs/hyper_plan.11$K', alors */ \ /* qu'il utilisait l'option "u_v_w_arbitraires=VRAI" avec 'v $xci/valeurs_Hilbert3D$K. */ \ /* A priori, les composantes {ROUGE,VERTE,BLEUE} devaient etre toutes egales a 1, mais en */ \ /* fait elles s'etalaient dans [0.9999999999999998,1.0000000000000002]... */ \ Test(IFEQ_a_peu_pres_absolu(minimum_des_ROUGE \ ,maximum_des_ROUGE \ ,epsilon_d_equivalence_des_minima_et_des_maxima \ ) \ ) \ Bblock \ DEFV(Float,INIT(moyenne_des_ROUGE,MOYE(minimum_des_ROUGE,maximum_des_ROUGE))); \ EGAL(minimum_des_ROUGE,moyenne_des_ROUGE); \ EGAL(maximum_des_ROUGE,moyenne_des_ROUGE); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IFEQ_a_peu_pres_absolu(minimum_des_VERTE \ ,maximum_des_VERTE \ ,epsilon_d_equivalence_des_minima_et_des_maxima \ ) \ ) \ Bblock \ DEFV(Float,INIT(moyenne_des_VERTE,MOYE(minimum_des_VERTE,maximum_des_VERTE))); \ EGAL(minimum_des_VERTE,moyenne_des_VERTE); \ EGAL(maximum_des_VERTE,moyenne_des_VERTE); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IFEQ_a_peu_pres_absolu(minimum_des_BLEUE \ ,maximum_des_BLEUE \ ,epsilon_d_equivalence_des_minima_et_des_maxima \ ) \ ) \ Bblock \ DEFV(Float,INIT(moyenne_des_BLEUE,MOYE(minimum_des_BLEUE,maximum_des_BLEUE))); \ EGAL(minimum_des_BLEUE,moyenne_des_BLEUE); \ EGAL(maximum_des_BLEUE,moyenne_des_BLEUE); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ \ DoIn(index_d_extraction_de_la_liste,PREMIER_POINT_DES_LISTES,index_de_rangement_dans_la_liste,I) \ Bblock \ EGAL(ACCES_LISTE(liste_des_ROUGE,index_d_extraction_de_la_liste) \ ,NORZ(ACCES_LISTE(liste_des_ROUGE,index_d_extraction_de_la_liste) \ ,minimum_des_ROUGE,maximum_des_ROUGE \ ,NIVEAU_NORMALISE_DE_ROUGE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ ) \ ); \ /* Renormalisation du ROUGE. */ \ EGAL(ACCES_LISTE(liste_des_VERTE,index_d_extraction_de_la_liste) \ ,NORZ(ACCES_LISTE(liste_des_VERTE,index_d_extraction_de_la_liste) \ ,minimum_des_VERTE,maximum_des_VERTE \ ,NIVEAU_NORMALISE_DE_VERTE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ ) \ ); \ /* Renormalisation du VERTE. */ \ EGAL(ACCES_LISTE(liste_des_BLEUE,index_d_extraction_de_la_liste) \ ,NORZ(ACCES_LISTE(liste_des_BLEUE,index_d_extraction_de_la_liste) \ ,minimum_des_BLEUE,maximum_des_BLEUE \ ,NIVEAU_NORMALISE_DE_BLEUE_LORSQUE_LE_MINIMUM_EGALE_LE_MAXIMUM \ ) \ ); \ /* Renormalisation du BLEUE. */ \ Eblock \ EDoI \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Recherche des extrema des couleurs, et renormalisation... */