/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S D E L A V I S U A L I S A T I O N D ' U N E S P H E R E : */
/* */
/* */
/* Author of '$xrv/champs_5.1C$I' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 1993??????????). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C O M P A T I B I L I T E : */
/* */
/*************************************************************************************************************************************/
#define RANDOMISER_LA_VISUALISATION_DES_PARTICULES \
LUNDEF
DEFV(Local,DEFV(Logical,INIT(randomiser_la_visualisation_des_particules,RANDOMISER_LA_VISUALISATION_DES_PARTICULES)));
#define RAYON_INTERIEUR_RELATIF_D_UNE_PARTICULE \
FLOT__UNDEF
DEFV(Local,DEFV(Float,INIT(rayon_interieur_relatif_d_une_particule,RAYON_INTERIEUR_RELATIF_D_UNE_PARTICULE)));
#define RAYON_EXTERIEUR_RELATIF_D_UNE_PARTICULE \
FLOT__UNDEF
DEFV(Local,DEFV(Float,INIT(rayon_exterieur_relatif_d_une_particule,RAYON_EXTERIEUR_RELATIF_D_UNE_PARTICULE)));
/* Donnees conservees pour des raisons de compatibilite, d'ou les valeurs implicites de */
/* type 'UNDEF', puisqu'elles ne servent plus a rien... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C O M P T A G E D E S S P H E R E S " E N - E C R A N " : */
/* */
/*************************************************************************************************************************************/
DEFV(Local,DEFV(Int,INIT(compteur_des_spheres_dans_l_image,UNDEF)));
/* Compteur des spheres visibles dans l'image courante. ATTENTION, on notera deux choses */
/* importantes : */
/* */
/* 1-l'intialisation de 'compteur_des_spheres_dans_l_image' est a la charge de quelqu'un */
/* d'autre (par exemple 'VISUALISATION_D_UNE_LISTE_DE_POINTS_AVEC_RENORMALISATION(...)' */
/* dans 'v $xrv/champs_5.12$I'). */
/* */
/* 2-une sphere dans l'image mais cachee entierement par une autre (via le 'Z-Buffer') */
/* sera malheureusement comptabilisee... */
/* */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E L A S P E C U L A R I T E D E L ' E C L A I R A G E : */
/* */
/*************************************************************************************************************************************/
#define INTENSITE_SPECULAIRE \
QUATRE
DEFV(Local,DEFV(Float,INIT(intensite_speculaire,FLOT(INTENSITE_SPECULAIRE))));
/* Constante destinee a accentuer le caractere speculaire de l'eclairage... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E L A T R A N S P A R E N C E : */
/* */
/*************************************************************************************************************************************/
#define COEFFICIENT_DE_TRANSPARENCE \
FZERO
DEFV(Local,DEFV(Float,INIT(coefficient_de_transparence,COEFFICIENT_DE_TRANSPARENCE)));
/* Coefficient de transparence : la valeur 0 indique une absence de transparence et la */
/* valeur 1, une transparence maximale... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D U B O R D A P P A R E N T D E S S P H E R E S : */
/* */
/*************************************************************************************************************************************/
#TestADef store_sphere__ANTI_ALIASING_____COMPATIBILITE_20060426 \
FAUX
DEFV(Local,DEFV(Logical,INIT(store_sphere__anti_aliasing_____compatibilite_20060426
,store_sphere__ANTI_ALIASING_____COMPATIBILITE_20060426
)
)
);
/* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */
/* du 20060426140714 (voir '$xrv/champs_5.1C$I distance_courante_au_Z_Buffer'...). */
#define DEFINITION_DU_CONTOUR_APPARENT_DE_LA_SPHERE \
FU \
/* Constante destinee a definir ce qui est a l'interieur d'un contour apparent : l'interieur */ \
/* correspond aux valeurs de 'equation_representative_du_contour' inferieures a cette */ \
/* constante. */
#define MINIMUM_DE_L_EPAISSEUR_DE_L_INTERSECTION \
FRA8(epaisseur_de_la_couronne_d_anti_aliasing_effective)
#define MAXIMUM_DE_L_EPAISSEUR_DE_L_INTERSECTION \
FRA2(epaisseur_de_la_couronne_d_anti_aliasing_effective)
#define EPAISSEUR_DE_L_INTERSECTION \
BARY(MAXIMUM_DE_L_EPAISSEUR_DE_L_INTERSECTION \
,MINIMUM_DE_L_EPAISSEUR_DE_L_INTERSECTION \
,HOMO(DIVI(ASD1(vecteur_normal_approxime,dz),RACX(carre_de_la_norme_du_vecteur_normal_approxime)) \
,FZERO,FU \
,COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE \
) \
) \
/* Definition de la distance-seuil en deca de laquelle on decrete que deux spheres forment */ \
/* a cet endroit leur intersection. On notera que l'on prend en compte ici l'inclinaison */ \
/* de la normale par rapport a l'axe 'OZ'. Ainsi plus une normale est inclinee par rapport */ \
/* a 'OZ', plus 'EPAISSEUR_DE_L_INTERSECTION' est important et proche de son maximum, et */ \
/* inversement, plus une normale est proche de 'OZ', plus 'EPAISSEUR_DE_L_INTERSECTION' */ \
/* est faible et proche de son minimum... */ \
/* */ \
/* Le 20060224114454, 'epaisseur_de_la_couronne_d_anti_aliasing_effective' a remplace */ \
/* 'epaisseur_de_la_couronne_d_anti_aliasing'... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* G E S T I O N D E S N I V E A U X ' RVB ' D E S P O I N T S : */
/* */
/*************************************************************************************************************************************/
#define FORCER_LE_NIVEAU_ANTERIEUR \
FAUX
DEFV(Local,DEFV(Logical,INIT(forcer_le_niveau_anterieur,FORCER_LE_NIVEAU_ANTERIEUR)));
#define NIVEAU_ANTERIEUR_A_FORCER \
NOIR
DEFV(Local,DEFV(genere_p,INIT(niveau_anterieur_ROUGE_a_forcer,NIVEAU_ANTERIEUR_A_FORCER)));
DEFV(Local,DEFV(genere_p,INIT(niveau_anterieur_VERTE_a_forcer,NIVEAU_ANTERIEUR_A_FORCER)));
DEFV(Local,DEFV(genere_p,INIT(niveau_anterieur_BLEUE_a_forcer,NIVEAU_ANTERIEUR_A_FORCER)));
/* Introduit le 20160806110540, au cas ou... */
#TestADef EDITER_LES_MESSAGES_DE_MAUVAIS_ENCADREMENT_DES_NIVEAUX_INTERPOLES \
FAUX
DEFV(Local,DEFV(Logical,INIT(editer_les_messages_de_mauvais_encadrement_des_niveaux_interpoles
,EDITER_LES_MESSAGES_DE_MAUVAIS_ENCADREMENT_DES_NIVEAUX_INTERPOLES
)
)
);
/* Introduit le 20130415134650 pour 'v $xiirv/.TREE.11.$U 20130415134953'... */
/* */
/* Le 20181227110537, le '#define' est devenu un '#TestADef' pour etre redefini dans */
/* 'v $xrv/particule.10$K EDITER_LES_MESSAGES_DE_MAUVAIS_ENCADREMENT_DES_NIVEAUX_INTERPOLES' */
/* lors de la mise au point de 'v $xrrv/CARR.35' avec "_____DistanceMini=0.050"... */
/* */
/* Le 20200325144451, la valeur par defaut est devenue 'FAUX' car, en effet, ce message ne */
/* sert a rien... */
#define niveau_RVB(niveau_RVB_du_point,nbRVB,ncRVB,iRVB,niveau_RVB_anterieur_eventuel_a_forcer) \
Bblock \
DEFV(genere_p,INIT(niveau_anterieur_du_point \
,COND(IL_FAUT(forcer_le_niveau_anterieur) \
,niveau_RVB_anterieur_eventuel_a_forcer \
,load_point_valide(iRVB,INTE(ASD1(point_2Dt_courant,x)),INTE(ASD1(point_2Dt_courant,y))) \
) \
) \
); \
/* Definition du niveau anterieur du point(X,Y), et ce afin d'aider le compilateur... */ \
DEFV(genere_p,INIT(niveau_posterieur_du_point \
,GENP(TRON(NIVA(HOMO(modulation_d_eclairement \
,COORDONNEE_BARYCENTRIQUE_MINIMALE \
,COORDONNEE_BARYCENTRIQUE_MAXIMALE \
,MUL2(modulation_courante_de_la_luminance \
,FLOT(NIVR(nbRVB)) \
) \
,MUL2(modulation_courante_de_la_luminance \
,FLOT(NIVR(ncRVB)) \
) \
) \
) \
,FLOT(NOIR_PLANCHER_SUBSTITUTION) \
,FLOT__BLANC \
) \
) \
) \
); \
/* Enfin, calcul du niveau du point courant. On notera la modulation de la luminance qui */ \
/* permet d'une part de simuler des fondus a l'ouverture et a la fermeture, et d'autre part */ \
/* de compenser la faible luminosite de certaines images... */ \
\
EGAL(niveau_posterieur_du_point \
,NIVA(vBARY(NIVR(niveau_posterieur_du_point) \
,NIVR(niveau_anterieur_du_point) \
,coefficient_de_transparence \
) \
) \
); \
/* Gestion de l'eventuelle transparence (cas ou le coefficient est non nul...). */ \
\
Test(IFNE(niveau_anterieur_du_point,niveau_posterieur_du_point)) \
Bblock \
EGAL(niveau_RVB_du_point \
,NIVA(vBARY(NIVR(niveau_anterieur_du_point) \
,NIVR(niveau_posterieur_du_point) \
,correction_d_anti_aliasing_au_bord \
) \
) \
); \
/* Enfin, prise en compte de la correction d'anti-aliasing ; le niveau a utiliser est donc */ \
/* interpole entre ce qui a ete calcule ('niveau_RVB_du_point') et ce qui se trouvait */ \
/* la avant ('load_point_valide(...)'), de facon a ce que tres pres du bord, le contenu */ \
/* anterieur soit preponderant : */ \
/* */ \
/* niveau = h.niveau + (1-h).anterieur */ \
/* */ \
/* ou 'h' designe 'correction_d_anti_aliasing_au_bord'. */ \
Eblock \
ATes \
Bblock \
EGAL(niveau_RVB_du_point \
,niveau_posterieur_du_point \
); \
/* Cas ou une correction n'est pas necessaire (ce test est surtout la pour eviter des */ \
/* problemes de "rebond" des splines...). */ \
Eblock \
ETes \
\
Test(NINCff(niveau_RVB_du_point,niveau_anterieur_du_point,niveau_posterieur_du_point)) \
Bblock \
Test(IL_FAUT(editer_les_messages_de_mauvais_encadrement_des_niveaux_interpoles)) \
/* Test introduit le 20130415134650... */ \
Bblock \
PRINT_ERREUR("un niveau interpole est mal encadre"); \
CAL1(Prer1(" niveau anterieur......................... = %d\n",niveau_anterieur_du_point)); \
CAL1(Prer1(" niveau posterieur calcule................ = %d\n",niveau_posterieur_du_point)); \
CAL1(Prer1(" niveau corrige (anti-aliasing)........... = %d\n",niveau_RVB_du_point)); \
CAL1(Prer1(" parametre d'interpolation (anti-aliasing) = %g\n",correction_d_anti_aliasing_au_bord)); \
/* Le 20081227102353, les messages precedents ont ete modifies afin d'ameliorer leur */ \
/* comprehension : */ \
/* */ \
/* "niveau calcule" --> "niveau posterieur calcule" */ \
/* "niveau corrige" --> "niveau corrige (anti-aliasing)" */ \
/* "parametre d'interpolation" --> "parametre d'interpolation (anti-aliasing)" */ \
/* */ \
/* lorsqu'ils sortent... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
EGAL(niveau_RVB_du_point \
,NIVA(MOYE(NIVR(niveau_anterieur_du_point) \
,NIVR(niveau_posterieur_du_point) \
) \
) \
); \
/* Et on corrige la correction... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Calcul d'une des composantes du niveau du point courant. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S C O O R D O N N E E S C U R V I L I G N E S D E L A S P H E R E : */
/* */
/*************************************************************************************************************************************/
#define MINIMUM_DE_THETA \
FZERO
#define MAXIMUM_DE_THETA \
CERCLE_TRIGONOMETRIQUE
#define PAS_DE_THETA \
FRA4(FRA10(SOUS(MAXIMUM_DE_THETA,MINIMUM_DE_THETA)))
DEFV(Local,DEFV(Float,INIT(pas_de_theta_de_la_sphere,PAS_DE_THETA)));
/* Definition de la coordonnee curviligne 'theta'. Avant le 19991216115606 'PAS_DE_THETA' */
/* etait defini avec 'FRA2(FRA10(...))'. */
#define MINIMUM_DE_PHI \
FZERO
#define MAXIMUM_DE_PHI \
PI
#define PAS_DE_PHI \
FRA2(FRA10(SOUS(MAXIMUM_DE_PHI,MINIMUM_DE_PHI)))
DEFV(Local,DEFV(Float,INIT(pas_de_phi_de_la_sphere,PAS_DE_PHI)));
/* Definition de la coordonnee curviligne 'phi'. Avant le 19991216115606 'PAS_DE_PHI' */
/* etait defini avec 'FRA1(FRA10(...))'. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C H O I X E N T R E V I S U A L I S E R C O M P L E T E M E N T U N E S P H E R E */
/* O U N E V I S U A L I S E R Q U E S O N C E N T R E A P P A R E N T : */
/* */
/*************************************************************************************************************************************/
#define NE_VISUALISER_QUE_LE_CENTRE_DES_SPHERES \
FAUX
DEFV(Local,DEFV(Logical,INIT(ne_visualiser_que_le_centre_des_spheres,NE_VISUALISER_QUE_LE_CENTRE_DES_SPHERES)));
/* Indicateur precisant si l'on ne visualise que le centre des spheres ('VRAI') ou bien les */
/* spheres dans leur integralite ('FAUX'). Ceci a ete introduit le 19980907124444 pour */
/* faciliter le comptage des particules dans 'v $xrk/rdn_walk.41$K' lorsque les particules */
/* sont bidimensionnelles... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* E Q U A T I O N D E L A S P H E R E E T P R O J E C T I O N : */
/* */
/*************************************************************************************************************************************/
#define L_ESPACE_DE_L_IMAGE_EST_UN_TORE_SELON_OX \
FAUX
#define L_ESPACE_DE_L_IMAGE_EST_UN_TORE_SELON_OY \
FAUX
DEFV(Local,DEFV(Logical,INIT(l_espace_de_l_image_est_un_tore_selon_OX,L_ESPACE_DE_L_IMAGE_EST_UN_TORE_SELON_OX)));
DEFV(Local,DEFV(Logical,INIT(l_espace_de_l_image_est_un_tore_selon_OY,L_ESPACE_DE_L_IMAGE_EST_UN_TORE_SELON_OY)));
/* Ceci fut introduit le 20090816174959 de facon experimentale et approximative, en */
/* notant que cela n'a de sens que si 'IL_FAUT(ne_visualiser_que_le_centre_des_spheres)'... */
DEFV(Local,DEFV(pointF_3D,centre_3D_de_la_sphere));
DEFV(Local,DEFV(pointF_2D,centre_2D_de_la_sphere));
/* Definition du centre de la sphere dans l'espace tridimensionnel, et sa projection. */
DEFV(Local,DEFV(pointF_3D,point_3D_courant));
DEFV(Local,DEFV(pointF_2D,point_2D_courant));
DEFV(Local,DEFV(pointF_2D,point_2Dt_courant));
/* Definition du point courant de la sphere dans l'espace bidimensionnel, et sa projection. */
DEFV(Local,DEFV(deltaF_3D,vecteur_normal));
/* --> */
/* Vecteur normal N au point courant de la sphere. */
DEFV(Local,DEFV(Float,INIT(minimum_des_coordonnees_X_projetees,F_INFINI)));
DEFV(Local,DEFV(Float,INIT(maximum_des_coordonnees_X_projetees,F_MOINS_L_INFINI)));
DEFV(Local,DEFV(Float,INIT(minimum_des_coordonnees_Y_projetees,F_INFINI)));
DEFV(Local,DEFV(Float,INIT(maximum_des_coordonnees_Y_projetees,F_MOINS_L_INFINI)));
/* Introduit le 20180531100339 pour faciliter ulterieurement une aide au cadrage des images. */
/* On notera que ces extrema peuvent evidemment etre hors-ecran... */
#define DEFINITION_DU_POINT_3D_COURANT_SUR_LA_SPHERE(point_3D_courant,rayon,theta,phi) \
Bblock \
INITIALISATION_ACCROISSEMENT_3D(vecteur_normal \
,Xcartesienne_3D(rayon,theta,phi) \
,Ycartesienne_3D(rayon,theta,phi) \
,Zcartesienne_3D(rayon,theta,phi) \
); \
INITIALISATION_POINT_3D(point_3D_courant \
,ADD2(ASD1(centre_3D_de_la_sphere,x),ASD1(vecteur_normal,dx)) \
,ADD2(ASD1(centre_3D_de_la_sphere,y),ASD1(vecteur_normal,dy)) \
,ADD2(ASD1(centre_3D_de_la_sphere,z),ASD1(vecteur_normal,dz)) \
); \
Eblock \
/* Calcul des coordonnees du point courant tridimensionnel de la sphere. */
#define EDITER_LES_EXTREMA_DES_COORDONNEES_X_ET_Y_PROJETEES \
FAUX
DEFV(Local,DEFV(Logical,INIT(editer_les_extrema_des_coordonnees_x_et_y_projetees
,EDITER_LES_EXTREMA_DES_COORDONNEES_X_ET_Y_PROJETEES
)
)
);
/* Introduit le 20180531101315 pour aider au cadrage bi-dimensionnel et transfere ici */
/* le 20180601081321 depuis 'v $xrv/champs_5.12$I 20180601081333'... */
DEFV(Local,DEFV(Float,INIT(translation_X_des_coordonnees_projetees,FZERO)));
DEFV(Local,DEFV(Float,INIT(translation_Y_des_coordonnees_projetees,FZERO)));
/* Introduit le 20180531131658 pour faciliter le centrage des images (donc apres */
/* projection des points tridimensionnels... */
#define DEFINITION_DU_POINT_2D_COURANT_SUR_LA_SPHERE(point_2D,point_3D) \
Bblock \
INITIALISATION_POINT_2D(point_2D \
,F__cDENORMALISE_OX(ADD2(Projection_OX(ASD1(point_3D,x) \
,ASD1(point_3D,y) \
,ASD1(point_3D,z) \
) \
,translation_X_des_coordonnees_projetees \
) \
) \
,F__cDENORMALISE_OY(ADD2(Projection_OY(ASD1(point_3D,x) \
,ASD1(point_3D,y) \
,ASD1(point_3D,z) \
) \
,translation_Y_des_coordonnees_projetees \
) \
) \
); \
/* ATTENTION, on notera que l'on ne fait pas : */ \
/* */ \
/* Test(EST_FAUX(LE_POINT_EST_INVISIBLE_OU_INDETERMINE(ASD1(point_3D,x) */ \
/* ,ASD1(point_3D,y) */ \
/* ,ASD1(point_3D,z) */ \
/* ) */ \
/* ) */ \
/* ) */ \
/* */ \
/* afin d'alleger le code qui suit. Tout repose donc sur l'hypothese que tous les points */ \
/* de la sphere sont visibles, en esperant que '$xrv/attractor.16$I' ait fait un tri */ \
/* correct dans 'MEMORISATION_DU_POINT_COURANT(...)'. */ \
/* */ \
/* Je note le 20090225105255 que c'est l'existence des "boites" {{minX,maxX}x{minY,maxY}}} */ \
/* et {{VminX,VmaxX}x{VminY,VmaxY}} qui interdit la possibilite de gerer, en option, l'image */ \
/* {iR,iV,iB} comme un tore via les fonctions {MOFX(...),MOFY(...)}. Si l'image {iR,iV,iB} */ \
/* etait un tore, alors les points d'image constituant la sphere courante pourrait former */ \
/* un ensemble non connexe, lorsque cette sphere est "a cheval" sur un ou plusieurs bords */ \
/* de l'image, ce qui est donc evidemment incompatible avec ces "boites". Cela fut verifie */ \
/* le 20090812171720 en introduisant ci-apres (et conditionnellement) : */ \
/* */ \
/* EGAL(ASD1(point_2D,x),MOFX(ASD1(point_2D,x))); */ \
/* EGAL(ASD1(point_2D,y),MOFY(ASD1(point_2D,y))); */ \
/* */ \
/* et effectivement le fonctionnement (teste avec 'v $xrs/cylindre.11$K' en tracant un */ \
/* cylindre incline ("ROTATION_OZ=1 ROTATION_OY=$pis2") etait incorrect pour les "fameux" */ \
/* points "a cheval". A cette date, je ne vois pas comment corriger cela. Finalement, le */ \
/* 20090814153037 j'essaye dans le cas 'IL_FAUT(ne_visualiser_que_le_centre_des_spheres)' */ \
/* et uniquement dans ce cas. Malheureusement cela ne marche pas mieux car, en effet */ \
/* le 'centre_2D_de_la_sphere' est calculee par la suite comme etant le centre de la */ \
/* boite {{VminX,VmaxX}x{VminY,VmaxY}} ; celle-ci etant mauvaise aux voisinages des bords, */ \
/* il en est de meme du centre de la sphere (trace alors tout seul en general a mi-distance */ \
/* des bords de l'image. Je renonce donc a cette solution "degradee" (valable donc */ \
/* uniquement dans le cas 'IL_FAUT(ne_visualiser_que_le_centre_des_spheres)'...). */ \
\
Test(IL_FAUT(editer_les_extrema_des_coordonnees_x_et_y_projetees)) \
/* Test d'optimisation de performances introduit le 20180601080652... */ \
Bblock \
EGAL(minimum_des_coordonnees_X_projetees,MIN2(minimum_des_coordonnees_X_projetees,ASD1(point_2D,x))); \
EGAL(maximum_des_coordonnees_X_projetees,MAX2(maximum_des_coordonnees_X_projetees,ASD1(point_2D,x))); \
EGAL(minimum_des_coordonnees_Y_projetees,MIN2(minimum_des_coordonnees_Y_projetees,ASD1(point_2D,y))); \
EGAL(maximum_des_coordonnees_Y_projetees,MAX2(maximum_des_coordonnees_Y_projetees,ASD1(point_2D,y))); \
/* Introduit le 20180531100339 pour faciliter ulterieurement un cadrage automatique... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Calcul des coordonnees du point courant bidimensionnel de la sphere. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C H O I X E N T R E L E M O D E R A P I D E E T L E M O D E L E N T : */
/* */
/*************************************************************************************************************************************/
/* Ce mode qui fonctionne mal en realite a ete supprime le 20090816110534... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* S I M U L A T I O N D E L A V I S U A L I S A T I O N D ' U N E S P H E R E E C L A I R E E : */
/* */
/*************************************************************************************************************************************/
#TestADef store_sphere__ANTI_ALIASING_____COMPATIBILITE_20050622 \
FAUX
DEFV(Local,DEFV(Logical,INIT(store_sphere__anti_aliasing_____compatibilite_20050622
,store_sphere__ANTI_ALIASING_____COMPATIBILITE_20050622
)
)
);
/* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */
/* du 20050622154321 (voir '$xrv/champs_5.1C$I epaisseur_de_l_intersection_normalisee' */
/* ci-apres...). */
#TestADef store_sphere__ANTI_ALIASING_____COMPATIBILITE_20181227 \
FAUX
DEFV(Local,DEFV(Logical,INIT(store_sphere__anti_aliasing_____compatibilite_20181227
,store_sphere__ANTI_ALIASING_____COMPATIBILITE_20181227
)
)
);
/* Afin d'assurer la compatibilite avec les resultats obtenus anterieurement a la date */
/* du 20181227094921 (ceci a ete introduit pour 'v $xiirv/CARR.35' lors des tests de */
/* sa generation avec '_____DistanceMini=0.001', ce qui introduisait des points sombres */
/* aux intersections des spheres et dont la disposition etait relativement aleatoire...). */
#define store_sphere(nbR,nbV,nbB,ncR,ncV,ncB,iR,iV,iB,X_centre,Y_centre,Z_centre,Arayon,Vrayon) \
/* ATTENTION : {X,Y,Z} E [0,1]x[0,1]x[0,1]. */ \
/* */ \
/* Les deux arguments de type "rayon" signifient : */ \
/* */ \
/* 1-'Arayon' (appele ailleurs 'rayon_reel_absolu') : donne le rayon de la sphere dans */ \
/* l'espace [0,1]x[0,1]x[0,1]. Il s'agit donc du rayon "Absolu". */ \
/* */ \
/* 2-'Vrayon' (appele ailleurs 'rayon_reel_de_visualisation') : donne le rayon de la */ \
/* apres projection et donc avec un effet de perspective. Il s'agit donc du rayon de */ \
/* "Visualisation". */ \
/* */ \
Bblock \
DEFV(Logical,INIT(la_sphere_est_entierement_hors_de_l_image,VRAI)); \
/* A priori, la sphere que l'on va tracer est completement hors du cadre de l'image... */ \
\
INITIALISATION_POINT_3D(centre_3D_de_la_sphere \
,X_centre \
,Y_centre \
,Z_centre \
); \
/* Initialisation du centre effectif de la sphere... */ \
/* */ \
/* On notera que 'centre_2D_de_la_sphere' est soit calcule par projection de */ \
/* 'centre_3D_de_la_sphere', soit comme centre de gravite du contour apparent, */ \
/* suivant que l'on ne trace que le centre des spheres ou les spheres "completes"... */ \
\
Test(IL_FAUT(ne_visualiser_que_le_centre_des_spheres)) \
Bblock \
DEFV(Int,INIT(Xt,UNDEF)); \
DEFV(Int,INIT(Yt,UNDEF)); \
\
DEFINITION_DU_POINT_2D_COURANT_SUR_LA_SPHERE(centre_2D_de_la_sphere,centre_3D_de_la_sphere); \
/* Projection du centre effectif de la sphere... */ \
\
EGAL(Xt \
,INTE(COND(EST_VRAI(l_espace_de_l_image_est_un_tore_selon_OX) \
,MOFX(ASD1(centre_2D_de_la_sphere,x)) \
,NEUT(ASD1(centre_2D_de_la_sphere,x)) \
) \
) \
); \
EGAL(Yt \
,INTE(COND(EST_VRAI(l_espace_de_l_image_est_un_tore_selon_OY) \
,MOFY(ASD1(centre_2D_de_la_sphere,y)) \
,NEUT(ASD1(centre_2D_de_la_sphere,y)) \
) \
) \
); \
/* Possibilite de "tore selon 'OX' et/ou 'OY'" introduite le 20090816174959... */ \
\
Test(TEST_DANS_L_IMAGE(Xt,Yt)) \
Bblock \
store_point_ND_RVB(ncR,ncV,ncB \
,iR,iV,iB \
,Xt,Yt \
,ASD1(centre_3D_de_la_sphere,z) \
,TRI_DIMENSIONNEL \
); \
/* Generation du centre d'une sphere lorsque l'on ne visualise que lui... */ \
/* */ \
/* Je note le 20090225105255 que c'est l'existence des "boites" {{minX,maxX},{minY,maxY}}} */ \
/* et {{VminX,VmaxX},{VminY,VmaxY}} qui interdit la possibilite de gerer, en option, l'image */ \
/* {iR,iV,iB} comme un tore via les fonctions {MOFX(...),MOFY(...)}. */ \
\
EGAL(la_sphere_est_entierement_hors_de_l_image,FAUX); \
/* La sphere (reduite donc a un point) est entierement dans le cadre de l'image... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
ATes \
Bblock \
DEFV(Float,INIT(theta_de_la_sphere,FLOT__UNDEF)); \
DEFV(Float,INIT(phi_de_la_sphere,FLOT__UNDEF)); \
/* Definition des coordonnees curvilignes de la sphere... */ \
DEFV(Float,INIT(affinage_des_pas,FLOT__UNDEF)); \
/* Afin de corriger les pas de 'theta' et de 'phi' afin de bien echantillonner la sphere... */ \
DEFV(pointF_3D,point_3D_le_plus_proche); \
DEFV(pointF_2D,point_2D_le_plus_proche); \
/* Definition du point le plus proche de l'observateur. */ \
DEFV(Float,INIT(theta_du_point_le_plus_proche,FLOT__UNDEF)); \
DEFV(Float,INIT(phi_du_point_le_plus_proche,FLOT__UNDEF)); \
/* Coordonnees curvilignes du point le plus proche de l'observateur. */ \
DEFV(Float,INIT(distance_du_point_le_plus_proche,F_INFINI)); \
/* Distance du point le plus proche de l'observateur. */ \
DEFV(Float,INIT(rayon_du_contour_apparent,FLOT__UNDEF)); \
/* Definition du contour apparent de la sphere... */ \
DEFV(Int,INIT(minX,INFINI)); \
DEFV(Int,INIT(maxX,MOINS_L_INFINI)); \
DEFV(Int,INIT(minY,INFINI)); \
DEFV(Int,INIT(maxY,MOINS_L_INFINI)); \
/* Definition du "sous-buffer" de collision grace a [minX,maxX]x[minY,maxY]. Cette */ \
/* definition est faite en variables locales afin d'automatiser sa reinitialisation */ \
/* pour chaque nouvelle sphere... */ \
/* */ \
/* Le 19991216115606 l'initialisation qui etait anterieurement : */ \
/* */ \
/* DEFV(Int,INIT(minX,Xmax)); */ \
/* DEFV(Int,INIT(maxX,Xmin)); */ \
/* DEFV(Int,INIT(minY,Ymax)); */ \
/* DEFV(Int,INIT(maxY,Ymin)); */ \
/* */ \
/* a ete modifiee afin d'eviter un defaut sur les spheres partiellement hors-image... */ \
DEFV(Float,INIT(VminX,F_INFINI)); \
DEFV(Float,INIT(VmaxX,F_MOINS_L_INFINI)); \
DEFV(Float,INIT(VminY,F_INFINI)); \
DEFV(Float,INIT(VmaxY,F_MOINS_L_INFINI)); \
/* Definition identique a [minX,maxX]x[minY,maxY] si ce n'est qu'ici meme les points hors */ \
/* de l'image sont pris en compte, et ce afin de calculer le rayon du contour apparent... */ \
/* */ \
/* Le 19991216115606 l'initialisation qui etait anterieurement : */ \
/* */ \
/* DEFV(Float,INIT(VminX,FLOT(Xmax))); */ \
/* DEFV(Float,INIT(VmaxX,FLOT(Xmin))); */ \
/* DEFV(Float,INIT(VminY,FLOT(Ymax))); */ \
/* DEFV(Float,INIT(VmaxY,FLOT(Ymin))); */ \
/* */ \
/* a ete modifiee afin d'eviter un defaut sur les spheres partiellement hors-image... */ \
DEFV(Float,INIT(equation_representative_du_contour,FLOT__UNDEF)); \
/* Valeur courante au point {X,Y} de la fonction representative du contour de la forme */ \
/* materialisant la particule. */ \
DEFV(Float,INIT(distance_normalisee_au_centre,FLOT__UNDEF)); \
/* Distance normalisee dans [0,1] du point courant {X,Y} au centre du disque. */ \
DEFV(deltaF_3D,vecteur_normal_approxime); \
/* --> */ \
/* Approximation du vecteur normal N au point courant de la sphere destinee a lutter */ \
/* contre le fait que les points tridimensionnels ne se projettent pas exactement sur des */ \
/* points bidimensionnels de coordonnees entieres... */ \
DEFV(deltaF_3D,rayon_lumineux_inverse); \
/* --> */ \
/* Rayon lumineux inverse S (allant du point courant de l'ellipsoide a la source */ \
/* lumineuse). */ \
DEFV(Float,INIT(produit_des_modules_de_N_et_S,FLOT__UNDEF)); \
/* --> */ \
/* Produit du module du vecteur normal N et du module du vecteur rayon lumineux */ \
/* --> */ \
/* inverse S . */ \
DEFV(Float,INIT(modulation_d_eclairement,FLOT__UNDEF)); \
/* Modulation de l'eclairement du point courant calcule a partir de l'angle entre la */ \
/* --> --> */ \
/* vecteur normal N et le rayon lumineux inverse S . */ \
\
DoIn(theta_de_la_sphere,MINIMUM_DE_THETA,MAXIMUM_DE_THETA,pas_de_theta_de_la_sphere) \
Bblock \
DoIn(phi_de_la_sphere,MINIMUM_DE_PHI,MAXIMUM_DE_PHI,pas_de_phi_de_la_sphere) \
Bblock \
DEFV(Float,INIT(distance_du_point_courant,FLOT__UNDEF)); \
/* Definition de la distance de l'observateur au point courant... */ \
DEFINITION_DU_POINT_3D_COURANT_SUR_LA_SPHERE(point_3D_le_plus_proche \
,Vrayon \
,theta_de_la_sphere \
,phi_de_la_sphere \
); \
DEFINITION_DU_POINT_2D_COURANT_SUR_LA_SPHERE(point_2D_le_plus_proche,point_3D_le_plus_proche); \
/* Calcul des coordonnees du point courant de la sphere, et projection... */ \
/* */ \
/* On notera que de plus cette operation initialise la premiere fois les valeurs de */ \
/* 'Projection_OX_OY_____position_de_l_observateur' et de */ \
/* 'Projection_OX_OY_____plan_de_projection' definies dans le fichier */ \
/* 'v $xiii/vecteurs$FON'. */ \
/* */ \
/* ATTENTION, on notera que l'on ne fait pas : */ \
/* */ \
/* Test(EST_FAUX(LE_POINT_EST_INVISIBLE_OU_INDETERMINE(ASD1(point_3D_le_plus_proche,x) */ \
/* ,ASD1(point_3D_le_plus_proche,y) */ \
/* ,ASD1(point_3D_le_plus_proche,z) */ \
/* ) */ \
/* ) */ \
/* ) */ \
/* */ \
/* afin d'alleger le code qui suit. Tout repose donc sur l'hypothese que tous les points */ \
/* de la sphere sont visibles, en esperant que '$xrv/attractor.16$I' ait fait un tri */ \
/* correct dans 'MEMORISATION_DU_POINT_COURANT(...)'. */ \
\
EGAL(VminX,MIN2(VminX,ASD1(point_2D_le_plus_proche,x))); \
EGAL(VmaxX,MAX2(VmaxX,ASD1(point_2D_le_plus_proche,x))); \
EGAL(VminY,MIN2(VminY,ASD1(point_2D_le_plus_proche,y))); \
EGAL(VmaxY,MAX2(VmaxY,ASD1(point_2D_le_plus_proche,y))); \
\
EGAL(minX,MIN2(minX,INTE(ASD1(point_2D_le_plus_proche,x)))); \
EGAL(maxX,MAX2(maxX,INTE(ASD1(point_2D_le_plus_proche,x)))); \
EGAL(minY,MIN2(minY,INTE(ASD1(point_2D_le_plus_proche,y)))); \
EGAL(maxY,MAX2(maxY,INTE(ASD1(point_2D_le_plus_proche,y)))); \
/* Puis on met a jour la definition du plus petit rectangle contenant le contour apparent */ \
/* de cette sphere projetee mais en tenant compte que des points dans l'image... */ \
/* */ \
/* Avant le 19991216115606, ce mise a jour avait lieu de facon conditionnelle grace a : */ \
/* */ \
/* Test(TEST_DANS_L_IMAGE(INTE(ASD1(point_2D_le_plus_proche,x)) */ \
/* ,INTE(ASD1(point_2D_le_plus_proche,y)) */ \
/* ) */ \
/* ) */ \
/* */ \
/* mais cela n'a plus d'utilite dorenavant... */ \
Eblock \
EDoI \
Eblock \
EDoI \
\
EGAL(rayon_du_contour_apparent \
,MOIT(MIN2(SOUS(VmaxX,VminX) \
,SOUS(VmaxY,VminY) \
) \
) \
); \
/* Calcul du rayon du contour apparent ; il vaut mieux le calculer ici que lors des boucles */ \
/* precedentes, car ici le pas relatif a (theta,phi) etant eventuellement plus fin, ce */ \
/* calcul sera plus precis. */ \
\
Test(IZLE(rayon_du_contour_apparent)) \
Bblock \
PRINT_ATTENTION("le Rayon du contour apparent est nul"); \
EGAL(rayon_du_contour_apparent,UN); \
/* Et ce afin d'eviter des problemes ulterieurs lors du calcul de l'equation du contour... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
INITIALISATION_POINT_2D(centre_2D_de_la_sphere \
,MOYE(VminX,VmaxX) \
,MOYE(VminY,VmaxY) \
); \
/* Et determination du veritable centre du contour apparent... */ \
\
CALCUL_DE_LA_DISTANCE_CRITIQUE_NORMALISEE_AU_BORD(rayon_du_contour_apparent,Arayon); \
/* Preparation du traitement anti-aliasing de cette sphere... */ \
/* */ \
/* L'argument 'Arayon' a ete introduit le 20060224151605... */ \
\
begin_colonneQ(DoIn,minY,maxY,pasY) \
Bblock \
begin_ligneQ(DoIn,minX,maxX,pasX) \
Bblock \
INITIALISATION_POINT_2D(point_2Dt_courant \
,FLOT(COND(EST_VRAI(l_espace_de_l_image_est_un_tore_selon_OX) \
,MODX(X) \
,NEUT(X) \
) \
) \
,FLOT(COND(EST_VRAI(l_espace_de_l_image_est_un_tore_selon_OY) \
,MODY(Y) \
,NEUT(Y) \
) \
) \
); \
/* Prise en compte eventuelle de la structure "Torique" de l'image (ceci a ete introduit */ \
/* le 20090818092838). */ \
\
Test(TEST_DANS_L_IMAGE(INTE(ASD1(point_2Dt_courant,x)),INTE(ASD1(point_2Dt_courant,y)))) \
Bblock \
DEFV(genere_p,INIT(niveau_ROUGE_du_point,ncR)); \
DEFV(genere_p,INIT(niveau_VERTE_du_point,ncV)); \
DEFV(genere_p,INIT(niveau_BLEUE_du_point,ncB)); \
/* Niveau du point courant initialise sur le maximum, et ce au cas ou le grand axe et le */ \
/* petit axe de l'ellipsoide seraient nuls... */ \
DEFV(Float,INIT(correction_d_anti_aliasing_au_bord,FLOT__UNDEF)); \
/* Afin de corriger l'aliasing sur le contour apparent des spheres... */ \
\
DEFV(Float,INIT(Z_approxime_au_carre,FLOT__UNDEF)); \
/* Valeurs intermediaires destinees a l'approximation de la coordonnee 'Z'... */ \
\
INITIALISATION_POINT_2D(point_2D_courant \
,FLOT(X) \
,FLOT(Y) \
); \
/* Le point projete courant est pris comme etant le point "raster" courant... */ \
\
EGAL(Z_approxime_au_carre \
,SOUS(EXP2(rayon_du_contour_apparent) \
,disF2D(ASD1(centre_2D_de_la_sphere,x),ASD1(centre_2D_de_la_sphere,y) \
,ASD1(point_2D_courant,x),ASD1(point_2D_courant,y) \
) \
) \
); \
/* Calcul du carre de la distance du point bidimensionnel au contour apparent. En effet, */ \
/* on calcule ici quelque chose qui ressemble fortement a : */ \
/* */ \
/* 2 2 2 2 */ \
/* Z = R - (X + Y ) */ \
/* */ \
/* c'est-a-dire le carre de la coordonnee 'Z' que l'on ne connait pas a priori... */ \
\
Test(IZLT(Z_approxime_au_carre)) \
Bblock \
EGAL(Z_approxime_au_carre,FZERO); \
/* Les valeurs negatives sont ramenees a 0... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
INITIALISATION_POINT_3D(point_3D_courant \
,_____cNORMALISE_OX(ASD1(point_2D_courant,x)) \
,_____cNORMALISE_OY(ASD1(point_2D_courant,y)) \
,ADD2(ASD1(centre_3D_de_la_sphere,z) \
,SCAL(RACX(Z_approxime_au_carre),rayon_du_contour_apparent,Arayon) \
) \
); \
/* Le point dans l'espace tridimensionnel est approxime grossierement en calculant une */ \
/* fausse troisieme dimension a partir des deux coordonnees bidimensionnelles... */ \
/* */ \
/* Avant le 19991216123813, on trouvait ici : */ \
/* */ \
/* _____cNORMALISE_OZ(RACX(Z_approxime_au_carre)) */ \
/* */ \
/* mais cela semble faux car la taille du contour apparent change en fonction de la */ \
/* coordonnee 'Z' alors que le rayon ne change pas en realite... */ \
\
EGAL(equation_representative_du_contour \
,DIVI(disF2D(ASD1(centre_2D_de_la_sphere,x),ASD1(centre_2D_de_la_sphere,y) \
,ASD1(point_2D_courant,x),ASD1(point_2D_courant,y) \
) \
,EXP2(rayon_du_contour_apparent) \
) \
); \
/* Valeur courante au point {X,Y} de la fonction representative du contour de la forme */ \
/* materialisant la particule. */ \
\
EGAL(distance_normalisee_au_centre \
,RACX(equation_representative_du_contour) \
); \
/* Calcul de la distance euclidienne normalisee du point courant {X,Y} au centre du disque. */ \
\
Test(IFLE(distance_normalisee_au_centre,DEFINITION_DU_CONTOUR_APPARENT_DE_LA_SPHERE)) \
Bblock \
DEFV(Float,INIT(carre_de_la_norme_du_vecteur_normal_approxime,FLOT__UNDEF)); \
/* Norme du vecteur normal approxime... */ \
DEFV(Float,INIT(distance_courante_au_Z_Buffer,FLOT__UNDEF)); \
/* Distance du point courant au contenu courant du 'Z_Buffer' au point {X,Y}. */ \
DEFV(Float,INIT(epaisseur_de_l_intersection_normalisee,FLOT__UNDEF)); \
/* Afin de resoudre le probleme du 20050622153457 documente ci-apres... */ \
\
INITIALISATION_ACCROISSEMENT_3D(vecteur_normal_approxime \
,SOUS(ASD1(point_2D_courant,x) \
,ASD1(centre_2D_de_la_sphere,x) \
) \
,SOUS(ASD1(point_2D_courant,y) \
,ASD1(centre_2D_de_la_sphere,y) \
) \
,FLOT__UNDEF \
); \
/* --> */ \
/* Debut de l'approximation du vecteur normal N au point courant. */ \
\
EGAL(ASD1(vecteur_normal_approxime,dz) \
,SOUS(EXP2(rayon_du_contour_apparent) \
,pytF2D(vecteur_normal_approxime) \
) \
); \
/* Le calcul de la troisieme composante du vecteur normal approxime se fait en deux temps */ \
/* car en effet la valeur calculee ci-dessus peut etre negative (a cause des 'INTE(...)' */ \
/* ci-dessus ; on ne peut donc prendre directement 'RACX(...)'... */ \
\
Test(IZLT(ASD1(vecteur_normal_approxime,dz))) \
Bblock \
EGAL(ASD1(vecteur_normal_approxime,dz),FZERO); \
/* Dans le cas ou une valeur negative est rencontree, on la ramene a 0... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
INITIALISATION_ACCROISSEMENT_3D(vecteur_normal_approxime \
,NEUT(ASD1(vecteur_normal_approxime,dx)) \
,NEUT(ASD1(vecteur_normal_approxime,dy)) \
,RACX(ASD1(vecteur_normal_approxime,dz)) \
); \
/* --> */ \
/* Suite et fin de l'approximation du vecteur normal N en prenant en compte le fait que */ \
/* les coordonnees sont entieres ; on approxime donc la normale avec les points de */ \
/* coordonnees entieres bien qu'elle soit connue exactement (mais en des points non */ \
/* entiers...). */ \
\
EGAL(carre_de_la_norme_du_vecteur_normal_approxime,pytF3D(vecteur_normal_approxime)); \
/* Norme du vecteur normal approxime... */ \
\
EGAL(correction_d_anti_aliasing_au_bord \
,CORRECTION_D_ANTI_ALIASING(distance_normalisee_au_centre) \
); \
/* En fait, 'modulation_d_eclairement' pourra etre corrige par ce facteur, car en effet, */ \
/* dans certaines circonstances, le point le plus lumineux de l'ellipsoide peut se trouver */ \
/* tres pres de son contour apparent, et donc creer un probleme d'aliasing. On calcule donc */ \
/* ici la correction en fonction du point courant par rapport au contour apparent de */ \
/* l'ellipsoide. Il convient de remarquer que la distance utilisee ici est une distance */ \
/* bidimensionnelle dans le plan, et non pas une distance dans l'espace tridimensionnel. */ \
/* Elle definie bien (ou du moins son complement a 'COORDONNEE_BARYCENTRIQUE_MAXIMALE') une */ \
/* distance du point courant bidimensionnel {X,Y} au contour apparent... */ \
\
INITIALISATION_ACCROISSEMENT_3D(rayon_lumineux_inverse \
,SOUS(X_PHYSIQUE_DANS_01(ASD1(LsourceT,x)) \
,ASD1(point_3D_courant,x) \
) \
,SOUS(Y_PHYSIQUE_DANS_01(ASD1(LsourceT,y)) \
,ASD1(point_3D_courant,y) \
) \
,SOUS(Z_PHYSIQUE_DANS_01(ASD1(LsourceT,z)) \
,ASD1(point_3D_courant,z) \
) \
); \
/* Generation du rayon lumineux inverse. */ \
EGAL(produit_des_modules_de_N_et_S \
,RACX(MUL2(carre_de_la_norme_du_vecteur_normal_approxime \
,pytF3D(rayon_lumineux_inverse) \
) \
) \
); \
/* Calcul de : */ \
/* */ \
/* --> --> */ \
/* |N|.|S| */ \
/* */ \
\
Test(IZGT(produit_des_modules_de_N_et_S)) \
Bblock \
EGAL(modulation_d_eclairement \
,PUIX(COS1(DIVI(prdF3D(vecteur_normal_approxime,rayon_lumineux_inverse) \
,produit_des_modules_de_N_et_S \
) \
) \
,intensite_speculaire \
) \
); \
/* --> --> */ \
/* Designant par N la normale et par S le rayon lumineux inverse, la modulation de */ \
/* --> --> */ \
/* l'eclairement s'obtient en calculant le cosinus de l'angle entre N et S : */ \
/* */ \
/* --> --> */ \
/* --> --> N . S */ \
/* cos( N , S ) = --------- */ \
/* --> --> */ \
/* |N|.|S| */ \
/* */ \
/* puis en le ramenant dans [0,1] et en accentuant le phenomene (reflets speculaires)... */ \
Eblock \
ATes \
Bblock \
EGAL(modulation_d_eclairement \
,COORDONNEE_BARYCENTRIQUE_MAXIMALE \
); \
/* Nous sommes ici dans le cas ou la particule est "tangente" a la source lumineuse... */ \
Eblock \
ETes \
\
Test(IFEXff(modulation_d_eclairement \
,COORDONNEE_BARYCENTRIQUE_MINIMALE \
,COORDONNEE_BARYCENTRIQUE_MAXIMALE \
) \
) \
Bblock \
PRINT_ERREUR("la modulation d'eclairement est hors de [0,1]"); \
CAL1(Prer1(" elle vaut : %g\n",modulation_d_eclairement)); \
CAL1(Prer1(" equation = %g\n",equation_representative_du_contour)); \
CAL1(Prer1(" distance = %g\n",distance_normalisee_au_centre)); \
CAL1(Prer1(" aliasing = %g\n",correction_d_anti_aliasing_au_bord)); \
CAL1(Prer3(" normale N = (%g,%g,%g)\n" \
,ASD1(vecteur_normal_approxime,dx) \
,ASD1(vecteur_normal_approxime,dy) \
,ASD1(vecteur_normal_approxime,dz) \
) \
); \
CAL1(Prer3(" lumiere S = (%g,%g,%g)\n" \
,ASD1(rayon_lumineux_inverse,dx) \
,ASD1(rayon_lumineux_inverse,dy) \
,ASD1(rayon_lumineux_inverse,dz) \
) \
); \
CAL1(Prer1(" N.S = %g\n" \
,prdF3D(vecteur_normal_approxime,rayon_lumineux_inverse) \
) \
); \
CAL1(Prer1(" |N|.|S| = %g\n",produit_des_modules_de_N_et_S)); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
EGAL(distance_courante_au_Z_Buffer \
,MUL2(COND(IL_FAUT(store_sphere__anti_aliasing_____compatibilite_20060426) \
,FU \
,rapport_courant_du_zoom \
) \
,SOUA(ASD1(point_3D_courant,z) \
,loadF_point(Z_Buffer \
,INTE(ASD1(point_2Dt_courant,x)) \
,INTE(ASD1(point_2Dt_courant,y)) \
) \
) \
) \
); \
/* Distance du point courant au contenu courant du 'Z_Buffer' au point {X,Y}. */ \
/* */ \
/* L'introduction du rapport courant de zoom a eu lieu le 20060426140714. Cela manquait */ \
/* car en effet, la gestion de l'anti-aliasing a lieu en coordonnees ecran (en pixels ; */ \
/* rappelons que 'EPAISSEUR_DE_L_INTERSECTION' est exprime en pixels...). Cela s'est vu */ \
/* lors du calcul de l'image 'v $xiirs/SPHE.61' qui, au debut, presentait d'affreux */ \
/* zig-zags dans la jonction du premier plan ; il est vite apparu que cela etait lie */ \
/* au fort zoom qu'elle subissait (ZOOM=0.22). Malheureusement, il est evident qu'apres */ \
/* le 20060426140714 la plupart des images anterieures ne seront pas recalculables */ \
/* exactement identiques a elles-memes : il y aura de petites differences, sauf usage */ \
/* de l'option : */ \
/* */ \
/* compatibilite_20060426=VRAI */ \
/* */ \
/* evidemment... */ \
\
Test(IL_FAUT(store_sphere__anti_aliasing_____compatibilite_20050622)) \
Bblock \
EGAL(epaisseur_de_l_intersection_normalisee \
,_____lNORMALISE_OZ(EPAISSEUR_DE_L_INTERSECTION) \
); \
/* Le 20050622154321, en testant le programme 'v $xrs/project3D.11$K', j'ai note que */ \
/* lorsque 'dimZ' est trop petit (il valait 8 dans ce test...), cela conduit a des */ \
/* corrections d'anti-aliasing aberrantes, d'ou le remplacement de l'appel a la procedure */ \
/* '_____lNORMALISE_OZ(...)' par quelque chose de plus complique... */ \
Eblock \
ATes \
Bblock \
EGAL(epaisseur_de_l_intersection_normalisee \
,_____lNORMALISE_AXES(MAX2(dimZ,k___dimZ),EPAISSEUR_DE_L_INTERSECTION) \
); \
/* Ainsi, lorsque 'dimZ' est trop petit, il est majore... */ \
Eblock \
ETes \
\
Test(IFLE(distance_courante_au_Z_Buffer \
,epaisseur_de_l_intersection_normalisee \
) \
) \
Bblock \
DEFV(Float,INIT(correction_d_anti_aliasing_aux_intersections \
,INTERPOLATION_MIXTE \
(store_sphere__anti_aliasing_____compatibilite_20181227 \
,COORDONNEE_BARYCENTRIQUE_MINIMALE \
,FZERO \
,COORDONNEE_BARYCENTRIQUE_MAXIMALE \
,FZERO \
,DIVI(distance_courante_au_Z_Buffer \
,epaisseur_de_l_intersection_normalisee \
) \
) \
) \
); \
/* Lorsque le point a marquer est pratiquement a la meme profondeur que le point precedent, */ \
/* c'est qu'il y a intersection de deux spheres : on va donc faire la moyenne du niveau a */ \
/* a marquer et du niveau anterieur... */ \
\
Test(IFGE(correction_d_anti_aliasing_au_bord,COORDONNEE_BARYCENTRIQUE_MAXIMALE)) \
/* Le 20060426123057, le 'IFEQ(...)' est devenu un 'IFGE(...)' car, en effet, la procedure */ \
/* 'INTERPOLATION_CUBIQUE(...)' a des "rebonds" et donc il n'est pas evident que ci-dessus */ \
/* 'correction_d_anti_aliasing_aux_intersections' soit effectivement dans le segment espere */ \
/* [COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE]... */ \
Bblock \
EGAL(correction_d_anti_aliasing_au_bord \
,correction_d_anti_aliasing_aux_intersections \
); \
/* Cas ou l'on est juste en presence d'une intersection... */ \
Eblock \
ATes \
Bblock \
EGAL(correction_d_anti_aliasing_au_bord \
,MIN2(correction_d_anti_aliasing_au_bord \
,correction_d_anti_aliasing_aux_intersections \
) \
); \
/* Cas ou l'on est en presence simultanement d'un bord et d'une intersection. On notera que */ \
/* l'on utilise la fonction 'MIN2(...)', car en effet l'utilisation de 'MOYE(...)' faisait */ \
/* apparaitre des defauts visuels (points sur-lumineux) la ou il y avait une forte disparite */ \
/* entre les deux corrections ("de bord" et "d'intersection") ; l'utilisation de 'MAX2(...)' */ \
/* ne faisait qu'amplifier ces defauts... */ \
Eblock \
ETes \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
Test(NINCff(correction_d_anti_aliasing_au_bord \
,COORDONNEE_BARYCENTRIQUE_MINIMALE \
,COORDONNEE_BARYCENTRIQUE_MAXIMALE \
) \
) \
Bblock \
Test(NINCff(correction_d_anti_aliasing_au_bord \
,SOUS(COORDONNEE_BARYCENTRIQUE_MINIMALE,GRAND_EPSILON) \
,ADD2(COORDONNEE_BARYCENTRIQUE_MAXIMALE,GRAND_EPSILON) \
) \
) \
/* Ce test destine a ne pas sortir de messages d'erreur a ete introduit le 20050516115705 */ \
/* car, en effet, le 'INTERPOLATION_CUBIQUE(...)' qui precede introduit des "rebonds" et */ \
/* il n'est donc pas anormal que l'on soit hors de [0,1] a epsilon pres... */ \
Bblock \
PRINT_ERREUR("le parametre d'interpolation n'est pas dans [0,1]"); \
CAL1(Prer1(" parametre d'interpolation = %g\n" \
,correction_d_anti_aliasing_au_bord \
) \
); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
EGAL(correction_d_anti_aliasing_au_bord \
,TRON(correction_d_anti_aliasing_au_bord \
,COORDONNEE_BARYCENTRIQUE_MINIMALE \
,COORDONNEE_BARYCENTRIQUE_MAXIMALE \
) \
); \
/* Et on corrige cette anomalie par troncation... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
niveau_RVB(niveau_ROUGE_du_point,nbR,ncR,iR,niveau_anterieur_ROUGE_a_forcer); \
niveau_RVB(niveau_VERTE_du_point,nbV,ncV,iV,niveau_anterieur_VERTE_a_forcer); \
niveau_RVB(niveau_BLEUE_du_point,nbB,ncB,iB,niveau_anterieur_BLEUE_a_forcer); \
/* Enfin, calcul du niveau du point courant. */ \
\
store_point_ND_RVB(niveau_ROUGE_du_point,niveau_VERTE_du_point,niveau_BLEUE_du_point \
,iR,iV,iB \
,INTE(ASD1(point_2Dt_courant,x)),INTE(ASD1(point_2Dt_courant,y)) \
,ASD1(point_3D_courant,z) \
,TRI_DIMENSIONNEL \
); \
/* Generation du point courant dans le cas d'une visualisation complete d'une sphere. */ \
/* */ \
/* La prise en compte eventuelle de la structure "torique" de l'image a ete introduite */ \
/* le 20090818092838). */ \
\
EGAL(la_sphere_est_entierement_hors_de_l_image,FAUX); \
/* On memorise qu'au moins un point de la sphere courante est dans l'image ; rappelons que */ \
/* cela ne signifie pas obligatoirement qu'il est visible, puisqu'il peut etre cache par */ \
/* une autre sphere plus proche de l'observateur... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
end_ligneQ(EDoI) \
Eblock \
end_colonneQ(EDoI) \
Eblock \
ETes \
\
Test(EST_FAUX(la_sphere_est_entierement_hors_de_l_image)) \
Bblock \
INCR(compteur_des_spheres_dans_l_image,I); \
/* Lorsqu'au moins un point de la sphere a ete marque, cette sphere est comptee parmi les */ \
/* spheres visibles. Rappelons que cela ne signifie pas obligatoirement qu'elle est visible, */ \
/* puisqu'elle peut etre cachee par une autre sphere plus proche de l'observateur... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
Eblock \
/* ATTENTION : {X,Y,Z} E [0,1]x[0,1]x[0,1]. */