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