_______________________________________________________________________________________________________________________________________
/*************************************************************************************************************************************/
/* */
/* R E P R E S E N T A T I O N D E S S U R F A C E S D E L ' E S P A C E : */
/* */
/* */
/* Definition : */
/* */
/* Dans ce fichier se trouvent toutes */
/* les fonctions necessaires a la re- */
/* presentation des surfaces dans */
/* l'espace a trois dimensions. */
/* Ces surfaces sont representees sous */
/* la forme parametrique : */
/* */
/* Fx(u,v), */
/* Fy(u,v), */
/* Fz(u,v), */
/* */
/* ou (u,v) sont deux nombres reels */
/* appartenant a [0,1]. */
/* */
/* On part ainsi d'un "quadrilatere" */
/* [Umin,Umax]*[Vmin,Vmax] que l'on */
/* subdivise recursivement jusqu'a */
/* ce que l'on arrive a la taille */
/* d'un point d'image : */
/* */
/* Umin Umax */
/* */
/* | | */
/* |uV |UV */
/* Vmax ---+---------+--- */
/* | | */
/* | | */
/* | | */
/* |uv |Uv */
/* Vmin ---+---------+--- */
/* | | */
/* | | */
/* */
/* */
/* Author of '$ximf/surfaces.1$FON' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 19870000000000). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 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 TRANSFORMATION_Fx(fx,fy,fz,u,v) \
ADD2(ADD3(COND(IZEQ(ASD2(vecteurs_____matrix_3D,cx,cx)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cx,cx),FLOT(fPOINTEUR(fx)(DPRE(u),DPRE(v)))) \
) \
,COND(IZEQ(ASD2(vecteurs_____matrix_3D,cx,cy)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cx,cy),FLOT(fPOINTEUR(fy)(DPRE(u),DPRE(v)))) \
) \
,COND(IZEQ(ASD2(vecteurs_____matrix_3D,cx,cz)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cx,cz),FLOT(fPOINTEUR(fz)(DPRE(u),DPRE(v)))) \
) \
) \
,ASI1(translation,dx) \
)
#define TRANSFORMATION_Fy(fx,fy,fz,u,v) \
ADD2(ADD3(COND(IZEQ(ASD2(vecteurs_____matrix_3D,cy,cx)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cy,cx),FLOT(fPOINTEUR(fx)(DPRE(u),DPRE(v)))) \
) \
,COND(IZEQ(ASD2(vecteurs_____matrix_3D,cy,cy)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cy,cy),FLOT(fPOINTEUR(fy)(DPRE(u),DPRE(v)))) \
) \
,COND(IZEQ(ASD2(vecteurs_____matrix_3D,cy,cz)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cy,cz),FLOT(fPOINTEUR(fz)(DPRE(u),DPRE(v)))) \
) \
) \
,ASI1(translation,dy) \
)
#define TRANSFORMATION_Fz(fx,fy,fz,u,v) \
ADD2(ADD3(COND(IZEQ(ASD2(vecteurs_____matrix_3D,cz,cx)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cz,cx),FLOT(fPOINTEUR(fx)(DPRE(u),DPRE(v)))) \
) \
,COND(IZEQ(ASD2(vecteurs_____matrix_3D,cz,cy)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cz,cy),FLOT(fPOINTEUR(fy)(DPRE(u),DPRE(v)))) \
) \
,COND(IZEQ(ASD2(vecteurs_____matrix_3D,cz,cz)) \
,FZERO \
,MUL2(ASD2(vecteurs_____matrix_3D,cz,cz),FLOT(fPOINTEUR(fz)(DPRE(u),DPRE(v)))) \
) \
) \
,ASI1(translation,dz) \
)
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S D E R I V E E S P A R T I E L L E S : */
/* */
/* */
/* Nota : */
/* */
/* Les derivees partielles sont */
/* calculees par des differences a */
/* 'u' ou 'v' constant (suivant le */
/* cas...) avec suppression des */
/* points singuliers (en calculant */
/* la difference "un peu plus loin" */
/* lorsqu'elle est nulle...). */
/* */
/*************************************************************************************************************************************/
/* La procedure 'DERIVATION_PARTIELLE(...)' a ete introduite le 20060317185633 ci-apres... */
#define dXdu1 \
DERIVATION_PARTIELLE(ASD1(coinF3_uv,x),ASD1(coinF3_Uv,x),SOUS(Umax,Umin))
#define dXdu2 \
DERIVATION_PARTIELLE(ASD1(coinF3_uV,x),ASD1(coinF3_UV,x),SOUS(Umax,Umin))
#define dXdu \
COND(IZNE(dXdu1),dXdu1,dXdu2)
/* DX/du ('u' variable et 'v' constant), */
#define dXdv1 \
DERIVATION_PARTIELLE(ASD1(coinF3_uv,x),ASD1(coinF3_uV,x),SOUS(Vmax,Vmin))
#define dXdv2 \
DERIVATION_PARTIELLE(ASD1(coinF3_Uv,x),ASD1(coinF3_UV,x),SOUS(Vmax,Vmin))
#define dXdv \
COND(IZNE(dXdv1),dXdv1,dXdv2)
/* DX/dv ('u' constant et 'v' variable). */
#define dYdu1 \
DERIVATION_PARTIELLE(ASD1(coinF3_uv,y),ASD1(coinF3_Uv,y),SOUS(Umax,Umin))
#define dYdu2 \
DERIVATION_PARTIELLE(ASD1(coinF3_uV,y),ASD1(coinF3_UV,y),SOUS(Umax,Umin))
#define dYdu \
COND(IZNE(dYdu1),dYdu1,dYdu2)
/* DY/du ('u' variable et 'v' constant), */
#define dYdv1 \
DERIVATION_PARTIELLE(ASD1(coinF3_uv,y),ASD1(coinF3_uV,y),SOUS(Vmax,Vmin))
#define dYdv2 \
DERIVATION_PARTIELLE(ASD1(coinF3_Uv,y),ASD1(coinF3_UV,y),SOUS(Vmax,Vmin))
#define dYdv \
COND(IZNE(dYdv1),dYdv1,dYdv2)
/* DY/dv ('u' constant et 'v' variable). */
#define dZdu1 \
DERIVATION_PARTIELLE(ASD1(coinF3_uv,z),ASD1(coinF3_Uv,z),SOUS(Umax,Umin))
#define dZdu2 \
DERIVATION_PARTIELLE(ASD1(coinF3_uV,z),ASD1(coinF3_UV,z),SOUS(Umax,Umin))
#define dZdu \
COND(IZNE(dZdu1),dZdu1,dZdu2)
/* DZ/du ('u' variable et 'v' constant), */
#define dZdv1 \
DERIVATION_PARTIELLE(ASD1(coinF3_uv,z),ASD1(coinF3_uV,z),SOUS(Vmax,Vmin))
#define dZdv2 \
DERIVATION_PARTIELLE(ASD1(coinF3_Uv,z),ASD1(coinF3_UV,z),SOUS(Vmax,Vmin))
#define dZdv \
COND(IZNE(dZdv1),dZdv1,dZdv2)
/* DZ/dv ('u' constant et 'v' variable). */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S D E L ' A N T I - A L I A S I N G : */
/* */
/*************************************************************************************************************************************/
#define TRUN(x) \
INTE(x) \
/* Methode de passage des coordonnees flottantes aux coordonnees entieres ; */ \
/* deux sont disponibles : 'ARRI' et 'INTE'. ATTENTION : suivant la methode */ \
/* choisie, la valeur de 'ERREUR_MAXIMALE change : */ \
/* */ \
/* ARRI(...) ==> FDU (c'est-a-dire un demi-cote de carre unite), */ \
/* INTE(...) ==> FU (c'est-a-dire un cote de carre unite). */ \
/* */
#define ERREUR_MAXIMALE \
COND(IFEQ(TRUN(FDU),ZERO),FU,FDU) \
/* Erreur maximale commise le long d'un axe lors du passage de 'coinF2_uv' */ \
/* a 'coinI2_uv'. */
#define PAS_D_ERREUR_D_ALIASING \
FLOT__UNDEF \
/* Valeur initiale des erreurs commises en passant de 'coinF2_uv' a 'coinI2_uv'. */
#define EPSILON_ANTI_ALIASING \
MOIT(FU) \
/* 'epsilon' destine a decreter a partir de quand, il y a discontinuite en 'Z'... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S D E T E X T U R A G E : */
/* */
/*************************************************************************************************************************************/
#define TEXTURAGE(coordonnee_minimale,coordonnee_maximale) \
MUL2(MOYS(coordonnee_maximale,coordonnee_minimale) \
,SOUS(GpytF2D(FU,FU) \
,FU \
) \
) \
/* Fonction d'amplification d'une "demi-longueur" de coordonnees de type 'u' ou 'v', */ \
/* suivant un facteur qui vaut Racine(2)-1 ; ce facteur est introduit pour lutter */ \
/* contre le phenomene suivant : lors du test de fin de subdivision, on compare */ \
/* les diagonales du "quadrilatere" courant a la taille du point (suivant le */ \
/* maillage courant (pasX,pasY), or pour un carre parfait, le rapport de la */ \
/* diagonale au cote vaut Racine(2), donc le "quadrilatere" sur lequel on */ \
/* s'arrete dans ce cas est 'Racine(2)' fois trop petit, d'ou le facteur */ \
/* d'amplification ci-dessus... */ \
/* */ \
/* La procedure 'GpytF2D(...)' a ete introduite le 20021120102824. */
#define TEXTURAGE_MINIMUM(coordonnee_minimale,coordonnee_maximale) \
SOUS(coordonnee_minimale,TEXTURAGE(coordonnee_minimale,coordonnee_maximale)) \
/* Diminution d'une coordonnee minimale de type 'u' ou 'v'. */
#define TEXTURAGE_MAXIMUM(coordonnee_minimale,coordonnee_maximale) \
ADD2(coordonnee_maximale,TEXTURAGE(coordonnee_minimale,coordonnee_maximale)) \
/* Augmentation d'une coordonnee maximale de type 'u' ou 'v'. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S D E S U B D I V I S I O N : */
/* */
/*************************************************************************************************************************************/
#define PROFONDEUR_SUBDIVISION \
INFINI \
/* Profondeur maximale de sub-division. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* S U B D I V I S I O N R E C U R S I V E D ' U N E S U R F A C E : */
/* */
/*************************************************************************************************************************************/
BFonctionP
#define SUBDIVISION_SURFACE(u_min,u_max,v_min,v_max) \
Bblock \
CALS(Isubdivision_surface(imageAR \
,texture,filtrage_texture \
,Fx,Fy,Fz \
,translation \
,u_min,u_max \
,v_min,v_max \
,PRED(profondeur) \
,source_lumineuse \
,anti_aliasing \
,X_erreurs,Y_erreurs \
) \
); \
Eblock \
/* Pour appeler recursivement 'subdivision_surface' avec comme argument (u,v) ; on */ \
/* notera l'appel des 'ARGUMENT_POINTEUR's. */
DEFV(Local,DEFV(FonctionP,POINTERp(Isubdivision_surface(imageAR
,texture,filtrage_texture
,ARGUMENT_FONCTION(Fx),ARGUMENT_FONCTION(Fy),ARGUMENT_FONCTION(Fz)
,ARGUMENT_POINTERs(translation)
,Umin,Umax
,Vmin,Vmax
,profondeur
,ARGUMENT_POINTERs(source_lumineuse)
,anti_aliasing
,X_erreurs,Y_erreurs
)
)
)
)
DEFV(Argument,DEFV(image,imageAR));
/* Image Argument et Resultat, dans laquelle on genere la surface. */
DEFV(Argument,DEFV(image,texture));
/* Texture a "mapper" sur la surface. */
DEFV(Argument,DEFV(Logical,filtrage_texture));
/* Indique si la texture doit etre filtree ('VRAI') afin d'avoir un rendu */
/* meilleur ou etre appliquee brutalement ('FAUX'). */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fx)));
/* Definition de la fonction 'Fx(u,v)', */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fy)));
/* Definition de la fonction 'Fy(u,v)', */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fz)));
/* Definition de la fonction 'Fz(u,v)'. */
DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation)));
/* Translation tri-dimensionnelle normalisee de la surface. */
DEFV(Argument,DEFV(Float,Umin));
/* Valeur inferieure de la coordonnee 'u', */
DEFV(Argument,DEFV(Float,Umax));
/* Valeur superieure de la coordonnee 'u'. */
DEFV(Argument,DEFV(Float,Vmin));
/* Valeur inferieure de la coordonnee 'v', */
DEFV(Argument,DEFV(Float,Vmax));
/* Valeur superieure de la coordonnee 'v'. */
DEFV(Argument,DEFV(Int,profondeur));
/* Donne en permanence le niveau (decroissant) de la recursivite. */
DEFV(Argument,DEFV(pointF_3D,POINTERs(source_lumineuse)));
/* Position de la source lumineuse. */
DEFV(Argument,DEFV(Logical,anti_aliasing));
/* Indique si le contour apparent de la surface doit etre anti-aliase ('AUTORISE') */
/* ou pas ('INTERDIT'). */
DEFV(Argument,DEFV(imageF,X_erreurs));
DEFV(Argument,DEFV(imageF,Y_erreurs));
/* Matrices contenant les erreurs commises en passant de 'coinF2_uv' */
/* a 'coinI2_uv' lorsque l'anti-aliasing est demande respectivement */
/* sur l'axe 'OX' et l'axe 'OY'. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(pointF_3D,coinF3_uv);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (u,v) = (Umin,Vmin) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
DEFV(pointF_2D,coinF2_uv);
/* Coordonnees {X,Y} flottantes dans l'espace a deux dimensions correspondant */
/* au couple (Umin,Vmin) et destinees a l'anti-aliasing du contour apparent */
/* de la surface ; on notera que ces coordonnees sont re-normalisees. */
DEFV(pointI_2D,coinI2_uv);
/* Coordonnees {X,Y} entieres dans l'espace a deux dimensions correspondant */
/* au couple (Umin,Vmin) ; on notera que ces coordonnees sont re-normalisees. */
DEFV(pointF_3D,coinF3_Uv);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (U,v) = (Umax,Vmin) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
DEFV(pointF_2D,coinF2_Uv);
/* Coordonnees {X,Y} flottantes dans l'espace a deux dimensions correspondant */
/* au couple (Umax,Vmin) et destinees a l'anti-aliasing du contour apparent */
/* de la surface ; on notera que ces coordonnees sont re-normalisees. */
DEFV(pointI_2D,coinI2_Uv);
/* Coordonnees {X,Y} entieres dans l'espace a deux dimensions correspondant */
/* au couple (Umax,Vmin) ; on notera que ces coordonnees sont re-normalisees. */
DEFV(pointF_3D,coinF3_UV);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (U,V) = (Umax,Vmax) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
DEFV(pointF_2D,coinF2_UV);
/* Coordonnees {X,Y} flottantes dans l'espace a deux dimensions correspondant */
/* au couple (Umax,Vmax) et destinees a l'anti-aliasing du contour apparent */
/* de la surface ; on notera que ces coordonnees sont re-normalisees. */
DEFV(pointI_2D,coinI2_UV);
/* Coordonnees {X,Y} entieres dans l'espace a deux dimensions correspondant */
/* au couple (Umax,Vmax) ; on notera que ces coordonnees sont re-normalisees. */
DEFV(pointF_3D,coinF3_uV);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (u,V) = (Umin,Vmax) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
DEFV(pointF_2D,coinF2_uV);
/* Coordonnees {X,Y} flottantes dans l'espace a deux dimensions correspondant */
/* au couple (Umin,Vmax) et destinees a l'anti-aliasing du contour apparent */
/* de la surface ; on notera que ces coordonnees sont re-normalisees. */
DEFV(pointI_2D,coinI2_uV);
/* Coordonnees {X,Y} entieres dans l'espace a deux dimensions correspondant */
/* au couple (Umin,Vmax) ; on notera que ces coordonnees sont re-normalisees. */
DEFV(vectorF_2D,diagonaleF_uv_UV);
/* Premiere diagonale du "quadrilatere" calculee a partir des 'coinF2', */
DEFV(vectorF_2D,diagonaleF_uV_Uv);
/* Deuxieme diagonale du "quadrilatere" calculee a partir des 'coinF2'. */
DEFV(deltaF_3D,normale);
/* Normale au "quadrilatere" courant. */
DEFV(Float,INIT(module_normale,FLOT__UNDEF));
/* Module de la normale au "quadrilatere" courant. */
DEFV(deltaF_3D,rayon_lumineux);
/* Direction du rayon lumineux du point courant a la source lumineuse. */
DEFV(Float,INIT(cosinus,FLOT__UNDEF));
/* Afin de calculer la modulation d'eclairement du point courant avec l'ombre */
/* propre (elle utilise l'angle entre la normale et le rayon lumineux). */
DEFV(Float,INIT(cumul_texture,FLOT__UNDEF));
/* Afin de calculer la valeur filtree d'un point de la texture. */
DEFV(Positive,INIT(nombre_de_points,UNDEF));
/* Nombre de points a cumuler autour du point courant afin de filtrer */
/* la texture lorsque cela est demande (voir 'filtrage_texture'). */
/*..............................................................................................................................*/
Test(IFOU(IFLE(Umax,Umin)
,IFLE(Vmax,Vmin)
)
)
Bblock
/* La deuxieme partie du test est rendue necessaire par le texturage, */
/* en effet, [Umin,Umax]*[Vmin,Vmax] doit alors etre en bijection */
/* avec [Xmin,Xmax]*[Ymin,Ymax] du champ de texture. */
PRINT_ERREUR("l'ordre des bornes inferieures et/ou superieures des coordonnees (u,v) est mauvais");
CAL1(Prer2("(Umin,Umax) = (%g,%g)\n",Umin,Umax));
CAL1(Prer2("(Vmin,Vmax) = (%g,%g)\n",Vmin,Vmax));
Eblock
ATes
Bblock
Test(IFOU(IFOU(IFLT(ARRI(_cDENORMALISE_OX(Umin)),Xmin)
,IFGT(ARRI(_cDENORMALISE_OX(Umax)),Xmax)
)
,IFOU(IFLT(ARRI(_cDENORMALISE_OY(Vmin)),Ymin)
,IFGT(ARRI(_cDENORMALISE_OY(Vmax)),Ymax)
)
)
)
Bblock
/* Ce test est rendu necessaire par l'eventuel texturage, */
/* en effet, [Umin,Umax]*[Vmin,Vmax] doit alors etre en bijection */
/* avec [Xmin,Xmax]*[Ymin,Ymax] du champ de texture. */
DEBU(PRINT_ATTENTION("les bornes inferieures et/ou superieures des coordonnees (u,v) sont 'hors-texture'");
CAL1(Prer2("(Umin,Umax) = (%g,%g)\n",Umin,Umax));
CAL1(Prer2("(Vmin,Vmax) = (%g,%g)\n",Vmin,Vmax));
);
Eblock
ATes
Bblock
Eblock
ETes
INITIALISATION_POINT_3D(coinF3_uv
,TRANSFORMATION_Fx(Fx,Fy,Fz,Umin,Vmin)
,TRANSFORMATION_Fy(Fx,Fy,Fz,Umin,Vmin)
,TRANSFORMATION_Fz(Fx,Fy,Fz,Umin,Vmin)
);
/* Calcul de 'X', 'Y' et 'Z' pour (Umin,Vmin), */
INITIALISATION_POINT_2D(coinF2_uv
,F__cDENORMALISE_OX(Projection_OX(ASD1(coinF3_uv,x),ASD1(coinF3_uv,y),ASD1(coinF3_uv,z)))
,F__cDENORMALISE_OY(Projection_OY(ASD1(coinF3_uv,x),ASD1(coinF3_uv,y),ASD1(coinF3_uv,z)))
);
INITIALISATION_POINT_2D(coinI2_uv
,TRUN(ASD1(coinF2_uv,x))
,TRUN(ASD1(coinF2_uv,y))
);
/* Et projection sur le plan de l'image, ce qui donne le coin "inferieur-gauche". */
INITIALISATION_POINT_3D(coinF3_Uv
,TRANSFORMATION_Fx(Fx,Fy,Fz,Umax,Vmin)
,TRANSFORMATION_Fy(Fx,Fy,Fz,Umax,Vmin)
,TRANSFORMATION_Fz(Fx,Fy,Fz,Umax,Vmin)
);
/* Calcul de 'X', 'Y' et 'Z' pour (Umax,Vmin), */
INITIALISATION_POINT_2D(coinF2_Uv
,F__cDENORMALISE_OX(Projection_OX(ASD1(coinF3_Uv,x),ASD1(coinF3_Uv,y),ASD1(coinF3_Uv,z)))
,F__cDENORMALISE_OY(Projection_OY(ASD1(coinF3_Uv,x),ASD1(coinF3_Uv,y),ASD1(coinF3_Uv,z)))
);
INITIALISATION_POINT_2D(coinI2_Uv
,TRUN(ASD1(coinF2_Uv,x))
,TRUN(ASD1(coinF2_Uv,y))
);
/* Et projection sur le plan de l'image, ce qui donne le coin "inferieur-droit". */
INITIALISATION_POINT_3D(coinF3_UV
,TRANSFORMATION_Fx(Fx,Fy,Fz,Umax,Vmax)
,TRANSFORMATION_Fy(Fx,Fy,Fz,Umax,Vmax)
,TRANSFORMATION_Fz(Fx,Fy,Fz,Umax,Vmax)
);
/* Calcul de 'X', 'Y' et 'Z' pour (Umax,Vmax), */
INITIALISATION_POINT_2D(coinF2_UV
,F__cDENORMALISE_OX(Projection_OX(ASD1(coinF3_UV,x),ASD1(coinF3_UV,y),ASD1(coinF3_UV,z)))
,F__cDENORMALISE_OY(Projection_OY(ASD1(coinF3_UV,x),ASD1(coinF3_UV,y),ASD1(coinF3_UV,z)))
);
INITIALISATION_POINT_2D(coinI2_UV
,TRUN(ASD1(coinF2_UV,x))
,TRUN(ASD1(coinF2_UV,y))
);
/* Et projection sur le plan de l'image, ce qui donne le coin "superieur-droit". */
INITIALISATION_POINT_3D(coinF3_uV
,TRANSFORMATION_Fx(Fx,Fy,Fz,Umin,Vmax)
,TRANSFORMATION_Fy(Fx,Fy,Fz,Umin,Vmax)
,TRANSFORMATION_Fz(Fx,Fy,Fz,Umin,Vmax)
);
/* Calcul de 'X', 'Y' et 'Z' pour (Umin,Vmax), */
INITIALISATION_POINT_2D(coinF2_uV
,F__cDENORMALISE_OX(Projection_OX(ASD1(coinF3_uV,x),ASD1(coinF3_uV,y),ASD1(coinF3_uV,z)))
,F__cDENORMALISE_OY(Projection_OY(ASD1(coinF3_uV,x),ASD1(coinF3_uV,y),ASD1(coinF3_uV,z)))
);
INITIALISATION_POINT_2D(coinI2_uV
,TRUN(ASD1(coinF2_uV,x))
,TRUN(ASD1(coinF2_uV,y))
);
/* Et projection sur le plan de l'image, ce qui donne le coin "superieur-gauche". */
INITIALISATION_VECTEUR_2D(diagonaleF_uv_UV
,ASD1(coinF2_uv,x)
,ASD1(coinF2_uv,y)
,ASD1(coinF2_UV,x)
,ASD1(coinF2_UV,y)
);
/* Definition de la premiere diagonale du "quadrilatere", */
INITIALISATION_VECTEUR_2D(diagonaleF_uV_Uv
,ASD1(coinF2_uV,x)
,ASD1(coinF2_uV,y)
,ASD1(coinF2_Uv,x)
,ASD1(coinF2_Uv,y)
);
/* Definition de la deuxieme diagonale du "quadrilatere". */
Test(IFET(IZGE(profondeur)
,IFOU(IFGT(normF2D(diagonaleF_uv_UV),MIN2(pasX,pasY))
,IFGT(normF2D(diagonaleF_uV_Uv),MIN2(pasX,pasY))
)
)
)
Bblock
/* Lorsque le "quadrilatere" (uv,Uv,UV,uV) ne se reduit pas a un point, on subdivise */
/* les coordonnees 'u' et 'v'. */
/* Nota : le 'IZGE' est destine a prendre en compte le fait que 'SUBDIVISION- */
/* SURFACE' est appele deja dans 'visualisation_surface', et decremente une */
/* premiere fois 'profondeur' pour rien... */
SUBDIVISION_SURFACE(Umin,ADD2(Umin,MOYS(Umax,Umin))
,Vmin,ADD2(Vmin,MOYS(Vmax,Vmin))
);
SUBDIVISION_SURFACE(ADD2(Umin,MOYS(Umax,Umin)),Umax
,Vmin,ADD2(Vmin,MOYS(Vmax,Vmin))
);
SUBDIVISION_SURFACE(ADD2(Umin,MOYS(Umax,Umin)),Umax
,ADD2(Vmin,MOYS(Vmax,Vmin)),Vmax
);
SUBDIVISION_SURFACE(Umin,ADD2(Umin,MOYS(Umax,Umin))
,ADD2(Vmin,MOYS(Vmax,Vmin)),Vmax
);
Eblock
ATes
/* Lorsque le "quadrilatere" (uv,Uv,UV,uV) se reduit a un point, on genere l'image. */
Bblock
INITIALISATION_ACCROISSEMENT_3D(rayon_lumineux
,SOUS(ASI1(source_lumineuse,x),ASD1(coinF3_uv,x))
,SOUS(ASI1(source_lumineuse,y),ASD1(coinF3_uv,y))
,SOUS(ASI1(source_lumineuse,z),ASD1(coinF3_uv,z))
);
/* Calcul du rayon lumineux allant du point courant a la source lumineuse. */
INITIALISATION_ACCROISSEMENT_3D(normale
,PvectX(dXdu,dYdu,dZdu
,dXdv,dYdv,dZdv
)
,PvectY(dXdu,dYdu,dZdu
,dXdv,dYdv,dZdv
)
,PvectZ(dXdu,dYdu,dZdu
,dXdv,dYdv,dZdv
)
);
/* Calcul de la normale : */
/* */
/* X(N)=(((dY/du)*(dZ/dv))-((dZ/du)*(dY/dv))), */
/* Y(N)=(((dZ/du)*(dX/dv))-((dX/du)*(dZ/dv))), */
/* Z(N)=(((dX/du)*(dY/dv))-((dY/du)*(dX/dv))). */
/* */
EGAL(module_normale,pytF3D(normale));
/* Calcul du module de la normale. */
Test(IZLE(module_normale))
Bblock
PRINT_ATTENTION("le vecteur normal au quadrilatere courant a une longueur negative ou nulle");
CAL1(Prer9("coin inferieur-gauche : X(%g,%g) = %g Y(%g,%g) = %g Z(%g,%g) = %g\n"
,Umin,Vmin,ASD1(coinF3_uv,x)
,Umin,Vmin,ASD1(coinF3_uv,y)
,Umin,Vmin,ASD1(coinF3_uv,z)
)
);
CAL1(Prer9("coin inferieur-droit : X(%g,%g) = %g Y(%g,%g) = %g Z(%g,%g) = %g\n"
,Umax,Vmin,ASD1(coinF3_Uv,x)
,Umax,Vmin,ASD1(coinF3_Uv,y)
,Umax,Vmin,ASD1(coinF3_Uv,z)
)
);
CAL1(Prer9("coin superieur-droit : X(%g,%g) = %g Y(%g,%g) = %g Z(%g,%g) = %g\n"
,Umax,Vmax,ASD1(coinF3_UV,x)
,Umax,Vmax,ASD1(coinF3_UV,y)
,Umax,Vmax,ASD1(coinF3_UV,z)
)
);
CAL1(Prer9("coin superieur-gauche : X(%g,%g) = %g Y(%g,%g) = %g Z(%g,%g) = %g\n"
,Umin,Vmax,ASD1(coinF3_uV,x)
,Umin,Vmax,ASD1(coinF3_uV,y)
,Umin,Vmax,ASD1(coinF3_uV,z)
)
);
CAL1(Prer3("diagonale(uv,UV) = %g diagonale(uV,Uv) = %g pas = %d\n"
,normF2D(diagonaleF_uv_UV),normF2D(diagonaleF_uV_Uv),MIN2(pasX,pasY)
)
);
Eblock
ATes
Bblock
Test(TEST_MASQUE_ACTIF(ARRI(_cDENORMALISE_OX(Umin)),ARRI(_cDENORMALISE_OY(Vmin)),MASQUER_PARCOURS))
Bblock
TEST_Z_Buffer_(ASD1(coinI2_uv,x),ASD1(coinI2_uv,y),ASD1(coinF3_uv,z)
,BLOC(EGAL(cosinus
,MOIT(ADD2(DIVI(prdF3D(normale,rayon_lumineux)
,RACX(MUL2(module_normale,pytF3D(rayon_lumineux)))
)
,FU
)
)
);
/* Calcul du cosinus de l'angle que fait la normale avec le rayon lumineux ; etant */
/* donne qu'un cosinus est dans [-1,+1], on le ramene dans [0,1] pour en faire */
/* un coefficient de ponderation en lui appliquant la fonction f(x)=(1+x)/2. */
Test(EST_AUTORISE(anti_aliasing))
Bblock
storeF_point_valide(SOUS(ASD1(coinF2_uv,x),FLOT(ASD1(coinI2_uv,x)))
,X_erreurs
,ASD1(coinI2_uv,x),ASD1(coinI2_uv,y)
);
storeF_point_valide(SOUS(ASD1(coinF2_uv,y),FLOT(ASD1(coinI2_uv,y)))
,Y_erreurs
,ASD1(coinI2_uv,x),ASD1(coinI2_uv,y)
);
/* Et memorisation de l'erreur suivant les deux axes... */
Eblock
ATes
Bblock
Eblock
ETes
Test(EST_VRAI(filtrage_texture))
Bblock
CLIR(nombre_de_points);
CLIR(cumul_texture);
begin_colonneQ(DoIn
,ARRI(_cDENORMALISE_OY(TEXTURAGE_MINIMUM(Vmin,Vmax)))
,ARRI(_cDENORMALISE_OY(TEXTURAGE_MAXIMUM(Vmin,Vmax)))
,pasY
)
Bblock
begin_ligneQ(DoIn
,ARRI(_cDENORMALISE_OX(TEXTURAGE_MINIMUM(Umin,Umax)))
,ARRI(_cDENORMALISE_OX(TEXTURAGE_MAXIMUM(Umin,Umax)))
,pasX
)
Bblock
INCR(cumul_texture
,FLOT(NIVR(load_point_valide(texture,X,Y)))
);
INCR(nombre_de_points,I);
Eblock
end_ligneQ(EDoI)
Eblock
end_colonneQ(EDoI)
EGAL(cumul_texture,DIVI(cumul_texture,FLOT(nombre_de_points)));
Eblock
ATes
Bblock
EGAL(cumul_texture
,FLOT(NIVR(load_point_valide(texture
,ARRI(_cDENORMALISE_OX(Umin))
,ARRI(_cDENORMALISE_OY(Vmin))
)
)
)
);
Eblock
ETes
store_point_valide(GENP(NIVA(MUL2(cumul_texture
,cosinus
)
)
)
,imageAR
,ASD1(coinI2_uv,x),ASD1(coinI2_uv,y)
,FVARIABLE
);
)
);
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Eblock
ETes
Eblock
ETes
RETI(imageAR);
Eblock
EFonctionP
#undef TEXTURAGE_MAXIMUM
#undef TEXTURAGE_MINIMUM
#undef TEXTURAGE
#undef dZdv
#undef dZdv2
#undef dZdv1
#undef dZdu
#undef dZdu2
#undef dZdu1
#undef dYdv
#undef dYdv2
#undef dYdv1
#undef dYdu
#undef dYdu2
#undef dYdu1
#undef dXdv
#undef dXdv2
#undef dXdv1
#undef dXdu
#undef dXdu2
#undef dXdu1
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D U N O Y A U D E C O N V O L U T I O N : */
/* */
/*************************************************************************************************************************************/
#define EPAISSEUR_DU_CONTOUR \
UN \
/* Epaisseur du contour ou appliquer la convolution... */
#define DEMI_TAILLE_DU_NOYAU \
QUATRE \
/* "Demi-taille" du noyau de convolution suivant les deux axes. */
#define TAILLE_DU_NOYAU \
DOUP(DEMI_TAILLE_DU_NOYAU) \
/* Taille du noyau de convolution suivant les deux axes. */
#define VOLUME_DU_NOYAU \
MUL2(TAILLE_DU_NOYAU,TAILLE_DU_NOYAU) \
/* Nombre d'elements contenus dans le noyau de convolution. */
#define DEBUT_DU_NOYAU \
UN \
/* Premier element du noyau. */
#define FIN_DU_NOYAU \
LSTX(DEBUT_DU_NOYAU,VOLUME_DU_NOYAU) \
/* Dernier element du noyau. */
#define NOYAU_DE_CONVOLUTION(numero,valeur) \
Bblock \
EGAL(ITb1(noyau_de_convolution,INDX(numero,DEBUT_DU_NOYAU)),valeur); \
EGAL(ITb1(inhibition_du_noyau_de_convolution,INDX(numero,DEBUT_DU_NOYAU)),ACTIF); \
Eblock \
/* Definition des elements du noyau de convolution. */
#define FONCTION_DE_CONVOLUTION(valeur) \
NEUT(valeur) \
/* A priori, on prend une fonction neutre... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* R E P R E S E N T A T I O N D ' U N E S U R F A C E P A R S U B D I V I S I O N R E C U R S I V E : */
/* */
/*************************************************************************************************************************************/
BFonctionP
DEFV(Common,DEFV(FonctionP,POINTERp(Ivisualisation_surface(imageAR
,texture,filtrage_texture
,ARGUMENT_FONCTION(Fx),ARGUMENT_FONCTION(Fy),ARGUMENT_FONCTION(Fz)
,ARGUMENT_POINTERs(translation)
,Umin,Umax
,Vmin,Vmax
,profondeur
,ARGUMENT_POINTERs(source_lumineuse)
,anti_aliasing
,epsilon_discontinuites_Z
,convolution
,genere_discontinuites
,ARGUMENT_FACULTATIF(discontinuites)
)
)
)
)
DEFV(Argument,DEFV(image,imageAR));
/* Image Argument et Resultat, dans laquelle on genere la surface. */
DEFV(Argument,DEFV(image,texture));
/* Texture a "mapper" sur la surface. */
DEFV(Argument,DEFV(Logical,filtrage_texture));
/* Indique si la texture doit etre filtree ('VRAI') afin d'avoir un rendu */
/* meilleur ou etre appliquee brutalement ('FAUX'). */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fx)));
/* Definition de la fonction 'Fx(u,v)', */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fy)));
/* Definition de la fonction 'Fy(u,v)', */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fz)));
/* Definition de la fonction 'Fz(u,v)'. */
DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation)));
/* Translation tri-dimensionnelle normalisee de la surface. */
DEFV(Argument,DEFV(Float,Umin));
/* Valeur inferieure de la coordonnee 'u', */
DEFV(Argument,DEFV(Float,Umax));
/* Valeur superieure de la coordonnee 'u'. */
DEFV(Argument,DEFV(Float,Vmin));
/* Valeur inferieure de la coordonnee 'v', */
DEFV(Argument,DEFV(Float,Vmax));
/* Valeur superieure de la coordonnee 'v'. */
DEFV(Argument,DEFV(Int,profondeur));
/* Donne en permanence le niveau (decroissant) de la recursivite. */
DEFV(Argument,DEFV(pointF_3D,POINTERs(source_lumineuse)));
/* Position de la source lumineuse. */
DEFV(Argument,DEFV(Logical,anti_aliasing));
/* Indique si le contour apparent de la surface doit etre anti-aliase ('AUTORISE') */
/* ou pas ('INTERDIT') ; on notera que ce traitement n'est fait qu'a condition */
/* que la 'profondeur' demandee egale 'PROFONDEUR_SUBDIVISION'. */
DEFV(Argument,DEFV(Float,epsilon_discontinuites_Z));
/* 'epsilon' permettant de decreter qu'il a discontinuites en 'Z'. */
DEFV(Argument,DEFV(Logical,convolution));
/* Cet indicateur, valide uniquement s'il y a un traitement anti-aliasing, */
/* indique s'il faut ('AUTORISE') ou pas ('INTERDIT') convoluer le contour */
/* de discontinuites en 'Z'. */
DEFV(Argument,DEFV(Logical,genere_discontinuites));
/* Cet indicateur controle le calcul de l'image des 'discontinuites', c'est-a-dire */
/* les lignes de discontinuites en 'Z', et par exemple les contours apparents ; cet */
/* indicateur n'a de sens que si l'anti-aliasing est demande. */
DEFV(Argument,DEFV(image,discontinuites));
/* Image donnant les lignes de discontinuites en 'Z' ; cet argument est */
/* facultatif... Enfin, on notera que l'initialisation de cette image est */
/* laissee a la discretion du demandeur. Les couleurs sont ainsi utilisees : */
/* */
/* NOIR : pour le fond, */
/* GRIS : pour l'"interieur" de la surface, et enfin, */
/* BLANC : pour le contour. */
/* */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(deltaI_2D,voisin);
/* Afin de disposer de l'increment de passage du point courant {X,Y} a l'un */
/* de ses voisins. */
BDEFV(imageF,X_erreurs);
BDEFV(imageF,Y_erreurs);
/* Matrices contenant les erreurs commises en passant de 'coinF2_uv' */
/* a 'coinI2_uv' lorsque l'anti-aliasing est demande respectivement le */
/* Long de l'axe 'OX' et de l'axe 'OY'. */
BDEFV(image,image_de_manoeuvre);
/* On memorise dans cette image le resultat non anti-aliase du calcul de la */
/* surface. */
DEFV(Logical,INIT(traitement_anti_aliasing,LUNDEF));
/* Cet indicateur logique precise, lorsque l'anti-aliasing a ete demande */
/* pour cette surface, si pour le point courant {X,Y} il y a lieu de le */
/* faire ('VRAI') ou si cela n'est pas utile ('FAUX'). */
DEFV(Float,INIT(cumul_des_niveaux_discontinus,FLOT__UNDEF));
/* Cumul du niveau de tous les points qui presentent une discontinuite en 'Z' */
/* avec le point courant {X,Y}. */
DEFV(Int,INIT(nombre_de_voisins_discontinus,UNDEF));
/* Nombre de points qui presentent une discontinuite en 'Z'avec le point */
/* courant {X,Y}. */
DEFV(Logical,DTb1(niveaux_cumulables,COULEURS));
/* Definit les niveaux qui sont cumulables lors du calcul de 'Pconvolution()'. */
DEFV(Int,INIT(volume_du_noyau_de_convolution,VOLUME_DU_NOYAU));
/* Nombre de points du noyau de convolution. */
DEFV(Int,INIT(index,UNDEF));
/* Pour parcourir le noyau de convolution. */
DEFV(Float,DTb1(noyau_de_convolution,VOLUME_DU_NOYAU));
/* Noyau de convolution memorise par un vecteur contenant en fait une spirale */
/* carree des coefficients de ponderation. */
DEFV(Logical,DTb1(inhibition_du_noyau_de_convolution,VOLUME_DU_NOYAU));
/* Precise pour chaque element du noyau s'il est 'ACTIF' (a utiliser dans */
/* les calculs) ou 'INACTIF' (a ignorer et a ne pas compter...). */
/*..............................................................................................................................*/
Test(IFET(EST_INTERDIT(anti_aliasing)
,EST_AUTORISE(genere_discontinuites)
)
)
Bblock
PRINT_ATTENTION("les discontinuites demandent l'anti-aliasing");
Eblock
ATes
Bblock
Eblock
ETes
Test(IFET(EST_INTERDIT(anti_aliasing)
,EST_AUTORISE(convolution)
)
)
Bblock
PRINT_ATTENTION("la convolution du contour de discontinuite en 'Z' demande l'anti-aliasing");
Eblock
ATes
Bblock
Eblock
ETes
INITIALISATION_TRANSFORMATION;
/* Au cas ou la transformation geometrique tri-dimensionnelle ne serait */
/* pas initialisee, on le fait sur la transformation unite. */
Test(IFET(EST_AUTORISE(anti_aliasing)
,IFEQ(profondeur,PROFONDEUR_SUBDIVISION)
)
)
Bblock
CALS(IFinitialisation(X_erreurs,PAS_D_ERREUR_D_ALIASING));
CALS(IFinitialisation(Y_erreurs,PAS_D_ERREUR_D_ALIASING));
/* On initialise les matrices d'erreurs sur "pas d'erreur"... */
Eblock
ATes
Bblock
Eblock
ETes
SUBDIVISION_SURFACE(Umin,Umax
,Vmin,Vmax
);
/* Visualisation de la surface par subdivision et sans traitement d'anti-aliasing. */
Test(IFET(EST_AUTORISE(anti_aliasing)
,IFEQ(profondeur,PROFONDEUR_SUBDIVISION)
)
)
Bblock
CALS(Imove(image_de_manoeuvre,imageAR));
/* On sauvegarde la version non anti-aliasee de la surface. */
begin_image
Bblock
Test(IFOU(IFNE(loadF_point_valide(X_erreurs,X,Y),PAS_D_ERREUR_D_ALIASING)
,IFNE(loadF_point_valide(Y_erreurs,X,Y),PAS_D_ERREUR_D_ALIASING)
)
)
Bblock
/* Nota : les points {X,Y} pour lesquels ce test est faux, sont */
/* des points qui n'ont pas ete atteints par la surface projetee, */
/* sauf malheureuse exception... */
Test(EST_AUTORISE(genere_discontinuites))
Bblock
store_point(GRIS,discontinuites,X,Y,FVARIABLE);
/* Et on memorise l'"interieur" de la surface... */
Eblock
ATes
Bblock
Eblock
ETes
EGAL(traitement_anti_aliasing,FAUX);
/* A priori, il n'y aura pas de traitement a faire pour le point courant {X,Y}. */
CLIR(cumul_des_niveaux_discontinus);
/* Initialisation du cumul du niveau de tous les points qui presentent */
/* une discontinuite en 'Z' avec le point courant {X,Y}. */
CLIR(nombre_de_voisins_discontinus);
/* Et initialisation de leur nombre... */
DoIn(ASD1(voisin,dy),NEGA(pasY),pasY,pasY)
Bblock
DoIn(ASD1(voisin,dx),NEGA(pasX),pasX,pasX)
Bblock
Test(IFOU(IZNE(ASD1(voisin,dx)),IZNE(ASD1(voisin,dy))))
Bblock
/* On elimine le point courant ; il est en effet inutile de le tester... */
Test(IFGT(SOUA(loadF_point_valide(Z_Buffer
,ADD2(X,ASD1(voisin,dx)),ADD2(Y,ASD1(voisin,dy))
)
,loadF_point_valide(Z_Buffer
,X,Y
)
)
,epsilon_discontinuites_Z
)
)
Bblock
/* Le test d'aliasing est en fait un test de discontinuite dans le 'Z-Buffer' ; */
/* il y a probleme, si deux points voisins en 'X' et 'Y' ne le sont pas en 'Z'... */
EGAL(traitement_anti_aliasing,VRAI);
/* Il faudra traiter le point courant... */
INCR(cumul_des_niveaux_discontinus
,load_point_valide(image_de_manoeuvre,ADD2(X,ASD1(voisin,dx)),ADD2(Y,ASD1(voisin,dy)))
);
INCR(nombre_de_voisins_discontinus,I);
/* Et on compte et cumule les voisins "discontinus"... */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
EDoI
Eblock
EDoI
Test(IL_FAUT(traitement_anti_aliasing))
Bblock
store_point(BARY(DIVI(cumul_des_niveaux_discontinus,FLOT(nombre_de_voisins_discontinus))
,load_point(image_de_manoeuvre,X,Y)
,DIVI(GpytF2D(loadF_point_valide(X_erreurs,X,Y)
,loadF_point_valide(Y_erreurs,X,Y)
)
,GpytF2D(ERREUR_MAXIMALE
,ERREUR_MAXIMALE
)
)
)
,imageAR
,X,Y
,FVARIABLE
);
/* Et le point courant {X,Y} est remplace par une valeur convoluee a partir */
/* de son voisinage. */
/* */
/* La procedure 'GpytF2D(...)' a ete introduite le 20021120102824. */
Test(EST_AUTORISE(genere_discontinuites))
Bblock
store_point(BLANC,discontinuites,X,Y,FVARIABLE);
/* Et on memorise les discontinuites. */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
end_image
Test(EST_AUTORISE(convolution))
Bblock
CALS(Imove(image_de_manoeuvre,imageAR));
/* On sauvegarde la nouvelle version de la surface. */
BoIn(niveau,NOIR,BLANC,PAS_COULEURS)
Bblock
EGAL(ITb1(niveaux_cumulables,INDX(niveau,NOIR)),VRAI);
/* Initialisation telle que tous les niveaux soient "cumulables". */
Eblock
EBoI
DoIn(index,DEBUT_DU_NOYAU,FIN_DU_NOYAU,I)
Bblock
NOYAU_DE_CONVOLUTION(index,FONCTION_DE_CONVOLUTION(FU));
/* Initialisation du noyau de convolution, element par element. */
Eblock
EDoI
begin_image
Bblock
Test(IFOU(IFNE(loadF_point_valide(X_erreurs,X,Y),PAS_D_ERREUR_D_ALIASING)
,IFNE(loadF_point_valide(Y_erreurs,X,Y),PAS_D_ERREUR_D_ALIASING)
)
)
Bblock
/* Nota : les points {X,Y} pour lesquels ce test est faux, sont */
/* des points qui n'ont pas ete atteints par la surface projetee, */
/* sauf malheureuse exception... */
EGAL(traitement_anti_aliasing,FAUX);
/* A priori, il n'y aura pas de traitement a faire pour le point courant {X,Y}. */
DoIn(ASD1(voisin,dy),NEGA(MUL2(EPAISSEUR_DU_CONTOUR,pasY)),MUL2(EPAISSEUR_DU_CONTOUR,pasY),pasY)
Bblock
DoIn(ASD1(voisin,dx),NEGA(MUL2(EPAISSEUR_DU_CONTOUR,pasX)),MUL2(EPAISSEUR_DU_CONTOUR,pasX),pasX)
Bblock
Test(IFOU(IZNE(ASD1(voisin,dx)),IZNE(ASD1(voisin,dy))))
Bblock
/* On elimine le point courant ; il est en effet inutile de le tester... */
Test(IFGT(SOUA(loadF_point_valide(Z_Buffer
,ADD2(X,ASD1(voisin,dx)),ADD2(Y,ASD1(voisin,dy))
)
,loadF_point_valide(Z_Buffer
,X,Y
)
)
,epsilon_discontinuites_Z
)
)
Bblock
/* Le test d'aliasing est en fait un test de discontinuite dans le 'Z-Buffer' ; */
/* il y a probleme, si deux points voisins en 'X' et 'Y' ne le sont pas en 'Z'... */
EGAL(traitement_anti_aliasing,VRAI);
/* Il faudra traiter le point courant... */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
EDoI
Eblock
EDoI
Test(IL_FAUT(traitement_anti_aliasing))
Bblock
store_point(Pconvolution(image_de_manoeuvre,image_de_manoeuvre
,X,Y
,niveaux_cumulables
,volume_du_noyau_de_convolution
,noyau_de_convolution
,inhibition_du_noyau_de_convolution
)
,imageAR
,X,Y
,FVARIABLE
);
/* Et le point courant {X,Y} est remplace par une valeur convoluee a partir */
/* de son voisinage. */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
end_image
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
EDEFV(image,image_de_manoeuvre);
/* On memorise dans cette image le resultat non anti-aliase du calcul de la */
/* surface. */
EDEFV(imageF,Y_erreurs);
EDEFV(imageF,X_erreurs);
/* Matrices contenant les erreurs commises en passant de 'coinF2_uv' */
/* a 'coinI2_uv' lorsque l'anti-aliasing est demande respectivement le */
/* Long de l'axe 'OX' et de l'axe 'OY'. */
RETI(imageAR);
Eblock
EFonctionP
#undef FONCTION_DE_CONVOLUTION
#undef NOYAU_DE_CONVOLUTION
#undef FIN_DU_NOYAU
#undef DEBUT_DU_NOYAU
#undef VOLUME_DU_NOYAU
#undef TAILLE_DU_NOYAU
#undef DEMI_TAILLE_DU_NOYAU
#undef EPAISSEUR_DU_CONTOUR
#undef SUBDIVISION_SURFACE
#undef PROFONDEUR_SUBDIVISION
#undef EPSILON_ANTI_ALIASING
#undef PAS_D_ERREUR_D_ALIASING
#undef ERREUR_MAXIMALE
#undef TRUN
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* R E M P L I S S A G E D ' U N E F A C E T T E : */
/* */
/*************************************************************************************************************************************/
BFonctionP
#define COORDONNEE_BARYCENTRIQUE_A \
COND(IL_FAUT(utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes) \
,DIVI(aire_du_triangle_MBC,aire_du_triangle_ABC) \
,coordonnee_barycentrique_A \
)
#define COORDONNEE_BARYCENTRIQUE_B \
COND(IL_FAUT(utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes) \
,DIVI(aire_du_triangle_MCA,aire_du_triangle_ABC) \
,coordonnee_barycentrique_B \
)
#define COORDONNEE_BARYCENTRIQUE_C \
COND(IL_FAUT(utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes) \
,DIVI(aire_du_triangle_MAB,aire_du_triangle_ABC) \
,coordonnee_barycentrique_C \
)
/* Definition des ponderateurs reellement utilises... */
DEFV(Common,DEFV(FonctionP,POINTERp(Iremplissage_d_une_facette(imageAR
,ARGUMENT_POINTERs(sommet_A),niveau_du_sommet_A
,ARGUMENT_POINTERs(sommet_B),niveau_du_sommet_B
,ARGUMENT_POINTERs(sommet_C),niveau_du_sommet_C
,utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes
)
)
)
)
DEFV(Argument,DEFV(image,imageAR));
/* Image Argument et Resultat, dans laquelle on genere la facette. */
DEFV(Argument,DEFV(pointF_3D,POINTERs(sommet_A)));
/* Sommet 'A' de la facette dans [0,1]x[0,1]x[0,1], */
DEFV(Argument,DEFV(genere_p,niveau_du_sommet_A));
/* Et son niveau de gris. */
DEFV(Argument,DEFV(pointF_3D,POINTERs(sommet_B)));
/* Sommet 'B' de la facette dans [0,1]x[0,1]x[0,1], */
DEFV(Argument,DEFV(genere_p,niveau_du_sommet_B));
/* Et son niveau de gris. */
DEFV(Argument,DEFV(pointF_3D,POINTERs(sommet_C)));
/* Sommet 'C' de la facette dans [0,1]x[0,1]x[0,1]. */
DEFV(Argument,DEFV(genere_p,niveau_du_sommet_C));
/* Et son niveau de gris. */
DEFV(Argument,DEFV(Logical,utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes));
/* Indique s'il faut utiliser en tant que ponderateurs directement les coordonnees */
/* barycentriques ('FAUX') ou bien l'aire des triangles ('VRAI') lors de l'interpolation */
/* a l'interieure des facettes... */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(pointI_2D,sommet_projete_A);
/* Sommet 'A' de la facette projete dans le plan de l'image, */
DEFV(pointI_2D,sommet_projete_B);
/* Sommet 'B' de la facette projete dans le plan de l'image, */
DEFV(pointI_2D,sommet_projete_C);
/* Sommet 'C' de la facette projete dans le plan de l'image. */
DEFV(Float,INIT(determinant,FLOT__UNDEF));
/* Determinant de resolution du systeme en {alpha,beta,gamma}. */
/*..............................................................................................................................*/
INITIALISATION_POINT_2D(sommet_projete_A
,_cDENORMALISE_OX(Projection_OX(ASI1(sommet_A,x),ASI1(sommet_A,y),ASI1(sommet_A,z)))
,_cDENORMALISE_OY(Projection_OY(ASI1(sommet_A,x),ASI1(sommet_A,y),ASI1(sommet_A,z)))
);
/* Sommet 'A' de la facette projete dans le plan de l'image, */
INITIALISATION_POINT_2D(sommet_projete_B
,_cDENORMALISE_OX(Projection_OX(ASI1(sommet_B,x),ASI1(sommet_B,y),ASI1(sommet_B,z)))
,_cDENORMALISE_OY(Projection_OY(ASI1(sommet_B,x),ASI1(sommet_B,y),ASI1(sommet_B,z)))
);
/* Sommet 'B' de la facette projete dans le plan de l'image, */
INITIALISATION_POINT_2D(sommet_projete_C
,_cDENORMALISE_OX(Projection_OX(ASI1(sommet_C,x),ASI1(sommet_C,y),ASI1(sommet_C,z)))
,_cDENORMALISE_OY(Projection_OY(ASI1(sommet_C,x),ASI1(sommet_C,y),ASI1(sommet_C,z)))
);
/* Sommet 'C' de la facette projete dans le plan de l'image. */
EGAL(determinant
,DET3(FLOT(ASD1(sommet_projete_A,x)),FLOT(ASD1(sommet_projete_B,x)),FLOT(ASD1(sommet_projete_C,x))
,FLOT(ASD1(sommet_projete_A,y)),FLOT(ASD1(sommet_projete_B,y)),FLOT(ASD1(sommet_projete_C,y))
,FU,FU,FU
)
);
/* Calcul du determinant necessaire a calculer {alpha,beta,gamma}. */
Test(IZNE(determinant))
Bblock
begin_colonneQ(DoIn
,MIN3(ASD1(sommet_projete_A,y),ASD1(sommet_projete_B,y),ASD1(sommet_projete_C,y))
,MAX3(ASD1(sommet_projete_A,y),ASD1(sommet_projete_B,y),ASD1(sommet_projete_C,y))
,pasY
)
Bblock
begin_ligneQ(DoIn
,MIN3(ASD1(sommet_projete_A,x),ASD1(sommet_projete_B,x),ASD1(sommet_projete_C,x))
,MAX3(ASD1(sommet_projete_A,x),ASD1(sommet_projete_B,x),ASD1(sommet_projete_C,x))
,pasX
)
Bblock
DEFV(Float,INIT(coordonnee_barycentrique_A
,DIVI(DET3(FLOT(X),FLOT(ASD1(sommet_projete_B,x)),FLOT(ASD1(sommet_projete_C,x))
,FLOT(Y),FLOT(ASD1(sommet_projete_B,y)),FLOT(ASD1(sommet_projete_C,y))
,COORDONNEE_BARYCENTRIQUE_MAXIMALE,FU,FU
)
,determinant
)
)
);
DEFV(Float,INIT(coordonnee_barycentrique_B
,DIVI(DET3(FLOT(ASD1(sommet_projete_A,x)),FLOT(X),FLOT(ASD1(sommet_projete_C,x))
,FLOT(ASD1(sommet_projete_A,y)),FLOT(Y),FLOT(ASD1(sommet_projete_C,y))
,FU,COORDONNEE_BARYCENTRIQUE_MAXIMALE,FU
)
,determinant
)
)
);
DEFV(Float,INIT(coordonnee_barycentrique_C
,DIVI(DET3(FLOT(ASD1(sommet_projete_A,x)),FLOT(ASD1(sommet_projete_B,x)),FLOT(X)
,FLOT(ASD1(sommet_projete_A,y)),FLOT(ASD1(sommet_projete_B,y)),FLOT(Y)
,FU,FU,COORDONNEE_BARYCENTRIQUE_MAXIMALE
)
,determinant
)
)
);
/* Calcul des coordonnees barycentriques {alpha,beta,gamma} pour le point {X,Y} courant. */
Test(I3ET(IFINff(coordonnee_barycentrique_A,COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE)
,IFINff(coordonnee_barycentrique_B,COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE)
,IFINff(coordonnee_barycentrique_C,COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE)
)
)
Bblock
/* Cas ou le point M(X,Y) est dans le triangle {A,B,C} projete : on le trace... */
DEFV(Float,INIT(minimum_de_la_coordonnee_z,MIN3(ASI1(sommet_A,z),ASI1(sommet_B,z),ASI1(sommet_C,z))));
DEFV(Float,INIT(maximum_de_la_coordonnee_z,MAX3(ASI1(sommet_A,z),ASI1(sommet_B,z),ASI1(sommet_C,z))));
/* Extrema de la coordonnee 'Z'. */
DEFV(Float,INIT(mimimum_du_niveau,MIN3(niveau_du_sommet_A,niveau_du_sommet_B,niveau_du_sommet_C)));
DEFV(Float,INIT(maximum_du_niveau,MAX3(niveau_du_sommet_A,niveau_du_sommet_B,niveau_du_sommet_C)));
/* Extrema du niveau. */
DEFV(Float,INIT(coordonnee_z_du_point_courant
,LIZ3(coordonnee_barycentrique_A,ASI1(sommet_A,z)
,coordonnee_barycentrique_B,ASI1(sommet_B,z)
,coordonnee_barycentrique_C,ASI1(sommet_C,z)
)
)
);
DEFV(genere_p,INIT(niveau_du_point_courant,NIVEAU_UNDEF));
/* Coordonnee 'Z' et niveau du point courant M(X,Y). */
DEFV(Float,INIT(aire_du_triangle_ABC
,AIRE_TRIANGLE_3D(ASD1(sommet_projete_A,x),ASD1(sommet_projete_A,y),ASI1(sommet_A,z)
,ASD1(sommet_projete_B,x),ASD1(sommet_projete_B,y),ASI1(sommet_B,z)
,ASD1(sommet_projete_C,x),ASD1(sommet_projete_C,y),ASI1(sommet_C,z)
)
)
);
DEFV(Float,INIT(aire_du_triangle_MAB
,AIRE_TRIANGLE_3D(X,Y,coordonnee_z_du_point_courant
,ASD1(sommet_projete_A,x),ASD1(sommet_projete_A,y),ASI1(sommet_A,z)
,ASD1(sommet_projete_B,x),ASD1(sommet_projete_B,y),ASI1(sommet_B,z)
)
)
);
DEFV(Float,INIT(aire_du_triangle_MBC
,AIRE_TRIANGLE_3D(X,Y,coordonnee_z_du_point_courant
,ASD1(sommet_projete_B,x),ASD1(sommet_projete_B,y),ASI1(sommet_B,z)
,ASD1(sommet_projete_C,x),ASD1(sommet_projete_C,y),ASI1(sommet_C,z)
)
)
);
DEFV(Float,INIT(aire_du_triangle_MCA
,AIRE_TRIANGLE_3D(X,Y,coordonnee_z_du_point_courant
,ASD1(sommet_projete_C,x),ASD1(sommet_projete_C,y),ASI1(sommet_C,z)
,ASD1(sommet_projete_A,x),ASD1(sommet_projete_A,y),ASI1(sommet_A,z)
)
)
);
/* Aires des triangles {AB,AC}, {MA,MB}, {MB,MC} et {MC,MA}. */
EGAL(niveau_du_point_courant
,GENP(NIVA(INTE(LIZ3(COORDONNEE_BARYCENTRIQUE_A,FLOT(NIVR(niveau_du_sommet_A))
,COORDONNEE_BARYCENTRIQUE_B,FLOT(NIVR(niveau_du_sommet_B))
,COORDONNEE_BARYCENTRIQUE_C,FLOT(NIVR(niveau_du_sommet_C))
)
)
)
)
);
/* Niveau du point courant M(X,Y). */
Test(I3OU(IFEXff(coordonnee_z_du_point_courant,minimum_de_la_coordonnee_z,maximum_de_la_coordonnee_z)
,IFEXff(niveau_du_point_courant,mimimum_du_niveau,maximum_du_niveau)
,IFGT(ADD3(aire_du_triangle_MAB,aire_du_triangle_MBC,aire_du_triangle_MCA),aire_du_triangle_ABC)
)
)
Bblock
DEBU(PRINT_ERREUR("il y a un probleme d'interpolation barycentrique"));
DEBU(CAL1(Prer4("sommet A = (%g,%g,%g;%d)\n"
,ASI1(sommet_A,x),ASI1(sommet_A,y),ASI1(sommet_A,z)
,niveau_du_sommet_A
)
)
);
DEBU(CAL1(Prer4("sommet B = (%g,%g,%g;%d)\n"
,ASI1(sommet_B,x),ASI1(sommet_B,y),ASI1(sommet_B,z)
,niveau_du_sommet_B
)
)
);
DEBU(CAL1(Prer4("sommet C = (%g,%g,%g;%d)\n"
,ASI1(sommet_C,x),ASI1(sommet_C,y),ASI1(sommet_C,z)
,niveau_du_sommet_C
)
)
);
DEBU(CAL1(Prer4("point courant = (%d,%d,%g;%d)\n"
,X,Y
,coordonnee_z_du_point_courant
,niveau_du_point_courant
)
)
);
DEBU(CAL1(Prer1("aire(ABC) = %g\n",aire_du_triangle_ABC)));
DEBU(CAL1(Prer1("aire(MAB) = %g\n",aire_du_triangle_MAB)));
DEBU(CAL1(Prer1("aire(MBC) = %g\n",aire_du_triangle_MBC)));
DEBU(CAL1(Prer1("aire(MCA) = %g\n",aire_du_triangle_MCA)));
DEBU(CAL1(Prer1("aire(MAB) + aire(MBC) + aire(MCA) = %g\n"
,ADD3(aire_du_triangle_MAB,aire_du_triangle_MBC,aire_du_triangle_MCA)
)
)
);
DEBU(CAL1(Prer3("coordonnees barycentriques = (%g,%g,%g)\n"
,coordonnee_barycentrique_A
,coordonnee_barycentrique_B
,coordonnee_barycentrique_C
)
)
);
EGAL(coordonnee_z_du_point_courant
,MAX2(minimum_de_la_coordonnee_z
,MIN2(maximum_de_la_coordonnee_z
,coordonnee_z_du_point_courant
)
)
);
EGAL(niveau_du_point_courant
,MAX2(mimimum_du_niveau
,MIN2(maximum_du_niveau
,niveau_du_point_courant
)
)
);
/* Et on force la coordonnee 'Z' et le niveau s'il y a eu un probleme d'interpolation (qui */
/* est en fait un probleme d'arrondi en general...). */
Eblock
ATes
Bblock
Eblock
ETes
store_point_3D(niveau_du_point_courant
,imageAR
,X,Y
,coordonnee_z_du_point_courant
);
/* Trace du point courant M(X,Y) en interpolant les niveaux et la troisieme coordonnee */
/* des trois sommets {A,B,C} de la facette projetee... */
Eblock
ATes
Bblock
/* Cas ou le point M(X,Y) n'est pas dans le triangle {A,B,C} projete : on l'ignore. */
Eblock
ETes
Eblock
end_ligneQ(EDoI)
Eblock
end_colonneQ(EDoI)
Eblock
ATes
Bblock
/* Le determinant nul ne doit plus etre considere comme une erreur, car, en effet, il est */
/* facile d'avoir des facettes degenerees (voir ce qui se passe au voisinage du pole d'une */
/* sphere maillee a l'aide de ses meridiens et de ses paralleles...). */
DEBU(PRINT_ERREUR("le determinant est nul ; les trois points projetes doivent etre alignes ou confondus"));
DEBU(CAL1(Prer2("A = (%d,%d)\n",ASD1(sommet_projete_A,x),ASD1(sommet_projete_A,y))));
DEBU(CAL1(Prer2("B = (%d,%d)\n",ASD1(sommet_projete_B,x),ASD1(sommet_projete_B,y))));
DEBU(CAL1(Prer2("C = (%d,%d)\n",ASD1(sommet_projete_C,x),ASD1(sommet_projete_C,y))));
DEBU(PRINT_ERREUR("la facette n'est pas tracee"));
DEBU(CAL1(Prer3("A = (%g,%g,%g)\n",ASI1(sommet_A,x),ASI1(sommet_A,y),ASI1(sommet_A,z))));
DEBU(CAL1(Prer3("B = (%g,%g,%g)\n",ASI1(sommet_B,x),ASI1(sommet_B,y),ASI1(sommet_B,z))));
DEBU(CAL1(Prer3("C = (%g,%g,%g)\n",ASI1(sommet_C,x),ASI1(sommet_C,y),ASI1(sommet_C,z))));
Eblock
ETes
RETI(imageAR);
Eblock
#undef COORDONNEE_BARYCENTRIQUE_A
#undef COORDONNEE_BARYCENTRIQUE_B
#undef COORDONNEE_BARYCENTRIQUE_C
EFonctionP
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D U " Q U A D R I L A T E R E " D E B A S E : */
/* */
/*************************************************************************************************************************************/
#define coordonnee_Umin \
coordonnee_U \
/* Pour definir le "cote gauche", */
#define coordonnee_Umax \
ADD2(coordonnee_U,pas_U) \
/* Pour definir le "cote droit", */
#define coordonnee_Vmin \
coordonnee_V \
/* Pour definir le "cote bas", */
#define coordonnee_Vmax \
ADD2(coordonnee_V,pas_V) \
/* Pour definir le "cote haut". */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S D E R I V E E S P A R T I E L L E S : */
/* */
/* */
/* Nota : */
/* */
/* Les derivees partielles sont */
/* calculees par des differences a */
/* 'u' ou 'v' constant (suivant le */
/* cas...) avec suppression des */
/* points singuliers (en calculant */
/* la difference "un peu plus loin" */
/* lorsqu'elle est nulle...). */
/* */
/*************************************************************************************************************************************/
/* La procedure 'DERIVATION_PARTIELLE(...)' a ete introduite le 20060317191007 ci-apres... */
#define dXdu \
DERIVATION_PARTIELLE(ASD1(coinF3_UV,x),ASD1(coinF3_uv,x),SOUS(Umax,Umin))
#define dXdv \
DERIVATION_PARTIELLE(ASD1(coinF3_uV,x),ASD1(coinF3_Uv,x),SOUS(Umax,Umin))
/* DX/du et dX/dv, */
#define dYdu \
DERIVATION_PARTIELLE(ASD1(coinF3_UV,y),ASD1(coinF3_uv,y),SOUS(Umax,Umin))
#define dYdv \
DERIVATION_PARTIELLE(ASD1(coinF3_uV,y),ASD1(coinF3_Uv,y),SOUS(Umax,Umin))
/* DY/du et dY/dv, */
#define dZdu \
DERIVATION_PARTIELLE(ASD1(coinF3_UV,z),ASD1(coinF3_uv,z),SOUS(Umax,Umin))
#define dZdv \
DERIVATION_PARTIELLE(ASD1(coinF3_uV,z),ASD1(coinF3_Uv,z),SOUS(Umax,Umin))
/* DZ/du et dZ/dv. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D U T E X T U R A G E D U M A I L L A G E : */
/* */
/*************************************************************************************************************************************/
#define TEXTURAGE_DU_MAILLAGE(u,v,ponderation) \
GENP(NIVA(MUL2(ponderation \
,FLOT(NIVR(load_point_valide(texture_du_maillage \
,_cDENORMALISE_OX(u) \
,_cDENORMALISE_OY(v) \
) \
) \
) \
) \
) \
) \
/* Pour definir le "cote gauche", */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* R E P R E S E N T A T I O N E N " F I L D E F E R " D ' U N E S U R F A C E : */
/* */
/*************************************************************************************************************************************/
BFonctionP
DEFV(Common,DEFV(FonctionP,POINTERp(Ifil_de_fer_surface(ARGUMENT_FONCTION(Fx),ARGUMENT_FONCTION(Fy),ARGUMENT_FONCTION(Fz)
,ARGUMENT_POINTERs(translation)
,Umin,Umax
,nombre_de_pas_U
,Vmin,Vmax
,nombre_de_pas_V
,remplir_les_facettes
,texture_du_maillage
,ARGUMENT_POINTERs(source_lumineuse)
,utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes
)
)
)
)
/* ATTENTION : l'image Resultat, dans laquelle on genere la surface, est 'ImageG'. */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fx)));
/* Definition de la fonction 'Fx(u,v)', */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fy)));
/* Definition de la fonction 'Fy(u,v)', */
DEFV(Argument,DEFV(Float,afPOINTEUR(Fz)));
/* Definition de la fonction 'Fz(u,v)'. */
DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation)));
/* Translation tri-dimensionnelle normalisee de la surface. */
DEFV(Argument,DEFV(Float,Umin));
/* Valeur inferieure de la coordonnee 'u', */
DEFV(Argument,DEFV(Float,Umax));
/* Valeur superieure de la coordonnee 'u'. */
DEFV(Argument,DEFV(Int,nombre_de_pas_U));
/* Nombre de pas pour parcourir [Umin,Umax], */
DEFV(Argument,DEFV(Float,Vmin));
/* Valeur inferieure de la coordonnee 'v', */
DEFV(Argument,DEFV(Float,Vmax));
/* Valeur superieure de la coordonnee 'v'. */
DEFV(Argument,DEFV(Int,nombre_de_pas_V));
/* Nombre de pas pour parcourir [Vmin,Vmax]. */
DEFV(Argument,DEFV(Logical,remplir_les_facettes));
/* Indique si l'on doit juste tracer les aretes ('FAUX') ou bien remplir les facettes */
/* par interpolation ('VRAI'). */
DEFV(Argument,DEFV(image,texture_du_maillage));
/* Image Argument definissant la texture a appliquer aux sommets du maillage. */
DEFV(Argument,DEFV(pointF_3D,POINTERs(source_lumineuse)));
/* Position de la source lumineuse. */
DEFV(Argument,DEFV(Logical,utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes));
/* Indique s'il faut utiliser en tant que ponderateurs directement les coordonnees */
/* barycentriques ('FAUX') ou bien l'aire des triangles ('VRAI') lors de l'interpolation */
/* a l'interieure des facettes... */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(coordonnee_U,FLOT__UNDEF));
/* Coordonnee 'u' dans [Umin,Umax], */
DEFV(Float,INIT(coordonnee_V,FLOT__UNDEF));
/* Coordonnee 'v' dans [Vmin,Vmax]. */
DEFV(Float,INIT(pas_U,FLOT__UNDEF));
/* Pas de parcours de [Umin,Umax], */
DEFV(Float,INIT(pas_V,FLOT__UNDEF));
/* Pas de parcours de [Vmin,Vmax]. */
DEFV(pointF_3D,coinF3_uv);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (u,v) = (Umin,Vmin) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
DEFV(pointF_3D,coinF3_Uv);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (U,v) = (Umax,Vmin) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
DEFV(pointF_3D,coinF3_UV);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (U,V) = (Umax,Vmax) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
DEFV(pointF_3D,coinF3_uV);
/* Coordonnees {X,Y,Z} flottantes dans l'espace a trois dimensions correspondant */
/* au couple (u,V) = (Umin,Vmax) ; on notera que ces coordonnees sont normalisees, de */
/* telles facon que [0,1] represente apres projection et renormalisation */
/* l'image a generer. */
/*..............................................................................................................................*/
Test(IFOU(IFLE(Umax,Umin)
,IFLE(Vmax,Vmin)
)
)
Bblock
PRINT_ERREUR("l'ordre des bornes inferieures et/ou superieures des coordonnees (u,v) est mauvais");
CAL1(Prer2("(Umin,Umax) = (%g,%g)\n",Umin,Umax));
CAL1(Prer2("(Vmin,Vmax) = (%g,%g)\n",Vmin,Vmax));
Eblock
ATes
Bblock
INITIALISATION_TRANSFORMATION;
/* Au cas ou la transformation geometrique tri-dimensionnelle ne serait */
/* pas initialisee, on le fait sur la transformation unite. */
EGAL(pas_U,DIVI(SOUS(Umax,Umin),FLOT(MAX2(nombre_de_pas_U,UNITE))));
EGAL(pas_V,DIVI(SOUS(Vmax,Vmin),FLOT(MAX2(nombre_de_pas_V,UNITE))));
/* Calcul des pas de parcours de [Umin,Umax] et [Vmin,Vmax]. */
DoIn(coordonnee_V,Vmin,SOUS(Vmax,pas_V),pas_V)
Bblock
DoIn(coordonnee_U,Umin,SOUS(Umax,pas_U),pas_U)
Bblock
INITIALISATION_POINT_3D(coinF3_uv
,TRANSFORMATION_Fx(Fx,Fy,Fz,coordonnee_Umin,coordonnee_Vmin)
,TRANSFORMATION_Fy(Fx,Fy,Fz,coordonnee_Umin,coordonnee_Vmin)
,TRANSFORMATION_Fz(Fx,Fy,Fz,coordonnee_Umin,coordonnee_Vmin)
);
/* Calcul de 'X', 'Y' et 'Z' pour (coordonnee_Umin,coordonnee_Vmin), */
INITIALISATION_POINT_3D(coinF3_Uv
,TRANSFORMATION_Fx(Fx,Fy,Fz,coordonnee_Umax,coordonnee_Vmin)
,TRANSFORMATION_Fy(Fx,Fy,Fz,coordonnee_Umax,coordonnee_Vmin)
,TRANSFORMATION_Fz(Fx,Fy,Fz,coordonnee_Umax,coordonnee_Vmin)
);
/* Calcul de 'X', 'Y' et 'Z' pour (coordonnee_Umax,coordonnee_Vmin), */
INITIALISATION_POINT_3D(coinF3_UV
,TRANSFORMATION_Fx(Fx,Fy,Fz,coordonnee_Umax,coordonnee_Vmax)
,TRANSFORMATION_Fy(Fx,Fy,Fz,coordonnee_Umax,coordonnee_Vmax)
,TRANSFORMATION_Fz(Fx,Fy,Fz,coordonnee_Umax,coordonnee_Vmax)
);
/* Calcul de 'X', 'Y' et 'Z' pour (coordonnee_Umax,coordonnee_Vmax), */
INITIALISATION_POINT_3D(coinF3_uV
,TRANSFORMATION_Fx(Fx,Fy,Fz,coordonnee_Umin,coordonnee_Vmax)
,TRANSFORMATION_Fy(Fx,Fy,Fz,coordonnee_Umin,coordonnee_Vmax)
,TRANSFORMATION_Fz(Fx,Fy,Fz,coordonnee_Umin,coordonnee_Vmax)
);
/* Calcul de 'X', 'Y' et 'Z' pour (coordonnee_Umin,coordonnee_Vmax), */
Test(IL_FAUT(remplir_les_facettes))
Bblock
DEFV(deltaF_3D,normale);
/* Normale au "quadrilatere" courant. */
DEFV(Float,INIT(module_normale,FLOT__UNDEF));
/* Module de la normale au "quadrilatere" courant. */
DEFV(deltaF_3D,rayon_lumineux);
/* Direction du rayon lumineux du point courant a la source lumineuse. */
DEFV(Float,INIT(cosinus,FLOT__UNDEF));
/* Afin de calculer la modulation d'eclairement du point courant avec l'ombre */
/* propre (elle utilise l'angle entre la normale et le rayon lumineux). */
INITIALISATION_ACCROISSEMENT_3D(rayon_lumineux
,SOUS(ASI1(source_lumineuse,x)
,LRZ4(FU,ASD1(coinF3_uv,x)
,FU,ASD1(coinF3_Uv,x)
,FU,ASD1(coinF3_UV,x)
,FU,ASD1(coinF3_uV,x)
)
)
,SOUS(ASI1(source_lumineuse,y)
,LRZ4(FU,ASD1(coinF3_uv,y)
,FU,ASD1(coinF3_Uv,y)
,FU,ASD1(coinF3_UV,y)
,FU,ASD1(coinF3_uV,y)
)
)
,SOUS(ASI1(source_lumineuse,z)
,LRZ4(FU,ASD1(coinF3_uv,z)
,FU,ASD1(coinF3_Uv,z)
,FU,ASD1(coinF3_UV,z)
,FU,ASD1(coinF3_uV,z)
)
)
);
/* Calcul du rayon lumineux allant du centre de la facette a la source lumineuse. */
INITIALISATION_ACCROISSEMENT_3D(normale
,PvectX(dXdu,dYdu,dZdu
,dXdv,dYdv,dZdv
)
,PvectY(dXdu,dYdu,dZdu
,dXdv,dYdv,dZdv
)
,PvectZ(dXdu,dYdu,dZdu
,dXdv,dYdv,dZdv
)
);
/* Calcul de la normale : */
/* */
/* X(N)=(((dY/du)*(dZ/dv))-((dZ/du)*(dY/dv))), */
/* Y(N)=(((dZ/du)*(dX/dv))-((dX/du)*(dZ/dv))), */
/* Z(N)=(((dX/du)*(dY/dv))-((dY/du)*(dX/dv))). */
/* */
EGAL(module_normale,pytF3D(normale));
/* Calcul du carre du module de la normale. */
Test(IZLE(module_normale))
Bblock
PRINT_ATTENTION("le vecteur normal au quadrilatere courant a une longueur negative ou nulle");
Eblock
ATes
Bblock
EGAL(cosinus
,MOIT(ADD2(DIVI(prdF3D(normale,rayon_lumineux)
,RACX(MUL2(module_normale,pytF3D(rayon_lumineux)))
)
,FU
)
)
);
/* Calcul du cosinus de l'angle que fait la normale avec le rayon lumineux ; etant */
/* donne qu'un cosinus est dans [-1,+1], on le ramene dans [0,1] pour en faire */
/* un coefficient de ponderation en lui appliquant la fonction f(x)=(1+x)/2. */
Test(IFEXff(cosinus,FZERO,FU))
Bblock
PRINT_ATTENTION("un cosinus 'renormalise' n'est pas dans [0,1]");
Eblock
ATes
Bblock
Eblock
ETes
CALS(Iremplissage_d_une_facette(ImageG
,ADRESSE(coinF3_uv)
,TEXTURAGE_DU_MAILLAGE(coordonnee_Umin,coordonnee_Vmin,cosinus)
,ADRESSE(coinF3_Uv)
,TEXTURAGE_DU_MAILLAGE(coordonnee_Umax,coordonnee_Vmin,cosinus)
,ADRESSE(coinF3_UV)
,TEXTURAGE_DU_MAILLAGE(coordonnee_Umax,coordonnee_Vmax,cosinus)
,utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes
)
);
/* Remplissage de la facette triangulaire {uv,Uv,UV}. */
CALS(Iremplissage_d_une_facette(ImageG
,ADRESSE(coinF3_uv)
,TEXTURAGE_DU_MAILLAGE(coordonnee_Umin,coordonnee_Vmin,cosinus)
,ADRESSE(coinF3_UV)
,TEXTURAGE_DU_MAILLAGE(coordonnee_Umax,coordonnee_Vmax,cosinus)
,ADRESSE(coinF3_uV)
,TEXTURAGE_DU_MAILLAGE(coordonnee_Umin,coordonnee_Vmax,cosinus)
,utiliser_l_aire_des_triangles_lors_de_l_interpolation_des_facettes
)
);
/* Remplissage de la facette triangulaire {uv,UV,uV}. */
Eblock
ETes
Eblock
ATes
Bblock
CALS(FgSET_CURSOR(ADRESSE(coinF3_uv)));
CALS(FgPA());
/* Positionnement en "bas" et "a gauche", */
CALS(FgSET_CURSOR(ADRESSE(coinF3_Uv)));
CALS(FgPB());
/* Trace du cote "horizontal" du "bas", */
CALS(FgSET_CURSOR(ADRESSE(coinF3_UV)));
CALS(FgPB());
/* Trace du cote "vertical" de "droite", */
CALS(FgSET_CURSOR(ADRESSE(coinF3_uV)));
CALS(FgPB());
/* Trace du cote "horizontal" du "haut", */
CALS(FgSET_CURSOR(ADRESSE(coinF3_uv)));
CALS(FgPB());
/* Trace du cote "vertical" de "gauche", */
Eblock
ETes
Eblock
EDoI
Eblock
EDoI
Eblock
ETes
RETI(ImageG);
Eblock
EFonctionP
#undef TEXTURAGE_DU_MAILLAGE
#undef dZdv
#undef dZdu
#undef dYdv
#undef dYdu
#undef dXdv
#undef dXdu
#undef coordonnee_Vmax
#undef coordonnee_Vmin
#undef coordonnee_Umax
#undef coordonnee_Umin
#undef TRANSFORMATION_Fz
#undef TRANSFORMATION_Fy
#undef TRANSFORMATION_Fx
_______________________________________________________________________________________________________________________________________
_______________________________________________________________________________________________________________________________________
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N P A R A M E T R I Q U E D U P L A N : */
/* */
/* */
/* Equations : */
/* */
/* X(u,v) = u */
/* Y(u,v) = v */
/* Z(u,v) = 0 */
/* */
/* avec : */
/* */
/* u E [0,1] ("abscisse") */
/* v E [0,1] ("ordonnee") */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F x ' D U P L A N : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fplan_x(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fx,u));
/*..............................................................................................................................*/
RETU(fx);
Eblock
EFonctionF
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F y ' D U P L A N : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fplan_y(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fy,v));
/*..............................................................................................................................*/
RETU(fy);
Eblock
EFonctionF
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F z ' D U P L A N : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fplan_z(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fz,FZERO));
/*..............................................................................................................................*/
RETU(fz);
Eblock
EFonctionF
_______________________________________________________________________________________________________________________________________
_______________________________________________________________________________________________________________________________________
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N P A R A M E T R I Q U E D E L A S P H E R E C E N T R E E : */
/* */
/* */
/* Equations : */
/* */
/* X(u,v) = R.cos(u).cos(v) */
/* Y(u,v) = R.sin(u).cos(v) */
/* Z(u,v) = R.sin(v) */
/* */
/* avec : */
/* */
/* u E [0,2.PI] ("longitude") */
/* v E [-PI/2,+PI/2] ("latitude") */
/* */
/*************************************************************************************************************************************/
DEFV(Common,DEFV(Float,INIT(Fsphere_x__Fsphere_y__Fsphere_z_____rayon,FLOT__UNDEF)));
/* Le rayon de la sphere est place dans une variable commune, afin */
/* de faire que 'Fx', 'Fy' et 'Fz' ne soient que des fonctions de (u,v)... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define Umin \
COORDONNEE_BARYCENTRIQUE_MINIMALE \
/* Definition de la longitude minimale, */
#define Umax \
COORDONNEE_BARYCENTRIQUE_MAXIMALE \
/* Definition de la longitude maximale. */
#define epsilon_u \
FRA10(FRA10(FU)) \
/* Pour que la surface ne se referme pas tout a fait... */
#define dPIu \
MUL2(SOUS(CERCLE_TRIGONOMETRIQUE,epsilon_u),u) \
/* Definition de la longitude 'u' dans [0,2.PI]. */
#define Vmin \
COORDONNEE_BARYCENTRIQUE_MINIMALE \
/* Definition de la latitude minimale, */
#define Vmax \
COORDONNEE_BARYCENTRIQUE_MAXIMALE \
/* Definition de la latitude maximale. */
#define translation_v \
SOUS(v,MOYS(Vmax,Vmin)) \
/* Definition de la translation de la latitude permettant de passer de [0,PI] */ \
/* a [-PI/2,+PI/2]. */
#define PIv \
MUL2(PI,translation_v) \
/* Definition de la latitude 'v' dans [-PI/2,+PI/2]. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F x ' D E L A S P H E R E C E N T R E E : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fsphere_x(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fx,MUL2(Xcartesienne_2D(Fsphere_x__Fsphere_y__Fsphere_z_____rayon,dPIu),COSX(PIv))));
/*..............................................................................................................................*/
RETU(fx);
Eblock
EFonctionF
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F y ' D E L A S P H E R E C E N T R E E : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fsphere_y(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fy,MUL2(Ycartesienne_2D(Fsphere_x__Fsphere_y__Fsphere_z_____rayon,dPIu),COSX(PIv))));
/*..............................................................................................................................*/
RETU(fy);
Eblock
EFonctionF
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F z ' D E L A S P H E R E C E N T R E E : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fsphere_z(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fz,MUL2(Fsphere_x__Fsphere_y__Fsphere_z_____rayon,SINX(PIv))));
/*..............................................................................................................................*/
RETU(fz);
Eblock
EFonctionF
#undef PIv
#undef translation_v
#undef Vmax
#undef Vmin
#undef dPIu
#undef epsilon_u
#undef Umax
#undef Umin
_______________________________________________________________________________________________________________________________________
_______________________________________________________________________________________________________________________________________
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N P A R A M E T R I Q U E D E L A S U R F A C E D E B O Y : */
/* */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * ** * * * * * ** * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * ** * * * * * ** */
/* * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* */
/* ATTENTION : */
/* */
/* Les definitions ici presentes se retrouvent */
/* dupliquees "betement" pour des raisons de */
/* simplicite dans 'v $xrs/sBoy.11$I' et dans */
/* 'v $xrs/sBoy.11$K'. */
/* */
/* */
/* Equations : */
/* */
/* PI PI */
/* A(v) = C0 + C1.sin(6.v - ----) + C2.sin(3.v - ----) */
/* 3 6 */
/* */
/* PI PI */
/* B(v) = C0 + C1.sin(6.v - ----) - C2.sin(3.v - ----) */
/* 3 6 */
/* */
/* PI */
/* ALPHA(v) = ----.sin(3.v) */
/* 8 */
/* */
/* 2 2 */
/* A(v) - B(v) */
/* X1(u,v) = -------------------- + [A(v).cos(u)] - [B(v).sin(u)] */
/* ______________ */
/* \ / 2 2 */
/* \/ A(v) + B(v) */
/* */
/* ______________ */
/* \ / 2 2 */
/* Z1(u,v) = \/ A(v) + B(v) + [A(v).cos(u)] + [B(v).sin(u)] */
/* */
/* */
/* X(u,v) = R.[(X1(u,v).cos(v)) - (Z1(u,v).sin(ALPHA(v)).sin(v))] */
/* Y(u,v) = R.[(X1(u,v).sin(v)) + (Z1(u,v).sin(ALPHA(v)).cos(v))] */
/* Z(u,v) = R.[Z1(u,v).cos(ALPHA(v))] */
/* */
/* avec : */
/* */
/* u E [0,2.PI] */
/* v E [0,PI] */
/* */
/*************************************************************************************************************************************/
DEFV(Common,DEFV(Float,INIT(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____rayon,FLOT__UNDEF)));
/* Coefficient 'R', */
DEFV(Common,DEFV(Float,INIT(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient0,FLOT__UNDEF)));
/* Coefficient 'C0', */
DEFV(Common,DEFV(Float,INIT(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient1,FLOT__UNDEF)));
/* Coefficient 'C1', */
DEFV(Common,DEFV(Float,INIT(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient2,FLOT__UNDEF)));
/* Coefficient 'C2' ; */
/* les coefficients de la surface de Boy sont places dans des variables */
/* communes, afin de faire que 'Fx', 'Fy' et 'Fz' ne soient que des */
/* fonctions de (u,v)... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D O N N E E S D ' A C C E L E R A T I O N D E S C A L C U L S : */
/* */
/*************************************************************************************************************************************/
DEFV(Local,DEFV(Float,INIT(u_surface_de_boy,FLOT__UNDEF)));
/* Coordonnee 'u' utilisee pour le calcul des valeurs courantes des */
/* fonctions 'A_BOY', 'B_BOY', 'ALPHA_BOY', 'X1_BOY' et 'Z1_BOY', */
DEFV(Local,DEFV(Float,INIT(v_surface_de_boy,FLOT__UNDEF)));
/* Coordonnee 'v' utilisee pour le calcul des valeurs courantes des */
/* fonctions 'A_BOY', 'B_BOY', 'ALPHA_BOY', 'X1_BOY' et 'Z1_BOY'. */
DEFV(Local,DEFV(Float,INIT(COS_surface_de_boy_u,FLOT__UNDEF)));
/* Valeur courante de la fonction 'COSX(dPIu)' pour 'u' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(SIN_surface_de_boy_u,FLOT__UNDEF)));
/* Valeur courante de la fonction 'SINX(dPIu)' pour 'u' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(COS_surface_de_boy_v,FLOT__UNDEF)));
/* Valeur courante de la fonction 'COSX(PIv)' pour 'v' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(SIN_surface_de_boy_v,FLOT__UNDEF)));
/* Valeur courante de la fonction 'SINX(PIv)' pour 'v' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(A_surface_de_boy_v,FLOT__UNDEF)));
/* Valeur courante de la fonction 'A_BOY(PIv)' pour 'v' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(B_surface_de_boy_v,FLOT__UNDEF)));
/* Valeur courante de la fonction 'B_BOY(PIv)' pour 'v' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(ALPHA_surface_de_boy_v,FLOT__UNDEF)));
/* Valeur courante de la fonction 'ALPHA_BOY(dPIu,PIv)' pour 'v' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(X1_surface_de_boy_u_v,FLOT__UNDEF)));
/* Valeur courante de la fonction 'X1_BOY(dPIu,PIv)' pour 'u' et 'v' ci-dessus, */
DEFV(Local,DEFV(Float,INIT(Z1_surface_de_boy_u_v,FLOT__UNDEF)));
/* Valeur courante de la fonction 'Z1_BOY(dPIu,PIv)' pour 'u' et 'v' ci-dessus. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define Umin \
COORDONNEE_BARYCENTRIQUE_MINIMALE \
/* Definition de la longitude minimale, */
#define Umax \
COORDONNEE_BARYCENTRIQUE_MAXIMALE \
/* Definition de la longitude maximale. */
#define epsilon_u \
FRA10(FRA10(FU)) \
/* Pour que la surface ne se referme pas tout a fait... */
#define dPIu \
MUL2(SOUS(CERCLE_TRIGONOMETRIQUE,epsilon_u),u) \
/* Definition de la longitude 'u' dans [0,2.PI]. */
#define Vmin \
COORDONNEE_BARYCENTRIQUE_MINIMALE \
/* Definition de la latitude minimale, */
#define Vmax \
COORDONNEE_BARYCENTRIQUE_MAXIMALE \
/* Definition de la latitude maximale. */
#define PIv \
MUL2(PI,v) \
/* Definition de la latitude 'v' dans [0,PI]. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F O N C T I O N I N T E R M E D I A I R E S : */
/* */
/*************************************************************************************************************************************/
#define A_BOY(v) \
ADD2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient0 \
,ADD2(MUL2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient1 \
,SINX(SOUS(MUL2(SIX,v) \
,DIVI(PI,TROIS) \
) \
) \
) \
,MUL2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient2 \
,SINX(SOUS(MUL2(TROIS,v) \
,DIVI(PI,SIX) \
) \
) \
) \
) \
)
#define B_BOY(v) \
ADD2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient0 \
,SOUS(MUL2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient1 \
,SINX(SOUS(MUL2(SIX,v) \
,DIVI(PI,TROIS) \
) \
) \
) \
,MUL2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____coefficient2 \
,SINX(SOUS(MUL2(TROIS,v) \
,DIVI(PI,SIX) \
) \
) \
) \
) \
)
#define ALPHA_BOY(v) \
MUL2(DIVI(PI,HUIT) \
,SINX(MUL2(TROIS,v)) \
)
#define X1_BOY(u,v) \
ADD2(DIVI(SOUS(EXP2(A_surface_de_boy_v) \
,EXP2(B_surface_de_boy_v) \
) \
,GpytF2D(A_surface_de_boy_v \
,B_surface_de_boy_v \
) \
) \
,SOUS(MUL2(A_surface_de_boy_v \
,COS_surface_de_boy_u \
) \
,MUL2(B_surface_de_boy_v \
,SIN_surface_de_boy_u \
) \
) \
) \
/* La procedure 'GpytF2D(...)' a ete introduite le 20021120102824. */
#define Z1_BOY(u,v) \
ADD2(GpytF2D(A_surface_de_boy_v \
,B_surface_de_boy_v \
) \
,ADD2(MUL2(A_surface_de_boy_v \
,COS_surface_de_boy_u \
) \
,MUL2(B_surface_de_boy_v \
,SIN_surface_de_boy_u \
) \
) \
) \
/* La procedure 'GpytF2D(...)' a ete introduite le 20021120102824. */
#define ACCELERATION_BOY(u,v) \
Bblock \
Test(IFOU(IFNE(u_surface_de_boy,u),IFNE(v_surface_de_boy,v))) \
Bblock \
/* ATTENTION : a l'ordre des calculs suivants... */ \
EGAL(u_surface_de_boy,u); \
/* Coordonnee 'u' utilisee pour le calcul des valeurs courantes des fonctions, */ \
EGAL(v_surface_de_boy,v); \
/* Coordonnee 'v' utilisee pour le calcul des valeurs courantes des fonctions. */ \
EGAL(COS_surface_de_boy_u,COSX(dPIu)); \
/* Valeur courante de la fonction 'COSX(dPIu)' pour 'u' ci-dessus, */ \
EGAL(SIN_surface_de_boy_u,SINX(dPIu)); \
/* Valeur courante de la fonction 'SINX(dPIu)' pour 'u' ci-dessus, */ \
EGAL(COS_surface_de_boy_v,COSX(PIv)); \
/* Valeur courante de la fonction 'COSX(PIv)' pour 'v' ci-dessus, */ \
EGAL(SIN_surface_de_boy_v,SINX(PIv)); \
/* Valeur courante de la fonction 'SINX(PIv)' pour 'v' ci-dessus, */ \
EGAL(A_surface_de_boy_v,A_BOY(PIv)); \
/* Valeur courante de la fonction 'A_BOY(u,v)' pour 'u' et 'v' ci-dessus, */ \
EGAL(B_surface_de_boy_v,B_BOY(PIv)); \
/* Valeur courante de la fonction 'B_BOY(u,v)' pour 'u' et 'v' ci-dessus, */ \
EGAL(ALPHA_surface_de_boy_v,ALPHA_BOY(PIv)); \
/* Valeur courante de la fonction 'ALPHA_BOY(u,v)' pour 'u' et 'v' ci-dessus, */ \
EGAL(X1_surface_de_boy_u_v,X1_BOY(dPIu,PIv)); \
/* Valeur courante de la fonction 'X1_BOY(u,v)' pour 'u' et 'v' ci-dessus, */ \
EGAL(Z1_surface_de_boy_u_v,Z1_BOY(dPIu,PIv)); \
/* Valeur courante de la fonction 'Z1_BOY(u,v)' pour 'u' et 'v' ci-dessus. */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Cette procedure permet d'accelerer le calcul de la surface de Boy ; elle */ \
/* memorise en permanence le couple (u,v), et les valeurs des differentes */ \
/* fonctions intermediaires pour ce couple ; etant donnees les relations de */ \
/* dependance entre ces neuf fonctions, l'ordre des calculs precedents est */ \
/* fondamental... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F x ' D E L A S U R F A C E D E B O Y : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fsurface_de_boy_x(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fx,FLOT__UNDEF));
/* Valeur de la fonction 'Fx' pour la surface de Boy. */
/*..............................................................................................................................*/
ACCELERATION_BOY(dPIu,PIv);
EGAL(fx
,MUL2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____rayon
,SOUS(MUL2(X1_surface_de_boy_u_v
,COS_surface_de_boy_v
)
,MUL2(MUL2(Z1_surface_de_boy_u_v
,SINX(ALPHA_surface_de_boy_v)
)
,SIN_surface_de_boy_v
)
)
)
);
RETU(fx);
Eblock
EFonctionF
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F y ' D E L A S U R F A C E D E B O Y : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fsurface_de_boy_y(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fy,FLOT__UNDEF));
/* Valeur de la fonction 'Fy' pour la surface de Boy. */
/*..............................................................................................................................*/
ACCELERATION_BOY(dPIu,PIv);
EGAL(fy
,MUL2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____rayon
,ADD2(MUL2(X1_surface_de_boy_u_v
,SIN_surface_de_boy_v
)
,MUL2(MUL2(Z1_surface_de_boy_u_v
,SINX(ALPHA_surface_de_boy_v)
)
,COS_surface_de_boy_v
)
)
)
);
RETU(fy);
Eblock
EFonctionF
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N ' F z ' D E L A S U R F A C E D E B O Y : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fsurface_de_boy_z(u,v)))
DEFV(Argument,DEFV(Float,u));
DEFV(Argument,DEFV(Float,v));
/* Coordonnees parametriques de la surface. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fz,FLOT__UNDEF));
/* Valeur de la fonction 'Fz' pour la surface de Boy. */
/*..............................................................................................................................*/
ACCELERATION_BOY(dPIu,PIv);
EGAL(fz
,MUL2(Fsurface_de_boy_x__Fsurface_de_boy_y__Fsurface_de_boy_z_____rayon
,MUL2(Z1_surface_de_boy_u_v
,COSX(ALPHA_surface_de_boy_v)
)
)
);
RETU(fz);
Eblock
EFonctionF
#undef ACCELERATION_BOY
#undef Z1_BOY
#undef X1_BOY
#undef ALPHA_BOY
#undef B_BOY
#undef A_BOY
#undef PIv
#undef Vmax
#undef Vmin
#undef dPIu
#undef epsilon_u
#undef Umax
#undef Umin
_______________________________________________________________________________________________________________________________________