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

_______________________________________________________________________________________________________________________________________



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.