/*************************************************************************************************************************************/
/* */
/* 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... */