/*************************************************************************************************************************************/ /* */ /* F O N C T I O N S G R A P H I Q U E S : */ /* */ /* */ /* Definition : */ /* */ /* Dans ce fichier se trouvent toutes */ /* les fonctions et les macros utiles */ /* pour tracer des vecteurs dans des images */ /* raster. */ /* */ /* */ /* Author of '$xiii/vecteurs$DEF' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 19870000000000). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N S D E B A S E : */ /* */ /*************************************************************************************************************************************/ #define INTER_POINT \ PAS_COORDONNEE \ /* Definition de l'inter-point. */ #define PAS_DE_POINTILLES \ MMOT \ /* La pattern continue d'absence de vecteurs_____pointilles est definie avec tous */ \ /* bits a 1 dans un mot. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* N O T I O N D E " C A D R E " : */ /* */ /* */ /* Definition : */ /* */ /* On appelle "cadre" courant, une */ /* fenetre definie par (Xgauche,Xdroite,Yinferieur,Ysuperieur) */ /* dans l'espace [Xmin,Xmax][Ymin,Ymax] */ /* initialisee telle qu'elle n'existe */ /* pas. Il peut etre redefini */ /* a tout moment par 'SET_CADRE', mais */ /* de plus, lors du marquage d'un point */ /* appartenant a un vecteur 2D, on */ /* regarde si ses coordonnee {X,Y} */ /* sortent du cadre courant ; si oui, */ /* on modifie ce dernier, afin qu'il */ /* englobe ce nouveau point. */ /* */ /* Ainsi, lorsque ces valeurs ont ete */ /* prealablement correctement initialisees, */ /* on peut savoir a l'interieur de quel */ /* "cadre" se trouve un vecteur donne. */ /* */ /* L'initialisation correct de ce */ /* cadre se fait par : */ /* */ /* INITIALISATION_CADRE; */ /* */ /* et son positionnement par : */ /* */ /* SET_CADRE(Xgauche,Xdroite,Yinferieur,Ysuperieur); */ /* */ /*************************************************************************************************************************************/ #if ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_01)) \ ) # define X_gauche_implicite \ SUCC(Xmax) \ /* Valeur initiale de la valeur minimale de 'X', */ # define X_droite_implicite \ PRED(Xmin) \ /* Valeur initiale de la valeur maximale de 'X'. */ # define Y_inferieur_implicite \ SUCC(Ymax) \ /* Valeur initiale de la valeur minimale de 'Y', */ # define Y_superieur_implicite \ PRED(Ymin) \ /* Valeur initiale de la valeur maximale de 'Y'. */ #Aif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_01)) \ ) #Eif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_01)) \ ) #if ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_02)) \ || (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_03)) \ ) # define X_gauche_implicite \ INFINI \ /* Valeur initiale de la valeur minimale de 'X', */ # define X_droite_implicite \ MOINS_L_INFINI \ /* Valeur initiale de la valeur maximale de 'X'. */ # define Y_inferieur_implicite \ INFINI \ /* Valeur initiale de la valeur minimale de 'Y', */ # define Y_superieur_implicite \ MOINS_L_INFINI \ /* Valeur initiale de la valeur maximale de 'Y'. */ #Aif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_02)) \ || (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_03)) \ ) #Eif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_02)) \ || (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_03)) \ ) #define SET_CADRE(Xgauche,Xdroite,Yinferieur,Ysuperieur) \ Bblock \ EGAL(Ipoint_segment_____cadre_Xgauche,Xgauche); \ EGAL(Ipoint_segment_____cadre_Xdroite,Xdroite); \ EGAL(Ipoint_segment_____cadre_Yinferieur,Yinferieur); \ EGAL(Ipoint_segment_____cadre_Ysuperieur,Ysuperieur); \ Eblock \ /* Positionnement du cadre courant. */ #define INITIALISATION_CADRE \ Bblock \ SET_CADRE(X_gauche_implicite,X_droite_implicite,Y_inferieur_implicite,Y_superieur_implicite); \ Eblock \ /* Initialisation du cadre courant avec les valeurs implicites. */ #define CADRE_GAUCHE \ _____cNORMALISE_OX(COND(IFEQ(Ipoint_segment_____cadre_Xgauche,X_gauche_implicite) \ ,Xmin \ ,Ipoint_segment_____cadre_Xgauche \ ) \ ) \ /* Definition de la gauche du cadre courant, */ #define CADRE_DROITE \ _____cNORMALISE_OX(COND(IFEQ(Ipoint_segment_____cadre_Xdroite,X_droite_implicite) \ ,Xmax \ ,Ipoint_segment_____cadre_Xdroite \ ) \ ) \ /* Definition de la droite du cadre courant. */ #define CADRE_INFERIEUR \ _____cNORMALISE_OY(COND(IFEQ(Ipoint_segment_____cadre_Yinferieur,Y_inferieur_implicite) \ ,Ymin \ ,Ipoint_segment_____cadre_Yinferieur \ ) \ ) \ /* Definition de l'inferieur du cadre courant, */ #define CADRE_SUPERIEUR \ _____cNORMALISE_OY(COND(IFEQ(Ipoint_segment_____cadre_Ysuperieur,Y_superieur_implicite) \ ,Ymax \ ,Ipoint_segment_____cadre_Ysuperieur \ ) \ ) \ /* Definition du superieur du cadre courant. */ #define CADRE_AVANT \ _____cNORMALISE_OZ(Zmin) #define CADRE_ARRIERE \ _____cNORMALISE_OZ(Zmax) /* Introduites le 20231201170630 par symetrie avec les quatre definitions precedentes... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E G R A D E D E S N I V E A U X L E L O N G D ' U N V E C T E U R : */ /* */ /*************************************************************************************************************************************/ #define SET_NIVEAU_DE_NOIR_DU_DEGRADE_D_UN_VECTEUR(niveau) \ Bblock \ EGAL(fonction_interpolation_degrade_des_vecteurs_____niveau_de_NOIR_du_degrade_d_un_vecteur,niveau); \ Eblock \ /* Positionnement du niveau de 'NOIR' de degrade d'un vecteur. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C H O I X D E L A F A C O N D E P R O J E T E R : */ /* */ /*************************************************************************************************************************************/ #nodefine PROJECTION_3D_2D_VERSION_01 \ /* Cette facon de projeter utilise "betement" les procedures 'PROJECTION_OX()' et */ \ /* 'PROJECTION_OY()'. */ #define PROJECTION_3D_2D_VERSION_02 \ /* Cette facon de projeter utilise la procedure 'PROJECTION_PLANE_QUELCONQUE()'... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L A P O S I T I O N D E L ' O B S E R V A T E U R : */ /* */ /*************************************************************************************************************************************/ #ifdef PROJECTION_3D_2D_VERSION_02 # define FACTEUR_D_ELOIGNEMENT_EN_Z_DE_L_OBSERVATEUR \ FDEUX \ /* Facteur d'eloignement en 'Z' de l'observateur ; on notera qu'en prenant un tres grand */ \ /* facteur, cela revient a faire de la projection parallele : {X,Y,Z} --> {X,Y}. La valeur */ \ /* 'FDEUX' est choisie de preference a 'FU' afin que l'observateur soit situe a l'exterieur */ \ /* du cube [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax]. */ # define FACTEUR_D_ELOIGNEMENT_EN_Z_D_UN_OBSERVATEUR_LOINTAIN \ FLOT(CENT) \ /* Facteur d'eloignement en 'Z' pour un observateur lointain. Ceci a ete introduit le */ \ /* 19961021144317 pour le programme 'v $xrv/champs_5.30$K' car, en effet, par rapport aux */ \ /* autres programmes du meme type, on trouve en general des points a visualiser partout a */ \ /* l'interieur de l'espace parallelepipedique de '$xrv/champs_5.30$K' et il ne faut pas, */ \ /* entendu, qu'ils s'approchent trop pres de l'observateur, par exemple lors d'une rotation, */ \ /* afin de ne pas induire de fortes distorsions... */ # define FACTEUR_D_ELOIGNEMENT_EN_Z_POUR_UNE_PROJECTION_PARALLELE \ FLOT(MILLION) \ /* Facteur d'eloignement en 'Z' de l'observateur destine a simuler la projection parallele, */ \ /* c'est-a-dire celle qui provoque : {X,Y,Z} --> {X,Y}. */ # define SET_FACTEUR_D_ELOIGNEMENT_EN_Z_DE_L_OBSERVATEUR(facteur_d_eloignement) \ Bblock \ EGAL(Projection_OX_OY_____facteur_d_eloignement_en_Z_de_l_observateur,facteur_d_eloignement); \ Eblock \ /* Positionnement du facteur d'eloignement courant de l'observateur... */ # define DECALAGE_ANGULAIRE_POUR_UNE_VISION_CYCLOPIQUE \ MOYE(DECALAGE_ANGULAIRE_POUR_UNE_VISION_OEIL_DROITE,DECALAGE_ANGULAIRE_POUR_UNE_VISION_OEIL_GAUCHE) \ /* Decalage angulaire de l'observateur permettant de donner le point de vue d'un pauvre */ \ /* cyclope ; cet angle est mesure dans le plan (OX,OZ). */ # define DECALAGE_ANGULAIRE_POUR_UNE_VISION_OEIL_DROITE \ NEUT(FRA4(FRA16(PI))) \ /* Decalage angulaire de l'observateur permettant de donner le point de vue de l'oeil */ \ /* droit de l'observateur, */ # define DECALAGE_ANGULAIRE_POUR_UNE_VISION_OEIL_GAUCHE \ NEGA(DECALAGE_ANGULAIRE_POUR_UNE_VISION_OEIL_DROITE) \ /* Decalage angulaire de l'observateur permettant de donner le point de vue de l'oeil */ \ /* gauche de l'observateur. */ # define SET_DECALAGE_ANGULAIRE_DE_L_OBSERVATEUR(decalage_angulaire) \ Bblock \ EGAL(Projection_OX_OY_____etat_de_la_projection,INVALIDE); \ /* ATTENTION, il est imperatif d'invalider 'Projection_OX_OY_____etat_de_la_projection' */ \ /* afin que le prochain appel aux fonctions 'Projection_OX(...)' ou 'Projection_OY(...)' */ \ /* recalcule la position de l'observateur en fonction du decalage stereoscopique... */ \ EGAL(Projection_OX_OY_____decalage_angulaire_de_l_observateur,decalage_angulaire); \ Eblock \ /* Positionnement du decalage angulaire courant de l'observateur dans le plan (OX,OZ). */ #Aifdef PROJECTION_3D_2D_VERSION_02 #Eifdef PROJECTION_3D_2D_VERSION_02 /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T E S T D ' I N V I S I B I L I T E O U D ' I N D E T E R M I N A T I O N */ /* D ' U N P O I N T A P R E S P R O J E C T I O N : */ /* */ /*************************************************************************************************************************************/ #ifdef PROJECTION_3D_2D_VERSION_01 # define LE_POINT_EST_INVISIBLE_OU_INDETERMINE(cX,cY,cZ) \ FAUX \ /* Test d'invisibilite ou d'indetermination d'un point 3D apres projection 2D... */ #Aifdef PROJECTION_3D_2D_VERSION_01 #Eifdef PROJECTION_3D_2D_VERSION_01 #ifdef PROJECTION_3D_2D_VERSION_02 # define LE_POINT_EST_INVISIBLE_OU_INDETERMINE(cX,cY,cZ) \ IMEQ(CHOI(Projection_OX(cX,cY,cZ),Projection_OY(cX,cY,cZ)) \ ,POINT_A_L_INFINI_INVISIBLE \ ,POINT_A_L_INFINI_INDETERMINE \ ) \ /* Test d'invisibilite ou d'indetermination d'un point 3D apres projection 2D... */ #Aifdef PROJECTION_3D_2D_VERSION_02 #Eifdef PROJECTION_3D_2D_VERSION_02 /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* N O T I O N D E " D E P T H - C U E I N G " : */ /* */ /* */ /* Definition : */ /* */ /* le niveau lumineux impose a */ /* chaque point d'un vecteur peut */ /* etre module par la profondeur 'Z', */ /* c'est le "depth-cueing". */ /* Il est controle par une va- */ /* riable 'Ipoint_segment_____taux_depth_cueing', */ /* qui appartient a [0,1] ; la */ /* valeur '0' correspond a l'absence */ /* de "depth-cueing", alors qu'avec */ /* la valeur '1', le phenomene est */ /* maximal. */ /* */ /* SET_DEPTH_CUEING(taux,Ipoint_segment_____Zed_min,Ipoint_segment_____Zed_max); */ /* */ /* permet de fixer le taux, ainsi que */ /* les bornes de variation de la */ /* coordonnee 'Z'... */ /* */ /*************************************************************************************************************************************/ #define SET_DEPTH_CUEING(taux,Z_minimal,Z_maximal) \ Bblock \ Test(IFET(INCLff(taux,PAS_DE_DEPTH_CUEING,DEPTH_CUEING_MAXIMAL) \ ,IFLT(Z_minimal,Z_maximal) \ ) \ ) \ Bblock \ EGAL(Ipoint_segment_____taux_depth_cueing,taux); \ /* Mise en place du taux de "depth-cueing". */ \ EGAL(Ipoint_segment_____Zed_min,Z_minimal); \ EGAL(Ipoint_segment_____Zed_max,Z_maximal); \ /* Et mise en place des bornes de la coordonnee 'Z'. */ \ Eblock \ ATes \ Bblock \ PRINT_ERREUR("les arguments du 'depth-cueing' sont mauvais"); \ Eblock \ ETes \ Eblock \ /* Mise en place des parametres de "depth-cueing". */ \ /* bits a 1 dans un mot. */ #define PAS_DE_DEPTH_CUEING \ FZERO \ /* Valeur du taux de "depth-cueing" pour que ce phenomene soit absent... */ #define DEPTH_CUEING_MAXIMAL \ FU \ /* Valeur du taux de "depth-cueing" pour que ce phenomene soit maximal... */ #define DEPTH_CUEING_MOYEN \ ADD2(PAS_DE_DEPTH_CUEING,GRO1(FRA4(SOUS(DEPTH_CUEING_MAXIMAL,PAS_DE_DEPTH_CUEING)))) \ /* Valeur du taux de "depth-cueing" pour que ce phenomene soit "sympathique"... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* N O T I O N D E C O N T E X T E : */ /* */ /* */ /* Definition : */ /* */ /* Le contexte est constitue de */ /* l'ensemble des donnees necessaires */ /* au trace graphique. Il est possible */ /* de le sauvegarder et de la restaurer */ /* globalement, et ce de facon "aleatoire", */ /* c'est-a-dire sans pile ni liste. */ /* */ /* A cause des problemes d'initialisation */ /* des structures a la compilation, les */ /* donnees graphiques courante ne sont pas */ /* rangees dans une structure de type "con- */ /* texte"... */ /* */ /* On notera que 'vecteurs_____vector_3D' ne */ /* fait pas partie des contextes, et */ /* ce afin de pouvoir en joindre deux */ /* a deux... */ /* */ /*************************************************************************************************************************************/ Dstruct14(contexte_graphique ,DEFV(pointF_3D,vecteurs_____cursor_3D) /* Curseur virtuel courant. */ ,DEFV(Float,vecteurs_____scale_globale) /* Echelle globale. */ ,DEFV(Float,vecteurs_____scale_OX) /* Echelle sur l'axe des 'X', */ ,DEFV(Float,vecteurs_____scale_OY) /* Echelle sur l'axe des 'Y', */ ,DEFV(Float,vecteurs_____scale_OZ) /* Echelle sur l'axe des 'Z'. */ ,DEFV(Logical,vecteurs_____etat_trace) /* Indicateur d'autorisation/interdiction du trace. */ ,DEFV(Logical,vecteurs_____etat_anti_aliasing) /* Indicateur d'activation du mode anti-aliasing. */ ,DEFV(genere_p,vecteurs_____niveau_minimal) /* Niveau minimal lors d'un trace anti-aliase. */ ,DEFV(genere_p,vecteurs_____niveau_maximal) /* Niveau de trace ou niveau maximal anti-aliasing. */ ,DEFV(binaire,vecteurs_____pointilles) /* Forme courante des vecteurs_____pointilles. */ ,DEFV(Logical,vecteurs_____etat_matrix) /* Etat d'initialisation de la matrice de transformation, */ ,DEFV(Float,vecteurs_____rapport_de_zoom_cumule_courant) /* Rapport de zoom courant, */ ,DEFV(Float,vecteurs_____angle_de_rotation) /* Angle de rotation courant (introduit le 20230722113214). */ ,DEFV(matrixF_3D,vecteurs_____matrix_3D) /* Matrice de transformation courante. */ ,NOM_VIDE ); TypedefP(Gcontexte,STRU(contexte_graphique)) TypedefS(E___Gcontexte,Gcontexte) /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* N O T I O N D E " B I B L I O T H E Q U E " : */ /* */ /* */ /* Definition : */ /* */ /* Certaines primitives sont en */ /* fait constituees d'un aiguillage */ /* portant sur la valeur de l'indicateur */ /* 'vecteurs_____num_bibliotheque' et qui fait */ /* qu'alors tel ou tel code est */ /* execute. */ /* */ /*************************************************************************************************************************************/ Denumer08(INIS(_BIBLIOTHEQUE_00,ZERO) /* Bibliotheque de base... */ ,_BIBLIOTHEQUE_01 ,_BIBLIOTHEQUE_02 ,_BIBLIOTHEQUE_03 ,_BIBLIOTHEQUE_04 /* Introduit le 20161116110016... */ ,_BIBLIOTHEQUE_05 /* Introduit le 20230516105953... */ ,_BIBLIOTHEQUE_06 /* Introduit le 20240419182601... */ ,DERNIERE_BIBLIOTHEQUE ,liste_des_BIBLIOTHEQUES ); #define BIBLIOTHEQUE_00 \ ENUM(_BIBLIOTHEQUE_00) #define BIBLIOTHEQUE_01 \ ENUM(_BIBLIOTHEQUE_01) #define BIBLIOTHEQUE_02 \ ENUM(_BIBLIOTHEQUE_02) #define BIBLIOTHEQUE_03 \ ENUM(_BIBLIOTHEQUE_03) #define BIBLIOTHEQUE_04 \ ENUM(_BIBLIOTHEQUE_04) #define BIBLIOTHEQUE_05 \ ENUM(_BIBLIOTHEQUE_05) #define BIBLIOTHEQUE_06 \ ENUM(_BIBLIOTHEQUE_06) /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T R A I T E M E N T D E S D E F I N I T I O N S I N E X I S T A N T E S : */ /* */ /*************************************************************************************************************************************/ #define Linex BLOC( \ PRINT_ERREUR("acces a une definition graphique inexistante"); \ CAL1(Prer1("le nom de cette fonction est '%s'\n",nom_de_la_Fg_courante)); \ ) /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* Q U E L Q U E S D E F I N I T I O N S G R A P H I Q U E S : */ /* */ /*************************************************************************************************************************************/ #define Xorigine \ Xmin #define k___FXorigine \ _____cNORMALISE_OX(Xorigine) /* Abscisse de l'origine (le 20110809112855, 'Xmin' a ete remplace par 'Xorigine' plus */ /* logique, mais equivalent...), */ #define Yorigine \ Ymin #define k___FYorigine \ _____cNORMALISE_OY(Yorigine) /* Ordonnee de l'origine (le 20110809112855, 'Ymin' a ete remplace par 'Yorigine' plus */ /* logique, mais equivalent...), */ #define Zorigine \ Zmin #define k___FZorigine \ _____cNORMALISE_OZ(Zorigine) /* Profondeur de l'origine (le 20110809112855, 'Zmin' a ete remplace par 'Zorigine' plus */ /* logique, mais equivalent...). */ #define Torigine \ Tmin #define k___FTorigine \ _____cNORMALISE_OT(Torigine) /* Temps de l'origine (introduit le 20171219120321)... */ #TestADef FXorigine \ k___FXorigine #TestADef FYorigine \ k___FYorigine #TestADef FZorigine \ k___FZorigine #TestADef FTorigine \ CHOY(FXorigine,FYorigine,FZorigine) /* La pregeneration des constantes suivantes par '$xcp/Konstantes$K' a ete introduite le */ /* 20071130142626 a cause de '$LACT18'. En effet sur cette MACHINE, lors de la compilation */ /* de 'v $xrs/CalabiYau.21$K' en particulier, le message suivant est apparu : */ /* */ /* In function 'main': */ /* internal compiler error: in add_stack_var_conflict, at cfgexpand.c:264 */ /* */ /* L'analyse du probleme a montre que le probleme pouvait venir de la "lourdeur" de la */ /* fonction 'v $xrs/CalabiYau.21$I FCalabiYau_2' et plus precisemment des procedures */ /* 'Ccosinus(...)' et 'Csinus(...)', qui elles-memes utilisent 'FCquotient(...)', qui */ /* lui-meme fait un 'INVZ(FCmodule2(...))', puis 'FCmodule2(...)' utilise 'CRho_2D(...)', */ /* qui lui-meme utilise 'CRho_2D(...)' et c'est-la que {FXorigine,FYorigine} apparaissent... */ /* On essaye donc d'alleger ces deux constantes ici. Il semble qu'en fait cela ne suffise */ /* pas... */ /* */ /* La solution a l'erreur interne de '$Cc' etait 'v $xrs/surfaces.12$I 20071204152647'... */ /* */ /* On notera que l'on ne pregenere pas le 20071201094812 {Xorigine,Yorigine,Zorigine} qui */ /* ne sont pas des constantes (elles dependent de {Xmin,Ymin,Zmin}), alors que sont nulles */ /* {FXorigine,FYorigine,FZorigine} par definition de '_____cNORMALISE_O?(...)'. */ /* */ /* Le 20080708122458 fut introduit 'FTorigine' pour 'v $ximd/operator.1$FON FTorigine'... */ #define FX1origine \ FZERO #define FX2origine \ FZERO #define FX3origine \ FZERO #define FX4origine \ FZERO #define FX5origine \ FZERO #define FX6origine \ FZERO #define FX7origine \ FZERO #define FX8origine \ FZERO /* Definitions introduites le 20110809204719 pour 'v $ximD/definit.1$DEF 20110809183726'... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* Q U E L Q U E S M A C R O S G R A P H I Q U E S U T I L E S P O U R L E T R A C E : */ /* */ /* */ /* Definition : */ /* */ /* SET_CURSOR(Cx,Cy,Cz); */ /* SET_CURSOR_AVEC_TRANSFORMATION(Cx,Cy,Cz); */ /* GET_CURSOR(Cx,Cy,Cz); */ /* PRINT_STATUS_GRAPHIQUE; */ /* */ /* Il conviendra de noter que les */ /* coordonnees (Cx,Cy,Cz) sont denor- */ /* malisees, c'est-a-dire dans [0,1]. */ /* */ /*************************************************************************************************************************************/ #define SET_CURSOR(Cx,Cy,Cz) \ Bblock \ INITIALISATION_POINT_3D(vecteurs_____cursor_3D,Cx,Cy,Cz); \ Eblock \ /* Positionnement du curseur avec des coordonnees denormalisees (dans [0,1]). */ #define SET_CURSOR_AVEC_TRANSFORMATION(Cx,Cy,Cz) \ Bblock \ CALS(FgMIK());CALS(FgMIX());CALS(FgMIY());CALS(FgMIZ()); \ /* Sauvegarde des echelles. */ \ SK(INTER_POINT); \ /* Definition de l'echelle globale. */ \ SX(INTER_POINT); \ /* Definition de l'echelle sur l'axe des 'X'. */ \ SY(INTER_POINT); \ /* Definition de l'echelle sur l'axe des 'Y'. */ \ SZ(INTER_POINT); \ /* Definition de l'echelle sur l'axe des 'Z'. */ \ CALS(FgPO()); \ MOVE(_cDENORMALISE_OX(Cx),_cDENORMALISE_OY(Cy),_cDENORMALISE_OZ(Cz)); \ /* On procede a un deplacement relatif (appliquant donc la transformation tridimensionnelle */ \ /* courante), mais puisque l'on a fait au prealable un positionnement a l'origine (par */ \ /* 'FgPO()'), le deplacement est en realite absolu. Bien sur, les coordonnees dans [0,1] */ \ /* sont converties en deplacements entiers suivant les conventions associees aux primitives */ \ /* "g1", "g2", "g3", "g4", "g5" et "g6". */ \ CALS(FgMOZ());CALS(FgMOY());CALS(FgMOX());CALS(FgMOK()); \ /* Restauration des echelles. */ \ Eblock \ /* Positionnement du curseur avec des coordonnees denormalisees (dans [0,1]), avec */ \ /* application preliminaire de la transformation tridimensionnelle courante. */ #define GET_CURSOR(Cx,Cy,Cz) \ Bblock \ EGAL(Cx,ASD1(vecteurs_____cursor_3D,x)); \ EGAL(Cy,ASD1(vecteurs_____cursor_3D,y)); \ EGAL(Cz,ASD1(vecteurs_____cursor_3D,z)); \ Eblock \ /* Recuperation des coordonnees denormalisees (dans [0,1]) du curseur. */ #define ORIGINE(Cx,Cy,Cz) \ Bblock \ INITIALISATION_POINT_3D(ASD1(vecteurs_____vector_3D,origine),Cx,Cy,Cz); \ Eblock \ /* Definition de l'origine courante. */ #define EXTREMITE(Cx,Cy,Cz) \ Bblock \ INITIALISATION_POINT_3D(ASD1(vecteurs_____vector_3D,extremite),Cx,Cy,Cz); \ Eblock \ /* Definition de l'extremite courante. */ #define CHAINAGE(Cx,Cy,Cz) \ Bblock \ ORIGINE(ASD2(vecteurs_____vector_3D,extremite,x) \ ,ASD2(vecteurs_____vector_3D,extremite,y) \ ,ASD2(vecteurs_____vector_3D,extremite,z) \ ); \ EXTREMITE(Cx,Cy,Cz); \ Eblock \ /* Chainage : l'extremite precedente devient la nouvelle origine. */ #define DELTA_AXE(echelle_sur_l_axe,deplacement_elementaire) \ MUL2(MUL2(I___vecteurs_____scale_globale,echelle_sur_l_axe),FLOT(deplacement_elementaire)) \ /* Deplacement elementaire sur l'un des trois axes 'X', 'Y' ou 'Z'. */ #define INITIALISATION_SYSTEMATIQUE_TRANSFORMATION \ Bblock \ CALS(FgT_INIT()); \ /* La valeur initiale de la matrice de transformation est une matrice unite. */ \ Eblock \ /* Initialisation systematique de la matrice de transformation et de */ \ /* 'vecteurs_____etat_matrix'. */ #define INITIALISATION_TRANSFORMATION \ Bblock \ Test(EST_INVALIDE(vecteurs_____etat_matrix)) \ Bblock \ INITIALISATION_SYSTEMATIQUE_TRANSFORMATION; \ /* La valeur initiale de la matrice de transformation est une matrice unite. */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Initialisation si necessaire de la matrice de transformation et de */ \ /* 'vecteurs_____etat_matrix'. */ #define MOVE(dX,dY,dZ) \ Bblock \ INITIALISATION_TRANSFORMATION; \ \ begin_nouveau_block \ Bblock \ DEFV(pointF_3D,ZINS(vecteurs_____cursor_3D_apres_MOVE \ ,IstructL03(ADD2(ASD1(vecteurs_____cursor_3D,x) \ ,LIZ3(ASD2(vecteurs_____matrix_3D,cx,cx) \ ,DELTA_AXE(I___vecteurs_____scale_OX,dX) \ ,ASD2(vecteurs_____matrix_3D,cx,cy) \ ,DELTA_AXE(I___vecteurs_____scale_OY,dY) \ ,ASD2(vecteurs_____matrix_3D,cx,cz) \ ,DELTA_AXE(I___vecteurs_____scale_OZ,dZ) \ ) \ ) \ ,ADD2(ASD1(vecteurs_____cursor_3D,y) \ ,LIZ3(ASD2(vecteurs_____matrix_3D,cy,cx) \ ,DELTA_AXE(I___vecteurs_____scale_OX,dX) \ ,ASD2(vecteurs_____matrix_3D,cy,cy) \ ,DELTA_AXE(I___vecteurs_____scale_OY,dY) \ ,ASD2(vecteurs_____matrix_3D,cy,cz) \ ,DELTA_AXE(I___vecteurs_____scale_OZ,dZ) \ ) \ ) \ ,ADD2(ASD1(vecteurs_____cursor_3D,z) \ ,LIZ3(ASD2(vecteurs_____matrix_3D,cz,cx) \ ,DELTA_AXE(I___vecteurs_____scale_OX,dX) \ ,ASD2(vecteurs_____matrix_3D,cz,cy) \ ,DELTA_AXE(I___vecteurs_____scale_OY,dY) \ ,ASD2(vecteurs_____matrix_3D,cz,cz) \ ,DELTA_AXE(I___vecteurs_____scale_OZ,dZ) \ ) \ ) \ ) \ ) \ ); \ \ SET_CURSOR(COND(IL_NE_FAUT_PAS(vecteurs_____cursor_3D__ramener_la_coordonnee_X_dans_l_image) \ ,ASD1(vecteurs_____cursor_3D_apres_MOVE,x) \ ,TRON(ASD1(vecteurs_____cursor_3D_apres_MOVE,x) \ ,_____cNORMALISE_OX(Xmin) \ ,_____cNORMALISE_OX(Xmax) \ ) \ ) \ ,COND(IL_NE_FAUT_PAS(vecteurs_____cursor_3D__ramener_la_coordonnee_Y_dans_l_image) \ ,ASD1(vecteurs_____cursor_3D_apres_MOVE,y) \ ,TRON(ASD1(vecteurs_____cursor_3D_apres_MOVE,y) \ ,_____cNORMALISE_OY(Ymin) \ ,_____cNORMALISE_OY(Ymax) \ ) \ ) \ ,COND(IL_NE_FAUT_PAS(vecteurs_____cursor_3D__ramener_la_coordonnee_Z_dans_l_image) \ ,ASD1(vecteurs_____cursor_3D_apres_MOVE,z) \ ,TRON(ASD1(vecteurs_____cursor_3D_apres_MOVE,z) \ ,_____cNORMALISE_OZ(Zmin) \ ,_____cNORMALISE_OZ(Zmax) \ ) \ ) \ ); \ /* La troncation eventuelle des coordonnees {X,Y,Z} dans l'image a ete introduite le */ \ /* 20180620134532 pour permettre a 'v $xci/grille.01$K 20180620140957' de generer des */ \ /* cadres inclus dans l'image ('v $xiio/RADRE$R16' par exemple...). */ \ Eblock \ end_nouveau_block \ Eblock \ /* Deplacement quelconque du curseur. */ #define T_PRODUIT_MATRICIEL(matrice,coeff11,coeff12,coeff13,coeff21,coeff22,coeff23,coeff31,coeff32,coeff33) \ Bblock \ DEFV(matrixF_3D,manoeuvre_3D); \ /* Matrice de manoeuvre dans l'espace 3D. */ \ INITIALISATION_TRANSFORMATION; \ INITIALISATION_MATRICE_3D \ (manoeuvre_3D \ ,LIZ3(ASD2(matrice,cx,cx),coeff11 \ ,ASD2(matrice,cx,cy),coeff21 \ ,ASD2(matrice,cx,cz),coeff31 \ ) \ ,LIZ3(ASD2(matrice,cx,cx),coeff12 \ ,ASD2(matrice,cx,cy),coeff22 \ ,ASD2(matrice,cx,cz),coeff32 \ ) \ ,LIZ3(ASD2(matrice,cx,cx),coeff13 \ ,ASD2(matrice,cx,cy),coeff23 \ ,ASD2(matrice,cx,cz),coeff33 \ ) \ ,LIZ3(ASD2(matrice,cy,cx),coeff11 \ ,ASD2(matrice,cy,cy),coeff21 \ ,ASD2(matrice,cy,cz),coeff31 \ ) \ ,LIZ3(ASD2(matrice,cy,cx),coeff12 \ ,ASD2(matrice,cy,cy),coeff22 \ ,ASD2(matrice,cy,cz),coeff32 \ ) \ ,LIZ3(ASD2(matrice,cy,cx),coeff13 \ ,ASD2(matrice,cy,cy),coeff23 \ ,ASD2(matrice,cy,cz),coeff33 \ ) \ ,LIZ3(ASD2(matrice,cz,cx),coeff11 \ ,ASD2(matrice,cz,cy),coeff21 \ ,ASD2(matrice,cz,cz),coeff31 \ ) \ ,LIZ3(ASD2(matrice,cz,cx),coeff12 \ ,ASD2(matrice,cz,cy),coeff22 \ ,ASD2(matrice,cz,cz),coeff32 \ ) \ ,LIZ3(ASD2(matrice,cz,cx),coeff13 \ ,ASD2(matrice,cz,cy),coeff23 \ ,ASD2(matrice,cz,cz),coeff33 \ ) \ ); \ INITIALISATION_MATRICE_3D \ (matrice \ ,ASD2(manoeuvre_3D,cx,cx),ASD2(manoeuvre_3D,cx,cy),ASD2(manoeuvre_3D,cx,cz) \ ,ASD2(manoeuvre_3D,cy,cx),ASD2(manoeuvre_3D,cy,cy),ASD2(manoeuvre_3D,cy,cz) \ ,ASD2(manoeuvre_3D,cz,cx),ASD2(manoeuvre_3D,cz,cy),ASD2(manoeuvre_3D,cz,cz) \ ); \ Eblock \ /* Definition d'un produit matriciel 3D. */ #define ABSENCE_D_EFFET_DE_ZOOM \ FU \ /* Lorsque le rapport de zoom vaut 1, il n'y a pas d'effet de zoom... */ #define T_ZOOM(rapport) \ Bblock \ EGAL(vecteurs_____rapport_de_zoom_cumule_courant,MUL2(rapport,vecteurs_____rapport_de_zoom_cumule_courant)); \ /* Cumul de l'ensemble des rapports de zoom... */ \ T_PRODUIT_MATRICIEL(vecteurs_____matrix_3D \ ,rapport ,FZERO ,FZERO \ ,FZERO ,rapport ,FZERO \ ,FZERO ,FZERO ,rapport \ ); \ Eblock \ /* Definition d'un zoom de rapport donne (rapport=1 <==> pas de zoom...). */ #define ABSENCE_DE_ROTATION \ FZERO \ /* Angle de rotation initial (introduit le 20230722112439)... */ #define PCOS(angle) \ NEUT(COSX(angle)) \ /* Definition de '+cos(angle)', */ #define MCOS(angle) \ NEGA(COSX(angle)) \ /* Definition de '-cos(angle)'. */ #define PSIN(angle) \ NEUT(SINX(angle)) \ /* Definition de '+sin(angle)', */ #define MSIN(angle) \ NEGA(SINX(angle)) \ /* Definition de '-sin(angle)'. */ #define T_ROTATION_X(angle) \ Bblock \ INCR(vecteurs_____angle_de_rotation,angle); \ \ T_PRODUIT_MATRICIEL(vecteurs_____matrix_3D \ ,FU ,FZERO ,FZERO \ ,FZERO ,PCOS(angle) ,MSIN(angle) \ ,FZERO ,PSIN(angle) ,PCOS(angle) \ ); \ Eblock \ /* Definition d'une rotation autour de l'axe des 'X' d'un angle exprime en radian. */ \ /* */ \ /* ATTENTION, ne pas oublier que le produit des rotations 'T_ROTATION_X', 'T_ROTATION_Y' et */ \ /* et 'T_ROTATION_Z' n'est pas commutatif dans l'espace tridimensionnel... */ #define T_ROTATION_Y(angle) \ Bblock \ INCR(vecteurs_____angle_de_rotation,angle); \ \ T_PRODUIT_MATRICIEL(vecteurs_____matrix_3D \ ,PCOS(angle) ,FZERO ,PSIN(angle) \ ,FZERO ,FU ,FZERO \ ,MSIN(angle) ,FZERO ,PCOS(angle) \ ); \ Eblock \ /* Definition d'une rotation autour de l'axe des 'Y' d'un angle exprime en radian. */ \ /* */ \ /* ATTENTION, ne pas oublier que le produit des rotations 'T_ROTATION_X', 'T_ROTATION_Y' et */ \ /* et 'T_ROTATION_Z' n'est pas commutatif dans l'espace tridimensionnel... */ #define T_ROTATION_Z(angle) \ Bblock \ INCR(vecteurs_____angle_de_rotation,angle); \ \ T_PRODUIT_MATRICIEL(vecteurs_____matrix_3D \ ,PCOS(angle) ,MSIN(angle) ,FZERO \ ,PSIN(angle) ,PCOS(angle) ,FZERO \ ,FZERO ,FZERO ,FU \ ); \ Eblock \ /* Definition d'une rotation autour de l'axe des 'Z' d'un angle exprime en radian. */ \ /* */ \ /* ATTENTION, ne pas oublier que le produit des rotations 'T_ROTATION_X', 'T_ROTATION_Y' et */ \ /* et 'T_ROTATION_Z' n'est pas commutatif dans l'espace tridimensionnel... */ /* Tout ce qui concerne l'ordre des rotations vient de 'v $xrq/nucleon.LX.2$I' et a ete */ /* deplace le 19971104162912. */ #define T_SYMETRIE_ORIGNE \ Bblock \ CALS(FgTSO()); \ Eblock #define T_SYMETRIE_XY \ Bblock \ CALS(FgTSXY()); \ Eblock #define T_SYMETRIE_YZ \ Bblock \ CALS(FgTSYZ()); \ Eblock #define T_SYMETRIE_ZX \ Bblock \ CALS(FgTSZX()); \ Eblock /* Les quatre symetries ont ete introduites le 20230929142425... */ #define PERMUTATION_DES_ROTATIONS(condition,permutation,rotation1,rotation2,rotation3) \ Bblock \ Test(IFET(EST_FAUX(on_a_trouve_une_permutation),condition)) \ Bblock \ permutation(rotation1,rotation2,rotation3); \ /* Choix d'un ordre entre les trois rotations... */ \ EGAL(on_a_trouve_une_permutation,VRAI); \ /* Et ce, afin de ne pas appliquer un peu plus loin une autre permutation... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Choix de l'ordre d'application des trois rotations dans l'espace tridimensionnel... */ #define GENERATION_DE_LA_MATRICE_DE_ROTATION(ordre1,rotation1,ordre2,rotation2,ordre3,rotation3) \ Bblock \ DEFV(Logical,INIT(on_a_trouve_une_permutation,FAUX)); \ /* Indicateur permettant de savoir si l'on a trouve une permutation. ATTENTION, cet */ \ /* indicateur a ete introduit tardivement (le 1993061500) pour corriger un bug etonnant. */ \ /* En effet, en son absence, supposons : */ \ /* */ \ /* vecteurs_____ordre_de_la_ROTATION_0X # ORDRE_DE_LA_ROTATION_0X */ \ /* vecteurs_____ordre_de_la_ROTATION_0Y = ORDRE_DE_LA_ROTATION_0Y */ \ /* vecteurs_____ordre_de_la_ROTATION_0Z = ORDRE_DE_LA_ROTATION_0Z */ \ /* */ \ /* ce qui correspond au cas ou seule la rotation par rapport a 'OX' a ete rencontree. Dans */ \ /* ces conditions (et l'absence de 'on_a_trouve_une_permutation'), il est clair que les */ \ /* deux permutations 'PERMUTATION_123' et 'PERMUTATION_132' vont etre activees, mettant */ \ /* ainsi dans le produit matriciel des transformations deux fois la rotation par rapport */ \ /* a 'OX', sachant qu'il y avait la sequence : */ \ /* */ \ /* PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre1,ordre2),IFLT(ordre1,ordre3)) */ \ /* ,PERMUTATION_123 */ \ /* ,rotation1,rotation2,rotation3 */ \ /* ); */ \ /* PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre1,ordre3),IFLT(ordre1,ordre2)) */ \ /* ,PERMUTATION_132 */ \ /* ,rotation1,rotation2,rotation3 */ \ /* ); */ \ /* PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre2,ordre3),IFLT(ordre2,ordre1)) */ \ /* ,PERMUTATION_231 */ \ /* ,rotation1,rotation2,rotation3 */ \ /* ); */ \ /* PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre2,ordre1),IFLT(ordre2,ordre3)) */ \ /* ,PERMUTATION_213 */ \ /* ,rotation1,rotation2,rotation3 */ \ /* ); */ \ /* PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre3,ordre1),IFLT(ordre3,ordre2)) */ \ /* ,PERMUTATION_312 */ \ /* ,rotation1,rotation2,rotation3 */ \ /* ); */ \ /* PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre3,ordre2),IFLT(ordre3,ordre1)) */ \ /* ,PERMUTATION_321 */ \ /* ,rotation1,rotation2,rotation3 */ \ /* ); */ \ /* */ \ /* sequence qui etait particulierement stupide puisque, par exemple, les deux premiers */ \ /* tests sont identiques puisque 'IFET(...)' commute... */ \ PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre1,ordre2),IFLT(ordre2,ordre3)) \ ,PERMUTATION_123 \ ,rotation1,rotation2,rotation3 \ ); \ PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre1,ordre3),IFLT(ordre3,ordre2)) \ ,PERMUTATION_132 \ ,rotation1,rotation2,rotation3 \ ); \ PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre2,ordre3),IFLT(ordre3,ordre1)) \ ,PERMUTATION_231 \ ,rotation1,rotation2,rotation3 \ ); \ PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre2,ordre1),IFLT(ordre1,ordre3)) \ ,PERMUTATION_213 \ ,rotation1,rotation2,rotation3 \ ); \ PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre3,ordre1),IFLT(ordre1,ordre2)) \ ,PERMUTATION_312 \ ,rotation1,rotation2,rotation3 \ ); \ PERMUTATION_DES_ROTATIONS(IFET(IFLT(ordre3,ordre2),IFLT(ordre2,ordre1)) \ ,PERMUTATION_321 \ ,rotation1,rotation2,rotation3 \ ); \ Eblock \ /* Puisque les rotations ne commutent pas dans l'espace tridimensionnel, l'ordre dans */ \ /* lequel elles sont effectuees est tres important. Pour avoir un exemple de memorisation */ \ /* de l'ordre courant des rotations on pourra consulter le fichier 'v $xrv/champs_5.1A$I' */ \ /* ou encore 'v $xci/fract_2D.01$K'. */ /* Tout ce qui concerne l'ordre des rotations vient de 'v $xrq/nucleon.LX.2$I' et a ete */ /* deplace le 19971104162912. */ #define DRAW \ Bblock \ Test(IL_FAUT(DRAW_____initialiser_les_extrema_de_X_Y_Z)) \ Bblock \ EGAL(DRAW_____minimum_X,F_INFINI); \ EGAL(DRAW_____minimum_Y,F_INFINI); \ EGAL(DRAW_____minimum_Z,F_INFINI); \ /* Minimum courant des coordonnees {X,Y,Z} (introduit le 20080909144655) et ce quel que soit */ \ /* 'vecteurs_____etat_trace'... */ \ EGAL(DRAW_____maximum_X,F_MOINS_L_INFINI); \ EGAL(DRAW_____maximum_Y,F_MOINS_L_INFINI); \ EGAL(DRAW_____maximum_Z,F_MOINS_L_INFINI); \ /* Maximum courant des coordonnees {X,Y,Z} (introduit le 20080909144655) et ce quel que soit */ \ /* 'vecteurs_____etat_trace'... */ \ \ Test(TOUJOURS_VRAI) \ /* L'initialisation etant conditionnee par 'DRAW_____initialiser_les_extrema_de_X_Y_Z', */ \ /* celle des extrema de type 'trace_AUTORISE' doit etre faite sans tester si l'etat est */ \ /* 'EST_AUTORISE(vecteurs_____etat_trace)'... */ \ Bblock \ EGAL(DRAW_____minimum_X__trace_AUTORISE,F_INFINI); \ EGAL(DRAW_____minimum_Y__trace_AUTORISE,F_INFINI); \ EGAL(DRAW_____minimum_Z__trace_AUTORISE,F_INFINI); \ /* Minimum courant des coordonnees {X,Y,Z} (introduit le 20080909144655) qui ne conncernent */ \ /* que les cas 'EST_AUTORISE(vecteurs_____etat_trace)'... */ \ EGAL(DRAW_____maximum_X__trace_AUTORISE,F_MOINS_L_INFINI); \ EGAL(DRAW_____maximum_Y__trace_AUTORISE,F_MOINS_L_INFINI); \ EGAL(DRAW_____maximum_Z__trace_AUTORISE,F_MOINS_L_INFINI); \ /* Maximum courant des coordonnees {X,Y,Z} (introduit le 20080909144655) qui ne conncernent */ \ /* que les cas 'EST_AUTORISE(vecteurs_____etat_trace)'... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ EGAL(DRAW_____initialiser_les_extrema_de_X_Y_Z,FAUX); \ /* Afin de ne plus reinitialiser les extrema precedents (provisoirement...). */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ EGAL(DRAW_____minimum_X \ ,MIN3(DRAW_____minimum_X \ ,ASD2(vecteurs_____vector_3D,origine,x),ASD2(vecteurs_____vector_3D,extremite,x) \ ) \ ); \ EGAL(DRAW_____minimum_Y \ ,MIN3(DRAW_____minimum_Y \ ,ASD2(vecteurs_____vector_3D,origine,y),ASD2(vecteurs_____vector_3D,extremite,y) \ ) \ ); \ EGAL(DRAW_____minimum_Z \ ,MIN3(DRAW_____minimum_Z \ ,ASD2(vecteurs_____vector_3D,origine,z),ASD2(vecteurs_____vector_3D,extremite,z) \ ) \ ); \ /* Minimum courant des coordonnees {X,Y,Z} (introduit le 20080909144655) et ce quel que soit */ \ /* 'vecteurs_____etat_trace'... */ \ EGAL(DRAW_____maximum_X \ ,MAX3(DRAW_____maximum_X \ ,ASD2(vecteurs_____vector_3D,origine,x),ASD2(vecteurs_____vector_3D,extremite,x) \ ) \ ); \ EGAL(DRAW_____maximum_Y \ ,MAX3(DRAW_____maximum_Y \ ,ASD2(vecteurs_____vector_3D,origine,y),ASD2(vecteurs_____vector_3D,extremite,y) \ ) \ ); \ EGAL(DRAW_____maximum_Z \ ,MAX3(DRAW_____maximum_Z \ ,ASD2(vecteurs_____vector_3D,origine,z),ASD2(vecteurs_____vector_3D,extremite,z) \ ) \ ); \ /* Maximum courant des coordonnees {X,Y,Z} (introduit le 20080909144655) et ce quel que soit */ \ /* 'vecteurs_____etat_trace'... */ \ Test(EST_AUTORISE(vecteurs_____etat_trace)) \ Bblock \ EGAL(DRAW_____minimum_X__trace_AUTORISE \ ,MIN3(DRAW_____minimum_X__trace_AUTORISE \ ,ASD2(vecteurs_____vector_3D,origine,x),ASD2(vecteurs_____vector_3D,extremite,x) \ ) \ ); \ EGAL(DRAW_____minimum_Y__trace_AUTORISE \ ,MIN3(DRAW_____minimum_Y__trace_AUTORISE \ ,ASD2(vecteurs_____vector_3D,origine,y),ASD2(vecteurs_____vector_3D,extremite,y) \ ) \ ); \ EGAL(DRAW_____minimum_Z__trace_AUTORISE \ ,MIN3(DRAW_____minimum_Z__trace_AUTORISE \ ,ASD2(vecteurs_____vector_3D,origine,z),ASD2(vecteurs_____vector_3D,extremite,z) \ ) \ ); \ /* Minimum courant des coordonnees {X,Y,Z} (introduit le 20080909144655) qui ne conncernent */ \ /* que les cas 'EST_AUTORISE(vecteurs_____etat_trace)'... */ \ EGAL(DRAW_____maximum_X__trace_AUTORISE \ ,MAX3(DRAW_____maximum_X__trace_AUTORISE \ ,ASD2(vecteurs_____vector_3D,origine,x),ASD2(vecteurs_____vector_3D,extremite,x) \ ) \ ); \ EGAL(DRAW_____maximum_Y__trace_AUTORISE \ ,MAX3(DRAW_____maximum_Y__trace_AUTORISE \ ,ASD2(vecteurs_____vector_3D,origine,y),ASD2(vecteurs_____vector_3D,extremite,y) \ ) \ ); \ EGAL(DRAW_____maximum_Z__trace_AUTORISE \ ,MAX3(DRAW_____maximum_Z__trace_AUTORISE \ ,ASD2(vecteurs_____vector_3D,origine,z),ASD2(vecteurs_____vector_3D,extremite,z) \ ) \ ); \ /* Maximum courant des coordonnees {X,Y,Z} (introduit le 20080909144655 qui ne conncernent */ \ /* que les cas 'EST_AUTORISE(vecteurs_____etat_trace)'... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(EST_AUTORISE(vecteurs_____etat_trace)) \ Bblock \ CALS(IFseg3D(ImageG \ ,ADRESSE(vecteurs_____vector_3D) \ ,vecteurs_____pointilles \ ,vecteurs_____niveau_minimal \ ,vecteurs_____niveau_maximal \ ,vecteurs_____etat_anti_aliasing \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Trace du vecteur courant. */ #define PRINT_MATRICE(matrice_a_editer) \ Bblock \ CAL3(Prme9("matrice :\n (%8.4g,%8.4g,%8.4g)\n (%8.4g,%8.4g,%8.4g)\n (%8.4g,%8.4g,%8.4g)\n" \ ,ASD2(matrice_a_editer,cx,cx),ASD2(matrice_a_editer,cx,cy),ASD2(matrice_a_editer,cx,cz) \ ,ASD2(matrice_a_editer,cy,cx),ASD2(matrice_a_editer,cy,cy),ASD2(matrice_a_editer,cy,cz) \ ,ASD2(matrice_a_editer,cz,cx),ASD2(matrice_a_editer,cz,cy),ASD2(matrice_a_editer,cz,cz) \ ) \ ); \ Eblock \ /* Edition d'une matrice (introduit le 20051107121335) afin de faire des tests de */ \ /* 'v $xrr/N_ellipso.11$K'. */ #define PRINT_STATUS_GRAPHIQUE__CURSEUR \ Bblock \ CAL3(Prme3("curseur = (%+.^^^,%+.^^^,%+.^^^)\n" \ ,ASD1(vecteurs_____cursor_3D,x) \ ,ASD1(vecteurs_____cursor_3D,y) \ ,ASD1(vecteurs_____cursor_3D,z) \ ) \ ); \ Eblock \ /* Edition du curseur (introduite le 20240517082818)... */ #define PRINT_STATUS_GRAPHIQUE \ Bblock \ CALS(Fsauts_de_lignes(DEUX)); \ \ CALS(FPrme0("ETAT GRAPHIQUE :\n")); \ CALS(Fsauts_de_lignes(UN)); \ \ CAL3(Prme4("SK = %+.^^^ SX = %+.^^^ SY = %+.^^^ SZ = %+.^^^\n" \ ,I___vecteurs_____scale_globale \ ,I___vecteurs_____scale_OX \ ,I___vecteurs_____scale_OY \ ,I___vecteurs_____scale_OZ \ ) \ ); \ \ CAL3(Prme1("etat du trace = %s\n",ETAT_LOGIQUE(vecteurs_____etat_trace))); \ CAL3(Prme1("etat de l'anti-aliasing = %s\n",ETAT_LOGIQUE(vecteurs_____etat_anti_aliasing))); \ CAL3(Prme2("niveau minimal = %08X niveau maximal = %08X\n" \ ,vecteurs_____niveau_minimal \ ,vecteurs_____niveau_maximal \ ) \ ); \ CAL3(Prme1("pattern des vecteurs_____pointilles = %08X\n",vecteurs_____pointilles)); \ CAL3(Prme1("rapport de zoom = %+.^^^\n",vecteurs_____rapport_de_zoom_cumule_courant)); \ CAL3(Prme1("angle de rotation = %+.^^^\n",vecteurs_____angle_de_rotation)); \ \ PRINT_MATRICE(vecteurs_____matrix_3D); \ \ PRINT_STATUS_GRAPHIQUE__CURSEUR; \ \ CAL3(Prme6("origine = (%+.^^^,%+.^^^,%+.^^^) extremite = (%+.^^^,%+.^^^,%+.^^^)\n" \ ,ASD2(vecteurs_____vector_3D,origine,x) \ ,ASD2(vecteurs_____vector_3D,origine,y) \ ,ASD2(vecteurs_____vector_3D,origine,z) \ ,ASD2(vecteurs_____vector_3D,extremite,x) \ ,ASD2(vecteurs_____vector_3D,extremite,y) \ ,ASD2(vecteurs_____vector_3D,extremite,z) \ ) \ ); \ Eblock \ /* Edition de l'etat graphique. L'introduction de '%+.^^^' a eu lieu le 20240517082818... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* Q U E L Q U E S M A C R O S G R A P H I Q U E S U T I L E S P O U R L A P I L E : */ /* */ /* */ /* Utilisation : */ /* */ /* GCREATION_PILE; */ /* */ /* */ /* Nota : */ /* */ /* Pour les variables flottantes, */ /* le "cast" 'FLOT' est redondant */ /* puisqu'en effet, on n'empile */ /* que des variables de type flottant... */ /* */ /*************************************************************************************************************************************/ #define GCREATION_PILE \ Bblock \ CREATION_PILE(vecteurs_____pile_graphique); \ Eblock \ /* Creation de la pile graphique. */ #define GpushX(fonction_push,variable) \ Bblock \ Test(IFEQ(vecteurs_____pile_graphique,PILE_UNDEF)) \ Bblock \ GCREATION_PILE; \ /* L'initialisation de la pile est automatique. */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ fonction_push(vecteurs_____pile_graphique,variable); \ Eblock \ /* Empilement d'une variable quelconque. */ #define GpushF(variable_flottante) \ Bblock \ GpushX(FpushF,FLOT(variable_flottante)); \ Eblock \ /* Empilement d'une variable flottante. */ #define GpushI(variable_entiere) \ Bblock \ GpushX(FpushI,INTE(variable_entiere)); \ Eblock \ /* Empilement d'une variable entiere. */ #define GpullX(fonction_pull,cast,variable) \ Bblock \ EGAL(variable,cast(fonction_pull(vecteurs_____pile_graphique))); \ Eblock \ /* Depilement d'une variable quelconque (sans initialisation automatique). */ #define GpullF(variable_flottante) \ Bblock \ GpullX(FpullF,FLOT,variable_flottante); \ Eblock \ /* Depilement d'une variable flottante (sans initialisation automatique). */ #define GpullI(cast,variable_entiere) \ Bblock \ GpullX(FpullI,cast,variable_entiere); \ Eblock \ /* Depilement d'une variable entiere (sans initialisation automatique). */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* Q U E L Q U E S M A C R O S G R A P H I Q U E S U T I L E S */ /* P O U R L A G E S T I O N D E S I N D I C A T E U R S : */ /* */ /* */ /* Utilisation : */ /* */ /* SET_TRACE(AUTORISE ou INTERDIT); */ /* SET_ANTI_ALIASING(VRAI ou FAUX); */ /* PUSH_ANTI_ALIASING; */ /* PULL_ANTI_ALIASING; */ /* SET_COULEURS(vecteurs_____niveau_minimal,vecteurs_____niveau_maximal); */ /* SET_NOIR_PLANCHER_DES_VECTEURS(niveau_plancher_des_vecteurs); */ /* SET_POINTILLES(pattern sur 32 bits); */ /* */ /*************************************************************************************************************************************/ #define set_indicateur(indicateur,valeur,test_de_validite) \ Bblock \ Test(test_de_validite) \ Bblock \ EGAL(indicateur,valeur); \ /* Mise en place de l'indicateur lorsque la valeur demandee est valide. */ \ Eblock \ ATes \ Bblock \ PRINT_ERREUR("l'initialisation de 'indicateur' est demandee avec 'valeur'"); \ Eblock \ ETes \ Eblock #define SET_TRACE(valeur) \ Bblock \ set_indicateur(vecteurs_____etat_trace,valeur,IFOU(IFEQ(valeur,AUTORISE),IFEQ(valeur,INTERDIT))); \ Eblock \ /* Autorisation ou inhibition du trace. */ #define SET_ANTI_ALIASING(valeur) \ Bblock \ set_indicateur(vecteurs_____etat_anti_aliasing,valeur,IFOU(IFEQ(valeur,VRAI),IFEQ(valeur,FAUX))); \ Eblock \ /* Autorisation ou inhibition du mode anti-aliasing. */ #define PUSH_ANTI_ALIASING \ Bblock \ /* Pour valider le couple (PUSH,PULL)... */ \ DEFV(Logical,INIT(EnTete_de_sauvegardM ## vecteurs_____etat_anti_aliasing,vecteurs_____etat_anti_aliasing)); \ /* Sauvegarde de l'etat d'anti-aliasing. */ #define PULL_ANTI_ALIASING \ SET_ANTI_ALIASING(EnTete_de_sauvegardM ## vecteurs_____etat_anti_aliasing); \ /* Restauration de l'etat d'anti-aliasing. */ \ Eblock \ /* Pour valider le couple (PUSH,PULL)... */ #define SET_COULEURS(couleur_minimale,couleur_maximale) \ Bblock \ Test(EST_AUTORISE(vecteurs_____SET_COULEURS)) \ /* A cause de 'v $xiii/alphabets$FON SET_COULEURS.niveau_fond,niveau_fond.', ce test */ \ /* a ete introduit le 20181023140540... */ \ Bblock \ VALIDATION_NIVEAU \ ( \ GENP(couleur_minimale) \ ,BLOC(EGAL(vecteurs_____niveau_minimal,GENP(couleur_minimale));) \ ,BLOC(PRINT_ERREUR("le niveau minimal demande est hors de [NOIR,BLANC]");) \ ) \ VALIDATION_NIVEAU \ ( \ GENP(couleur_maximale) \ ,BLOC(EGAL(vecteurs_____niveau_maximal,GENP(couleur_maximale));) \ ,BLOC(PRINT_ERREUR("le niveau maximal demande est hors de [NOIR,BLANC]");) \ ) \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Mise en place du niveau de trace ('vecteurs_____niveau_maximal') et du niveau */ \ /* minimal lors d'un trace anti-aliase ('vecteurs_____niveau_minimal'). */ #define SET_NOIR_PLANCHER_DES_VECTEURS(niveau_plancher_des_vecteurs) \ Bblock \ EGAL(noir_plancher_des_vecteurs,niveau_plancher_des_vecteurs); \ Eblock \ /* Mise en place du "noir-plancher" des vecteurs. */ \ /* ATTENTION, nota important : la variable 'noir_plancher_des_vecteurs' (niveau minimal */ \ /* utilise lors du marquage des points d'un vecteur ; cette variable est introduite pour */ \ /* permettre une generation correcte des mires de barres) se situe dans le fichier */ \ /* '$xiii/Images$STR' et non pas dans '$xiii/vecteurs$FON' car en effet elle est referencee */ \ /* d'une part par 'SET_FILTRAGE(INACTIF)' et d'autre part par la fonction "incontournable" */ \ /* 'Nsubstitution(...)' via la procedure 'CAS_ACCES_LISTE_DE_SUBSTITUTION(...)' ; ainsi */ \ /* cette variable est positionnee meme si les fonctions vectorielles ne sont par utilisees. */ #define SET_POINTILLES(pattern) \ Bblock \ EGAL(vecteurs_____pointilles,pattern); \ Eblock \ /* Mise en place de la "forme" des vecteurs_____pointilles. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* Q U E L Q U E S M A C R O S G R A P H I Q U E S U T I L E S */ /* P O U R L A G E S T I O N D E S B I B L I O T H E Q U E S : */ /* */ /* */ /* Utilisation : */ /* */ /* SET_BIBLIOTHEQUE(nom de bibliotheque); */ /* */ /*************************************************************************************************************************************/ #define SET_BIBLIOTHEQUE(numero_de_bibliotheque) \ Bblock \ EGAL(vecteurs_____num_bibliotheque,numero_de_bibliotheque); \ Eblock \ /* Mise en place sans validation du numero de bibliotheque. */ #define call_bibliotheque(BIBLIOTHEQUE_XX,fonction_XX) \ Ca1e(BIBLIOTHEQUE_XX) \ Bblock \ CALS(fonction_XX); \ /* Execution du fonction relatif a la bonne bibliotheque. */ \ /* Le 20180130134026 'BLOC(...)' a ete remplace par 'CALS(...)' plus logique... */ \ Eblock \ ECa1 #define call_in_bibliotheque(fonction_00,fonction_01,fonction_02,fonction_03,fonction_04,fonction_05,fonction_06) \ Bblock \ Choi(vecteurs_____num_bibliotheque) \ Bblock \ call_bibliotheque(BIBLIOTHEQUE_00,fonction_00); \ call_bibliotheque(BIBLIOTHEQUE_01,fonction_01); \ call_bibliotheque(BIBLIOTHEQUE_02,fonction_02); \ call_bibliotheque(BIBLIOTHEQUE_03,fonction_03); \ call_bibliotheque(BIBLIOTHEQUE_04,fonction_04); \ call_bibliotheque(BIBLIOTHEQUE_05,fonction_05); \ call_bibliotheque(BIBLIOTHEQUE_06,fonction_06); \ Defo \ Bblock \ PRINT_ERREUR("la bibliotheque demandee n'existe pas"); \ Eblock \ EDef \ Eblock \ ECho \ Eblock \ /* Cette macro permet d'appeler un fonction de nom donne parmi plusieurs a l'interieur de la */ \ /* bibliotheque selectionnee. */ \ /* */ \ /* La 'fonction_04' a ete introduit le 20161116105744... */ \ /* */ \ /* La 'fonction_05' a ete introduit le 20230516110153... */ \ /* */ \ /* La 'fonction_06' a ete introduit le 20240419182113... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P R I M I T I V E S G R A P H I Q U E S D E B A S E : */ /* */ /* */ /* Definitions : */ /* */ /* */ /* "PO;" : mise du curseur a l'origine. */ /* "PA;" : definition de l'origine d'un segment. */ /* "PS;" : definition de l'extremite d'un segment et trace. */ /* "PB;" : definition de l'extremite d'un segment et trace, puis chainage. */ /* */ /* "M1;" : deplacement 'EST', */ /* "M3;" : deplacement 'OUEST'. */ /* "M2;" : deplacement 'NORD', */ /* "M4;" : deplacement 'SUD'. */ /* "M5;" : deplacement 'AVANT', */ /* "M6;" : deplacement 'ARRIERE'. */ /* */ /* "SUPER_ECHELLE_RECTANGULAIRE;" */ /* "SUPER_ECHELLE_GRAND_CARRE;" */ /* "SUPER_ECHELLE_PETIT_CARRE;" */ /* "SAUVEGARDE_DE_LA_SUPER_ECHELLE;" */ /* "RESTAURATION_DE_LA_SUPER_ECHELLE;" */ /* : changement des "super-echelles", et donc du format apparent des images. */ /* */ /* "SK(k);" : definition de l'echelle globale telle que l'unite soit l'inter-point "physique", */ /* "SX(x);" : definition de l'echelle sur l'axe des 'X', */ /* "SY(y);" : definition de l'echelle sur l'axe des 'Y', */ /* "SZ(z);" : definition de l'echelle sur l'axe des 'Z'. */ /* */ /* "SKH(k);" : definition homothetique de l'echelle globale telle que l'unite soit dans le */ /* rapport des dimensions de l'image courante definies dans 'format' aux */ /* dimensions de l'image de BASE definies aussi dans 'format'. */ /* "SXH(x);" : definition homothetique de l'echelle sur l'axe des 'X', */ /* "SYH(y);" : definition homothetique de l'echelle sur l'axe des 'Y', */ /* "SZH(z);" : definition homothetique de l'echelle sur l'axe des 'Z', l'expression "homothetique" */ /* signifiant que la DENORMALISATION effectuee est telle qu'elle soit la meme sur les */ /* trois axes ce qui permet de faire tourner des figures sans que change leur apparence */ /* lorsque le format d'image n'est pas carre (par exemple en mode 'Pal') ; le programme */ /* 'v $xrd/Salomon.01$K' en donne un exemple d'utilisation. ATTENTION, ces definitions */ /* utilisent {{Xmin,Xmax},{Ymin,Ymax},{Zmin,Zmax}} et donc, '$formatI' pour les deux */ /* premiers couples et "Zmin=... Zmax" pour le troisieme, doivent etre definis... */ /* */ /* "XADDI;" : incrementation de l'echelle sur l'axe des 'X', */ /* "XSOUS;" : incrementation de l'echelle sur l'axe des 'X', */ /* "XMULT;" : multiplication de l'echelle sur l'axe des 'X', */ /* "XDIVI;" : division de l'echelle sur l'axe des 'X', */ /* "YADDI;" : incrementation de l'echelle sur l'axe des 'Y', */ /* "YSOUS;" : incrementation de l'echelle sur l'axe des 'Y', */ /* "YMULT;" : multiplication de l'echelle sur l'axe des 'Y', */ /* "YDIVI;" : division de l'echelle sur l'axe des 'Y', */ /* "ZADDI;" : incrementation de l'echelle sur l'axe des 'Z', */ /* "ZSOUS;" : incrementation de l'echelle sur l'axe des 'Z', */ /* "ZMULT;" : multiplication de l'echelle sur l'axe des 'Z', */ /* "ZDIVI;" : division de l'echelle sur l'axe des 'Z', */ /* */ /* "MIK;" : empilement de l'echelle globale. */ /* "MIX;" : empilement de l'echelle sur l'axe des 'X', */ /* "MIY;" : empilement de l'echelle sur l'axe des 'Y', */ /* "MIZ;" : empilement de l'echelle sur l'axe des 'Z'. */ /* "MI1;" : empilement de l'abscisse du curseur, */ /* "MI2;" : empilement de l'ordonnee du curseur, */ /* "MI3;" : empilement de la profondeur du curseur. */ /* "MIC;" : empilement des trois coordonnees du curseur dans l'ordre (Z,Y,X), */ /* "MIT;" : empilement de la matrice de transformation courante. */ /* "MIN;" : empilement des niveaux et des etats de trace dans l'ordre (min,max). */ /* "MON;" : depilement des niveaux et des etats de trace dans l'ordre (min,max). */ /* "MOT;" : depilement de la matrice de transformation courante. */ /* "MOC;" : depilement des trois coordonnees du curseur dans l'ordre {X,Y,Z}. */ /* "MO3;" : depilement de la profondeur du curseur, */ /* "MO2;" : depilement de l'ordonnee du curseur, */ /* "MO1;" : depilement de l'abscisse du curseur. */ /* "MOZ;" : depilement de l'echelle sur l'axe des 'Z', */ /* "MOY;" : depilement de l'echelle sur l'axe des 'Y', */ /* "MOX;" : depilement de l'echelle sur l'axe des 'X'. */ /* "MOK;" : depilement de l'echelle globale. */ /* */ /* "INITIALISATION_SYSTEMATIQUE_TRANSFORMATION;" */ /* : (re-)initialisation systematique de la transformation courante, */ /* "INITIALISATION_TRANSFORMATION;" */ /* : initialisation si necessaire de la transformation courante. */ /* "TRX1;" : rotation autour de l'axe des 'X' de +pi/2, */ /* "TRX3;" : rotation autour de l'axe des 'X' de -pi/2. */ /* "TRX(a);" : rotation autour de l'axe des 'X' d'un angle exprime en radian. */ /* "TRY1;" : rotation autour de l'axe des 'Y' de +pi/2, */ /* "TRY3;" : rotation autour de l'axe des 'Y' de -pi/2. */ /* "TRY(a);" : rotation autour de l'axe des 'Y' d'un angle exprime en radian. */ /* "TRZ1;" : rotation autour de l'axe des 'Z' de +pi/2, */ /* "TRZ3;" : rotation autour de l'axe des 'Z' de -pi/2. */ /* "TRZ(a);" : rotation autour de l'axe des 'Z' d'un angle exprime en radian. */ /* "TSO;" : symetrie origine (qui est le produit de trois symetries planes), */ /* "TSXY;" : symetrie par rapport au plan 'XY', */ /* "TSYZ;" : symetrie par rapport au plan 'YZ', */ /* "TSZX;" : symetrie par rapport au plan 'ZX', */ /* */ /* "ERASE;" : effacement de l'image de trace... */ /* */ /*************************************************************************************************************************************/ #nodefine super_echelle_OZ_VERSION_01 \ /* Cette facon de gerer 'super_echelle_OZ' la rend eventuellement variable et ce en fonction */ \ /* des dimesnions de l'un des axes 'OX' ou 'OY'. */ #define super_echelle_OZ_VERSION_02 \ /* Cette facon de gerer 'super_echelle_OZ' la rend constante (introduit le 20020218090942). */ #if ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_01)) \ ) # define I___vecteurs_____scale_globale \ vecteurs_____scale_globale \ /* Acces a l'echelle globale avec initialisation dynamique eventuelle... */ # define I___vecteurs_____scale_OX \ vecteurs_____scale_OX \ /* Acces a l'echelle sur l'axe 'OX' avec initialisation dynamique eventuelle... */ # define I___vecteurs_____scale_OY \ vecteurs_____scale_OY \ /* Acces a l'echelle sur l'axe 'OY' avec initialisation dynamique eventuelle... */ # define I___vecteurs_____scale_OZ \ vecteurs_____scale_OZ \ /* Acces a l'echelle sur l'axe 'OZ' avec initialisation dynamique eventuelle... */ #Aif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_01)) \ ) #Eif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_01)) \ ) #if ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_02)) \ || (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_03)) \ ) # define INITIALISER_LES_ECHELLES \ FZERO \ /* Afin de pouvoir initialiser dynamiquement les echelles (ce que l'on ne peut plus faire */ \ /* a la compilation sous 'GESTION_DU_FORMAT_DES_IMAGES_VERSION_02')... */ # define ACCES_A_UNE_ECHELLE_AVEC_INITIALISATION_EVENTUELLE(echelle,valeur_initiale) \ COND(IFEQ(echelle,INITIALISER_LES_ECHELLES) \ ,EGAL(echelle,valeur_initiale) \ ,echelle \ ) \ /* Acces a une echelle avec initialisation dynamique eventuelle... */ # define I___vecteurs_____scale_globale \ ACCES_A_UNE_ECHELLE_AVEC_INITIALISATION_EVENTUELLE(vecteurs_____scale_globale \ ,ECHELLES_INITIALES \ ) \ /* Acces a l'echelle globale avec initialisation dynamique eventuelle... */ # define I___vecteurs_____scale_OX \ ACCES_A_UNE_ECHELLE_AVEC_INITIALISATION_EVENTUELLE(vecteurs_____scale_OX \ ,_____lNORMALISE_OX(ECHELLES_INITIALES) \ ) \ /* Acces a l'echelle sur l'axe 'OX' avec initialisation dynamique eventuelle... */ # define I___vecteurs_____scale_OY \ ACCES_A_UNE_ECHELLE_AVEC_INITIALISATION_EVENTUELLE(vecteurs_____scale_OY \ ,_____lNORMALISE_OY(ECHELLES_INITIALES) \ ) \ /* Acces a l'echelle sur l'axe 'OY' avec initialisation dynamique eventuelle... */ # define I___vecteurs_____scale_OZ \ ACCES_A_UNE_ECHELLE_AVEC_INITIALISATION_EVENTUELLE(vecteurs_____scale_OZ \ ,_____lNORMALISE_OZ(ECHELLES_INITIALES) \ ) \ /* Acces a l'echelle sur l'axe 'OZ' avec initialisation dynamique eventuelle... */ #Aif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_02)) \ || (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_03)) \ ) #Eif ( (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_02)) \ || (defined(GESTION_DU_FORMAT_DES_IMAGES_VERSION_03)) \ ) #define SUPER_ECHELLE_DE_BASE \ FU \ /* Valeur standard des deux "super-echelles"... */ #define SUPER_ECHELLE_RECTANGULAIRE \ Bblock \ EGAL(super_echelle_OX,SUPER_ECHELLE_DE_BASE); \ EGAL(super_echelle_OY,SUPER_ECHELLE_DE_BASE); \ EGAL(super_echelle_OZ,SUPER_ECHELLE_DE_BASE); \ Eblock \ /* Definition des deux "super-echelles" telle qu'un carre trace sur l'ecran aura les memes */ \ /* proportions que l'image elle-meme. Par exemple en format 'Pal', il donnera l'impression */ \ /* d'un rectangle horizontal. */ #ifdef super_echelle_OZ_VERSION_01 # define SUPER_ECHELLE_GRAND_CARRE \ Bblock \ EGAL(super_echelle_OX,SUPER_ECHELLE_DE_BASE); \ EGAL(super_echelle_OY,fDIVZ(FLOT(LONGUEUR(dimX)),FLOT(LONGUEUR(dimY)))); \ EGAL(super_echelle_OZ,fDIVZ(FLOT(LONGUEUR(dimX)),FLOT(LONGUEUR(dimZ)))); \ Eblock \ /* Definition des deux "super-echelles" telle qu'un carre trace sur l'ecran aura bien l'air */ \ /* d'un "grand" carre... */ \ /* */ \ /* On notera que jusqu'au 20001222095956, on trouvait ici : */ \ /* */ \ /* EGAL(super_echelle_OY,DIVI(FLOT(dimX),FLOT(dimY))); */ \ /* */ \ /* mais il convient d'etre en "phase" avec 'v $xiiD/definit.1$DEF ______NORMALISE_AXES'. */ \ /* */ \ /* Le 20071203093149, les 'DIVZ(...)'s furent remplaces par des 'fDIVZ(...)'s, ceci etant */ \ /* une solution au probleme 'v $xil/defi_K2$vv$DEF 20071202113349'... */ # define SUPER_ECHELLE_PETIT_CARRE \ Bblock \ EGAL(super_echelle_OX,fDIVZ(FLOT(LONGUEUR(dimY)),FLOT(LONGUEUR(dimX)))); \ EGAL(super_echelle_OY,SUPER_ECHELLE_DE_BASE); \ EGAL(super_echelle_OZ,fDIVZ(FLOT(LONGUEUR(dimY)),FLOT(LONGUEUR(dimZ)))); \ Eblock \ /* Definition des deux "super-echelles" telle qu'un carre trace sur l'ecran aura bien l'air */ \ /* d'un "petit" carre (par rapport au format ci-dessus)... */ \ /* */ \ /* On notera que jusqu'au 20001222095956, on trouvait ici : */ \ /* */ \ /* EGAL(super_echelle_OX,DIVI(FLOT(dimY),FLOT(dimX))); */ \ /* */ \ /* mais il convient d'etre en "phase" avec 'v $xiiD/definit.1$DEF ______NORMALISE_AXES'. */ \ /* */ \ /* Le 20071203093149, les 'DIVZ(...)'s furent remplaces par des 'fDIVZ(...)'s, ceci etant */ \ /* une solution au probleme 'v $xil/defi_K2$vv$DEF 20071202113349'... */ #Aifdef super_echelle_OZ_VERSION_01 #Eifdef super_echelle_OZ_VERSION_01 #ifdef super_echelle_OZ_VERSION_02 # define SUPER_ECHELLE_GRAND_CARRE \ Bblock \ EGAL(super_echelle_OX,SUPER_ECHELLE_DE_BASE); \ EGAL(super_echelle_OY,fDIVZ(FLOT(LONGUEUR(dimX)),FLOT(LONGUEUR(dimY)))); \ EGAL(super_echelle_OZ,SUPER_ECHELLE_DE_BASE); \ Eblock \ /* Definition des deux "super-echelles" telle qu'un carre trace sur l'ecran aura bien l'air */ \ /* d'un "grand" carre... */ \ /* */ \ /* Le 20071203093149, les 'DIVZ(...)'s furent remplaces par des 'fDIVZ(...)'s, ceci etant */ \ /* une solution au probleme 'v $xil/defi_K2$vv$DEF 20071202113349'... */ # define SUPER_ECHELLE_PETIT_CARRE \ Bblock \ EGAL(super_echelle_OX,fDIVZ(FLOT(LONGUEUR(dimY)),FLOT(LONGUEUR(dimX)))); \ EGAL(super_echelle_OY,SUPER_ECHELLE_DE_BASE); \ EGAL(super_echelle_OZ,SUPER_ECHELLE_DE_BASE); \ Eblock \ /* Definition des deux "super-echelles" telle qu'un carre trace sur l'ecran aura bien l'air */ \ /* d'un "petit" carre (par rapport au format ci-dessus)... */ \ /* */ \ /* Le 20071203093149, les 'DIVZ(...)'s furent remplaces par des 'fDIVZ(...)'s, ceci etant */ \ /* une solution au probleme 'v $xil/defi_K2$vv$DEF 20071202113349'... */ #Aifdef super_echelle_OZ_VERSION_02 #Eifdef super_echelle_OZ_VERSION_02 #define CHOIX_DE_LA_SUPER_ECHELLE(utiliser_le_mode_rectangulaire,utiliser_le_mode_carre__grand_carre) \ /* Les deux arguments {utiliser_le_mode_rectangulaire,utiliser_le_mode_carre__grand_carre} */ \ /* ont ete introduits le 20051217135429 a cause de l'usage possible de cette procedure dans */ \ /* 'PROCESS_ARGUMENT_N(...)' ('v $xrv/champs_5.1A$I PROCESS_ARGUMENT_N'). Dans ce cas, */ \ /* il est imperatif d'inverser la valeur logique de l'indicateur que l'on est en train de */ \ /* traiter... */ \ Bblock \ Test(IL_FAUT(utiliser_le_mode_rectangulaire)) \ Bblock \ SUPER_ECHELLE_RECTANGULAIRE; \ Eblock \ ATes \ Bblock \ Test(IL_FAUT(utiliser_le_mode_carre__grand_carre)) \ Bblock \ SUPER_ECHELLE_GRAND_CARRE; \ Eblock \ ATes \ Bblock \ SUPER_ECHELLE_PETIT_CARRE; \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ /* Procedure introduite le 20051216101259... */ #define SAUVEGARDE_DE_LA_SUPER_ECHELLE \ Bblock \ DEFV(Float,INIT(EnTete_de_sauvegardM ## super_echelle_OX,super_echelle_OX)); \ DEFV(Float,INIT(EnTete_de_sauvegardM ## super_echelle_OY,super_echelle_OY)); \ DEFV(Float,INIT(EnTete_de_sauvegardM ## super_echelle_OZ,super_echelle_OZ)); #define RESTAURATION_DE_LA_SUPER_ECHELLE \ EGAL(super_echelle_OX,EnTete_de_sauvegardM ## super_echelle_OX); \ EGAL(super_echelle_OY,EnTete_de_sauvegardM ## super_echelle_OY); \ EGAL(super_echelle_OZ,EnTete_de_sauvegardM ## super_echelle_OZ); \ Eblock /* Sauvegarde et restauration des super-echelles... */ #define SUPER_ECHELLE_OX(x) \ MUL2(super_echelle_OX,x) #define SUPER_ECHELLE_OY(y) \ MUL2(super_echelle_OY,y) #define SUPER_ECHELLE_OZ(z) \ MUL2(super_echelle_OZ,z) /* Application des super-echelles a des coordonnees {x,y,z}. */ #define ANTI_SUPER_ECHELLE_OX(x) \ DIVI(x,super_echelle_OX) #define ANTI_SUPER_ECHELLE_OY(y) \ DIVI(y,super_echelle_OY) #define ANTI_SUPER_ECHELLE_OZ(z) \ DIVI(z,super_echelle_OZ) /* Et inverse... */ #define SUPER_cDENORMALISE_OX(x) \ _cDENORMALISE_OX(SUPER_ECHELLE_OX(x)) #define SUPER_cDENORMALISE_OY(y) \ _cDENORMALISE_OY(SUPER_ECHELLE_OY(y)) #define SUPER_cDENORMALISE_OZ(z) \ _cDENORMALISE_OZ(SUPER_ECHELLE_OZ(z)) #define TRANS_SUPER_cDENORMALISE_OX(x,translation) \ SUPER_cDENORMALISE_OX(SOUS(x,translation)) #define TRANS_SUPER_cDENORMALISE_OY(y,translation) \ SUPER_cDENORMALISE_OY(SOUS(y,translation)) #define TRANS_SUPER_cDENORMALISE_OZ(z,translation) \ SUPER_cDENORMALISE_OZ(SOUS(z,translation)) /* Denormalisation des coordonnees {x,y,z} avec application des super-echelles sans, puis */ /* avec translation... */ #define SUPER_lDENORMALISE_OX(x) \ _lDENORMALISE_OX(SUPER_ECHELLE_OX(x)) #define SUPER_lDENORMALISE_OY(y) \ _lDENORMALISE_OY(SUPER_ECHELLE_OY(y)) #define SUPER_lDENORMALISE_OZ(z) \ _lDENORMALISE_OZ(SUPER_ECHELLE_OZ(z)) /* Denormalisation des longueurs {x,y,z} avec application des super-echelles ; ceci fut */ /* introduit le 20050912133506... */ #define SUPER_cNORMALISE_OX(x) \ ANTI_SUPER_ECHELLE_OX(_____cNORMALISE_OX(x)) #define SUPER_cNORMALISE_OY(y) \ ANTI_SUPER_ECHELLE_OY(_____cNORMALISE_OY(y)) #define SUPER_cNORMALISE_OZ(z) \ ANTI_SUPER_ECHELLE_OZ(_____cNORMALISE_OZ(z)) #define TRANS_SUPER_cNORMALISE_OX(x,translation) \ ADD2(SUPER_cNORMALISE_OX(x),translation) #define TRANS_SUPER_cNORMALISE_OY(y,translation) \ ADD2(SUPER_cNORMALISE_OY(y),translation) #define TRANS_SUPER_cNORMALISE_OZ(z,translation) \ ADD2(SUPER_cNORMALISE_OZ(z),translation) /* Et inverse pour les coordonnees sans, puis avec translation... */ #define SUPER_lNORMALISE_OX(x) \ ANTI_SUPER_ECHELLE_OX(_____lNORMALISE_OX(x)) #define SUPER_lNORMALISE_OY(y) \ ANTI_SUPER_ECHELLE_OY(_____lNORMALISE_OY(y)) #define SUPER_lNORMALISE_OZ(z) \ ANTI_SUPER_ECHELLE_OZ(_____lNORMALISE_OZ(z)) /* Et inverse pour les longuers ; ceci fut introduit le 20050912133506... */ #define SK(K) \ Bblock \ EGAL(vecteurs_____scale_globale,K); \ Eblock \ /* "K" : definition "physique" de l'echelle globale, c'est-a-dire telle */ \ /* que l'unite soit l'inter-point. */ #define SX(KX) \ Bblock \ EGAL(vecteurs_____scale_OX \ ,COND(IL_FAUT(SX_SY_SZ_____compatibilite_20070416) \ ,_____lNORMALISE_OX(KX) \ ,_____cNORMALISE_OX(KX) \ ) \ ); \ Eblock \ /* "X" : definition de l'echelle sur l'axe des 'X'. */ \ /* */ \ /* ATTENTION : jusqu'au 20070416150831 on trouvait '_____lNORMALISE_OX(...)' ci-dessus. */ \ /* Or un probleme est apparu a cette date dans 'v $xci/mire$K MIRE_DE_BARRES' a cause de */ \ /* l'increment de la coordonnee 'X' qui est alors : */ \ /* */ \ /* SX(INTER_POINT); */ \ /* */ \ /* Par exemple, prenons le format 'Sud'. Partant de X=0, il faut arriver a X=255. Il faut */ \ /* donc que le pas soit egal a 1/255, d'ou l'usage de '_____cNORMALISE_OX(...)' qui utilise */ \ /* 'LONGUEUR(...)' via '_____cNORMALISE_AXES(...)'. Une modification similaire a ete */ \ /* apportee a 'SY(...)' et a 'SZ(...)' par "symetrie"... */ #define SY(KY) \ Bblock \ EGAL(vecteurs_____scale_OY \ ,COND(IL_FAUT(SX_SY_SZ_____compatibilite_20070416) \ ,_____lNORMALISE_OY(KY) \ ,_____cNORMALISE_OY(KY) \ ) \ ); \ Eblock \ /* "Y" : definition de l'echelle sur l'axe des 'Y'. */ #define SZ(KZ) \ Bblock \ EGAL(vecteurs_____scale_OZ \ ,COND(IL_FAUT(SX_SY_SZ_____compatibilite_20070416) \ ,_____lNORMALISE_OZ(KZ) \ ,_____cNORMALISE_OZ(KZ) \ ) \ ); \ Eblock \ /* "Z" : definition de l'echelle sur l'axe des 'Z'. */ #define NORMALISATION_ECHELLE_K(echelle) \ COND(IL_FAUT(vecteurs_____renormaliser_scale_globale) \ ,MUL2(echelle \ ,DIVI(FLOT(PLUS_PETITE_IMAGE_CARREE_CIRCONSCRITE) \ ,FLOT(MAX2(dimX_BASE,dimY_BASE)) \ ) \ ) \ ,NEUT(echelle) \ ) \ /* Fonction de normalisation des echelles telle que l'unite soit alors */ \ /* le rapport des dimensions de l'image courante a celles de l'image */ \ /* de BASE (toutes celles-ci etant definies dans 'format'). */ \ /* */ \ /* Le controle de la renormalisation a ete introduit le 20160527135104. Cela a ete mis en */ \ /* place lors de la mise au point de 'v $xiird/.ACIN.Z1.2.$U .xci.mire.X' lorsque je me */ \ /* suis rendu compte qu'il etait quasiment impossible de definir une hauteur correcte pour */ \ /* la mire et ce independemment du format (ainsi, par exemple, une hauteur de 0.5, donc */ \ /* normalisee dans [0,1], ne donnait une mire faisant 50% de la hauteur que pour le */ \ /* format 'Std'... */ #define ECHELLES_INITIALES \ NORMALISATION_ECHELLE_K(INTER_POINT) \ /* Definition de toutes les echelles initiales. */ #define SKH(K) \ Bblock \ EGAL(vecteurs_____scale_globale,NORMALISATION_ECHELLE_K(K)); \ Eblock \ /* "KH" : definition normalisee de l'echelle globale, c'est-a-dire telle */ \ /* que l'unite soit alors le rapport des dimensions de l'image courante */ \ /* a celles de l'image de BASE (toutes celles-ci etant definies dans 'format'). */ #define DENORMALISATION_ECHELLES_XYZ(echelle) \ MIN3(_____lNORMALISE_OX(echelle) \ ,_____lNORMALISE_OY(echelle) \ ,_____lNORMALISE_OZ(echelle) \ ) \ /* Fonction de denormalisation des echelles sur les trois axes telle que l'unite y soit */ \ /* alors la meme, ce qui permet de faire tourner des figures sans que leur apparence ne */ \ /* change, meme si le format d'image n'est pas carre, et par exemple 'Pal'. Le programme */ \ /* 'v $xrd/Salomon.01$K' en donne un exemple d'utilisation... */ #define SXH(KX) \ Bblock \ EGAL(vecteurs_____scale_OX,DENORMALISATION_ECHELLES_XYZ(KX)); \ Eblock \ /* "X" : definition homothetique de l'echelle sur l'axe des 'X', */ #define SYH(KY) \ Bblock \ EGAL(vecteurs_____scale_OY,DENORMALISATION_ECHELLES_XYZ(KY)); \ Eblock \ /* "Y" : definition homothetique de l'echelle sur l'axe des 'Y', */ #define SZH(KZ) \ Bblock \ EGAL(vecteurs_____scale_OZ,DENORMALISATION_ECHELLES_XYZ(KZ)); \ Eblock \ /* "Z" : definition homothetique de l'echelle sur l'axe des 'Z'. */ #define TRX(angle) \ Bblock \ T_ROTATION_X(angle); \ Eblock \ /* "TRX(angle);" : rotation autour de l'axe des 'X' d'un angle exprime en radian. */ #define TRY(angle) \ Bblock \ T_ROTATION_Y(angle); \ Eblock \ /* "TRY(angle);" : rotation autour de l'axe des 'Y' d'un angle exprime en radian. */ #define TRZ(angle) \ Bblock \ T_ROTATION_Z(angle); \ Eblock \ /* "TRZ(angle);" : rotation autour de l'axe des 'Z' d'un angle exprime en radian. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E T O U T E S L E S F O N C T I O N S G R A P H I Q U E S P R I M I T I V E S : */ /* */ /*************************************************************************************************************************************/ #define GENERE__FonctionI_GRAPHIQUES(nom_de_la_fonction,dummy,instructions_graphiques) \ /* ATTENTION : le nom de la fonction est toujours suivi par la chaine de caracteres */ \ /* 'dummy'="PARENTHESES_DES_FONCTIONS" pour des raisons liees a la recuperation */ \ /* automatique des fichiers de declarations externes ; on trouvera donc : */ \ /* */ \ /* GENERE__FonctionI_GRAPHIQUES(nom_de_la_fonction,PARENTHESE_DES_FONCTIONS,instructions) */ \ /* */ \ DEFV(FonctionI,nom_de_la_fonction()) \ /* ATTENTION, il ne faut pas ecrire : */ \ /* */ \ /* DEFV(Common,DEFV(FonctionI,nom_de_la_fonction())) */ \ /* */ \ /* puisqu'en effet la directive 'Common' est utilisee lors de l'appel par : */ \ /* */ \ /* DEFV(Common,GENERE__FonctionI_GRAPHIQUES(...)) */ \ /* */ \ /* Actuellement cette redondance ne serait pas genante, mais plus tard... */ \ /*-----------------------------------------------------------------------------------------------------------------------------------*/ \ Bblock \ DEFV(Schar,INIS(DTb0(nom_de_la_Fg_courante),"nom_de_la_fonction")); \ /* Ceci a ete introduit le 20000104162210 afin que 'Linex' puisse editer le nom exact des */ \ /* fonction de type 'Fg*(...)' non implementees. */ \ INIT_ERROR; \ /*..............................................................................................................................*/ \ BLOC(instructions_graphiques); \ /* Instructions graphiques composant la fonction proprement dite. */ \ RETU_ERROR; \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E S T I O N D E S C O N T E X T E S : */ /* */ /* */ /* Utilisation : */ /* */ /* WCG(contexte); */ /* RCG(contexte); */ /* MCG(contexte_recepteur,contexte_emetteur); */ /* */ /* qui permettent respectivement d'ecrire */ /* un contexte ('WCG'), de lire un contexte */ /* ('RCG') et de copier ('mover') un contexte */ /* "emetteur" dans un contexte "recepteur" */ /* ('MCG'). */ /* */ /* On notera que 'vecteurs_____vector_3D' ne */ /* fait pas partie des contextes, et */ /* ce afin de pouvoir en joindre deux */ /* a deux... */ /* */ /*************************************************************************************************************************************/ #define WCG_ELEMENT_1(contexte,nom_de_l_element) \ Bblock \ EGAL(ASD1(contexte,nom_de_l_element),nom_de_l_element); \ Eblock #define WCG_ELEMENT_2(contexte,nom_de_l_element,element1) \ Bblock \ EGAL(ASD2(contexte,nom_de_l_element,element1),ASD1(nom_de_l_element,element1)); \ Eblock #define WCG_ELEMENT_3(contexte,nom_de_l_element,element1,element2) \ Bblock \ EGAL(ASD3(contexte,nom_de_l_element,element1,element2),ASD2(nom_de_l_element,element1,element2)); \ Eblock /* Mise dans un contexte d'un element unique. */ #define WCG(contexte) \ Bblock \ WCG_ELEMENT_2(contexte,vecteurs_____cursor_3D,x); \ WCG_ELEMENT_2(contexte,vecteurs_____cursor_3D,y); \ WCG_ELEMENT_2(contexte,vecteurs_____cursor_3D,z); \ WCG_ELEMENT_1(contexte,vecteurs_____scale_globale); \ WCG_ELEMENT_1(contexte,vecteurs_____scale_OX); \ WCG_ELEMENT_1(contexte,vecteurs_____scale_OY); \ WCG_ELEMENT_1(contexte,vecteurs_____scale_OZ); \ WCG_ELEMENT_1(contexte,vecteurs_____etat_trace); \ WCG_ELEMENT_1(contexte,vecteurs_____etat_anti_aliasing); \ WCG_ELEMENT_1(contexte,vecteurs_____niveau_minimal); \ WCG_ELEMENT_1(contexte,vecteurs_____niveau_maximal); \ WCG_ELEMENT_1(contexte,vecteurs_____pointilles); \ WCG_ELEMENT_1(contexte,vecteurs_____etat_matrix); \ WCG_ELEMENT_1(contexte,vecteurs_____rapport_de_zoom_cumule_courant); \ WCG_ELEMENT_1(contexte,vecteurs_____angle_de_rotation); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cx,cx); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cx,cy); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cx,cz); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cy,cx); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cy,cy); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cy,cz); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cz,cx); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cz,cy); \ WCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cz,cz); \ Eblock \ /* "WCG(contexte)" : sauvegarde du contexte courant dans le contexte nomme. */ \ /* ATTENTION : 'WCG' ne peut qu'etre un 'define' et non pas une */ \ /* 'fonction' parce que il a un argument ('nom du contexte') qui est valide */ \ /* a la compilation... */ #define RCG_ELEMENT_1(contexte,nom_de_l_element) \ Bblock \ EGAL(nom_de_l_element,ASD1(contexte,nom_de_l_element)); \ Eblock #define RCG_ELEMENT_2(contexte,nom_de_l_element,element1) \ Bblock \ EGAL(ASD1(nom_de_l_element,element1),ASD2(contexte,nom_de_l_element,element1)); \ Eblock #define RCG_ELEMENT_3(contexte,nom_de_l_element,element1,element2) \ Bblock \ EGAL(ASD2(nom_de_l_element,element1,element2),ASD3(contexte,nom_de_l_element,element1,element2)); \ Eblock /* Recuperation d'un element dans un contexte. */ #define RCG(contexte) \ Bblock \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cz,cz); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cz,cy); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cz,cx); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cy,cz); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cy,cy); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cy,cx); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cx,cz); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cx,cy); \ RCG_ELEMENT_3(contexte,vecteurs_____matrix_3D,cx,cx); \ RCG_ELEMENT_1(contexte,vecteurs_____angle_de_rotation); \ RCG_ELEMENT_1(contexte,vecteurs_____rapport_de_zoom_cumule_courant); \ RCG_ELEMENT_1(contexte,vecteurs_____etat_matrix); \ RCG_ELEMENT_1(contexte,vecteurs_____pointilles); \ RCG_ELEMENT_1(contexte,vecteurs_____niveau_maximal); \ RCG_ELEMENT_1(contexte,vecteurs_____niveau_minimal); \ RCG_ELEMENT_1(contexte,vecteurs_____etat_anti_aliasing); \ RCG_ELEMENT_1(contexte,vecteurs_____etat_trace); \ RCG_ELEMENT_1(contexte,vecteurs_____scale_OZ); \ RCG_ELEMENT_1(contexte,vecteurs_____scale_OY); \ RCG_ELEMENT_1(contexte,vecteurs_____scale_OX); \ RCG_ELEMENT_1(contexte,vecteurs_____scale_globale); \ RCG_ELEMENT_2(contexte,vecteurs_____cursor_3D,z); \ RCG_ELEMENT_2(contexte,vecteurs_____cursor_3D,y); \ RCG_ELEMENT_2(contexte,vecteurs_____cursor_3D,x); \ Eblock \ /* "RCG(contexte)" : restauration du contexte courant a partir du contexte nomme. */ \ /* ATTENTION : 'RCG' ne peut qu'etre un 'define' et non pas une */ \ /* fonction parce que il a un argument ('nom du contexte') qui est valide */ \ /* a la compilation... */ #define MCG_ELEMENT(contexte_recepteur,contexte_emetteur,nom_de_l_element) \ Bblock \ EGAL(ASD1(contexte_recepteur,nom_de_l_element),ASD1(contexte_emetteur,nom_de_l_element)); \ Eblock \ /* Deplacement d'un element d'un contexte "emetteur" vers un "recepteur". */ #define MCG(contexte_recepteur,contexte_emetteur) \ Bblock \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cz,cz)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cz,cy)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cz,cx)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cy,cz)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cy,cy)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cy,cx)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cx,cz)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cx,cy)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD2(vecteurs_____matrix_3D,cx,cx)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____etat_matrix); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____rapport_de_zoom_cumule_courant); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____angle_de_rotation); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____pointilles); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____niveau_maximal); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____niveau_minimal); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____etat_anti_aliasing); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____etat_trace); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____scale_OZ); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____scale_OY); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____scale_OX); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,vecteurs_____scale_globale); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD1(vecteurs_____cursor_3D,z)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD1(vecteurs_____cursor_3D,y)); \ MCG_ELEMENT(contexte_recepteur,contexte_emetteur,ASD1(vecteurs_____cursor_3D,x)); \ Eblock \ /* "MCG(contexte)" : deplacement d'un contexte "emetteur" vers un "recepteur". */ \ /* ATTENTION : 'MCG' ne peut qu'etre un 'define' et non pas une */ \ /* fonction parce que il a un argument ('nom du contexte') qui est valide */ \ /* a la compilation... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P R I M I T I V E S G R A P H I Q U E S D E C O N T R O L E : */ /* */ /* */ /* Utilisation : */ /* */ /* DO(nombre_d_iterations,BLOC(sequence_graphique)); */ /* CALL(BLOC(sequence_graphique)); */ /* */ /* On notera que dans 'DO' sont disponibles */ /* dans 'BLOC(sequence_graphique)' l'index */ /* de controle de la boucle 'Gindex' ainsi */ /* que sa valeur initiale 'Gpremier_index'. */ /* */ /*************************************************************************************************************************************/ #define Gpremier_index \ UN \ /* Valeur initiale de 'Gindex'. */ #define DO(nombre_d_iterations,instructions_graphiques) \ Bblock \ Test(IFGE(nombre_d_iterations,Gpremier_index)) \ Bblock \ DEFV(Int,INIT(Gindex,UNDEF)); \ /* Index de controle de la boucle d'iterations (disponible dans 'BLOC'. */ \ DoIn(Gindex,Gpremier_index,LSTX(Gpremier_index,nombre_d_iterations),I) \ Bblock \ BLOC(instructions_graphiques); \ /* La suite d'instructions graphiques est iteree... */ \ Eblock \ EDoI \ Eblock \ ATes \ Bblock \ Test(IZEQ(nombre_d_iterations)) \ Bblock \ /* Lorsque le nombre d'iterations est nul, la sequence graphique est sautee. */ \ Eblock \ ATes \ Bblock \ PRINT_ERREUR("un nombre d'iterations negatif est demande"); \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ /* "%" : iteration d'une sequence d'instructions graphiques. */ \ /* ATTENTION : 'DO' recevant en argument un 'BLOC' de */ \ /* primitives graphiques, il ne peut qu'etre un 'define' et non pas une */ \ /* 'fonction'... */ #define CALL(sequence_graphique) \ Bblock \ BLOC(sequence_graphique); \ Eblock \ /* "&" : appel d'une sequence graphique. */ \ /* ATTENTION : 'CALL' recevant en argument un 'BLOC' de */ \ /* primitives graphiques, il ne peut qu'etre un 'define' et non pas une */ \ /* 'fonction'... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* Q U E L Q U E S M A C R O S G R A P H I Q U E S D ' I N T E R E T G E N E R A L : */ /* */ /* */ /* Utilisation : */ /* */ /* DEBUT_CENTRAGE(BLOC(sequence_graphique)); */ /* CENTRAGE(BLOC(sequence_graphique)); */ /* MIRE_DE_BARRES(facteur_d_echelle_de_la_hauteur); */ /* HISTOGRAMME(facteur_d_echelle_de_la_hauteur,niveau_lisere); */ /* DECOUPAGE_EN_QUATRE(niveau_de_detourage,niveau_de_la_croix); */ /* */ /*************************************************************************************************************************************/ #define DEBUT_CENTRAGE(sequence_graphique) \ Bblock \ DEFV(pointF_3D,sauvegarde_vecteurs_____cursor_3D); \ /* Afin de memoriser le curseur initial. */ \ TRANSFERT_POINT_3D(sauvegarde_vecteurs_____cursor_3D,vecteurs_____cursor_3D); \ /* Memorisation du curseur graphique initial. */ \ CALS(FgMIN()); \ SET_TRACE(INTERDIT); \ \ Test(IL_FAUT(DEBUT_CENTRAGE_____compatibilite_20080909)) \ Bblock \ Eblock \ ATes \ Bblock \ EGAL(DRAW_____initialiser_les_extrema_de_X_Y_Z,VRAI); \ /* Afin de calculer les extrema des trois coordonnees dans 'sequence_graphique'... */ \ Eblock \ ETes \ \ BLOC(sequence_graphique); \ /* Ainsi, on regarde l'encombrement de la sequence, mais sans la tracer. */ \ CALS(FgMON()); \ /* Et on restaure les conditions de trace. */ \ \ Test(IL_FAUT(DEBUT_CENTRAGE_____compatibilite_20080909)) \ Bblock \ SET_CURSOR(SOUS(ASD1(sauvegarde_vecteurs_____cursor_3D,x) \ ,MOYS(ASD1(vecteurs_____cursor_3D,x),ASD1(sauvegarde_vecteurs_____cursor_3D,x)) \ ) \ ,SOUS(ASD1(sauvegarde_vecteurs_____cursor_3D,y) \ ,MOYS(ASD1(vecteurs_____cursor_3D,y),ASD1(sauvegarde_vecteurs_____cursor_3D,y)) \ ) \ ,SOUS(ASD1(sauvegarde_vecteurs_____cursor_3D,z) \ ,MOYS(ASD1(vecteurs_____cursor_3D,z),ASD1(sauvegarde_vecteurs_____cursor_3D,z)) \ ) \ ); \ /* Et on positionne le curseur... */ \ Eblock \ ATes \ Bblock \ SET_CURSOR(SOUS(ASD1(sauvegarde_vecteurs_____cursor_3D,x) \ ,MOYS(DRAW_____maximum_X,DRAW_____minimum_X) \ ) \ ,SOUS(ASD1(sauvegarde_vecteurs_____cursor_3D,y) \ ,MOYS(DRAW_____maximum_Y,DRAW_____minimum_Y) \ ) \ ,SOUS(ASD1(sauvegarde_vecteurs_____cursor_3D,z) \ ,MOYS(DRAW_____maximum_Z,DRAW_____minimum_Z) \ ) \ ); \ /* Cette nouvelle methode implantee le 20080909142220 garantit un centrage effectif */ \ /* selon les trois coordonnees puisqu'elle utilise les extrema reellement atteints */ \ /* lors de l'execution de 'sequence_graphique', alors que la methode anterieure ne */ \ /* connait que les coordonnees AVANT et APRES l'execution de 'sequence_graphique', */ \ /* celles-ci n'etant pas les extrema en general... */ \ Eblock \ ETes \ Eblock \ /* Macro de positionnement du curseur pour un texte a centrer. */ \ /* ATTENTION : 'DEBUT_CENTRAGE' recevant en argument un 'BLOC' de */ \ /* primitives graphiques, il ne peut qu'etre un 'define' et non pas une */ \ /* 'fonction'... */ #define CENTRAGE(sequence_graphique) \ Bblock \ CALS(FgMIC()); \ /* Sauvegarde du curseur initial dans la pile... */ \ DEBUT_CENTRAGE(BLOC(sequence_graphique)); \ /* Positionnement correct du curseur afin de centrer la chaine a tracer. */ \ BLOC(sequence_graphique); \ /* Et on execute la sequence graphique centree. */ \ CALS(FgMOC()); \ /* Et enfin, on restaure le curseur... */ \ Eblock \ /* Macro de centrage d'une chaine quelconque par rapport au curseur courant */ \ /* qui sera restaure tel quel a la fin du trace. */ \ /* ATTENTION : 'CENTRAGE' recevant en argument un 'BLOC' de */ \ /* primitives graphiques, il ne peut qu'etre un 'define' et non pas une */ \ /* 'fonction'... */ #define MIRE_Y_MINIMAL \ PAR1(HUIT) \ /* Pour fixer l'echelle verticale des mires de barres ; cette ECHELLE est */ \ /* prise IMPAIRE afin que si 'hauteur' est impaire, la hauteur reelle en */ \ /* nombre de points d'une barre verticale soit impaire, et qu'ainsi (suivant */ \ /* le principe des piquets et des intervalles...), PARTANT D'UNE ORDONNEE PAIRE */ \ /* (Y=Ymin par exemple), on arrive a une ordonnee impaire ; donc, si ensuite */ \ /* on procede a une REDUCTION DE MOITIE de l'image contenant la mire de barres, */ \ /* la mire sera correctement reduite, et ne "bavera" pas sur le voisinage... */ #define MIRE_Y_MAXIMAL \ DOUB(DOUB(DOUB(MIRE_Y_MINIMAL))) \ /* Pour fixer l'echelle verticale maximale des mires de barres. */ #define MIRE_Y_LISERE \ INTER_POINT \ /* Pour fixer la taille du lisere dispose au-dessus de l'histogramme. */ #define MIRE_DE_BARRES_GENERALE(facteur_d_echelle_de_la_hauteur,echelle_verticale,action_specifique_1,action_specifique_2) \ /* Le 20081006114949, 'hauteur' a ete change en 'facteur_d_echelle_de_la_hauteur' plus */ \ /* logique... */ \ Bblock \ DEFV(Float,INIT(Fniveau,FLOT(NIVR(NOIR)))); \ /* Niveau courant de trace, mais en flottant pour l'incrementer petit a petit... */ \ Test(IZGT(facteur_d_echelle_de_la_hauteur)) \ Bblock \ BLOC(action_specifique_1); \ \ CALS(FgMIC());CALS(FgPO()); \ /* Mise a l'origine. */ \ CALS(FgMIT());CALS(FgT_INIT()); \ /* Mise en place de la transformation unite. */ \ CALS(FgMIN()); \ \ SET_COULEURS(NOIR,NOIR); \ SET_TRACE(AUTORISE); \ SET_ANTI_ALIASING(FAUX); \ SET_POINTILLES(PAS_DE_POINTILLES); \ SET_NOIR_PLANCHER_DES_VECTEURS(NOIR); \ /* Mise en place des conditions de trace et du "noir-plancher" des vecteurs. */ \ \ CALS(FgMIK());CALS(FgMIX());CALS(FgMIY()); \ \ DO(dimX \ ,BLOC( \ Bblock \ CALS(FgMIC()); \ \ SET_COULEURS(NOIR,NIVA(Fniveau)); \ /* Choix de la couleur du trace de la barre courante. */ \ \ SKH(INTER_POINT); \ SY(echelle_verticale); \ /* Mise en place de l'echelle verticale, dans le 'DO' a cause de 'HISTOGRAMME'... */ \ /* ATTENTION : voir le commentaire qui suit... */ \ \ Test(IZGT(echelle_verticale)) \ /* Test introduit le 20081006141642 car il manquait. Or il est tres utile dans le cas ou */ \ /* 'Ihistogramme______hauteur_de_la_mire_de_barres_situee_a_la_base_de_l_histogramme' est */ \ /* nul et ou donc il est preferable que rien n'apparaisse... */ \ Bblock \ CALS(FgPA()); \ DO(facteur_d_echelle_de_la_hauteur,BLOC(CALS(FgM2());)); \ CALS(FgPB()); \ /* Trace d'une barre de la mire. */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ BLOC(action_specifique_2); \ /* Par exemple, generation d'un lisere pour 'HISTOGRAMME'. */ \ \ SK(INTER_POINT); \ SX(INTER_POINT); \ /* Mise en place de l'echelle horizontale. ATTENTION : a cause de la difference entre */ \ /* 'SKH(...)' (pour les echelles verticales) et 'SK(...)' (pour les echelles horizontales) */ \ /* on est oblige de faire plusieurs changements d'echelle par iteration... */ \ \ CALS(FgMOC());CALS(FgM1()); \ \ INCR(Fniveau,DIVI(FLOT(COULEURS),FLOT(dimX))); \ /* Changement de couleur... */ \ Eblock \ ) \ ); \ \ CALS(FgMOY());CALS(FgMOX());CALS(FgMOK()); \ /* Restauration de echelles. */ \ CALS(FgMON()); \ /* Restauration de l'etat de trace, des couleurs et du "noir-plancher" des vecteurs. */ \ CALS(FgMOT()); \ /* Restauration des transformations geometriques. */ \ CALS(FgMOC()); \ /* Et enfin, restauration du curseur... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Fonction d'edition d'une mire de barres generale en bas de l'image. */ #define MIRE_DE_BARRES(facteur_d_echelle_de_la_hauteur) \ /* Le 20081006114949, 'hauteur' a ete change en 'facteur_d_echelle_de_la_hauteur' plus */ \ /* logique... */ \ Bblock \ MIRE_DE_BARRES_GENERALE(facteur_d_echelle_de_la_hauteur,MIRE_Y_MINIMAL,BLOC(VIDE;),BLOC(VIDE;)) \ Eblock \ /* Fonction d'edition d'une petite mire de barres en bas de l'image. */ #define hauteur_de_la_mire_de_barres_situee_a_la_base_de_l_histogramme \ Ihistogramme______hauteur_de_la_mire_de_barres_situee_a_la_base_de_l_histogramme #define renormaliser_la_hauteur_de_la_mire_de_barres_par_rapport_au_maximum \ Ihistogramme______renormaliser_la_hauteur_de_la_mire_de_barres_par_rapport_au_maximum #define facteur_de_renormalisation_hauteur_mire_de_barres_par_rapport_au_maximum \ Ihistogramme______facteur_de_renormalisation_hauteur_mire_de_barres_par_rapport_au_maximum /* Afin de raccourcir la longueur de certaines lignes qui suivent... */ #define HISTOGRAMME(facteur_d_echelle_de_la_hauteur,niveau_lisere) \ /* Le 20081006114949, 'hauteur' a ete change en 'facteur_d_echelle_de_la_hauteur' plus */ \ /* logique (au niveau du nom...). */ \ Bblock \ MIRE_DE_BARRES_GENERALE \ (facteur_d_echelle_de_la_hauteur \ ,COND(EST_VALIDE(Ihistogramme_____etat) \ ,FLOT(ADD2(hauteur_de_la_mire_de_barres_situee_a_la_base_de_l_histogramme \ ,DIVZ(FLOT(MUL2(SOUS(MIRE_Y_MAXIMAL \ ,hauteur_de_la_mire_de_barres_situee_a_la_base_de_l_histogramme \ ) \ ,SOUS(ACCES_HISTOGRAMME(vecteurs_____niveau_maximal) \ ,SE22(Ihistogramme______nombre_de_points_minimal \ ,ZERO \ ) \ ) \ ) \ ) \ ,COND(IL_FAUT(renormaliser_la_hauteur_de_la_mire_de_barres_par_rapport_au_maximum) \ ,FLOT(SOUS(Ihistogramme______nombre_de_points_maximal \ ,SE22(Ihistogramme______nombre_de_points_minimal \ ,ZERO \ ) \ ) \ ) \ ,MUL2(facteur_de_renormalisation_hauteur_mire_de_barres_par_rapport_au_maximum \ ,FLOT(dimXY) \ ) \ ) \ ) \ ) \ ) \ ,hauteur_de_la_mire_de_barres_situee_a_la_base_de_l_histogramme \ ) \ /* Le 20081006105148 'MIRE_Y_MINIMAL' fut remplace par 'Ihistogramme______hauteur_de_la...'. */ \ /* */ \ /* Les 'FLOT(...)'s furent introduits le 20081006143514 pour ameliorer la precision et */ \ /* visualiser malgre tout les valeurs faibles de 'ACCES_HISTOGRAMME(...)'... */ \ /* */ \ /* Le 20081007181725, les 'SE22(...)'s furent introduits afin d'utiliser 'ZERO' plutot */ \ /* que 'Ihistogramme______nombre_de_points_minimal', tout en laissant la trace de ce */ \ /* dernier. Cela s'est vu a cette date avec : */ \ /* */ \ /* Pal */ \ /* */ \ /* $xci/lineaire$X \ */ \ /* A=1 B=0 \ */ \ /* standard=FAUX \ */ \ /* $formatI | \ */ \ /* $xci/acces$X \ */ \ /* standard=FAUX zero=FAUX \ */ \ /* $formatI | \ */ \ /* $xci/egaliseH.01$X \ */ \ /* plat=VRAI \ */ \ /* $formatI | \ */ \ /* $xci/histogramme$X \ */ \ /* R=$xTV/HISTOGRAMME \ */ \ /* $formatI */ \ /* */ \ /* donnant un histogramme ou manquait a droite de nombreuses barres blanches correspondant */ \ /* aux populations 1751, soit 'Ihistogramme______nombre_de_points_minimal' (a gauche, pour */ \ /* les populations 1752, cela marchait bien evidemment puisqu'il s'agissait alors de */ \ /* 'Ihistogramme______nombre_de_points_maximal'). */ \ ,BLOC( \ Bblock \ Test(EST_INVALIDE(Ihistogramme_____etat)) \ Bblock \ PRINT_ERREUR("l'histogramme est invalide"); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ) \ ,BLOC( \ Bblock \ CALS(FgMIY()); \ /* Sauvegarde de l'echelle verticale. */ \ SY(MIRE_Y_LISERE); \ /* Choix de l'epaisseur du lisere. */ \ CALS(FgMIN()); \ /* Sauvegarde des conditions de trace. */ \ SET_COULEURS(niveau_lisere,niveau_lisere); \ /* Choix du niveau de trace du lisere. */ \ CALS(FgPA()); \ CALS(FgM2());CALS(FgPB()); \ /* Le lisere consiste d'abord en un point noir trace au sommet de la barre courante ; c'est */ \ /* lui que l'on trace ici... */ \ \ Test(IFGE(vecteurs_____scale_globale,INTER_POINT)) \ Bblock \ CALS(FgM1()); \ CALS(FgPB()); \ SET_CURSOR(ASD1(vecteurs_____cursor_3D,x) \ ,_____cNORMALISE_OY(Yorigine) \ ,_____cNORMALISE_OZ(Zorigine) \ ); \ CALS(FgPB()); \ /* Le lisere consiste ensuite en une barre verticale noire dont la hauteur est celle de la */ \ /* barre de couleur precedente (plus le point noir), et qui apparait immediatement a la */ \ /* droite de cette derniere. On notera que l'on peut proceder ainsi puisque le trace des */ \ /* barres de couleur va de la gauche vers la droite ; les barres noires voient donc en */ \ /* general une partie de leurs points effaces par la barre en couleurs suivante (en */ \ /* particulier, les points du bas). Ceci explique enfin pourquoi on ne trace pas de lisere */ \ /* vertical a gauche... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ CALS(FgMON()); \ /* Restauration des conditions de trace. */ \ CALS(FgMOY()); \ /* Restauration de l'echelle verticale. */ \ Eblock \ ) \ ) \ Eblock \ /* Fonction d'edition d'une mire de barres de la forme de l'histogramme courant. */ #define DECOUPAGE_EN_QUATRE(niveau_de_detourage,niveau_de_la_croix) \ /* Cette procedure decoupe l'image en quatre parties par une croix detouree. */ \ Bblock \ CALS(FgMIK());CALS(FgMIX());CALS(FgMIY());CALS(FgMIZ()); \ /* Sauvegarde des echelles. */ \ SK(INTER_POINT); \ /* Definition de l'echelle globale. */ \ SX(MOIT(dimX)); \ /* Definition de l'echelle sur l'axe des 'X'. */ \ SY(MOIT(dimY)); \ /* Definition de l'echelle sur l'axe des 'Y'. */ \ SZ(INTER_POINT); \ /* Definition de l'echelle sur l'axe des 'Z'. */ \ CALS(FgMIN()); \ /* Sauvegarde des conditions de trace. */ \ SET_ANTI_ALIASING(FAUX); \ SET_POINTILLES(PAS_DE_POINTILLES); \ SET_COULEURS(NOIR,niveau_de_detourage); \ CALS(FgMIC()); \ /* Sauvegarde du point courant. */ \ CALS(FgMIT());CALS(FgT_INIT()); \ /* Mise en place de la transformation unite. */ \ CALS(FgPO());CALS(FgM1()); \ CALS(FgMIX()); \ SX(INTER_POINT); \ /* Afin d'effectuer un deplacement minimal... */ \ CALS(FgM3()); \ DO(TROIS,BLOC(CALS(FgMIC());CALS(FgPA());CALS(FgM2());CALS(FgM2());CALS(FgPB());CALS(FgMOC());CALS(FgM1());)); \ /* Detourage vertical, */ \ CALS(FgMOX()); \ CALS(FgPO());CALS(FgM2()); \ CALS(FgMIY()); \ SY(INTER_POINT); \ /* Afin d'effectuer un deplacement minimal... */ \ CALS(FgM4()); \ DO(TROIS,BLOC(CALS(FgMIC());CALS(FgPA());CALS(FgM1());CALS(FgM1());CALS(FgPB());CALS(FgMOC());CALS(FgM2());)); \ /* Detourage horizontal, */ \ CALS(FgMOY()); \ /* Detourage autour de la croix de decoupage en quatre de l'image. */ \ SET_COULEURS(NOIR,niveau_de_la_croix); \ CALS(FgPO());CALS(FgM1()); \ CALS(FgPA());CALS(FgM2());CALS(FgM2());CALS(FgPB()); \ /* Bras vertical, */ \ CALS(FgPO());CALS(FgM2()); \ CALS(FgPA());CALS(FgM1());CALS(FgM1());CALS(FgPB()); \ /* Bras horizontal, */ \ /* trace d'une croix de separation de l'image en quatre parties ; le */ \ /* detourage est fait avant le trace de la croix afin de resoudre */ \ /* correctement le probleme de l'intersection. */ \ CALS(FgMOT()); \ /* Restauration des transformations geometriques. */ \ CALS(FgMOC()); \ /* Restauration du point courant. */ \ CALS(FgMON()); \ /* Restauration des conditions de trace. */ \ CALS(FgMOZ());CALS(FgMOY());CALS(FgMOX());CALS(FgMOK()); \ /* Restauration des echelles. */ \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P O U R L ' A C C E S R A P I D E S A U X P R I M I T I V E S L E S P L U S U S I T E E S : */ /* */ /* */ /* Rappel sur les orientations : */ /* */ /* */ /* Y ^ */ /* | */ /* | */ /* | */ /* | */ /* | / */ /* g 2 / */ /* | / */ /* | g 6 */ /* | / */ /* | / */ /* |/ */ /* -------- g3 --------O-------- g1 --------> */ /* /| X */ /* / | */ /* / | */ /* g 5 | */ /* / | */ /* / g 4 */ /* Z / | */ /* + | */ /* | */ /* | */ /* | */ /* */ /* */ /*************************************************************************************************************************************/ #define gO \ Bblock \ CALS(FgPO()); \ Eblock /* Introduit le 20220315164349, on ne peut plus tardivement... */ #define gA \ Bblock \ CALS(FgPA()); \ Eblock #define gS \ Bblock \ CALS(FgPS()); \ Eblock /* Introduit le 20120129102624, on ne peut plus tardivement... */ #define gB \ Bblock \ CALS(FgPB()); \ Eblock #define g1 \ Bblock \ CALS(FgM1()); \ Eblock #define g2 \ Bblock \ CALS(FgM2()); \ Eblock #define g3 \ Bblock \ CALS(FgM3()); \ Eblock #define g4 \ Bblock \ CALS(FgM4()); \ Eblock #define g5 \ Bblock \ CALS(FgM5()); \ Eblock #define g6 \ Bblock \ CALS(FgM6()); \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D O N N E E S D E T R A N S F O R M A T I O N G E O M E T R I Q U E 3 D : */ /* */ /*************************************************************************************************************************************/ #define gTRANSFORMATION_GEOMETRIQUE_3D_Fxyz(matrix_3D,fx,fy,fz,cxyz,translation_OXYZ) \ LIN3(ASD2(matrix_3D,cxyz,cx),fx \ ,ASD2(matrix_3D,cxyz,cy),fy \ ,ASD2(matrix_3D,cxyz,cz),fz \ ,translation_OXYZ \ ) \ /* Introduit le 20080731123051 pour une eventuelle utilisation a venir dans les */ \ /* deux fonctions 'v $xiipf/fonction.2$FON FFload_point_coordonnees_01' et dans */ \ /* 'v $xiipf/fonction.2$FON FFAload_point_coordonnees_01'... */ #define TRANSFORMATION_GEOMETRIQUE_3D_Fxyz(fx,fy,fz,cxyz,translation_OXYZ) \ gTRANSFORMATION_GEOMETRIQUE_3D_Fxyz(vecteurs_____matrix_3D \ ,fx,fy,fz \ ,cxyz \ ,MUL2(vecteurs_____rapport_de_zoom_cumule_courant,translation_OXYZ) \ ) #define TRANSFORMATION_GEOMETRIQUE_3D_Fx(fx,fy,fz,translation_OX) \ TRANSFORMATION_GEOMETRIQUE_3D_Fxyz(fx,fy,fz,cx,translation_OX) #define TRANSFORMATION_GEOMETRIQUE_3D_Fy(fx,fy,fz,translation_OY) \ TRANSFORMATION_GEOMETRIQUE_3D_Fxyz(fx,fy,fz,cy,translation_OY) #define TRANSFORMATION_GEOMETRIQUE_3D_Fz(fx,fy,fz,translation_OZ) \ TRANSFORMATION_GEOMETRIQUE_3D_Fxyz(fx,fy,fz,cz,translation_OZ) #define NE_PAS_TRANSLATER_LORS_DE_TRANSFORMATION_GEOMETRIQUE_3D_Fxyz \ FZERO \ /* Valeur a donner a 'translation_OXYZ' pour ne pas faire de translation... */