_______________________________________________________________________________________________________________________________________
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F O N C T I O N S   D E   B A S E   P O U R   L A   M I S E   E N   M O N T A G N E S  :                                   */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Definition :                                                                                                               */
/*                                                                                                                                   */
/*                    Ce fichier contient toutes les fonctions                                                                       */
/*                  necessaires a mettre une image en "montagnes"...                                                                 */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xiii/montagnes$FON' :                                                                                          */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 19870000000000).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        A I D E   A U   C A D R A G E   A U T O M A T I Q U E   V E R T I C A L   D E S   M O N T A G N E S  :                     */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   PLUS_GRANDE_ORDONNEE_SUR_LA_MONTAGNE                                                                                          \
                    F_MOINS_L_INFINI                                                                                                    \
                                        /* Valeur initiale de 'Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_montagne' et  */ \
                                        /* de 'Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_last_ligne_de_la_montagne'    */
                                        /* au debut de chaque generation.                                                            */
DEFV(Common,DEFV(Float,ZINT(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_montagne,PLUS_GRANDE_ORDONNEE_SUR_LA_MONTAGNE)));
                                        /* Donne (dans [0,1]) la plus grande ordonnee rencontree lors du trace de tous les           */
                                        /* vecteurs verticaux composant une montagne.                                                */
DEFV(Common,DEFV(Float,ZINT(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_last_ligne_de_la_montagne
                           ,PLUS_GRANDE_ORDONNEE_SUR_LA_MONTAGNE
                            )
                 )
     );
                                        /* Donne (dans [0,1]) la plus grande ordonnee rencontree lors du trace de la derniere        */
                                        /* ligne de vecteurs verticaux composant une montagne.                                       */
                                        /*                                                                                           */
                                        /*                         .........................................................         */
                                        /*              :@-*     --                                                         .        */
                                        /*             :--o@** o-@@o                                                    plus grande  */
                                        /*           -:.+-@@o@+-*+@+@*o                                                 ordonnee sur */
                                        /*        o -:.:+@-*+o:o-**o:*+                                                 la montagne  */
                                        /*        o*.--*-@-@@@-*-o*oo*@* -                                       o                   */
                                        /*        @@*@:-:-*o++@+*o-*+*@**oo.                                :+-*--                   */
                                        /*        @@-@o-:-*--****+o+*o@++*+o++@       +*                   .+@++:-                   */
                                        /*        +*oo@*.:--*+*@*o-o-@@o*-o**-+@@@@ +@@@@:+@*+* o         -+**+.-:                   */
                                        /*        *@o-@*-:+-o+@+@@o@-o@@@-o@*-o*+-:-:-++:@o*@o**o*oo+*++-@@@+o-:*:                   */
                                        /*        --@@@@@*oo*o:+-@o@*o+@@o**+o+*+-+.**:o+@@--:o--@+:@:-++o:*oo:@:-                   */
                                        /*        o-@@@+o+@*@@--**oo@*o*@@o**+++::::--+-o*:@@+o*-*++*---++o*@++o:-                   */
                                        /*        o+@-o@o@o*@*-**o*oo*o*@o@@oo*o:..:o---*-:-@ooooo:o*-@:o*oo@:@**:                   */
                                        /*        *+o@@@-@-**+oo@****@-*o@@--*oo.:.:-.+++-+***o*o+o:o*-*+o+*@:+-:+                   */
                                        /*        @@**@@@+@@@+***@*-++****o@+*o:::.-::.o+++---*:::--@-***+o++++-+@                   */
                                        /*        **@@+@:-@**+--@oo@-o+*+-@*@+---::::.-----:@:o-.--*@@*@:-@@++:+o:                   */
                                        /*        o+@o*-*+*ooo*+*@o*@*o**+-@*o+:::..-:-+-o@:o-::--:o**o+**+*-*@:@-                   */
                                        /*        o*@*@+@*o@*@o**@@-*@@-*@:@@*-::..+::-@++:::::-.-:*+:**+*:--o-+o@                   */
                                        /*        +++*@@@@o+*@*+o+*++*@o@*@@*@:.+*oo:o@*-++-::.-:--*ooo@*+..+:o@@-                   */
                                        /*        o++o@@@*@@@@*o@@o:+o*@+*-@o*--:-+@:.::*-o+-@::-+++o:@@+**::*o@+o                   */
                                        /*        o+o:*o@o-@*--*@+-::+@**oo+@+-.:+o@.@-@+@@***++:@-o-*o:-+-:+@-o++                   */
                                        /*        o+o-o***@@+@*-*@-:+@o@*o@---::-.+o++*o**o-*@-.+@:::*-:-o:+-@*o+:                   */
                                        /*        **.*-o@@o*@**-:-@-@@@@@@o+:+.....++++o*@@:*-*+@oo.::.+.+-:o*+o*+                   */
                                        /*        o+oo:@@**@@o:@*@-*@o@o@***+::...-:o+:-@@:**+*-@+o+-:.:.-.-+o+@**                   */
                                        /*        @oo-:--*@+.-*@*@:-***oo*@+::...:++o:-oo@:*oo@-@*-::.....:o+o@oo:                   */
                                        /*        @o---.+:+@@**o:oo@:--@*+oo-*+:.@-@*--+-*@*o:@*oo:-:::...::+-@+o@                   */
                                        /*        +@*:--:@+:+@-:*@-@*o@@-o@+:*::o*o-@*:-+@@*-@o++o--::@@+:-::+@**+                   */
                                        /*        -*:*-*o-o@*-:-+:-+*@@o:@*-@@o@***@o@@.-*o@@ ...........................            */
                                        /*        +o:----++*o--@+o@o:-+o@*@@@**+@@*+@*o-:@      +:o-@-::-+::+*oo@@      plus grande  */
                                        /*        -...--o.@**--@o*-@@@*@-o@*o-+-*@*o+*--         @+:@**:++::o*:oo+      ordonnee sur */
                                        /*        *o+-+@o+-o+o*.+:.+o-@@@*@o@o*:-o@+*@:            @@@+---:-*++*@:      la 'last'    */
                                        /*                                                                              ligne de la  */
                                        /*                                                                              montagne     */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M I S E   E N   M O N T A G N E S   D ' U N E   I M A G E  :                                                               */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Definition :                                                                                                               */
/*                                                                                                                                   */
/*                    Cette fonction genere une repre-                                                                               */
/*                  sentation 3D d'une image 2D, en                                                                                  */
/*                  utilisant la valeur de chaque point                                                                              */
/*                  comme troisieme dimension ; le calcul                                                                            */
/*                  est fait pour tout le champ {X,Y}, mais                                                                          */
/*                  le trace n'a lieu que la ou l'image                                                                              */
/*                  n'est pas masquee.                                                                                               */
/*                                                                                                                                   */
/*                    Le 'Z-Buffer' est correcte-                                                                                    */
/*                  ment mis a jour afin de pouvoir                                                                                  */
/*                  integrer cette montagne a d'autres                                                                               */
/*                  objets 3D.                                                                                                       */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                                                           *                                                                       */
/*                                                          ..@  .@                                                                  */
/*                                                        .* *.@ .@.@                                                                */
/*                                                      ...@ . ..*@@@@                                                               */
/*                              *@                  .. ..  ..   .**@@@*                                                              */
/*                  @ .**  .  .*.@*@               **.. .   .   *@@@@@.@  .@                                                         */
/*                  @****@.. @. **.*@    **..  .@.. .@..   ..   ...@*@*@.*.@*                                                        */
/*                  .*.@@@*. .**.*@@.@.  .*. . .@.  @... ....   . .@.** ..@@@*                                                       */
/*                  @.@@.@.  *..**** @@@   .. * ** **..   . . .. . *.@ *..@@@@*  .@                                                  */
/*                  @*.   @@.. @ @.@ ..@. .. .*@*@. ..@@@. ...*..****.. ...@*@@@****                                                 */
/*                  .  .**@..@@ @*.   *@@..*. * @.**@.@@. ** ..*@@.@**. .@@@.*@ *@@                                                  */
/*                  . .  ** ..@@*@. *@****@.   .***@..@@*....  @.*@ * .. .**.****@..                                                 */
/*                  .... **.@@@@*.  .*@**...  .@.*.@ .*@ .    .**@@....  **.@*@*@**                                                  */
/*                  *.... .@*@*...*.. @.@...   .**@.@*@. **..  ***@..    *   @*@.@                                                   */
/*                  *.... .***.*@.* ..**.@..@. @*.*@@ *.* ..... .*@@... ..* @. ...                                                   */
/*                  @..   .*.@.**** ..@***@@@* *@. *.@@.*..*.**. @*@@ .  * ** ...                                                    */
/*                  @@. . .@.* *.**. *.*@**@.*@@*@..@.@@@.*......@@.@..  .......   .                                                 */
/*                  @@ *. @.*@ **@.....@@*@.*@@*@*.@* *@  @@*.****.**.      ..... .*                                                 */
/*                  @.@ @@*.@@ .@ .* @ .@@*@**@@*@@* * *.**. . ..... ...      ....@.                                                 */
/*                  *@*..@*.**   @*  * *@@*@**@@@*.. .. .*....  ...  .. .  . . . .*.                                                 */
/*                  .@*@@**.    .*.**@*@@@@*.@@@**. ..  *@*.......   . .....      .                                                  */
/*                  @@@..*  **. .   @.**@*@@@.@@@...    *.**....  .@... . ... @...                                                   */
/*                  @**.  ** .   *.@@.@**@@ *.*@@* **  *.@.*.@@@. @***     .. @@*  .                                                 */
/*                  @. .   .     . @@..***@ @* ..@* *. *  .@*@*.  .*@* . ...  *@ .**                                                 */
/*                  @* .... ....  .** *@@*@ .. @.** *.*. @@*....   @@@@ @*..* .  @@*                                                 */
/*                  @  .**.   *@*@@..*@..**. . * *..@ @ * @...*... @@@*****.... .***                                                 */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Definition des lignes :                                                                                                    */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                  Ymax                .................................. |                                                         */
/*                  .                                                      |                                                         */
/*                  .                          (lignes non tracees)        | AVANT                                                   */
/*                  .                                                      |                                                         */
/*                  Yfirst              .................................. v                                                         */
/*                  Yfirst_trace        ----------------------------------                                                           */
/*                  .                                                                                                                */
/*                  .                                                                                                                */
/*                  .                            (lignes tracees)                                                                    */
/*                  .                                                                                                                */
/*                  .                                                                                                                */
/*                  Ylast_trace         ----------------------------------                                                           */
/*                  Ylast               .................................. ^                                                         */
/*                  .                                                      |                                                         */
/*                  .                          (lignes non tracees)        | ARRIERE                                                 */
/*                  .                                                      |                                                         */
/*                  Ymin                .................................. |                                                         */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

#ifdef    TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : avec 'VERSION_01'.       */
DEFV(Common,DEFV(Logical,_____TYPE_DE_imageA_surface_VERSION_01));
#Aifdef   TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : avec 'VERSION_01'.       */
#Eifdef   TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : avec 'VERSION_01'.       */

#ifdef    TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : avec 'VERSION_02'.       */
DEFV(Common,DEFV(Logical,_____TYPE_DE_imageA_surface_VERSION_02));
#Aifdef   TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : avec 'VERSION_02'.       */
#Eifdef   TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : avec 'VERSION_02'.       */

DEFV(Common,DEFV(Logical,ZINT(Imontagnes_precises_____compatibilite_20090202,FAUX)));
                                        /* Le 20090202103137 en essayant de corriger le probleme de "tricherie" du 20090130181639,   */
                                        /* je me suis rendu compte que les definitions de 'Yfirst' et de 'Ylast' pouvaient etre      */
                                        /* plus "strictes"...                                                                        */
                                        /*                                                                                           */
                                        /* Le 20090203162610, au test 'IL_FAUT(Imontagnes_precises_____compatibilite_20090203)' fut  */
                                        /* ajoute celui de 'IL_NE_FAUT_PAS(vue_d_avion)' car en effet, il semble que l'absence de    */
                                        /* compatibilite deteriore le traitement "anti-aliasing" des lignes de crete d'arriere-plan  */
                                        /* (le plus lointain...).                                                                    */
DEFV(Common,DEFV(Logical,ZINT(Imontagnes_precises_____compatibilite_20090203,FAUX)));
                                        /* Meme remarque le 20090203154615 concernant 'Yfirst_trace' et 'Ylast_trace'...             */
                                        /*                                                                                           */
                                        /* Le 20090203162610, au test 'IL_FAUT(Imontagnes_precises_____compatibilite_20090203)' fut  */
                                        /* ajoute celui de 'IL_NE_FAUT_PAS(vue_d_avion)' car en effet, il semble que l'absence de    */
                                        /* compatibilite deteriore le traitement "anti-aliasing" des lignes de crete d'arriere-plan  */
                                        /* (le plus lointain...).                                                                    */
DEFV(Common,DEFV(Logical,ZINT(Imontagnes_precises_____compatibilite_20210928,FAUX)));
DEFV(Common,DEFV(Logical,ZINT(Imontagnes_precises_____compatibilite_20211001,FAUX)));
                                        /* Le 20210928134325 j'ai decouvert une anomalie dans 'ARRIERE(...)' et 'AVANT(...)' dans    */
                                        /* lesquels 'SUCY(...)' et 'PREY(...)' pouvait faire sortir l'ordonnee 'y' de [Ymin,Ymax].   */
                                        /* Ceci a ete mis en evidence a cette date sur '$LACT1B', ou 'v $xci/montagne.01$K' a partir */
                                        /* du format 'Suq' donnait :                                                                 */
                                        /*                                                                                           */
                                        /*                  Segmentation fault (core dumped)                                         */
                                        /*                                                                                           */
                                        /* pour (avec le format 'Suq'...) :                                                          */
                                        /*                                                                                           */
                                        /*                  X=126     Y=0                                                            */
                                        /*                                                                                           */
                                        /* et c'est ce "Y=0" qui a attire mon attention...                                           */
                                        /*                                                                                           */
                                        /* Le 20211001175847, cela fut complete par l'utilisation de la procedure d'acces aux        */
                                        /* champs...                                                                                 */
                                        /*                                                                                           */
                                        /* Le 20211002110514, on notera un phenomene tres curieux. L'usage des options :             */
                                        /*                                                                                           */
                                        /*                  compatibilite_20210928=VRAI                                              */
                                        /*                                                                                           */
                                        /* et/ou :                                                                                   */
                                        /*                                                                                           */
                                        /*                  compatibilite_20211001=VRAI                                              */
                                        /*                                                                                           */
                                        /* ne re-provoque pas la "Segmentation fault", contrairement a toute attente. De plus les    */
                                        /* images alors generees SANS et AVEC ces options semblent identiques... Par contre si les   */
                                        /* procedures en cause sont redefinies ainsi :                                               */
                                        /*                                                                                           */
                                        /*                  #define   vPREX(x)                                                     \ */
                                        /*                                      PREX(x)                                              */
                                        /*                  #define   vSUCX(x)                                                     \ */
                                        /*                                      SUCX(x)                                              */
                                        /*                                                                                           */
                                        /*                  #define   vPREY(y)                                                     \ */
                                        /*                                      PREY(y)                                              */
                                        /*                  #define   vSUCY(y)                                                     \ */
                                        /*                                      SUCY(y)                                              */
                                        /*                                                                                           */
                                        /*                  #define   VloadF_point(imageA,X,Y)                                     \ */
                                        /*                                      loadF_point(imageA,X,Y)                              */
                                        /*                                                                                           */
                                        /* la "Segmentation fault" revient... Peut-etre cela change-t-il l'implantation memoire...   */

#define   vPREX(x)                                                                                                                      \
                    COND(IL_FAUT(Imontagnes_precises_____compatibilite_20210928),NEUT(PREX(x)),TROX(PREX(x)))
#define   vSUCX(x)                                                                                                                      \
                    COND(IL_FAUT(Imontagnes_precises_____compatibilite_20210928),NEUT(SUCX(x)),TROX(SUCX(x)))

#define   vPREY(y)                                                                                                                      \
                    COND(IL_FAUT(Imontagnes_precises_____compatibilite_20210928),NEUT(PREY(y)),TROY(PREY(y)))
#define   vSUCY(y)                                                                                                                      \
                    COND(IL_FAUT(Imontagnes_precises_____compatibilite_20210928),NEUT(SUCY(y)),TROY(SUCY(y)))

#define   vNEUT(x_ou_y)                                                                                                                 \
                    NEUT(x_ou_y)
                                        /* Definitions introduites le 20210928135900, 'vNEUT(...)' etant destine uniquement a        */
                                        /* assurer de belles tabulations...                                                          */
#define   VloadF_point(imageA,X,Y)                                                                                                      \
                    OPC3(IL_FAUT(Imontagnes_precises_____compatibilite_20211001),loadF_point,loadF_point_valide,imageA,X,Y)             \
                                        /* Definition introduite le 20211001175847...                                                */

#define   ARRIERE(y)                                                                                                                    \
                    vSUCY(y)                                                                                                            \
                                        /* Definition de la fonction de retour arriere.                                              */
#define   AVANT(y)                                                                                                                      \
                    vPREY(y)                                                                                                            \
                                        /* Definition de la fonction de marche en avant.                                             */

#define   Xlast                                                                                                                         \
                    SUCX(Xmin)                                                                                                          \
                                        /* Definition de la derniere colonne calculee ; la colonne 'Xmin' sera                       */ \
                                        /* obtenue par duplication de celle-ci...                                                    */
#define   Yfirst                                                                                                                        \
                    OPC1(IFOU(IL_NE_FAUT_PAS(vue_d_avion),IL_FAUT(Imontagnes_precises_____compatibilite_20090202)),AVANT,NEUT,Ymax)     \
                                        /* Definition de la premiere ligne de la matrice argument a generer en relief sans tracer ;  */ \
                                        /* la definition de 'Yfirst' est l'inverse de 'z_point_precedent(...)'.                      */
#define   Yfirst_trace                                                                                                                  \
                    OPC1(IFOU(IL_NE_FAUT_PAS(vue_d_avion),IL_FAUT(Imontagnes_precises_____compatibilite_20090203)),AVANT,NEUT,Yfirst)   \
                                        /* Definition de la premiere ligne de la matrice argument a visualiser.                      */
#define   Ylast                                                                                                                         \
                    OPC1(IFOU(IL_NE_FAUT_PAS(vue_d_avion),IL_FAUT(Imontagnes_precises_____compatibilite_20090202)),ARRIERE,NEUT,Ymin)   \
                                        /* Definition de la derniere ligne de la matrice argument avant la premiere visualisee ;     */ \
                                        /* la definition de 'Ylast' est l'inverse de 'z_point_suivant(....)'.                        */
#define   Ylast_trace                                                                                                                   \
                    OPC1(IFOU(IL_NE_FAUT_PAS(vue_d_avion),IL_FAUT(Imontagnes_precises_____compatibilite_20090203)),ARRIERE,NEUT,Ylast)  \
                                        /* Definition de la derniere ligne de la matrice argument a etre visualisee (tracee) ;       */ \
                                        /* la definition de 'Ylast_trace' est l'inverse de 'z_point_suivant_suivant(...)'.           */

#define   DECALAGE_VERTICAL(y)                                                                                                          \
                    INTE(MUL2(Imontagnes_precises_____importance_du_decalage_vertical,FLOT(y)))                                         \
                                        /* Decalage vertical de la composante 'y' lors de la reconstitution de la                    */ \
                                        /* montagne tranche par tranche...                                                           */

DEFV(Common,DEFV(Logical,ZINT(Imontagnes_precises_____verification_de_la_correction_perspective,FAUX)));
                                        /* Introduit le 20170413103352...                                                            */
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____facteur_de_correction_perspective,FZERO)));
                                        /* Facteur de correction perspective (la valeur nulle implicite permet d'assurer la          */
                                        /* compatibilite avec les versions anterieures...) ; plus cette valeur est grande, plus      */
                                        /* l'effet est accentue... ATTENTION, il ne s'agit pas d'une vraie perspective : l'effet     */
                                        /* consiste a translater verticalement les vecteurs traces d'une quantite qui est fonction   */
                                        /* croissante de la coordonnee 'y' dans 'EQUATION_DE_LA_SURFACE(...)' ; une coordonnee 'z'   */
                                        /* est donc remplacee par :                                                                  */
                                        /*                                                                                           */
                                        /*                  z - k.y                                                                  */
                                        /*                                                                                           */
                                        /* (ou 'k' designe 'Imontagnes_precises_____facteur_de_correction_perspective').             */
                                        /*                                                                                           */
                                        /* Ainsi, ce sont a la fois l'origine et l'extremite de chaque vecteurs qui sont translatees */
                                        /* d'une meme quantite alors que pour bien faire, seule l'extremite devrait l'etre...        */
                                        /* Malheureusement, on ne peut pas mieux faire, car cela vient des affectations du type      */
                                        /* suivant :                                                                                 */
                                        /*                                                                                           */
                                        /*                  ASD2(vecteur_vertical,origine,y)   = z_point_suivant(X,Y)                */
                                        /*                  ASD2(vecteur_vertical,extremite,y) = z_point_courant(X,Y)                */
                                        /*                                                                                           */
                                        /* et des definitions des deux fonctions 'z_point_suivant(...)' et 'z_point_courant(...)'    */
                                        /* qui se font via 'EQUATION_DE_LA_SURFACE(...)'.                                            */
                                        /*                                                                                           */
                                        /* ATTENTION, l'experience montre qu'avec une image 'standard=FAUX' il est important qu'elle */
                                        /* soit "relativement normalisee" (donc dans [0,1]) si l'on souhaite pouvoir "jouer"         */
                                        /* facilement avec 'Imontagnes_precises_____facteur_de_correction_perspective'.              */
                                        /* En particulier, lors de la mise au point de la sequence :                                 */
                                        /*                                                                                           */
                                        /*                  xivPdf 10 2 / 013313_013824                                              */
                                        /*                                                                                           */
                                        /* il y a eu une difficulte car toutes les images 'imageA_surface' etaient approximativement */
                                        /* dans [1,16] ; il a donc fallu leur apporter une renormalisation globale. Cela s'est vu de */
                                        /* nouveau aux environs du 20150112125523 lors de la generation 'v $xiirv/CHAR.12$M'...      */
                                        /*                                                                                           */
                                        /* On notera que 'Imontagnes_precises_____facteur_de_correction_perspective' intervient      */
                                        /* dans la definition de 'EQUATION_DE_LA_SURFACE(x,y)'. Or cette equation est elle-meme      */
                                        /* multipliee par 'facteur_d_echelle' dans les definitions du type 'z_point_precedent(x,y)'  */
                                        /* (et toutes celles qui lui sont similaires...). Ainsi donc, 'facteur_d_echelle' et         */
                                        /* et 'Imontagnes_precises_____facteur_de_correction_perspective' interferent l'un avec      */
                                        /* l'autre. Le 20020211111705, j'ai remarque que les deux parametres 'facteur_d_echelle'     */
                                        /* et 'Imontagnes_precises_____facteur_de_correction_perspective' devaient etre de meme      */
                                        /* signe...                                                                                  */

#define   LAMBDA_DE_CORRECTION_PERSPECTIVE(y)                                                                                           \
                    MUL2(MEME_SIGNE_QUE                                                                                                 \
                             (facteur_d_echelle                                                                                         \
                             ,Imontagnes_precises_____facteur_de_correction_perspective                                                 \
                              )                                                                                                         \
                        ,_____cNORMALISE_OY(y)                                                                                          \
                         )                                                                                                              \
                                        /* Definition introduite le 20170413095025 afin de permettre de valider initialement les     */ \
                                        /* differents parametres...                                                                  */

#ifdef    TYPE_DE_imageA_surface_VERSION_01
#    define    EQUATION_DE_LA_SURFACE(x,y)                                                                                              \
                         F__cDENORMALISE_OY(SOUS(MUL2(facteur_d_ajustement_de_l_equation_de_la_surface                                  \
                                                     ,______NORMALISE_NIVEAU(load_point(imageA_surface,x,y))                            \
                                                      )                                                                                 \
                                                ,BARY(COORDONNEE_BARYCENTRIQUE_MINIMALE                                                 \
                                                     ,COORDONNEE_BARYCENTRIQUE_MAXIMALE                                                 \
                                                     ,LAMBDA_DE_CORRECTION_PERSPECTIVE(y)                                               \
                                                      )                                                                                 \
                                                 )                                                                                      \
                                            )                                                                                           \
                                        /* Definition de l'equation de la surface a partir de l'image 'imageA_surface'. On notera    */ \
                                        /* les deux facteurs multiplicatifs :                                                        */ \
                                        /*                                                                                           */ \
                                        /* 1-facteur_d_ajustement_de_l_equation_de_la_surface : qui permet de prendre en compte le   */ \
                                        /* le fait que l'intervalle [NOIR,BLANC] ne change jamais, alors que [Ymin,Ymax] lui depend  */ \
                                        /* du format de l'image.                                                                     */ \
                                        /*                                                                                           */ \
                                        /* 2-Imontagnes_precises_____facteur_de_correction_perspective : qui permet de simuler       */ \
                                        /* une vue perspective en reduisant l'altitude de la surface proportionnellement a           */ \
                                        /* l'eloignement par rapport a l'observateur (ATTENTION, voir les commentaires de            */ \
                                        /* 'Imontagnes_precises_____facteur_de_correction_perspective').                             */ \
                                        /*                                                                                           */ \
                                        /* ATTENTION, l'ecriture :                                                                   */ \
                                        /*                                                                                           */ \
                                        /*                  SOUS(F__cDENORMALISE_OY(...))                                            */ \
                                        /*                                        .                                                  */ \
                                        /*                                       /|\                                                 */ \
                                        /*                                        |                                                  */ \
                                        /*                                        |                                                  */ \
                                        /*                                                                                           */ \
                                        /*                                        Y                                                  */ \
                                        /*                                                                                           */ \
                                        /* referencant 'Y' et non pas 'Z' n'est pas fausse, et vient du fait que la coordonnee 'Z'   */ \
                                        /* de la surface est materialisee suivant l'axe 'OY' de l'image generee...                   */ \
                                        /*                                                                                           */ \
                                        /* Le 'MEME_SIGNE_QUE(...)' a ete introduit le 20020211111705...                             */
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
#    define    EQUATION_DE_LA_SURFACE(x,y)                                                                                              \
                         F__cDENORMALISE_OY(SOUS(MUL2(facteur_d_ajustement_de_l_equation_de_la_surface                                  \
                                                     ,VloadF_point(imageA_surface,x,y)                                                  \
                                                      )                                                                                 \
                                                ,BARY(COORDONNEE_BARYCENTRIQUE_MINIMALE                                                 \
                                                     ,COORDONNEE_BARYCENTRIQUE_MAXIMALE                                                 \
                                                     ,LAMBDA_DE_CORRECTION_PERSPECTIVE(y)                                               \
                                                      )                                                                                 \
                                                 )                                                                                      \
                                            )                                                                                           \
                                        /* Definition de l'equation de la surface a partir de l'image 'imageA_surface'. On notera    */ \
                                        /* les deux facteurs multiplicatifs :                                                        */ \
                                        /*                                                                                           */ \
                                        /* 1-facteur_d_ajustement_de_l_equation_de_la_surface : qui permet de prendre en compte le   */ \
                                        /* le fait que l'intervalle [NOIR,BLANC] ne change jamais, alors que [Ymin,Ymax] lui depend  */ \
                                        /* du format de l'image.                                                                     */ \
                                        /*                                                                                           */ \
                                        /* 2-Imontagnes_precises_____facteur_de_correction_perspective : qui permet de simuler       */ \
                                        /* une vue perspective en reduisant l'altitude de la surface proportionnellement a           */ \
                                        /* l'eloignement par rapport a l'observateur (ATTENTION, voir les commentaires de            */ \
                                        /* 'Imontagnes_precises_____facteur_de_correction_perspective').                             */ \
                                        /*                                                                                           */ \
                                        /* ATTENTION, l'ecriture :                                                                   */ \
                                        /*                                                                                           */ \
                                        /*                  SOUS(F__cDENORMALISE_OY(...))                                            */ \
                                        /*                                        .                                                  */ \
                                        /*                                       /|\                                                 */ \
                                        /*                                        |                                                  */ \
                                        /*                                        |                                                  */ \
                                        /*                                                                                           */ \
                                        /*                                        Y                                                  */ \
                                        /*                                                                                           */ \
                                        /* referencant 'Y' et non pas 'Z' n'est pas fausse, et vient du fait que la coordonnee 'Z'   */ \
                                        /* de la surface est materialisee suivant l'axe 'OY' de l'image generee...                   */ \
                                        /*                                                                                           */ \
                                        /* Le 'MEME_SIGNE_QUE(...)' a ete introduit le 20020211111705...                             */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

#define   z_point_precedent(x,y)                                                                                                        \
                    MUL2(facteur_d_echelle,EQUATION_DE_LA_SURFACE(x,ARRIERE(y)))
#define   z_point_courant(x,y)                                                                                                          \
                    MUL2(facteur_d_echelle,EQUATION_DE_LA_SURFACE(x,y))                                                                 \
                                        /* 'z_point_courant' donne l'extremite (le "haut") du vecteur vertical courant.              */
#define   z_point_suivant(x,y)                                                                                                          \
                    MUL2(facteur_d_echelle,COND(IFOU(IL_FAUT(vue_d_avion)                                                               \
                                                    ,IFGT(Y,Ylast_trace)                                                                \
                                                     )                                                                                  \
                                               ,EQUATION_DE_LA_SURFACE(x,AVANT(y))                                                      \
                                               ,FLOT(Zmin)                                                                              \
                                                )                                                                                       \
                         )                                                                                                              \
                                        /* 'z_point_suivant' donne l'origine (le "bas") du vecteur vertical courant ; de             */ \
                                        /* plus lorsqu'on est au bord inferieur de l'image, et qu'une vue d'avion n'est              */ \
                                        /* pas demandee, on force le 'Zmin' afin de creer une falaise verticale artificielle         */ \
                                        /* terminant correctement la visualisation...                                                */
#define   z_point_suivant_suivant(x,y)                                                                                                  \
                    MUL2(facteur_d_echelle,COND(IFOU(IL_FAUT(vue_d_avion)                                                               \
                                                    ,IFGT(Y,Ylast_trace)                                                                \
                                                     )                                                                                  \
                                               ,EQUATION_DE_LA_SURFACE(x,AVANT(AVANT(y)))                                               \
                                               ,FLOT(Zmin)                                                                              \
                                                )                                                                                       \
                         )

#define   texture_courante(x,y,z)                                                                                                       \
                    FLOT(NIVR(load_point(imageA_texture,x,y)))                                                                          \
                                        /* Definition de la texture a appliquer au point {x,y,z} de la montagne, mais on notera      */ \
                                        /* que dans la version actuelle, la cote 'z' n'est pas utilisee, mais ouvre la porte a un    */ \
                                        /* texturage tri-dimensionnel...                                                             */

#define   CLIPPING_INTENSITE                                                                                                            \
                    FLOT(NIVR(NOIR_CLIPPING))                                                                                           \
                                        /* Niveau lumineux a utiliser pour marquer la "falaise" avant d'une montagne,                */ \
                                        /* lorsqu'une vue d'avion n'est pas demandee...                                              */
#define   MIN_INTENSITE                                                                                                                 \
                    FLOT(NIVR(ADD2(NOIR_CLIPPING,pas_entre_CLIPPING_INTENSITE_et_MIN_INTENSITE)))                                       \
                                        /* Niveau lumineux plancher a ne pas depasser ; on prend un niveau suivant celui             */ \
                                        /* de marquage de la falaise, afin de pouvoir le distinguer visuellement...                  */
#define   MAX_NIVEAU_LUMINEUX                                                                                                           \
                    FLOT(NIVR(BLANC))                                                                                                   \
                                        /* Donne le niveau lumineux maximum.                                                         */

DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____facteur_d_attenuation_a_l_ombre,FDU)));
                                        /* Facteur d'attenuation des points a l'ombre. Plus la valeur est proche de 1, plus          */
                                        /* l'attenuation est forte, et inversement, plus elle est proche de 0 et plus elle est       */
                                        /* faible...                                                                                 */
#define   ATTENUATION_A_L_OMBRE(niveau_Relatif)                                                                                         \
                    MUL2(Imontagnes_precises_____facteur_d_attenuation_a_l_ombre,FLOT(niveau_Relatif))                                  \
                                        /* Donne la fonction d'attenuation a l'ombre ; plus sa valeur est proche de 'niveau',        */ \
                                        /* plus l'attenuation est forte, et inversement, plus elle est proche de '0', moins les      */ \
                                        /* effets de l'ombre se font sentir (tout cela vient du 'NEGA()' fait sur cette fonction).   */ \
                                        /* On notera que l'argument est un niveau Relatif (de type 'NIVR(...)'), ce qui est en       */ \
                                        /* accord avec le fait que cette procedure n'est utilisee qu'avec 'MAX_NIVEAU_LUMINEUX'      */ \
                                        /* (qui est de ce type...).                                                                  */

#define   TRACE_VECTEUR_VERTICAL(image,vecteur,Yf_origine,Yf_extremite,X,Y,Zf,c_est_la_phase_d_anti_aliasing)                           \
                    Bblock                                                                                                              \
                    CALS(Itrace_segment_vertical(image                                                                                  \
                                                ,vue_d_avion                                                                            \
                                                ,ADRESSE(vecteur),Yf_origine,Yf_extremite                                               \
                                                ,X,Y,Zf                                                                                 \
                                                ,intensite_origine,intensite_extremite                                                  \
                                                ,Zf_extremite                                                                           \
                                                ,c_est_la_phase_d_anti_aliasing                                                         \
                                                ,anti_aliasing                                                                          \
                                                 )                                                                                      \
                         );                                                                                                             \
                    Eblock                                                                                                              \
                                        /* Trace le vecteur vertical courant.                                                        */

#define   C_EST_LA_PHASE_D_ANTI_ALIASING                                                                                                \
                    VRAI                                                                                                                \
                                        /* Indique pour 'Itrace_segment_vertical' que c'est la phase d'anti-aliasing.                */
#define   CE_N_EST_PAS_LA_PHASE_D_ANTI_ALIASING                                                                                         \
                    NOTL(C_EST_LA_PHASE_D_ANTI_ALIASING)                                                                                \
                                        /* Indique pour 'Itrace_segment_vertical' que ce n'est pas la phase d'anti-aliasing.         */

DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____importance_du_decalage_vertical,FU)));
                                        /* Importance relative (dans [0,1]) du decalage vertical applique a chaque                   */
                                        /* tranche verticale qui compose la montagne ; avec '1' on obtient le                        */
                                        /* decalage "standard", et avec '0' aucun decalage.                                          */
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____inclinaison_de_la_source_lumineuse,FZERO)));
                                        /* Importance relative (dans [0,1]) de la composante selon l'axe 'OY' du                     */
                                        /* rayon lumineux : '0' correspond a l'etat anterieur ou cette composante                    */
                                        /* etait completement negligee, et '1' ou elle prend toute son importance.                   */
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____source_lumineuse_Z,DOUB(FU))));
                                        /* En fait, on introduit ici une troisieme composante a la position de la source             */
                                        /* lumineuse afin de resoudre le probleme des grandes facettes verticales                    */
                                        /* paralleles au plan de projection ; les deux degres de liberte laisses a                   */
                                        /* l'utilisateur ('X' et 'Y') sont suffisants. Enfin, le calcul des ombres portees           */
                                        /* demeure bi-dimensionnel...                                                                */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        T R A C E   D ' U N   S E G M E N T   V E R T I C A L  :                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

BFonctionI

DEFV(Common,DEFV(Logical,SINT(Imontagnes_precises_____compatibilite_20061220,FAUX)));
                                        /* Le 20061220094855 la correction d'anti-alisaing a ete introduite sur l'ensemble des       */
                                        /* lignes de crete (et non plus sur celles de l'arriere-plan comme cela avait ete rappele    */
                                        /* le 20061220094638 ci-apres...). Cet indicateur permet donc d'assuer, si besoin est, la    */
                                        /* compatibilite anterieure...                                                               */
DEFV(Common,DEFV(Logical,SINT(Imontagnes_precises_____compatibilite_20090130,FAUX)));
                                        /* Le 20090130181639 un dispositif permettant d'inhiber la tricherie concernant les lignes   */
                                        /* [Ymin,Ylast] et [Yfirst,Ymax]. Par defaut ce dispositif n'est pas actif (contrairement    */
                                        /* a ce qui se fait habituellement pour les '..._____compatibilite_...').                    */
                                        /*                                                                                           */
                                        /* Le 20090203133525 la valeur par defaut et passee de 'VRAI' a 'FAUX' car c'est en effet    */
                                        /* moins dangereux de voir le defaut (deux lignes NOIRes, une en bas et une en haut) que     */
                                        /* de le corriger en trichant et en oubliant ensuite qu'il y a eut cette correction...       */
                                        /* A compter du 20090203154615 le defaut a ete reduit a une seule ligne NOIRe (en haut)...   */

DEFV(Common,DEFV(Logical,SINT(Imontagnes_precises_____interpoler_les_lignes_de_crete_sur_la_montagne,VRAI)));
                                        /* Afin d'inhiber la correction des lignes de crete ci-apres...                              */
                                        /*                                                                                           */
                                        /* ATTENTION : je note le 20061220094638 qu'il ne s'agit pas alors de toutes les lignes      */
                                        /* crete de la montagne, mais uniquement de celles qui correspondent a l'arriere-plan,       */
                                        /* c'est-a-dire a 'Yfirst_trace' et a 'Ylast_trace'. C'est pourquoi le 20061220094855        */
                                        /* fut introduit l'interpolation suivante sur toutes les lignes de crete...                  */
DEFV(Common,DEFV(Float,SINT(Imontagnes_precises_____facteur_profondeur_toutes_lignes_de_crete,GRO3(FRA2(FU)))));
                                        /* Facteur destine a la profondeur d'une ligne de crete par rapport a l'arriere-plan         */
                                        /* (introduit le 20061220155451).                                                            */
DEFV(Common,DEFV(Float,SINT(Imontagnes_precises_____facteur_1_interpolation_toutes_lignes_de_crete,FZERO)));
DEFV(Common,DEFV(Float,SINT(Imontagnes_precises_____facteur_2_interpolation_toutes_lignes_de_crete,FDU)));
                                        /* Facteur de ponderation introduit le 20061220115138 pour anti-aliaser l'integralite des    */
                                        /* lignes de crete. L'interpolation utilisee est la suivante :                               */
                                        /*                                                                                           */
                                        /*                  [(1-f1).(1-f2).IntensiteCourante]    +                                   */
                                        /*                  [(1-f1).(f2-0).IntensiteArrierePlan] +                                   */
                                        /*                  [(f1-0).(1-f2).NOIR]                 +                                   */
                                        /*                  [(f1-0).(f2-0).BLANC]                                                    */
                                        /*                                                                                           */
                                        /* avec quatre utilisations extremes :                                                       */
                                        /*                                                                                           */
                                        /*                  f1=0 f2=0           IntensiteCourante   (et donc compatibilite           */
                                        /*                                                           anterieure au 20061220094855),  */
                                        /*                                                                                           */
                                        /*                  f1=0 f2=1           IntensiteArrierePlan                                 */
                                        /*                                                                                           */
                                        /*                  f1=1 f2=0           NOIR                                                 */
                                        /*                                                                                           */
                                        /*                  f1=1 f2=1           BLANC                                                */
                                        /*                                                                                           */
                                        /* les valeurs par defaut (f1=f2=1/2) assurant le moyennage de 'IntensiteCourante' et        */
                                        /* de 'IntensiteArrierePlan'.                                                                */

DEFV(Common,DEFV(Logical,SINT(Imontagnes_precises_____visualiser_la_falaise_avant_de_la_montagne,FAUX)));
                                        /* Afin de visualiser la falaise situee a l'avant de la montagne ('VRAI') ou bien de         */
                                        /* l'estomper ('FAUX').                                                                      */

DEFV(Common,DEFV(Logical,SINT(Imontagnes_precises_____interpoler_le_Z_Buffer_lors_de_l_anti_aliasing,VRAI)));
                                        /* Afin de choisir entre l'ancien mode ('FAUX', anterieur au 20011226142146) et le nouveau   */
                                        /* mode ('VRAI') dans 'TRACE_POINT_3D(...)'. Ce dernier mode doit etre utilise lorsque le    */
                                        /* 'Z-Buffer' va etre memorise et utilise par exemple pour generer un effet de brume.        */
                                        /* Il conviendra alors que 'v $xiii/mono_image$FON Z_Buffer_____valeur_initiale' soit        */
                                        /* initialise a 0 (introduit le 20011226142146). Renoncant a la compatibilite, cette         */
                                        /* option est immediatement passe a 'VRAI' le 20011226165021...                              */
                                        /*                                                                                           */
                                        /* ATTENTION : le 20011227172915 j'ai note une propriete tres importante de cette            */
                                        /* interpolation du 'Z'. En effet les segments traces pour lesquels il y a interpolation     */
                                        /* sont verticaux et donc a 'Z' constant. L'interpolation du 'Z' ne donnent donc pas les     */
                                        /* 'Z' des points de ces segments, mais uniquement quelque chose destine a "anti-aliaser"    */
                                        /* des effets de brume...                                                                    */
                                        /*                                                                                           */
                                        /* ATTENTION : on notera que lorsque le 'Z-Buffer' est genere pour etre utilise pour sa      */
                                        /* nature tridimensionnelle ('v $xci/merge_3D.01$K ImoveM_3D_volume_avec_marquage'), il      */
                                        /* est essentiel que cette option soit 'FAUX'...                                             */

#define   ARRONDI_NIVEAU(niveau)                                                                                                        \
                    TRNP(ARRI(niveau))                                                                                                  \
                                        /* A compter du 19980605181852, la fonction 'NEUT(...)' a ete remplacee par 'ARRI(...)'      */ \
                                        /* afin de reduire certains effets de "rebonds" des niveaux qui accentuaient les bandes      */ \
                                        /* de Mach...                                                                                */

#define   visualiser_la_falaise_avant_de_la_montagne                                                                                    \
                    Imontagnes_precises_____visualiser_la_falaise_avant_de_la_montagne                                                  \
                                        /* Pour reduire plus loin la longueur d'une ligne...                                         */
#define   TRACE_POINT_3D(c_est_la_phase_d_anti_aliasing)                                                                                \
                    Bblock                                                                                                              \
                    DEFV(Int,INIT(abscisse_courante,ASI2(vecteur_vertical,origine,x)));                                                 \
                    DEFV(genere_Float,INIT(Zf_courant,_____cNORMALISE_OZ(ADD2(Yfirst_trace,SOUS(Ylast_trace,Y)))));                     \
                                        /* Coordonnees 'x' et 'z' courantes. ATTENTION, il est impossible de donner, si besoin est   */ \
                                        /* (c'est-a-dire si a la fois 'EST_VRAI(c_est_la_phase_d_anti_aliasing)'                     */ \
                                        /* et 'IL_FAUT(Imontagnes_precises_____interpoler_le_Z_Buffer_lors_de_l_anti_aliasing)'),    */ \
                                        /* a 'Zf_courant' la valeur 'Zf_courant_vecteur_vertical' sous peine d'artefacts genants,    */ \
                                        /* par exemple dans le cas ou l'interpolation du 'Z' (si elle est demandee) se fait avec     */ \
                                        /* un point du fond et donc en quelque sorte a l'infini ; ainsi les segments, qui sont dans  */ \
                                        /* un plan parallele au plan de l'image (donc a 'Z' constants), se retrouveraient inclines   */ \
                                        /* vers l'arriere, puisque leurs 'Z' sont interpoles. Moralite, la mise a jour du 'Z-Buffer' */ \
                                        /* avec 'Zf_courant_vecteur_vertical' ne peut se faire qu'apres l'appel a                    */ \
                                        /* 'TEST_Z_Buffer_(...)' et donc en fait a l'interieur meme de 'TEST_Z_Buffer_(...)'.        */ \
                                                                                                                                        \
                    Test(IFEXff(intensite_courante,FLOT__NOIR,FLOT__BLANC))                                                             \
                                        /* Test introduit le 20100220184023 car il est tout a fait justifie (en particulier a        */ \
                                        /* cause des 'GENP(...)'s qui suivent...).                                                   */ \
                         Bblock                                                                                                         \
                         PRINT_ERREUR("le niveau calcule est mauvais");                                                                 \
                         CAL1(Prer1("niveau calcule.................=%f\n",intensite_courante));                                        \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                                                                                                                                        \
                    TEST_Z_Buffer_(abscisse_courante                                                                                    \
                                  ,ordonnee_courante                                                                                    \
                                  ,Zf_courant                                                                                           \
                                  ,BLOC(DEFV(genere_p,INIT(intensite_courante_utilisee,GENP(ARRONDI_NIVEAU(intensite_courante))));      \
                                        /* Niveau a utiliser a priori...                                                             */ \
                                                                                                                                        \
                                        Test(IFET(IL_FAUT(Imontagnes_precises_____interpoler_les_lignes_de_crete_sur_la_montagne)       \
                                                 ,I3ET(IFOU(IFEQ(Y,Yfirst_trace)                                                        \
                                                           ,IFEQ(Y,Ylast_trace)                                                         \
                                                            )                                                                           \
                                                      ,IFEQ(ENTE(Yf_extremite),ASI2(vecteur_vertical,extremite,y))                      \
                                                      ,IFEQ(ordonnee_courante,ASI2(vecteur_vertical,extremite,y))                       \
                                                       )                                                                                \
                                                  )                                                                                     \
                                             )                                                                                          \
                                             Bblock                                                                                     \
                                             DEFV(genere_p,INIT(intensite_anterieure                                                    \
                                                               ,loadS_point_valide(imageAR                                              \
                                                                                  ,abscisse_courante                                    \
                                                                                  ,ordonnee_courante                                    \
                                                                                   )                                                    \
                                                                )                                                                       \
                                                  );                                                                                    \
                                             DEFV(Float,INIT(parametre_d_interpolation                                                  \
                                                            ,SOUS(Yf_extremite                                                          \
                                                                 ,FLOT(ASI2(vecteur_vertical,extremite,y))                              \
                                                                  )                                                                     \
                                                             )                                                                          \
                                                  );                                                                                    \
                                                                                                                                        \
                                             EGAL(intensite_courante_utilisee                                                           \
                                                 ,GENP(NIVA(ARRONDI_NIVEAU(BARY(FLOT(NIVR(intensite_anterieure))                        \
                                                                               ,NIVR(intensite_courante)                                \
                                                                               ,parametre_d_interpolation                               \
                                                                                )                                                       \
                                                                           )                                                            \
                                                            )                                                                           \
                                                       )                                                                                \
                                                  );                                                                                    \
                                        /* Niveau a utiliser ; dans le cas ou l'on se situe a l'extremite du vecteur, on applique    */ \
                                        /* une correction dependant de la position exacte par rapport a la "grille" des points       */ \
                                        /* d'une image...                                                                            */ \
                                                                                                                                        \
                                             Test(IFOU(IFEXff(parametre_d_interpolation                                                 \
                                                             ,COORDONNEE_BARYCENTRIQUE_MINIMALE                                         \
                                                             ,COORDONNEE_BARYCENTRIQUE_MAXIMALE                                         \
                                                              )                                                                         \
                                                      ,NINCff(intensite_courante_utilisee                                               \
                                                             ,intensite_anterieure                                                      \
                                                             ,GENP(ARRONDI_NIVEAU(intensite_courante))                                  \
                                                              )                                                                         \
                                                       )                                                                                \
                                                  )                                                                                     \
                                                  Bblock                                                                                \
                                                  PRINT_ERREUR("l'interpolation des niveaux est incorrecte");                           \
                                                  CAL1(Prer4("segment........................={{%d,%d},{%d,%d}}\n"                      \
                                                            ,abscisse_courante,ASI2(vecteur_vertical,origine,y)                         \
                                                            ,ASI2(vecteur_vertical,extremite,x),ASI2(vecteur_vertical,extremite,y)      \
                                                             )                                                                          \
                                                       );                                                                               \
                                                  CAL1(Prer1("ordonnee precise de l'origine..=%f\n",Yf_origine));                       \
                                                  CAL1(Prer1("ordonnee precise de l'extremite=%f\n",Yf_extremite));                     \
                                                  CAL1(Prer1("parametre d'interpolation......=%f\n",parametre_d_interpolation));        \
                                                  CAL1(Prer1("niveau anterieur...............=%d\n",intensite_anterieure));             \
                                                  CAL1(Prer1("niveau calcule.................=%f\n",intensite_courante));               \
                                                  CAL1(Prer1("niveau interpole...............=%f\n",intensite_courante_utilisee));      \
                                                  Eblock                                                                                \
                                             ATes                                                                                       \
                                                  Bblock                                                                                \
                                                  Eblock                                                                                \
                                             ETes                                                                                       \
                                             Eblock                                                                                     \
                                        ATes                                                                                            \
                                             Bblock                                                                                     \
                                             Eblock                                                                                     \
                                        ETes                                                                                            \
                                                                                                                                        \
                                        Test(I3ET(IL_FAUT(anti_aliasing)                                                                \
                                                 ,IFEQ(ordonnee_courante                                                                \
                                                      ,MAX2(ASI2(vecteur_vertical,origine,y)                                            \
                                                           ,ASI2(vecteur_vertical,extremite,y)                                          \
                                                            )                                                                           \
                                                       )                                                                                \
                                                 ,IL_NE_FAUT_PAS(Imontagnes_precises_____compatibilite_20061220)                        \
                                                  )                                                                                     \
                                             )                                                                                          \
                                             Bblock                                                                                     \
                                             Test(IFGT(SOUA(loadF_point_valide(Z_Buffer,abscisse_courante,vSUCY(ordonnee_courante))     \
                                                           ,Zf_courant                                                                  \
                                                            )                                                                           \
                                                      ,MUL2(Imontagnes_precises_____facteur_profondeur_toutes_lignes_de_crete           \
                                                           ,_____cNORMALISE_OZ(pasY)                                                    \
                                                            )                                                                           \
                                                       )                                                                                \
                                                  )                                                                                     \
                                                  Bblock                                                                                \
                                        /* Cas ou il semble que l'arriere-plan est un peu plus loin que la distance definie par      */ \
                                        /* 'pasY' : on considere qu'on est donc sur une ligne de crete...                            */ \
                                        /*                                                                                           */ \
                                        /* On notera que l'on utilise 'SUCY(ordonnee_courante)' et non pas 'ordonnee_courante'       */ \
                                        /* (qui serait en fait la valeur logique...) a cause de 'C_EST_LA_PHASE_D_ANTI_ALIASING'     */ \
                                        /* car, en effet, celle-ci consiste en un trace d'un vecteur situe a l'abscisse 'SUCX(X)'    */ \
                                        /* ce qui fait que l'on modifie alors le 'Z' du point {SUCX(X),Y}. Or celui-ci sera teste    */ \
                                        /* de nouveau lors de 'CE_N_EST_PAS_LA_PHASE_D_ANTI_ALIASING' suivante avec les coordonnees  */ \
                                        /* {X,Y} courante et alors le 'Z' anterieur ne sera plus celui de l'arriere-plan, mais du    */ \
                                        /* vecteur "degrade" trace lors de 'C_EST_LA_PHASE_D_ANTI_ALIASING' precedent. On triche     */ \
                                        /* donc en regardant un point au-dessus...                                                   */ \
                                                  EGAL(intensite_courante_utilisee                                                      \
                                                      ,BAR4(intensite_courante_utilisee                                                 \
                                                           ,loadS_point_valide(imageAR                                                  \
                                                                              ,abscisse_courante                                        \
                                                                              ,ordonnee_courante                                        \
                                                                               )                                                        \
                                                           ,NOIR                                                                        \
                                                           ,BLANC                                                                       \
                                                           ,Imontagnes_precises_____facteur_1_interpolation_toutes_lignes_de_crete      \
                                                           ,Imontagnes_precises_____facteur_2_interpolation_toutes_lignes_de_crete      \
                                                            )                                                                           \
                                                       );                                                                               \
                                        /* Le 20061220094855 la correction d'anti-aliasing a ete introduite sur toutes les           */ \
                                        /* lignes de crete. Elle consiste en une interpolation simple (par une moyenne) avec         */ \
                                        /* le niveau d'arriere-plan (deja trace puisque l'on va d'arriere en avant...).              */ \
                                        /*                                                                                           */ \
                                        /* Le 20061220115138, 'MOYE(...)' a ete remplace par 'BARY(...)' plus general, soit :        */ \
                                        /*                                                                                           */ \
                                        /*                  (1-facteur).IntensiteCourante + (facteur-0).IntensiteArrierePlan         */ \
                                        /*                                                                                           */ \
                                        /* puis remplace le 20061220134021 par 'BAR4(...)' encore plus general :                     */ \
                                        /*                                                                                           */ \
                                        /*                  [(1-f1).(1-f2).IntensiteCourante]    +                                   */ \
                                        /*                  [(1-f1).(f2-0).IntensiteArrierePlan] +                                   */ \
                                        /*                  [(f1-0).(1-f2).NOIR]                 +                                   */ \
                                        /*                  [(f1-0).(f2-0).BLANC]                                                    */ \
                                        /*                                                                                           */ \
                                        /* puisqu'il permet de marquer les lignes de crete (en NOIR, en BLANC,...).                  */ \
                                                  Eblock                                                                                \
                                             ATes                                                                                       \
                                                  Bblock                                                                                \
                                                  Eblock                                                                                \
                                             ETes                                                                                       \
                                             Eblock                                                                                     \
                                        ATes                                                                                            \
                                             Bblock                                                                                     \
                                             Eblock                                                                                     \
                                        ETes                                                                                            \
                                                                                                                                        \
                                        store_point_valide(GENP(COND(I3ET(IL_NE_FAUT_PAS(visualiser_la_falaise_avant_de_la_montagne)    \
                                                                         ,IFEQ(Y,Ylast_trace)                                           \
                                                                         ,IFNE(ordonnee_courante,ASI2(vecteur_vertical,extremite,y))    \
                                                                          )                                                             \
                                                                    ,CLIPPING_INTENSITE                                                 \
                                                                    ,MAX2(intensite_courante_utilisee                                   \
                                                                         ,MIN_INTENSITE                                                 \
                                                                          )                                                             \
                                                                     )                                                                  \
                                                                )                                                                       \
                                                          ,imageAR                                                                      \
                                                          ,abscisse_courante                                                            \
                                                          ,ordonnee_courante                                                            \
                                                          ,FVARIABLE                                                                    \
                                                           );                                                                           \
                                        /* Rangement du point courant...                                                             */ \
                                                                                                                                        \
                                        Test(IFET(EST_VRAI(c_est_la_phase_d_anti_aliasing)                                              \
                                                 ,IL_FAUT(Imontagnes_precises_____interpoler_le_Z_Buffer_lors_de_l_anti_aliasing)       \
                                                  )                                                                                     \
                                             )                                                                                          \
                                             Bblock                                                                                     \
                                             EGAL(Zf_courant,Zf_courant_vecteur_vertical);                                              \
                                             Eblock                                                                                     \
                                        ATes                                                                                            \
                                             Bblock                                                                                     \
                                             Eblock                                                                                     \
                                        ETes                                                                                            \
                                        /* Maintenant que 'Zf_courant' a ete utilise precedemment pour tester le 'Z-Buffer'          */ \
                                        /* on va le mettre a jour avec 'Zf_courant_vecteur_vertical' et non avec 'Zf_courant'. En    */ \
                                        /* effet si on avait donne des le debut de 'TEST_Z_Buffer_(...)' a 'Zf_courant'              */ \
                                        /* la valeur 'Zf_courant_vecteur_vertical' les points du segment "anti-aliase" courant       */ \
                                        /* aurait pu se trouver memorise avec des 'Z' incoherents : c'est le cas ou l'interpolation  */ \
                                        /* du 'Z' a lieu avec un point du fond qui est donc en quelque sorte a l'infini...           */ \
                                        )                                                                                               \
                                   );                                                                                                   \
                    Eblock                                                                                                              \
                                        /* Trace du point 3D de coordonnees :                                                        */ \
                                        /*                                                                                           */ \
                                        /*                  x = ASI2(vecteur_vertical,origine,x),                                    */ \
                                        /*                  y = ordonnee_courante,                                                   */ \
                                        /*                  z = _____cNORMALISE_OZ(ADD2(Yfirst_trace,SOUS(Ylast_trace,Y))).          */ \
                                        /*                                                                                           */ \
                                        /* On notera qu'autrefois on utilisait (ce qui donnait une montagne situee du                */ \
                                        /* cote des 'Z' negatifs, c'est-a-dire a l'oppose de l'observateur) :                        */ \
                                        /*                                                                                           */ \
                                        /*                  z = _____cNORMALISE_OZ(SOUS(Ylast_trace,Y)),                             */ \
                                        /*                                                                                           */ \
                                        /* maintenant, on translate de 'Yfirst_trace'...                                             */ \
                                        /*                                                                                           */ \
                                        /* Le 19970116144453, la mise en place de 'CLIPPING_INTENSITE' a ete inhibe meme lorsque     */ \
                                        /* 'Y' vaut 'Ylast_trace' et ce lorsque l'on est a l'extremite du vecteur vertical courant.  */

DEFV(Common,DEFV(Float,SINT(Imontagnes_precises_____translation_de_la_coordonnee_Z_lors_d_une_vue_d_avion,FZERO)));
                                        /* Introduit le 20080214130808 lors de la regeneration de 'v $xiirf/PAYS.R5$M' pour laquelle */
                                        /* 'facteur_d_echelle' est negatif ce qui provoquait alors des 'Zf' tous negatifs ci-apres   */
                                        /* dans 'TRACE_POINT_3D_VUE_D_AVION(...)' et donc des points invisibles...                   */

#define   TRACE_POINT_3D_VUE_D_AVION(X,Y,Zf)                                                                                            \
                    Bblock                                                                                                              \
                    TEST_Z_Buffer_(X,Y,ADD2(Zf,Imontagnes_precises_____translation_de_la_coordonnee_Z_lors_d_une_vue_d_avion)           \
                                  ,BLOC(store_point_valide(GENP(MAX2(ARRONDI_NIVEAU(intensite_extremite)                                \
                                                                    ,MIN_INTENSITE                                                      \
                                                                     )                                                                  \
                                                                )                                                                       \
                                                          ,imageAR                                                                      \
                                                          ,X                                                                            \
                                                          ,Y                                                                            \
                                                          ,FVARIABLE                                                                    \
                                                           );                                                                           \
                                        )                                                                                               \
                                   );                                                                                                   \
                    Eblock                                                                                                              \
                                        /* Trace du point 3D de coordonnees (X,Y,z) vu d'avion. ATTENTION, il y a eu pendant         */ \
                                        /* longtemps ici :                                                                           */ \
                                        /*                                                                                           */ \
                                        /*        TEST_Z_Buffer_(X,Y,_____cNORMALISE_OZ(ASI2(vecteur_vertical,extremite,y))          */ \
                                        /*                                                                                           */ \
                                        /* ce qui donnait en fait un 'Z' incorrect (par definition du vecteur a tracer, et en        */ \
                                        /* particulier de 'ASI2(vecteur_vertical,extremite,y)'), d'ou l'introduction de la veritable */ \
                                        /* coordonnee 'z' le 1996053000.                                                             */

DEFV(Common,DEFV(Logical,SINT(Imontagnes_precises_____compatibilite_20100223,FAUX)));
                                        /* Le 20100223170213 une variante a ete introduite lors des tests du probleme                */
                                        /* 'v $xiii/montagnes$FON 20100220204800'. En activant cette option (impliquant un           */
                                        /* comportement d'ailleurs plus logique) on y perd en anti-aliasing sur les pentes de        */
                                        /* droite des montagnes...                                                                   */

#define   NOMBRE_DE_PAS_D_INTERPOLATION_DE_L_INTENSITE(origine,extremite)                                                               \
                    OPC1(IL_FAUT(Imontagnes_precises_____compatibilite_20100223)                                                        \
                        ,TRMU                                                                                                           \
                        ,TRPU                                                                                                           \
                        ,LENG(origine,extremite)                                                                                        \
                         )                                                                                                              \
                                        /* Calcul du nombre de pas d'interpolation necessaires au calcul de l'intensite courante. On */ \
                                        /* verra avec interet le commentaire relatif a 'DEFV(Int,INIT(longueur_pour_intensite,...))' */ \
                                        /* un peu plus loin...                                                                       */ \
                                        /*                                                                                           */ \
                                        /* Avant le 20100223102733 le 'TRMU(...)' etait un 'TRPU(...)' et l'une des causes           */ \
                                        /* principales du probleme 'v $xiii/montagnes$FON 20100220204800'...                         */
#define   NOMBRE_DE_PAS_D_INTERPOLATION_DE_LA_PROFONDEUR(origine,extremite)                                                             \
                    TRMU(LENG(origine,extremite))                                                                                       \
                                        /* Calcul du nombre de pas d'interpolation necessaires au calcul de la profondeur courante.  */

DEFV(Common,DEFV(Logical,SINT(Itrace_segment_vertical_____editer_la_coordonnee_Z_d_un_point,FAUX)));
DEFV(Common,DEFV(Int,SINT(Itrace_segment_vertical_____coordonnee_X_du_point_dont_on_veut_la_coordonnee_Z,k___Xmin)));
DEFV(Common,DEFV(Int,SINT(Itrace_segment_vertical_____coordonnee_Y_du_point_dont_on_veut_la_coordonnee_Z,k___Ymin)));
                                        /* Introduit le 20240330120041 a des fins de test...                                         */

DEFV(Local,DEFV(FonctionI,Itrace_segment_vertical(imageAR
                                                 ,vue_d_avion
                                                 ,ARGUMENT_POINTERs(vecteur_vertical),Yf_origine,Yf_extremite
                                                 ,X,Y,Zf
                                                 ,intensite_origine,intensite_extremite
                                                 ,Zf_extremite
                                                 ,c_est_la_phase_d_anti_aliasing
                                                 ,anti_aliasing
                                                  )
                )
     )
DEFV(Argument,DEFV(image,imageAR));
                                        /* Image a la fois Argument et Resultat...                                                   */
DEFV(Argument,DEFV(Logical,vue_d_avion));
                                        /* Indique le mode de representation : vue d'avion ('VRAI') ou vue de cote ('FAUX').         */
DEFV(Argument,DEFV(vectorI_2D,POINTERs(vecteur_vertical)));
DEFV(Argument,DEFV(Float,Yf_origine));
DEFV(Argument,DEFV(Float,Yf_extremite));
                                        /* Vecteur vertical argument.                                                                */
DEFV(Argument,DEFV(Int,X));
DEFV(Argument,DEFV(Int,Y));
DEFV(Argument,DEFV(Float,Zf));
                                        /* Coordonnees (X,Y,Zf) dans le champ ; ces arguments ne sont utilises que pour les vues     */
                                        /* d'avion...                                                                                */
DEFV(Argument,DEFV(Float,intensite_origine));
                                        /* Intensite lumineuse du point bas ("origine") du vecteur,                                  */
DEFV(Argument,DEFV(Float,intensite_extremite));
                                        /* Intensite lumineuse du point haut ("extremite") du vecteur.                               */
DEFV(Argument,DEFV(Float,Zf_extremite));
                                        /* Coordonnee 'Z' du point haut ("extremite") du vecteur.                                    */
DEFV(Argument,DEFV(Logical,c_est_la_phase_d_anti_aliasing));
                                        /* Indique si c'est la phase d'anti-aliasing ('VRAI') ou pas ('FAUX')                        */
                                        /* sur le vecteur courant.                                                                   */
DEFV(Argument,DEFV(Logical,anti_aliasing));
                                        /* Indique s'il faut faire ('VRAI') ou pas ('FAUX') de l'anti-aliasing                       */
                                        /* sur l'image Resultat. Ceci fut introduit le 20061220094855 suite a l'usage qui en         */
                                        /* est fait dorenavant dans 'TRACE_POINT_3D(...)'.                                           */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     INIT_ERROR;
                                        /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples      */
                                        /* ('BDEFV','EDEFV') suivraient...                                                           */
     DEFV(Int,INIT(ordonnee_courante,UNDEF));
                                        /* Ordonnee courante lors du marquage du vecteur vertical.                                   */
     DEFV(Float,INIT(intensite_courante
                    ,COND(IFNE(ASI2(vecteur_vertical,origine,y),ASI2(vecteur_vertical,extremite,y))
                         ,NEUT(intensite_extremite)
                         ,MOYE(intensite_origine,intensite_extremite)
                          )
                     )
          );
                                        /* Intensite lumineuse courante lors du marquage du vecteur.                                 */
     DEFV(Float,INIT(pas_intensite,SOUS(intensite_origine,intensite_extremite)));
                                        /* Pas de passage de l'intensite "haute" a l'intensite "basse".                              */
     DEFV(Float,INIT(Zf_courant_vecteur_vertical,COND(EST_VRAI(c_est_la_phase_d_anti_aliasing),Zf_extremite,FLOT__UNDEF)));
                                        /* Coordonnee 'Z' courante lors du marquage du vecteur.                                      */
     DEFV(Float,INIT(pas_Zf
                    ,COND(EST_VRAI(c_est_la_phase_d_anti_aliasing)
                         ,SOUS(_____cNORMALISE_OZ(ADD2(Yfirst_trace,SOUS(Ylast_trace,Y))),Zf_extremite)
                         ,FLOT__UNDEF
                          )
                     )
          );
                                        /* Pas de passage de la coordonnee 'Z' "haute" a la coordonnee 'Z' "basse".                  */
     DEFV(Int,INIT(longueur_pour_intensite,NOMBRE_DE_PAS_D_INTERPOLATION_DE_L_INTENSITE(ASI2(vecteur_vertical,origine,y)
                                                                                       ,ASI2(vecteur_vertical,extremite,y)
                                                                                        )
                   )
          );
                                        /* Longueur du vecteur a tracer plus deux unites afin de generer correctement les niveaux    */
                                        /* d'un vecteur reduit a un point. En particulier, on notera le 'TRPU(LENG(...))' qui, par   */
                                        /* exemple, permet la chose suivante :                                                       */
                                        /*                                                                                           */
                                        /* soit un vecteur reduit a un point (extremite=origine) ; d'apres la formule ci-dessus,     */
                                        /* on a :                                                                                    */
                                        /*                                                                                           */
                                        /*                  longueur        = 2.                                                     */
                                        /*                                                                                           */
                                        /* imaginons de plus que :                                                                   */
                                        /*                                                                                           */
                                        /*                  intensite_origine = NOIR,                                                */
                                        /*                  intensite_extremite = BLANC,                                             */
                                        /*                                                                                           */
                                        /* le pas d'interpolation de l'intensite reellement utilise sera donc :                      */
                                        /*                                                                                           */
                                        /*                                     BLANC - NOIR                                          */
                                        /*                  pas_intensite   = --------------                                         */
                                        /*                                           2                                               */
                                        /*                                                                                           */
                                        /* le seul point du vecteur sera donc marque en GRIS, ce qui represente le bon intermediaire */
                                        /* entre la basse et la haute intensite...                                                   */
     DEFV(Int,INIT(longueur_pour_profondeur,NOMBRE_DE_PAS_D_INTERPOLATION_DE_LA_PROFONDEUR(ASI2(vecteur_vertical,origine,y)
                                                                                          ,ASI2(vecteur_vertical,extremite,y)
                                                                                           )
                   )
          );
                                        /* Longueur fictive du vecteur a tracer afin de generer correctement les profondeurs...      */
     /*..............................................................................................................................*/
     PUSH_MASQUE;
                                        /* Sauvegarde de l'etat de masquage avant le trace,                                          */
     DEMASQUE_IMAGES;
                                        /* Et on le desactive ; car en effet, le masque correspond au champ, et donc                 */
                                        /* au "sol" de la montagne, et non pas a sa projection sur l'ecran...                        */

     Test(IL_FAUT(vue_d_avion))
          Bblock
          TRACE_POINT_3D_VUE_D_AVION(X,Y,Zf);
                                        /* Lors d'une vue d'avion, il n'y a pas de translation ; malgre cela,                        */
                                        /* on genere simultanement le Z_Buffer, qui en fait ne sert a rien au niveau                 */
                                        /* de l'elimination des lignes cachees de la montagne (vu le principe de                     */
                                        /* construction), mais qui permet ensuite d'integrer une structure 3D autour                 */
                                        /* de la montagne (par exemple en graphique).                                                */

          Test(IL_FAUT(Imontagnes_precises_____compatibilite_20090130))
                                        /* Test introduit le 20090130181639...                                                       */
               Bblock
               Test(IFEQ(Y,Ylast_trace))
                                        /* Lorsque l'on est sur la ligne 'Ylast_trace', etant donne que les lignes [Ymin,Ylast]      */
                                        /* qui la precedent ne seront jamais traitees "normalement", on les remplit ci-apres         */
                                        /* arbitrairement par duplication du niveau courant 'intensite_extremite' via la procedure   */
                                        /* 'TRACE_POINT_3D_VUE_D_AVION(...)'.                                                        */
                    Bblock
                    begin_colonneQ(DoIn,Ymin,Ylast,pasY)
                         Bblock
                         TRACE_POINT_3D_VUE_D_AVION(X,Y,Zf);
                         Eblock
                    end_colonneQ(EDoI)
                                        /* Lors d'une vue d'avion, on triche un peu en dupliquant afin de remplir les lignes         */
                                        /* non generees [Ymin,AVANT(Ylast)] et [Yfirst,Ymax].                                        */
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               Test(IFEQ(Y,Yfirst_trace))
                                        /* Lorsque l'on est sur la ligne 'Yfirst_trace', etant donne que les lignes [Yfirst,Ymax]    */
                                        /* qui la suivent ne seront jamais traitees "normalement", on les remplit ci-apres           */
                                        /* arbitrairement par duplication du niveau courant 'intensite_extremite' via la procedure   */
                                        /* 'TRACE_POINT_3D_VUE_D_AVION(...)'.                                                        */
                    Bblock
                    begin_colonneQ(DoDe,Yfirst,Ymax,pasY)
                         Bblock
                         TRACE_POINT_3D_VUE_D_AVION(X,Y,Zf);
                         Eblock
                    end_colonneQ(EDoD)
                                        /* Lors d'une vue d'avion, on triche un peu en dupliquant afin de remplir les lignes         */
                                        /* non generees [Ymin,AVANT(Ylast)] et [Yfirst,Ymax].                                        */
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes
               Eblock
          ATes
               Bblock
               Eblock
          ETes
          Eblock
     ATes
          Bblock
          Test(IFNE(ASI2(vecteur_vertical,origine,x),ASI2(vecteur_vertical,extremite,x)))
               Bblock
               PRINT_ERREUR("les abscisses argument sont mauvaises");
               CAL1(Prer1("X(origine)  =%d\n",ASI2(vecteur_vertical,origine,x)));
               CAL1(Prer1("Y(origine)  =%d\n",ASI2(vecteur_vertical,origine,y)));
               CAL1(Prer1("X(extremite)=%d\n",ASI2(vecteur_vertical,extremite,x)));
               CAL1(Prer1("Y(extremite)=%d\n",ASI2(vecteur_vertical,extremite,y)));
               Eblock
          ATes
               Bblock
               Eblock
          ETes

          Test(IFET(IFGT(ASI2(vecteur_vertical,origine,y),ASI2(vecteur_vertical,extremite,y))
                   ,EST_INACTIF(EnTete_de_sauvegardM ## Masque_____etat)
                    )
               )
               Bblock
               PRINT_ERREUR("les ordonnees argument sont mauvaises");
               CAL1(Prer1("X(origine)  =%d\n",ASI2(vecteur_vertical,origine,x)));
               CAL1(Prer1("Y(origine)  =%d\n",ASI2(vecteur_vertical,origine,y)));
               CAL1(Prer1("X(extremite)=%d\n",ASI2(vecteur_vertical,extremite,x)));
               CAL1(Prer1("Y(extremite)=%d\n",ASI2(vecteur_vertical,extremite,y)));
               Eblock
          ATes
               Bblock
               Eblock
          ETes

          EGAL(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_montagne
              ,MAX2(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_montagne
                   ,_____cNORMALISE_OY(MAX2(ASI2(vecteur_vertical,origine,y)
                                           ,ASI2(vecteur_vertical,extremite,y)
                                            )
                                       )
                    )
               );
                                        /* Recherche de la plus grande ordonnee dans [0,1] sur l'ensemble de la montagne.            */

          Test(IFEQ(Y,Ylast_trace))
               Bblock
               EGAL(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_last_ligne_de_la_montagne
                   ,MAX2(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_last_ligne_de_la_montagne
                        ,_____cNORMALISE_OY(MAX2(ASI2(vecteur_vertical,origine,y)
                                                ,ASI2(vecteur_vertical,extremite,y)
                                                 )
                                            )
                         )
                    );
                                        /* Recherche de la plus grande ordonnee dans [0,1] sur la 'last' ligne de la montagne.       */
               Eblock
          ATes
               Bblock
               Eblock
          ETes

          Test(IFET(IZGT(longueur_pour_intensite)
                   ,IFGE(longueur_pour_intensite,NOMBRE_DE_PAS_D_INTERPOLATION_DE_L_INTENSITE(UNDEF,UNDEF))
                    )
               )
               Bblock
               EGAL(pas_intensite,DIVI(pas_intensite,FLOT(longueur_pour_intensite)));
                                        /* On ramene le pas de l'intensite au nombre de points a marquer...                          */
               Eblock
          ATes
               Bblock
               CLIR(pas_intensite);
               Eblock
          ETes

          Test(EST_VRAI(c_est_la_phase_d_anti_aliasing))
               Bblock
               Test(IZGT(longueur_pour_profondeur))
                    Bblock
                    EGAL(pas_Zf,DIVI(pas_Zf,FLOT(longueur_pour_profondeur)));
                                        /* On ramene le pas de la coordonnee 'Z' au nombre de points a marquer...                    */
                    Eblock
               ATes
                    Bblock
                    CLIR(pas_Zf);
                    Eblock
               ETes
               Eblock
          ATes
               Bblock
               Eblock
          ETes

          Test(IL_FAUT(Itrace_segment_vertical_____editer_la_coordonnee_Z_d_un_point))
                                        /* Possibilite introduite le 20240330120041...                                               */
               Bblock
               Test(IFET(IFEQ(X,Itrace_segment_vertical_____coordonnee_X_du_point_dont_on_veut_la_coordonnee_Z)
                        ,IFEQ(Y,Itrace_segment_vertical_____coordonnee_Y_du_point_dont_on_veut_la_coordonnee_Z)
                         )
                    )
                                        /* On notera qu'il est fort possible que ce test soit toujours FAUX pour un champ donne...   */
                    Bblock
                    CAL3(Prme2("Y(OrigineVecteur)=%d Y(ExtremiteVecteur)=%d\n"
                              ,ASI2(vecteur_vertical,origine,y)
                              ,ASI2(vecteur_vertical,extremite,y)
                               )
                         );
                    CAL3(Prme3("X=%d Y=%d Z=%d\n"
                              ,X
                              ,Y
                              ,MAX2(ASI2(vecteur_vertical,origine,y),ASI2(vecteur_vertical,extremite,y))
                               )
                         );
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes
               Eblock
          ATes
               Bblock
               Eblock
          ETes

          Test(IFLE(ASI2(vecteur_vertical,origine,y),ASI2(vecteur_vertical,extremite,y)))
               Bblock
                                        /* Trace des vecteurs des faces "avant", c'est-a-dire les vecteurs qui sont                  */
                                        /* toujours visibles (jusqu'a ce qu'une eventuelle face placee plus pres de                  */
                                        /* l'observateur vienne ulterieurement le masquer...) :                                      */
                                        /*                                                                                           */
                                        /*                  * extremite                                                              */
                                        /*                 /|\                                                                       */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  * origine                                                                */
                                        /*                                                                                           */
               DoDe(ordonnee_courante,ASI2(vecteur_vertical,origine,y),ASI2(vecteur_vertical,extremite,y),pasY)
                    Bblock
                    Test(IL_NE_FAUT_PAS(Imontagnes_precises_____compatibilite_20100223))
                         Bblock
                         INCR(intensite_courante,pas_intensite);
                                        /* Dans ce cas ('compatibilite_20100223=FAUX') lors de l'interpolation entre les niveaux     */
                                        /* 'N1' et 'N2', en fait les niveaux marques seront dans [N1+k,N2-k] (en supposant N1<N2),   */
                                        /* ce qui assure un bon anti-aliasing sur les pentes a droite.                               */
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes

                    TRACE_POINT_3D(c_est_la_phase_d_anti_aliasing);
                                        /* On genere simultanement le Z_Buffer, qui en fait ne sert a rien au niveau                 */
                                        /* de l'elimination des lignes cachees de la montagne (vu le principe de                     */
                                        /* construction), mais qui permet ensuite d'integrer une structure 3D autour                 */
                                        /* de la montagne (par exemple en graphique).                                                */

                    Test(IL_FAUT(Imontagnes_precises_____compatibilite_20100223))
                         Bblock
                         INCR(intensite_courante,pas_intensite);
                                        /* Dans ce cas ('compatibilite_20100223=VRAI') lors de l'interpolation entre les niveaux     */
                                        /* 'N1' et 'N2', les niveaux marques seront bien dans [N1,N2] ce qui provoque des defauts    */
                                        /* d'aliasing sur les pentes a droite.                                                       */
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes

                    INCR(Zf_courant_vecteur_vertical,pas_Zf);
                    Eblock
               EDoD
               Eblock
          ATes
               Bblock
                                        /* Trace des vecteurs des faces "arriere", c'est-a-dire les vecteurs qui sont                */
                                        /* theoriquement invisibles, sauf a travers des "trous" crees par l'effet du                 */
                                        /* Masque :                                                                                  */
                                        /*                                                                                           */
                                        /*                  * origine                                                                */
                                        /*                 /|\                                                                       */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  * extremite                                                              */
                                        /*                                                                                           */
               DoIn(ordonnee_courante,ASI2(vecteur_vertical,extremite,y),ASI2(vecteur_vertical,origine,y),pasY)
                    Bblock
                    Test(IL_NE_FAUT_PAS(Imontagnes_precises_____compatibilite_20100223))
                         Bblock
                         INCR(intensite_courante,pas_intensite);
                                        /* Dans ce cas ('compatibilite_20100223=FAUX') lors de l'interpolation entre les niveaux     */
                                        /* 'N1' et 'N2', en fait les niveaux marques seront dans [N1+k,N2-k] (en supposant N1<N2),   */
                                        /* ce qui assure un bon anti-aliasing sur les pentes a droite.                               */
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes

                    TRACE_POINT_3D(c_est_la_phase_d_anti_aliasing);
                                        /* On genere simultanement le Z_Buffer, qui en fait ne sert a rien au niveau                 */
                                        /* de l'elimination des lignes cachees de la montagne (vu le principe de                     */
                                        /* construction), mais qui permet ensuite d'integrer une structure 3D autour                 */
                                        /* de la montagne (par exemple en graphique).                                                */

                    Test(IL_FAUT(Imontagnes_precises_____compatibilite_20100223))
                         Bblock
                         INCR(intensite_courante,pas_intensite);
                                        /* Dans ce cas ('compatibilite_20100223=VRAI') lors de l'interpolation entre les niveaux     */
                                        /* 'N1' et 'N2', les niveaux marques seront bien dans [N1,N2] ce qui provoque des defauts    */
                                        /* d'aliasing sur les pentes a droite.                                                       */
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes

                    INCR(Zf_courant_vecteur_vertical,pas_Zf);
                    Eblock
               EDoI
               Eblock
          ETes
          Eblock
     ETes

     PULL_MASQUE;
                                        /* Restauration de l'etat de masquage apres le trace, et ce avant l'eventuel                 */
                                        /* trace suivant...                                                                          */

     Test(IFET(IFGT(Xlast,Xmin)
              ,IFEQ(INTX(ASI2(vecteur_vertical,origine,x)),Xlast)
               )
          )
          Bblock
          DEFV(vectorI_2D,premiere_colonne);
                                        /* Lorsque l'on est en presence de la colonne 'Xlast', on trace simultanement                */
                                        /* sa voisinne de gauche ('Xmin' en general...) qui en fait n'est pas calculee ;             */
                                        /* ce vecteur la contient.                                                                   */
          INITIALISATION_VECTEUR_2D(premiere_colonne
                                   ,vPREX(ASI2(vecteur_vertical,origine,x))
                                   ,vNEUT(ASI2(vecteur_vertical,origine,y))
                                   ,vPREX(ASI2(vecteur_vertical,extremite,x))
                                   ,vNEUT(ASI2(vecteur_vertical,extremite,y))
                                    );
          TRACE_VECTEUR_VERTICAL(imageAR
                                ,premiere_colonne
                                ,Yf_origine,Yf_extremite
                                ,vPREX(X),Y,Zf
                                ,CE_N_EST_PAS_LA_PHASE_D_ANTI_ALIASING
                                 );
                                        /* Ainsi, on triche un peu, en dupliquant la colonne de gauche...                            */
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     RETU_ERROR;
     Eblock

#undef    NOMBRE_DE_PAS_D_INTERPOLATION_DE_LA_PROFONDEUR
#undef    NOMBRE_DE_PAS_D_INTERPOLATION_DE_L_INTENSITE
#undef    TRACE_POINT_3D_VUE_D_AVION
#undef    TRACE_POINT_3D
#undef    visualiser_la_falaise_avant_de_la_montagne
#undef    ARRONDI_NIVEAU

EFonctionI

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N   D E   L A   S P E C U L A R I T E  :                                                                 */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____source_lumineuse_specularite,FU)));
                                        /* Definition de la specularite introduite le 20130101105228 en garantissant la              */
                                        /* compatibilite anterieure...                                                               */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N   D U   " D E P T H - C U E I N G "   G E N E R A L I S E  :                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____depth_cueing_ponderation_niveau,FU)));
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____depth_cueing_ponderation_coordonnee_X,FZERO)));
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____depth_cueing_ponderation_coordonnee_Y,FZERO)));
DEFV(Common,DEFV(Float,ZINT(Imontagnes_precises_____depth_cueing_translation,FZERO)));
                                        /* A compter du 19970908091406, le niveau calcule 'intensite_origine' (appele par la suite   */
                                        /* 'N' pour "niveau") subit avant d'etre utilise pour le trace la transformation lineaire    */
                                        /* suivante :                                                                                */
                                        /*                                                                                           */
                                        /*                  (pN.N) + (pX.f(X)) + (pY.f(Y)) + t                                       */
                                        /*                                                                                           */
                                        /* ou 'f(...)' represente une fonction qui fait passer d'abord les coordonnees dans [0,1]    */
                                        /* puis dans [NOIR,BLANC].                                                                   */
                                        /*                                                                                           */
                                        /* Ceci permet donc, par exemple, d'implementer de facon triviale un "depth-cueing" ou       */
                                        /* chacun des plans verticaux est represente par un code different des autres (aux           */
                                        /* restrictions pres du nombre de couleurs disponibles) tout en etant "anti-aliase" en       */
                                        /* faisant :                                                                                 */
                                        /*                                                                                           */
                                        /*                  pN = 0                                                                   */
                                        /*                  pX = 0                                                                   */
                                        /*                  pY = -1                                                                  */
                                        /*                  t  = BLANC                                                               */
                                        /*                                                                                           */
                                        /* ('v $xiirf/PAYS.R7$M').                                                                   */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N S   D E S   " B U G S "   P R E S E N T S  :                                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

#ifdef    BUG_SYSTEME_C_complexite_02                                           /* Common,DEFV(Fonction,) : bug...                   */
DEFV(Common,DEFV(Logical,_____BUG_SYSTEME_C_complexite_02));
#Aifdef   BUG_SYSTEME_C_complexite_02                                           /* Common,DEFV(Fonction,) : bug...                   */
#Eifdef   BUG_SYSTEME_C_complexite_02                                           /* Common,DEFV(Fonction,) : bug...                   */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M I S E   E N   M O N T A G N E S   " P R E C I S E "   D ' U N E   I M A G E  :                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
                                        /* ATTENTION, on introduit deux fonctions 'Imontagnes(...)' et 'Imontagnes_precises(...)'    */
                                        /* qui sont de toute evidence inutiles en 'TYPE_DE_imageA_surface_VERSION_01' mais dont la   */
                                        /* presence permet de simplifier considerablement la coexistence des deux versions...        */

#define   POSITION_DANS_LA_ZONE_DE_PENOMBRE(position)                                                                                   \
                    COND(IZGT(pente_rayon_lumineux),DIVI(position,pente_rayon_lumineux),FLOT(INFINI))                                   \
                                        /* Calcul de la largeur de la zone de penombre en fonction de la pente du rayon lumineux     */ \
                                        /* courant ; on notera la prise en compte des rayons lumineux horizontaux...                 */

#ifdef    TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_01'.    */

BFonctionP

DEFV(Common,DEFV(FonctionP,POINTERp(Imontagnes_precises(imageR
                                                       ,facteur_d_echelle,imageA_surface
                                                       ,imageA_texture
                                                       ,nettoyer
                                                       ,ARGUMENT_POINTERs(translation)
                                                       ,ombres_portees,largeur_zone_penombre
                                                       ,ARGUMENT_POINTERs(source_lumineuse)
                                                       ,depth_cueing,min_depth_cueing
                                                       ,vue_d_avion
                                                       ,anti_aliasing
                                                        )
                                    )
                 )
     )
DEFV(Argument,DEFV(image,imageR));
                                        /* Image Resultat, qui est une vue texturee de la surface.                                   */
DEFV(Argument,DEFV(Float,facteur_d_echelle));
                                        /* Facteur d'echelle permettant de moduler le champ contenu dans 'imageA_surface',           */
                                        /* et par exemple de l'inverser. On notera bien que les parametres 'facteur_d_echelle' et    */
                                        /* 'Imontagnes_precises_____facteur_de_correction_perspective' interferent l'un avec         */
                                        /* l'autre comme cela est documente lors de la definition de ce dernier...                   */
                                        /* Le 20020211111705, j'ai remarque que les deux parametres 'facteur_d_echelle'              */
                                        /* et 'Imontagnes_precises_____facteur_de_correction_perspective' devaient etre de meme      */
                                        /* signe...                                                                                  */
DEFV(Argument,DEFV(image,imageA_surface));
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface,                 */
DEFV(Argument,DEFV(image,imageA_texture));
                                        /* Deuxieme image Argument, qui donne la texture de la surface.                              */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Logical,nettoyer));
                                        /* Indicateur demandant ('VRAI') ou pas ('FAUX') la mise a noir                              */
                                        /* de l'image 'imageR'.                                                                      */
DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation)));
                                        /* Translation horizontale ('dx') et verticale ('dy') de la montagne dans l'image            */
                                        /* Resultat exprimee en nombre de points de la matrice "imageR" ; on n'oubliera              */
                                        /* pas que cette translation est exprimee dans des unites telles que l'unite vaut            */
                                        /* respectivement [Xmin,Xmax] et [Ymin,Ymax].                                                */
DEFV(Argument,DEFV(Logical,ombres_portees));
                                        /* Les ombres portees doivent-elles etre presentes ('VRAI') ou non ('FAUX').                 */
DEFV(Argument,DEFV(Float,largeur_zone_penombre));
                                        /* Donne la largeur de la zone de penombre (valeur arbitraire, mais une valeur de            */
                                        /* l'ordre de la dizaine donne de bons resultats...).                                        */
DEFV(Argument,DEFV(pointF_2D,POINTERs(source_lumineuse)));
                                        /* Donne dans le plan de l'image Resultat ('imageR'), les coordonnees de                     */
                                        /* la source lumineuse ; ces coordonnees sont exprimees dans des unites                      */
                                        /* telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax].                        */
DEFV(Argument,DEFV(Logical,depth_cueing));
                                        /* Doit-on faire ('VRAI') ou pas ('FAUX') du depth-cueing ?                                  */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Float,min_depth_cueing));
                                        /* Ce parametre est inclus dans le segment [0,1] ; plus il est                               */
                                        /* proche de zero, plus, le "depth-cueing" est fort...                                       */
DEFV(Argument,DEFV(Logical,vue_d_avion));
                                        /* Definit le mode de representation : 'VRAI' donne une vue de dessus,                       */
                                        /* alors que 'FAUX' donne une vue de cote.                                                   */
DEFV(Argument,DEFV(Logical,anti_aliasing));
                                        /* Indique s'il faut faire ('VRAI') ou pas ('FAUX') de l'anti-aliasing                       */
                                        /* sur l'image Resultat.                                                                     */
                                        /*                                                                                           */
                                        /* Le 20011227173520 (c'est-a-dire un peu tard...) j'ai remarque que cet "anti-aliasing"     */
                                        /* qui est fait par interpolation entre les niveaux anterieurs des points extremes des       */
                                        /* segments verticaux, ne prenait pas en compte les niveaux anterieurs des points            */
                                        /* intermediaires de ces segments. Ceci peut donc avoir des consequences visibles, en        */
                                        /* particulier en ce qui concerne les vecteurs verticaux les plus longs sur un fond varie... */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
#Aifdef   TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_01'.    */
#Eifdef   TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_01'.    */

#ifdef    TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_02'.    */

BFonctionP

DEFV(Common,DEFV(Float,SINT(Imontagnes_precises_____Ay_reduit,FU)));
DEFV(Common,DEFV(Float,SINT(Imontagnes_precises_____By_reduit,FZERO)));
                                        /* Introduit le 20140627115130 afin de pouvoir, par exemple, inverser le "depth-cueing"      */
                                        /* ('v $xiirf/PAYU.I1$M' ou encore 'v $xiirf/PAYU.I2$M')...                                  */

DEFV(Common,DEFV(FonctionP,POINTERp(Imontagnes_precises(imageR
                                                       ,facteur_d_echelle,imageA_surface
                                                       ,imageA_texture
                                                       ,nettoyer
                                                       ,ARGUMENT_POINTERs(translation)
                                                       ,ombres_portees,largeur_zone_penombre
                                                       ,ARGUMENT_POINTERs(source_lumineuse)
                                                       ,depth_cueing,min_depth_cueing
                                                       ,vue_d_avion
                                                       ,anti_aliasing
                                                        )
                                    )
                 )
     )
DEFV(Argument,DEFV(image,imageR));
                                        /* Image Resultat, qui est une vue texturee de la surface.                                   */
DEFV(Argument,DEFV(Float,facteur_d_echelle));
                                        /* Facteur d'echelle permettant de moduler le champ contenu dans 'imageA_surface',           */
                                        /* et par exemple de l'inverser. On notera bien que les parametres 'facteur_d_echelle' et    */
                                        /* 'Imontagnes_precises_____facteur_de_correction_perspective' interferent l'un avec         */
                                        /* l'autre comme cela est documente lors de la definition de ce dernier...                   */
                                        /* Le 20020211111705, j'ai remarque que les deux parametres 'facteur_d_echelle'              */
                                        /* et 'Imontagnes_precises_____facteur_de_correction_perspective' devaient etre de meme      */
                                        /* signe...                                                                                  */
DEFV(Argument,DEFV(imageF,imageA_surface));
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface,                 */
DEFV(Argument,DEFV(image,imageA_texture));
                                        /* Deuxieme image Argument, qui donne la texture de la surface.                              */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Logical,nettoyer));
                                        /* Indicateur demandant ('VRAI') ou pas ('FAUX') la mise a noir                              */
                                        /* de l'image 'imageR'.                                                                      */
DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation)));
                                        /* Translation horizontale ('dx') et verticale ('dy') de la montagne dans l'image            */
                                        /* Resultat exprimee en nombre de points de la matrice "imageR" ; on n'oubliera              */
                                        /* pas que cette translation est exprimee dans des unites telles que l'unite vaut            */
                                        /* respectivement [Xmin,Xmax] et [Ymin,Ymax].                                                */
DEFV(Argument,DEFV(Logical,ombres_portees));
                                        /* Les ombres portees doivent-elles etre presentes ('VRAI') ou non ('FAUX').                 */
DEFV(Argument,DEFV(Float,largeur_zone_penombre));
                                        /* Donne la largeur de la zone de penombre (valeur arbitraire, mais une valeur de            */
                                        /* l'ordre de la dizaine donne de bons resultats...).                                        */
DEFV(Argument,DEFV(pointF_2D,POINTERs(source_lumineuse)));
                                        /* Donne dans le plan de l'image Resultat ('imageR'), les coordonnees de                     */
                                        /* la source lumineuse ; ces coordonnees sont exprimees dans des unites                      */
                                        /* telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax].                        */
DEFV(Argument,DEFV(Logical,depth_cueing));
                                        /* Doit-on faire ('VRAI') ou pas ('FAUX') du depth-cueing ?                                  */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Float,min_depth_cueing));
                                        /* Ce parametre est inclus dans le segment [0,1] ; plus il est                               */
                                        /* proche de zero, plus, le "depth-cueing" est fort...                                       */
DEFV(Argument,DEFV(Logical,vue_d_avion));
                                        /* Definit le mode de representation : 'VRAI' donne une vue de dessus,                       */
                                        /* alors que 'FAUX' donne une vue de cote.                                                   */
DEFV(Argument,DEFV(Logical,anti_aliasing));
                                        /* Indique s'il faut faire ('VRAI') ou pas ('FAUX') de l'anti-aliasing                       */
                                        /* sur l'image Resultat.                                                                     */
                                        /*                                                                                           */
                                        /* Le 20011227173520 (c'est-a-dire un peu tard...) j'ai remarque que cet "anti-aliasing"     */
                                        /* qui est fait par interpolation entre les niveaux anterieurs des points extremes des       */
                                        /* segments verticaux, ne prenait pas en compte les niveaux anterieurs des points            */
                                        /* intermediaires de ces segments. Ceci peut donc avoir des consequences visibles, en        */
                                        /* particulier en ce qui concerne les vecteurs verticaux les plus longs sur un fond varie... */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
#Aifdef   TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_02'.    */
#Eifdef   TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_02'.    */

     Bblock
     DEFV(Float,INIT(facteur_d_ajustement_de_l_equation_de_la_surface
                    ,DIVI(FLOT(COULEURS)
                         ,FLOT(k___dimY)
                          )
                     )
          );
                                        /* Ce facteur d'ajustement est lie au fait que l'echelle des niveaux de gris [NOIR,BLANC]    */
                                        /* d'une image ne change jamais, alors que le format d'une image, lui, le peut (via le       */
                                        /* format [dimX,dimY]). Ainsi pour eviter d'avoir des montagnes tres hautes dans une toute   */
                                        /* petite image (par exemple en mode 'Suq'), il faut reajuster les niveaux...                */
     DEFV(Float,INIT(pente_rayon_lumineux,FLOT__UNDEF));
                                        /* Pente de la droite allant de la source lumineuse au point de cote                         */
                                        /* maximale courant, en faisant les hypotheses suivantes :                                   */
                                        /*                                                                                           */
                                        /* 1 - on trace la "montagne" de la droite vers la gauche,                                   */
                                        /* 2 - on suppose ce rayon lumineux contenu dans le plan vertical courant,                   */
                                        /*                                                                                           */
                                        /* enfin, cette pente vaut : (Ymax-Ysource)/(Xmax-Xsource) ; elle                            */
                                        /* donne aussi ce que j'appelle le seuil de visibilite depuis la source                      */
                                        /* lumineuse.                                                                                */
     DEFV(Logical,INIT(initialisation_pente_rayon_lumineux,LUNDEF));
                                        /* Indicateur d'initialisation de "pente_rayon_lumineux" ; tant que la pente n'a             */
                                        /* pas ete calculee, et que l'initialisation est donc a faire, cet indicateur                */
                                        /* vaut 'VRAI', puis ensuite 'FAUX'.                                                         */
     DEFV(vectorI_2D,vecteur_vertical);
     DEFV(Float,INIT(Yf_origine,FLOT__UNDEF));
     DEFV(Float,INIT(Yf_extremite,FLOT__UNDEF));
                                        /* Definition du vecteur vertical courant ; le point "origine" designe                       */
                                        /* le point le plus bas, alors que le point "extremite" designe celui                        */
                                        /* qui est le plus haut. La variable 'Yf_extremite' a ete introduite                         */
                                        /* le 19970115125406 afin d'ameliorer le traitement anti-aliasing ; cette solution n'est     */
                                        /* certes pas tres elegante mais elle a l'avantage d'eviter de tout chambouler (il en est    */
                                        /* de meme pour la variable 'Yf_origine').                                                   */
     DEFV(Logical,INIT(premier_vecteur_vertical,LUNDEF));
                                        /* Indicateur permettant de discriminer le premier vecteur vertical de chaque                */
                                        /* ligne ('VRAI') des autres ('FAUX') ; en fait, cet indicateur n'a de                       */
                                        /* sens que lorsque l'anti-aliasing est demande...                                           */
     DEFV(Int,INIT(extremite_precedente,UNDEF));
                                        /* Contient l'ordonnee 'y' de l'extremite du vecteur vertical precedent.                     */
     DEFV(Int,INIT(sauvegarde_de_l_extremite,UNDEF));
                                        /* Contient l'ordonnee 'y' de l'extremite du vecteur vertical courant.                       */
     DEFV(Float,INIT(seuil_de_visibilite,FLOT__UNDEF));
                                        /* Donne le seuil de visibilite depuis la source lumineuse.                                  */
     DEFV(Float,INIT(niveau_lumineux,MAX_NIVEAU_LUMINEUX));
                                        /* Donne le niveau lumineux courant ; il est initialise sur le                               */
                                        /* maximum, afin d'etre correct si l'ombrage n'est pas demande...                            */
     DEFV(Float,INIT(y_reduit,FLOT__UNDEF));
                                        /* Donne la coordonnee 'Y' reduite lors d'un depth-cueing dans [0,1[.                        */
     DEFV(deltaF_3D,normale);
                                        /* Vecteur normal a la facette courante ; il est definit comme un accroissement, et non      */
                                        /* comme un vrai vecteur, car seule sa direction nous importe...                             */
     DEFV(deltaF_3D,rayon_lumineux);
                                        /* Direction du rayon lumineux du point courant a la source lumineuse.                       */
     DEFV(Float,INIT(intensite_extremite,FLOT__UNDEF));
                                        /* Intensite lumineuse du point du haut d'un vecteur vertical.                               */
     BDEFV(ligneF,liste_intensite_extremite);
                                        /* Liste des hautes intensites d'une ligne ; elle contient en fait une                       */
                                        /* partie de celles de la ligne precedente, puis celle de la ligne courante.                 */
     DEFV(Float,INIT(intensite_extremite_precedente,FLOT__UNDEF));
                                        /* Contient l'intensite lumineuse du point du haut (c'est-a-dire l'extremite)                */
                                        /* du vecteur vertical precedent.                                                            */
     DEFV(Float,INIT(sauvegarde_de_l_intensite_extremite,FLOT__UNDEF));
                                        /* Contient l'intensite lumineuse du point du haut (c'est-a-dire l'extremite)                */
                                        /* du vecteur vertical courant.                                                              */
     DEFV(Float,INIT(intensite_origine,FLOT__UNDEF));
                                        /* Intensite lumineuse du point du bas d'un vecteur vertical.                                */
     DEFV(Float,INIT(Zf_extremite,FLOT__UNDEF));
                                        /* Coordonnee 'Z' du point du haut d'un vecteur vertical.                                    */
     /*..............................................................................................................................*/
     BSaveModifyVariable(Logical
                        ,Z_Buffer_____test_strict
                        ,COND(IFET(IL_NE_FAUT_PAS(vue_d_avion)
                                  ,IL_NE_FAUT_PAS(Imontagnes_precises_____compatibilite_20100223)
                                   )
                             ,VRAI
                             ,Z_Buffer_____test_strict
                              )
                         );

     Test(IL_FAUT(Imontagnes_precises_____verification_de_la_correction_perspective))
                                        /* Test introduit le 20170413103352 lors de la regeneration de 'v $xiirf/PAYU.K3.21$M'.      */
          Bblock
          Test(IFOU(IFEXff(LAMBDA_DE_CORRECTION_PERSPECTIVE(Ymin),COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE)
                   ,IFEXff(LAMBDA_DE_CORRECTION_PERSPECTIVE(Ymax),COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE)
                    )
               )
                                        /* Test introduit le 20170413095025 lors de la regeneration de 'v $xiirf/PAYU.K3.21$M'.      */
               Bblock
               PRINT_ATTENTION("certains parametres ne sont pas compatibles pour une correction perspective correcte");
               CAL1(Prer2("lambda(%d)=%f\n",Ymin,LAMBDA_DE_CORRECTION_PERSPECTIVE(Ymin)));
               CAL1(Prer2("lambda(%d)=%f\n",Ymax,LAMBDA_DE_CORRECTION_PERSPECTIVE(Ymax)));
               CAL1(Prer1("facteur d'echelle=%f\n",facteur_d_echelle));
               CAL1(Prer1("facteur de correction perspective=%f\n",Imontagnes_precises_____facteur_de_correction_perspective));
               Eblock
          ATes
               Bblock
               Eblock
          ETes
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     TesF(IFET(IL_FAUT(vue_d_avion)
              ,IL_FAUT(anti_aliasing)
               )
          )
          Bblock
          PRINT_ATTENTION("la vue d'avion demandee sera faite sans 'anti-aliasing'");
                                        /* ATTENTION, on n'edite plus ce message qui parait relativement inutile ; de plus, il me    */
                                        /* semble faux puisque les images "vues d'avion" sont correctement calculees...              */
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     Test(I3ET(IL_FAUT(vue_d_avion)
              ,IZLE(facteur_d_echelle)
              ,IZLE(Imontagnes_precises_____translation_de_la_coordonnee_Z_lors_d_une_vue_d_avion)
               )
          )
                                        /* Test introduit le 20080214135820 lors de la regeneration de 'v $xiirf/PAYS.R5$M'...       */
          Bblock
          PRINT_ATTENTION("une vue d'avion avec facteur d'echelle negatif demande une translation strictement positive de 'Z'");
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     Test(I3ET(IL_FAUT(anti_aliasing)
              ,IL_FAUT(Imontagnes_precises_____interpoler_le_Z_Buffer_lors_de_l_anti_aliasing)
              ,IFNE(Z_Buffer_____valeur_initiale,VALEUR_INITIALE_DU_Z_BUFFER_POUR_LES_MONTAGNES)
               )
          )
          Bblock
          PRINT_ATTENTION("la valeur d'initialisation du 'Z-Buffer' n'est pas compatible avec un eventuel effet de brume");
          Eblock
     ATes
          Bblock
          Eblock
     ETes

                                        /* A la date du 20090308184756 j'ai reussi, sans trop de difficultes, a autoriser le         */
                                        /* texturage en l'absence d'ombres portees. Le 20090309170209, il en fut de meme pour        */
                                        /* le "depth-cueing"...                                                                      */

     Test(IFLE(_cDENORMALISE_OX(ASI1(source_lumineuse,x)),Xmax))
          Bblock
          PRINT_ERREUR("l'abscisse 'X' de la source lumineuse doit etre superieure a 'Xmax'");
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     Test(IL_FAUT(nettoyer))
          Bblock
          CALS(Inoir(imageR));
                                        /* Nettoyage de l'image resultat.                                                            */
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     EGAL(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_montagne,PLUS_GRANDE_ORDONNEE_SUR_LA_MONTAGNE);
     EGAL(Itrace_segment_vertical_____plus_grande_ordonnee_sur_la_last_ligne_de_la_montagne,PLUS_GRANDE_ORDONNEE_SUR_LA_MONTAGNE);
                                        /* Initialisation de l'aide au cadrage automatique des montagnes ; on va ainsi detecter      */
                                        /* les plus grandes ordonnees (globalement sur l'ensemble de la montagne -pour avoir le      */
                                        /* plus haut- et sur la 'last' ligne -pour avoir le plus bas-).                              */

     begin_ligne
          Bblock
          EGAL(LIGNE(liste_intensite_extremite,X,Ymin),FLOT__NOIR);
          Eblock
     end_ligne

     EGAL(ASD1(normale,dz),FLOT(ADD2(PasZ,PasZ)));
                                        /* La troisieme composante d'une normale a une facette vaut toujours 2, car elle est en      */
                                        /* fait la somme de deux normales calculees dans les triangles {A,B,C} et {D,B,C}.           */

     begin_colonne_back
          Bblock
          Test(IFET(IFLE(Y,Yfirst)
                   ,IFGE(Y,Ylast_trace)
                    )
               )
               Bblock
               EGAL(initialisation_pente_rayon_lumineux,VRAI);
                                        /* Ainsi, pour cette nouvelle coupe de la "montagne", on sait                                */
                                        /* que la pente du rayon lumineux n'a pas encore ete calculee,                               */
                                        /* et que l'initialisation est donc a faire...                                               */
               EGAL(premier_vecteur_vertical,VRAI);
                                        /* Ainsi, on indique que l'on va tracer le premier vecteur vertical ; en fait,               */
                                        /* cet indicateur n'a de sens que lorsque l'anti-aliasing est demande...                     */

               Test(IL_FAUT(depth_cueing))
                    Bblock
                    EGAL(y_reduit,__DENORMALISE_NIVEAU(_____cNORMALISE_OY(RENY(Y))));
                                        /* Ainsi, on convertit la coordonnee 'Y' en un niveau...                                     */

                    EGAL(y_reduit,AXPB(Imontagnes_precises_____Ay_reduit,y_reduit,Imontagnes_precises_____By_reduit));
                                        /* Introduit le 20140627115130 afin de pouvoir, par exemple, inverser le "depth-cueing"      */
                                        /* ('v $xiirf/PAYU.I1$M' ou encore 'v $xiirf/PAYU.I2$M')...                                  */

                    EGAL(y_reduit,______NORMALISE_NIVEAU(NIVA(MAX2(y_reduit,MIN_INTENSITE))));
                                        /* En effet, on ne peut tracer en noir...                                                    */
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               begin_ligne_back
                    Bblock
                    Test(IFGE(X,Xlast))
                         Bblock
                         PUSH_MASQUE;
                                        /* Sauvegarde de l'etat de masquage avant l'acces aux differentes images,                    */
                         DEMASQUE_IMAGES;
                                        /* Et on le desactive pour acceder a leur integralite...                                     */

                         EGAL(ASD2(vecteur_vertical,origine,x)
                             ,ADD2(X,_lDENORMALISE_OX(ASI1(translation,dx)))
                              );

                         EGAL(ASD2(vecteur_vertical,extremite,x)
                             ,ASD2(vecteur_vertical,origine,x)
                              );

                         EGAL(Yf_origine
                             ,ADD2(SOUS(z_point_suivant(X,Y)
                                       ,FLOT(SOUS(Ymax,DECALAGE_VERTICAL(Y)))
                                        )
                                  ,F__lDENORMALISE_OY(ASI1(translation,dy))
                                   )
                              );
                         EGAL(ASD2(vecteur_vertical,origine,y)
                             ,ENTE(Yf_origine)
                              );

                         EGAL(Yf_extremite
                             ,ADD2(SOUS(z_point_courant(X,Y)
                                       ,FLOT(SOUS(Ymax,DECALAGE_VERTICAL(ARRIERE(Y))))
                                        )
                                  ,F__lDENORMALISE_OY(ASI1(translation,dy))
                                   )
                              );
                         EGAL(ASD2(vecteur_vertical,extremite,y)
                             ,ENTE(Yf_extremite)
                              );

                         Test(IL_FAUT(ombres_portees))
                              Bblock
                              Test(IL_NE_FAUT_PAS(initialisation_pente_rayon_lumineux))
                                        /* ATTENTION : il ne faut pas optimiser le "if" ci-dessous en le                             */
                                        /* remplacant par un "ATes", car lorsqu'IL_NE_FAUT_PAS, et que le 'z' du                     */
                                        /* point courant est au-dessus du seuil, on force une initialisation du                      */
                                        /* rayon lumineux...                                                                         */
                                   Bblock
                                   EGAL(seuil_de_visibilite
                                       ,AXPB(pente_rayon_lumineux
                                            ,SOUS(FLOT(X),F__cDENORMALISE_OX(ASI1(source_lumineuse,x)))
                                            ,F__cDENORMALISE_OY(ASI1(source_lumineuse,y))
                                             )
                                        );

                                   Test(IFGT(z_point_courant(X,Y),seuil_de_visibilite))
                                        Bblock
                                        EGAL(initialisation_pente_rayon_lumineux,VRAI);
                                        /* Lorsqu'on est visible depuis la source lumineuse, il faut mettre a jour la                */
                                        /* pente courante du rayon lumineux de visibilite...                                         */
                                        Eblock
                                   ATes
                                        Bblock
                                        DEFV(Float,INIT(penombre,FLOT__UNDEF));
                                        /* Permet de calculer le degrade de penombre lorsqu'il y a lieu...                           */

                                        EGAL(penombre,SOUS(seuil_de_visibilite,z_point_courant(X,Y)));
                                        /* Lorsqu'on est invisible depuis la source lumineuse, on est donc                           */
                                        /* a l'ombre ; on regarde malgre tout si l'on est pas dans la penombre...                    */

                                        Test(IFLE(penombre,largeur_zone_penombre))
                                        /* ATTENTION, avant le 19980206162821, il y avait ici :                                      */
                                        /*                                                                                           */
                                        /*        Test(IFLT(penombre,POSITION_DANS_LA_ZONE_DE_PENOMBRE(largeur_zone_penombre)))      */
                                        /*                                                                                           */
                                        /* ce qui avait des consequences facheuses quand des points de la surface etaient situes     */
                                        /* plus haut que la source lumineuse...                                                      */
                                             Bblock
                                        /* Cas ou on est dans la penombre (entre l'ombre et la lumiere) :                            */
                                             EGAL(niveau_lumineux
                                                 ,SCAL(NEGA(ATTENUATION_A_L_OMBRE(MAX_NIVEAU_LUMINEUX))
                                                      ,POSITION_DANS_LA_ZONE_DE_PENOMBRE(largeur_zone_penombre)
                                                      ,POSITION_DANS_LA_ZONE_DE_PENOMBRE(penombre)
                                                       )
                                                  );
                                        /* ATTENTION, ici, 'niveau_lumineux' est un niveau Relatif (de type 'NIVR(...)').            */
                                             Eblock
                                        ATes
                                             Bblock
                                        /* Cas ou on est dans l'ombre "absolue" :                                                    */
                                             EGAL(niveau_lumineux,NEGA(ATTENUATION_A_L_OMBRE(MAX_NIVEAU_LUMINEUX)));
                                        /* ATTENTION, ici, 'niveau_lumineux' est un niveau Relatif (de type 'NIVR(...)').            */
                                             Eblock
                                        ETes

                                        INCR(niveau_lumineux,NIVA(MAX_NIVEAU_LUMINEUX));
                                        /* ATTENTION, ici, 'niveau_lumineux' est devenu ici un niveau Absolu (de type 'NIVA(...)').  */
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              Test(IL_FAUT(initialisation_pente_rayon_lumineux))
                                        /* ATTENTION : il ne faut pas optimiser le "if" ci-dessus en le                              */
                                        /* remplacant par un "ATes", car lorsqu'IL_NE_FAUT_PAS, et que le 'z' du                     */
                                        /* point courant est au-dessus du seuil, on force une initialisation du                      */
                                        /* rayon lumineux...                                                                         */
                                   Bblock
                                   EGAL(initialisation_pente_rayon_lumineux,FAUX);
                                        /* Ainsi, on sait que l'initialisation de la pente du rayon lumineux                         */
                                        /* de visibilite a ete faite...                                                              */
                                   EGAL(pente_rayon_lumineux
                                       ,DIVI(SOUS(z_point_courant(X,Y)
                                                 ,F__cDENORMALISE_OY(ASI1(source_lumineuse,y))
                                                  )
                                            ,SOUS(FLOT(X),F__cDENORMALISE_OX(ASI1(source_lumineuse,x)))
                                             )
                                        );
                                   EGAL(niveau_lumineux,MAX_NIVEAU_LUMINEUX);
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes
                              Eblock
                         ATes
                              Bblock
                              EGAL(niveau_lumineux,MAX_NIVEAU_LUMINEUX);
                                        /* Ceci fut introduit le 20090309170209 afin de rendre le "depth-cueing" ainsi que le        */
                                        /* texturage independants de l'ombrage. C'est pourquoi le 'Test(...)' qui precedait avant    */
                                        /* cette date, est passe apres...                                                            */
                              Eblock
                         ETes

                         Test(IL_FAUT(depth_cueing))
                                        /* Le 20090309170209 le "depth-cueing" ainsi que le texturage sont devenus independants de   */
                                        /* l'ombrage...                                                                              */
                              Bblock

#if       (         (! defined(BUG_SYSTEME_C_complexite_02))                                                                            \
           )
                              EGAL(niveau_lumineux
                                  ,MAX2(NIVA(MUL2(BARY(y_reduit
                                                      ,______NORMALISE_NIVEAU(MAX_NIVEAU_LUMINEUX)
                                                      ,min_depth_cueing
                                                       )
                                                 ,NIVR(niveau_lumineux)
                                                  )
                                             )
                                       ,MIN_INTENSITE
                                        )
                                   );
#Aif      (         (! defined(BUG_SYSTEME_C_complexite_02))                                                                            \
           )
                              EGAL(niveau_lumineux
                                  ,fMAX2(NIVA(MUL2(BARY(y_reduit
                                                       ,______NORMALISE_NIVEAU(MAX_NIVEAU_LUMINEUX)
                                                       ,min_depth_cueing
                                                        )
                                                  ,NIVR(niveau_lumineux)
                                                   )
                                              )
                                        ,MIN_INTENSITE
                                         )
                                   );
                                        /* ATTENTION : on trouvait autrefois 'MAX2(...)' a la place de 'fMAX2(...)'. Malheureusement */
                                        /* un probleme invraisemblable rencontre sur les SYSTEMEs 'SYSTEME_NWS3000_NEWSOS_CC' et     */
                                        /* 'SYSTEME_NWS3000_NEWSOS_2CC' a ainsi trouve sa solution. La situation etait la suivante : */
                                        /*                                                                                           */
                                        /* 1-la commande '$xci/montagne.01$K' fonctionnait parfaitement bien,                        */
                                        /* 2-le programme '$xrc/mandel.02$K' par contre ne donnait pas le resultat attendu ; les     */
                                        /* tests ont montre que le resultat du 'MAX2(...)' etait une valeur tres faible (de l'ordre  */
                                        /* de 5.0e-310, alors qu'elle ne devrait pas etre inferieure a 'MIN_INTENSITE').             */
                                        /*                                                                                           */
                                        /* Encore une fois, il est difficile de comprendre comment cela pouvait marcher dans un cas  */
                                        /* et pas dans l'autre, le defaut, par exemple, ne dependant pas de l'ordre des includes :   */
                                        /*                                                                                           */
                                        /*                  #include  maths_compl_fonct_ITERATIONS_EXT                               */
                                        /*                  #include  image_image_MONTAGNES_EXT                                      */
                                        /*                                                                                           */
                                        /* Le 20090309170209 le "depth-cueing" ainsi que le texturage sont devenus independants de   */
                                        /* l'ombrage...                                                                              */
#Eif      (         (! defined(BUG_SYSTEME_C_complexite_02))                                                                            \
           )

                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes

                         EGAL(niveau_lumineux
                             ,NIVA(SCAL(NIVR(niveau_lumineux)
                                       ,MAX_NIVEAU_LUMINEUX
                                       ,texture_courante(X,Y,z_point_courant(X,Y))
                                        )
                                   )
                              );
                                        /* Et on applique la texture donnee par "imageA_texture".                                    */
                                        /*                                                                                           */
                                        /* Le 20090309170209 le "depth-cueing" ainsi que le texturage sont devenus independants de   */
                                        /* l'ombrage...                                                                              */

                         EGAL(intensite_extremite,LIGNE(liste_intensite_extremite,X,Y));
                                        /* Note sur l'orientation actuelle des axes :                                                */
                                        /*                                                                                           */
                                        /*                                                                                           */
                                        /*              Y ^                                                                          */
                                        /*                |                                                                          */
                                        /*                |    plan                                                                  */
                                        /*                |     de                                                                   */
                                        /*                |  l'image                                                                 */
                                        /*                |                                                                          */
                                        /*                O-------------> X                                                          */
                                        /*               /                                                                           */
                                        /*              /                                                                            */
                                        /*             /                                                                             */
                                        /*            /                                                                              */
                                        /*         Z .                                                                               */
                                        /*                                                                                           */
                                        /*        (Pour le graphique, les arguments et le 'Z-Buffer').                               */
                                        /*                                                                                           */
                                        /*                                                                                           */
                                        /*              Z ^                                                                          */
                                        /*                |                                                                          */
                                        /*                |                                                                          */
                                        /*                |                                                                          */
                                        /*                |                              Z      = Yfirst_trace + (Ylast_trace - Y)   */
                                        /*                |                         (profondeur                                /     */
                                        /*           Ymin O-------------> X           dans  le                                /      */
                                        /*               /                           'Z-Buffer')                             /       */
                                        /*              /                                                                   /        */
                                        /*             /  plan du champ 2D                                             coordonnee    */
                                        /*       Ymax /  a visualiser en 3D                                           'Y' du champ   */
                                        /*         Y .                                                                               */
                                        /*                                                                                           */
                                        /*        (Pour la surface montagneuse ; le referentiel n'est pas "direct").                 */
                                        /*                                                                                           */
                                        /*                                                                                           */
                                        /*                |        |                                                                 */
                                        /*                                                                                           */
                                        /*        Y  ---- D ------ C -----                                                           */
                                        /*                       .                                                                   */
                                        /*                |    .   |                                                                 */
                                        /*                |  .     |                                                                 */
                                        /*                                                                                           */
                                        /*       Y-1 ---- B ------ A -----                                                           */
                                        /*                                                                                           */
                                        /*                |        |                                                                 */
                                        /*                                                                                           */
                                        /*               X-1       X                                                                 */
                                        /*                                                                                           */
                         EGAL(ASD1(normale,dx),NEUT(SOUS(z_point_suivant(vPREX(X),vNEUT(Y)),z_point_suivant(vNEUT(X),vNEUT(Y)))));
                         EGAL(ASD1(normale,dy),NEUT(SOUS(z_point_courant(vNEUT(X),vNEUT(Y)),z_point_suivant(vNEUT(X),vNEUT(Y)))));
                                        /* Generation de la normale "basse" : on considere la facette triangulaire {A,B,C}           */
                                        /* suivante :                                                                                */
                                        /*                                                                                           */
                                        /*                  [A(X,Y-I,Z(A)),B(X-I,Y-I,Z(B)),C(X,Y,Z(C))]                              */
                                        /*                                                                                           */
                                        /* elle definit un plan d'equation :                                                         */
                                        /*                                                                                           */
                                        /*                  |  X-XA  Y-YA  Z-ZA  |                                                   */
                                        /*                  |  XB-XA YB-YA ZB-ZA | = 0                                               */
                                        /*                  |  XC-XA YC-YA ZC-ZA |                                                   */
                                        /*                                                                                           */
                                        /* soit par definition :                                                                     */
                                        /*                                                                                           */
                                        /*                  |  X-XA  Y-YA  Z-ZA  |                                                   */
                                        /*                  |   -1     0   ZB-ZA | = 0                                               */
                                        /*                  |    0    -1   ZC-ZA |                                                   */
                                        /*                                                                                           */
                                        /* la normale a cette facette est donc le vecteur de coordonnees :                           */
                                        /*                                                                                           */
                                        /*                  [(ZB-ZA),(ZC-ZA),1].                                                     */
                                        /*                                                                                           */
                         INCR(ASD1(normale,dx),NEGA(SOUS(z_point_courant(vNEUT(X),vNEUT(Y)),z_point_courant(vPREX(X),vNEUT(Y)))));
                         INCR(ASD1(normale,dy),NEGA(SOUS(z_point_suivant(vPREX(X),vNEUT(Y)),z_point_courant(vPREX(X),vNEUT(Y)))));
                                        /* Passage du reseau triangulaire au reseau carre de base :                                  */
                                        /*                                                                                           */
                                        /* on considere la facette triangulaire {D,B,C} :                                            */
                                        /*                                                                                           */
                                        /*                  [D(X-I,Y,Z(D)),B(X-I,Y-I,Z(B)),C(X,Y,Z(C))]                              */
                                        /*                                                                                           */
                                        /* elle definit le plan d'equation :                                                         */
                                        /*                                                                                           */
                                        /*                  |  X-XD  Y-YD  Z-ZD  |                                                   */
                                        /*                  |  XB-XD YB-YD ZB-ZD | = 0                                               */
                                        /*                  |  XC-XD YC-YD ZC-ZD |                                                   */
                                        /*                                                                                           */
                                        /* soit, par definition :                                                                    */
                                        /*                                                                                           */
                                        /*                  |  X-XD  Y-YD  Z-ZD  |                                                   */
                                        /*                  |    0     1   ZB-ZD | = 0                                               */
                                        /*                  |    1     0   ZC-ZD |                                                   */
                                        /*                                                                                           */
                                        /* la normale a cette facette est donc le vecteur de coordonnees :                           */
                                        /*                                                                                           */
                                        /*                  [(ZC-ZD),(ZB-ZD),-1],                                                    */
                                        /*                                                                                           */
                                        /* ou en inversant l'orientation, car en effet, les deux                                     */
                                        /* facettes (A,B,C) ET (D,B,C) sont parcourus en sens                                        */
                                        /* inverses l'une de l'autre :                                                               */
                                        /*                                                                                           */
                                        /*                  [-(ZC-ZD),-(ZB-ZD),1].                                                   */
                                        /*                                                                                           */
                                        /* enfin, on fait la moyenne entre cette normale                                             */
                                        /* [-(ZC-ZD),-(ZB-ZD),1], et la normale [(ZB-ZA),(ZC-ZA),1]                                  */
                                        /* calculee precedemment...                                                                  */

#define   source_lumineuse_Z                                                                                                            \
                    Imontagnes_precises_____source_lumineuse_Z                                                                          \
                                        /* Pour raccourcir certaines lignes...                                                       */

                         INITIALISATION_ACCROISSEMENT_3D(rayon_lumineux
                                                        ,NEGA(SOUS(FLOT(X)
                                                                  ,F__cDENORMALISE_OX(ASI1(source_lumineuse,x))
                                                                   )
                                                              )
                                                        ,NEGA(MUL2(Imontagnes_precises_____inclinaison_de_la_source_lumineuse
                                                                  ,SOUS(FLOT(Y)
                                                                       ,FLOT(NEGA(_cDENORMALISE_OZ(source_lumineuse_Z)))
                                                                        )
                                                                   )
                                                              )
                                        /* La deuxieme composante du rayon lumineux est traitee differemment                         */
                                        /* des deux autres ; de plus l'inversion ('NEGA') supplementaire                             */
                                        /* qu'elle contient est liee au fait que l'axe 'OY' de la surface                            */
                                        /* montagneuse et l'axe 'OZ' des arguments sont de sens oppose.                              */
                                                        ,NEGA(SOUS(FLOT(z_point_courant(X,Y))
                                                                  ,F__cDENORMALISE_OY(ASI1(source_lumineuse,y))
                                                                   )
                                                              )
                                                         );
                                        /* Un point important est a noter : il y a une difference avec la                            */
                                        /* programmation SOLAR, car je crois qu'en effet, elle est mauvaise...                       */

#undef    source_lumineuse_Z

                         EGAL(intensite_origine
                             ,NIVA(MUL2(HOMO(PUIX(DIVI(prdF3D(normale,rayon_lumineux)
                                                      ,RACX(MUL2(pytF3D(normale)
                                                                ,pytF3D(rayon_lumineux)
                                                                 )
                                                            )
                                                       )
                                                 ,Imontagnes_precises_____source_lumineuse_specularite
                                                  )
                                            ,COSINUS_DE_PI
                                            ,COSINUS_DE_0
                                            ,minimum_normalise_du_cosinus_d_une_normale
                                            ,maximum_normalise_du_cosinus_d_une_normale
                                             )
                                       ,NIVR(niveau_lumineux)
                                        )
                                   )
                              );
                                        /* Normalisation (a priori dans [0,1]) du cosinus de la normale...                           */
                                        /*                                                                                           */
                                        /* La specularite a ete introduite le 20130101105228...                                      */

                         EGAL(intensite_origine
                             ,NIVA(LIN3(Imontagnes_precises_____depth_cueing_ponderation_niveau
                                       ,NIVR(intensite_origine)
                                       ,Imontagnes_precises_____depth_cueing_ponderation_coordonnee_X
                                       ,F___DENORMALISE_NIVEAU(_____cNORMALISE_OX(X))
                                       ,Imontagnes_precises_____depth_cueing_ponderation_coordonnee_Y
                                       ,F___DENORMALISE_NIVEAU(_____cNORMALISE_OY(Y))
                                       ,Imontagnes_precises_____depth_cueing_translation
                                        )
                                   )
                              );
                                        /* Normalisation (a priori dans [0,1]) du cosinus de la normale...                           */

                         EGAL(LIGNE(liste_intensite_extremite,X,Y),intensite_origine);
                                        /* Et cette "intensite_origine" deviendra la "intensite_extremite" pour la                   */
                                        /* ligne suivante ; notons d'ailleurs que c'est a cause de l'initialisation                  */
                                        /* de cette liste que l'on ne trace qu'a partir de 'Yfirst_trace'...                         */
                         EGAL(intensite_origine,MAX2(intensite_origine,MIN_INTENSITE));
                         EGAL(intensite_extremite,MAX2(intensite_extremite,MIN_INTENSITE));
                                        /* Lorsque l'intensite lumineuse est trop faible, on la majore...                            */
                         PULL_MASQUE;
                                        /* Restauration de l'etat de masquage apres l'acces aux differentes images,                  */
                                        /* et ce avant le trace...                                                                   */

                         Test(IFET(IL_NE_FAUT_PAS(vue_d_avion)
                                  ,IL_FAUT(anti_aliasing)
                                   )
                              )
                              Bblock
                              Test(EST_FAUX(premier_vecteur_vertical))
                                   Bblock
                                   EGAL(sauvegarde_de_l_extremite,extremite_precedente);
                                   EGAL(sauvegarde_de_l_intensite_extremite,intensite_extremite_precedente);
                                        /* Pour tous les vecteurs verticaux (excepte le premier de chaque ligne), on memorise        */
                                        /* ses caracteristiques afin de faire son anti-aliasing lors du vecteur suivant...           */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              EGAL(extremite_precedente,ASD2(vecteur_vertical,extremite,y));
                              EGAL(intensite_extremite_precedente,intensite_extremite);
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes

                         Test(IFET(IL_FAUT(Imontagnes_precises_____visualiser_la_falaise_avant_de_la_montagne)
                                  ,IFEQ(Y,Ylast_trace)
                                   )
                              )
                              Bblock
                              EGAL(ASD2(vecteur_vertical,origine,y),Ymin);
                                        /* Ceci a ete introduit le 20030326121557 et cela devait manquer depuis bien longtemps...    */
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes

                         Test(IFOU(IL_FAUT(vue_d_avion)
                                  ,IFOU(IFGE(ASD2(vecteur_vertical,extremite,y),ASD2(vecteur_vertical,origine,y))
                                       ,EST_ACTIF(Masque_____etat)
                                        )
                                   )
                              )
                              Bblock
                                        /* Le trace a lieu lorsque l'une (au moins) des trois conditions est presente :              */
                                        /*                                                                                           */
                                        /* 1 - c'est une vue d'avion : en effet, rien n'est cache...                                 */
                                        /* 2 - c'est un vecteur "montant" (origine <= extremite) :                                   */
                                        /*                                                                                           */
                                        /*                  * extremite                                                              */
                                        /*                 /|\                                                                       */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  |                                                                        */
                                        /*                  * origine                                                                */
                                        /*                                                                                           */
                                        /*     ce vecteur appartient a une face "avant", on le voit donc actuellement                */
                                        /*     (c'est-a-dire qu'il pourra etre cache ulterieurement par une autre face).             */
                                        /* 3 - le Masque est actif : on trace systematiquement tous les vecteurs (et donc            */
                                        /*     meme ceux des faces "arriere") car en effet on est incapable de savoir ce             */
                                        /*     qui sera visible a travers les "trous" du Masque...                                   */
                                        /*                                                                                           */
                              Test(IFLE(Y,Yfirst_trace))
                                   Bblock
                                   Test(TEST_MASQUE_ACTIF(X,Y,MASQUER_PARCOURS))
                                        Bblock
                                        TRACE_VECTEUR_VERTICAL(imageR
                                                              ,vecteur_vertical
                                                              ,Yf_origine,Yf_extremite
                                                              ,X,Y,z_point_courant(X,Y)
                                                              ,CE_N_EST_PAS_LA_PHASE_D_ANTI_ALIASING
                                                               );
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes

                                   Test(IFET(IL_NE_FAUT_PAS(vue_d_avion)
                                            ,IL_FAUT(anti_aliasing)
                                             )
                                        )
                                        Bblock
                                        Test(EST_FAUX(premier_vecteur_vertical))
                                             Bblock
                                             Test(TEST_MASQUE_ACTIF(X,Y,MASQUER_PARCOURS))
                                                  Bblock
                                                  Test(IFNE(ASD2(vecteur_vertical,extremite,y)
                                                           ,sauvegarde_de_l_extremite
                                                            )
                                                       )
                                                       Bblock
                                        /* Cas ou le vecteur vertical (abscisse 'X') que l'on vient de tracer n'a pas son extremit   */
                                        /* au meme niveau que son voisin de droite (abscisse 'X+1') : il y a donc une discontinuite  */
                                        /* (une marche...) que l'on va essayer de combler en montant ou en descendant...             */
                                                       DEFV(vectorI_2D,complement_d_anti_aliasing);
                                                       TRANSFERT_VECTEUR_2D(complement_d_anti_aliasing
                                                                           ,vecteur_vertical
                                                                            );
                                        /* Vecteur introduit le 20100222122101...                                                    */

                                                       EGAL(ASD2(complement_d_anti_aliasing,origine,y),sauvegarde_de_l_extremite);

                                                       Test(IFLT(ASD2(complement_d_anti_aliasing,origine,y)
                                                                ,ASD2(complement_d_anti_aliasing,extremite,y)
                                                                 )
                                                            )
                                                            Bblock
                                                            EGAL(ASD2(complement_d_anti_aliasing,origine,x)
                                                                ,vSUCX(ASD2(complement_d_anti_aliasing,origine,x))
                                                                 );
                                                            EGAL(ASD2(complement_d_anti_aliasing,extremite,x)
                                                                ,vSUCX(ASD2(complement_d_anti_aliasing,extremite,x))
                                                                 );
                                                            EGAL(intensite_origine,sauvegarde_de_l_intensite_extremite);
                                        /* Cas ou le voisin de droite (abscisse 'X+1') monte moins haut : c'est donc lui qu'il va    */
                                        /* falloir completer (vers le haut), d'ou les 'SUCX(...)' qui precedent :                    */
                                        /*                                                                                           */
                                        /*                  |    +                                                                   */
                                        /*                  |    +                                                                   */
                                        /*                  |    +                                                                   */
                                        /*                  |    | <-- sauvegarde_de_l_{intensite_extremite,extremite}               */
                                        /*                  |    |                                                                   */
                                        /*                  |    |                                                                   */
                                        /*                  |    |                                                                   */
                                        /*                                                                                           */
                                        /*                  X   X+1                                                                  */
                                        /*                                                                                           */
                                        /* (les "+" indiquant le vecteur "complement" a tracer correspondant a l'anti-aliasing).     */
                                                            Eblock
                                                       ATes
                                                            Bblock
                                                            SWAP(ASD2(complement_d_anti_aliasing,origine,y)
                                                                ,ASD2(complement_d_anti_aliasing,extremite,y)
                                                                 );
                                                            EGAL(intensite_origine,intensite_extremite);
                                        /* Cas ou le voisin de droite (abscisse 'X+1') monte plus haut : c'est donc le vecteur       */
                                        /* que l'on vient de tracer qu'il va falloir completer (vers le haut) :                      */
                                        /*                                                                                           */
                                        /*                  +    |                                                                   */
                                        /*                  +    |                                                                   */
                                        /*                  +    |                                                                   */
                                        /*                  |    |                                                                   */
                                        /*                  |    |                                                                   */
                                        /*                  |    |                                                                   */
                                        /*                  |    |                                                                   */
                                        /*                                                                                           */
                                        /*                  X   X+1                                                                  */
                                        /*                                                                                           */
                                        /* (les "+" indiquant le vecteur "complement" a tracer correspondant a l'anti-aliasing).     */
                                                            Eblock
                                                       ETes

                                                       Test(IFGT(Yf_origine,Yf_extremite))
                                                            Bblock
                                                            fSWAP(Yf_origine
                                                                 ,Yf_extremite
                                                                  );
                                                            Eblock
                                                       ATes
                                                            Bblock
                                                            Eblock
                                                       ETes

                                                       Test(TEST_DANS_L_IMAGE(ASD2(complement_d_anti_aliasing,extremite,x)
                                                                             ,ASD2(complement_d_anti_aliasing,extremite,y)
                                                                              )
                                                            )
                                                            Bblock
                                                            DEFV(Float,INIT(intensite_extremite,FLOT__UNDEF));
                                        /* Cette variable locale est destinee a ne pas perdre la valeur de 'intensite_extremite'     */
                                        /* pour pouvoir generer 'sauvegarde_de_l_intensite_extremite' pour le vecteur suivant...     */
                                                            INITIALISATION_VECTEUR_2D(complement_d_anti_aliasing
                                                                                     ,TRON(ASD2(complement_d_anti_aliasing,origine,x)
                                                                                          ,Xmin
                                                                                          ,Xmax
                                                                                           )
                                                                                     ,TRON(ASD2(complement_d_anti_aliasing,origine,y)
                                                                                          ,Ymin
                                                                                          ,Ymax
                                                                                           )
                                                                                     ,TRON(ASD2(complement_d_anti_aliasing,extremite,x)
                                                                                          ,Xmin
                                                                                          ,Xmax
                                                                                           )
                                                                                     ,TRON(ASD2(complement_d_anti_aliasing,extremite,y)
                                                                                          ,Ymin
                                                                                          ,Ymax
                                                                                           )
                                                                                      );

                                                            PUSH_MASQUE;
                                        /* Sauvegarde de l'etat de masquage avant l'acces a l'image.                                 */
                                                            DEMASQUE_IMAGES;
                                        /* Et on le desactive a priori...                                                            */

                                                            EGAL(Zf_extremite
                                                                ,loadF_point_valide(Z_Buffer
                                                                                   ,ASD2(complement_d_anti_aliasing,extremite,x)
                                                                                   ,ASD2(complement_d_anti_aliasing,extremite,y)
                                                                                    )
                                                                 );
                                                            EGAL(intensite_extremite
                                                                ,FLOT(loadS_point_valide(imageR
                                                                                        ,ASD2(complement_d_anti_aliasing,extremite,x)
                                                                                        ,ASD2(complement_d_anti_aliasing,extremite,y)
                                                                                         )
                                                                      )
                                                                 );

                                                            PULL_MASQUE;
                                        /* Restauration de l'etat de masquage apres l'acces a l'image.                               */

                                                            TRACE_VECTEUR_VERTICAL(imageR
                                                                                  ,complement_d_anti_aliasing
                                                                                  ,Yf_origine,Yf_extremite
                                                                                  ,vSUCX(X),Y,z_point_courant(X,Y)
                                                                                  ,C_EST_LA_PHASE_D_ANTI_ALIASING
                                                                                   );
                                        /* Je note le 20100220204800 que c'est ce 'TRACE_VECTEUR_VERTICAL(...)' avec                 */
                                        /* 'C_EST_LA_PHASE_D_ANTI_ALIASING' qui est responsable d'un artefact ennuyeux               */
                                        /* dans les zones de penombre. Pour le voir, il suffit de faire :                            */
                                        /*                                                                                           */
                                        /*                  Pal                                                                      */
                                        /*                                                                                           */
                                        /*                  $xci/gauss$X                                                          \  */
                                        /*                                      standard=FAUX                                     \  */
                                        /*                                                                    $formatI       |    \  */
                                        /*                  $xci/montagne.01$X                                                    \  */
                                        /*                                      standard=FAUX zero=FAUX                           \  */
                                        /*                                      T=$BLANC                                          \  */
                                        /*                                      avion=FAUX                                        \  */
                                        /*                                      Ty=0.9                                            \  */
                                        /*                                      penombre=0                                        \  */
                                        /*                                      attenuation=1                                     \  */
                                        /*                                                                    $formatI       |    \  */
                                        /*                  $xci/display$X                                                        \  */
                                        /*                                      p=$xiP/cercle.35                                  \  */
                                        /*                                                                    $formatI               */
                                        /*                                                                                           */
                                        /*                                                                                           */
                                        /* pour voir apparaitre dans la zone de penombre au premier plan a gauche des petits         */
                                        /* segments verticaux incorrects qui partent de la penombre et descendent vers le bas        */
                                        /* de l'image. Ils font quelques pixels de haut et sont cyans sur fond jaune...              */
                                        /*                                                                                           */
                                        /* Ce probleme fut "attaque" le 20100222122101 par l'introduction d'un vecteur specifique    */
                                        /* 'complement_d_anti_aliasing' different de 'vecteur_vertical'. C'etait la "confusion"      */
                                        /* anterieure des deux qui etait la cause du probleme : en effet 'vecteur_vertical' etait    */
                                        /* modifie pour la phase d'anti-aliasing et ce de facon irreversible. Alors il ne            */
                                        /* correspondait plus ensuite au vecteur vertical que l'on venait de tracer (avant           */
                                        /* "anti-aliasing"...).                                                                      */
                                        /*                                                                                           */
                                        /* La vraie solution au probleme du 20100220204800 fut appliquee en permettant un test       */
                                        /* strict dans la gestion du 'Z-Buffer' ('v $xiii/Images$DEF Z_Buffer_____test_strict')...   */
                                        /*                                                                                           */
                                        /*                                                                                           */
                                        /* Aux environs du 20140704103958 je note un nouveau probleme que l'on peut mettre en        */
                                        /* evidence avec l'image 'v $xiirf/PAYU.K1$M' a condition de definir :                       */
                                        /*                                                                                           */
                                        /*                  set                 _____Deformation=$xiP/gris.54                        */
                                        /*                                                                                           */
                                        /* Il y a alors une mesa a gauche qui en projection intersecte la "ligne d'horizon" H.       */
                                        /* A la gauche de celle-ci apparait une ligne verticale TC de la couleur du ciel alors       */
                                        /* qu'elle devrait etre du couleur de la terre. Cela vient du 'TRACE_VECTEUR_VERTICAL(...)'  */
                                        /* qui precede. En effet, il trace en segment vertical TC qui est "a cheval" sur la terre    */
                                        /* et le ciel :                                                                              */
                                        /*                                                                                           */
                                        /*                                                 _________                                 */
                                        /*                  Ciel                          |  Mesa   |                                */
                                        /*                                                |         |                                */
                                        /*                            extremite : ...... C|         |                                */
                                        /*                                               ^|         |                                */
                                        /*                  H                            ^|         |                                */
                                        /*                  -----------------------------^--------------------                       */
                                        /*                                               ^|         |                                */
                                        /*                                               ^|         |                                */
                                        /*                            orgine : ......... T|         |                                */
                                        /*                                                |         |                                */
                                        /*                  Terre                         |         |                                */
                                        /*                                                                                           */
                                        /* Il est des lors evident que ce segment TC peut avoir la couleur du ciel en dessous de H.  */
                                        /* A cette date, je ne vois pas comment corriger cela. En particulier, des solutions         */
                                        /* possibles pourraient tester (et/ou interpoler) les niveaux anterieurs, mais il ne faut    */
                                        /* pas oublier que 'v $xiirf/PAYU.K1$M' est une image en vraies couleurs ce qui implique     */
                                        /* que ces tests (et/ou interpolations) hypothetiques seraient en general differents d'une   */
                                        /* composante chromatique a l'autre induisant alors d'autres anomalies (par exemple des      */
                                        /* incoherences chromatiques)...                                                             */
                                                            Eblock
                                                       ATes
                                                            Bblock
                                                            Eblock
                                                       ETes
                                                       Eblock
                                                  ATes
                                                       Bblock
                                                       Eblock
                                                  ETes
                                                  Eblock
                                             ATes
                                                  Bblock
                                                  Eblock
                                             ETes
                                             Eblock
                                        ATes
                                             Bblock
                                             EGAL(premier_vecteur_vertical,FAUX);
                                        /* Ainsi, on sait que l'on vient de traiter le premier vecteur vertical de la ligne          */
                                        /* courante...                                                                               */
                                             Eblock
                                        ETes
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes
                    Eblock
               end_ligne_back
               Eblock
          ATes
               Bblock
               Eblock
          ETes
          Eblock
     end_colonne_back

     ESaveModifyVariable(Logical
                        ,Z_Buffer_____test_strict
                         );

     EDEFV(ligneF,liste_intensite_extremite);
                                        /* Liste des hautes intensites d'une ligne ; elle contient en fait une                       */
                                        /* partie de celles de la ligne precedente, puis celle de la ligne courante.                 */

     RETI(imageR);
     Eblock

EFonctionP

#undef    POSITION_DANS_LA_ZONE_DE_PENOMBRE

#undef    CE_N_EST_PAS_LA_PHASE_D_ANTI_ALIASING
#undef    C_EST_LA_PHASE_D_ANTI_ALIASING

#undef    TRACE_VECTEUR_VERTICAL

#undef    ATTENUATION_A_L_OMBRE

#undef    texture_courante
#undef    z_point_suivant_suivant
#undef    z_point_suivant
#undef    z_point_courant
#undef    z_point_precedent

#ifdef    TYPE_DE_imageA_surface_VERSION_01
#    undef     EQUATION_DE_LA_SURFACE
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
#    undef     EQUATION_DE_LA_SURFACE
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

#undef    LAMBDA_DE_CORRECTION_PERSPECTIVE

#undef    DECALAGE_VERTICAL
#undef    Ylast_trace
#undef    Ylast
#undef    Yfirst_trace
#undef    Yfirst
#undef    Xlast
#undef    AVANT
#undef    ARRIERE

#undef    PLUS_GRANDE_ORDONNEE_SUR_LA_MONTAGNE

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M I S E   E N   M O N T A G N E S   " S T A N D A R D "   D ' U N E   I M A G E  :                                         */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

BFonctionP

                                        /* ATTENTION, on introduit deux fonctions 'Imontagnes(...)' et 'Imontagnes_precises(...)'    */
                                        /* qui sont de toute evidence inutiles en 'TYPE_DE_imageA_surface_VERSION_01' mais dont la   */
                                        /* presence permet de simplifier considerablement la coexistence des deux versions...        */

#ifdef    TYPE_DE_imageA_surface_VERSION_02
                                        /* ATTENTION, les deux definitions qui suivent sont faites independamment pour les deux      */
                                        /* fonctions 'Imontagnes(...)' et 'Imontagnes_en_perspective(...)' afin qu'elles puissent    */
                                        /* prendre alors des valeurs differentes, ce qui n'est pas le cas actuellement...            */

#    define    NIVEAU_PRECIS_MINIMAL                                                                                                    \
                         ______________NOIR_NORMALISE
#    define    NIVEAU_PRECIS_MAXIMAL                                                                                                    \
                         ______________BLANC_NORMALISE
                                        /* Niveaux minimal et maximal dans 'imageA_surface_flottante'.                               */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

DEFV(Common,DEFV(FonctionP,POINTERp(Imontagnes(imageR
                                              ,facteur_d_echelle,imageA_surface
                                              ,imageA_texture
                                              ,nettoyer
                                              ,ARGUMENT_POINTERs(translation)
                                              ,ombres_portees,largeur_zone_penombre
                                              ,ARGUMENT_POINTERs(source_lumineuse)
                                              ,depth_cueing,min_depth_cueing
                                              ,vue_d_avion
                                              ,anti_aliasing
                                               )
                                    )
                 )
     )
DEFV(Argument,DEFV(image,imageR));
                                        /* Image Resultat, qui est une vue texturee de la surface.                                   */
DEFV(Argument,DEFV(Float,facteur_d_echelle));
                                        /* Facteur d'echelle permettant de moduler le champ contenu dans 'imageA_surface',           */
                                        /* et par exemple de l'inverser. On notera bien que les parametres 'facteur_d_echelle' et    */
                                        /* 'Imontagnes_precises_____facteur_de_correction_perspective' interferent l'un avec         */
                                        /* l'autre comme cela est documente lors de la definition de ce dernier...                   */
                                        /* Le 20020211111705, j'ai remarque que les deux parametres 'facteur_d_echelle'              */
                                        /* et 'Imontagnes_precises_____facteur_de_correction_perspective' devaient etre de meme      */
                                        /* signe...                                                                                  */
DEFV(Argument,DEFV(image,imageA_surface));
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface,                 */
DEFV(Argument,DEFV(image,imageA_texture));
                                        /* Deuxieme image Argument, qui donne la texture de la surface.                              */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Logical,nettoyer));
                                        /* Indicateur demandant ('VRAI') ou pas ('FAUX') la mise a noir                              */
                                        /* de l'image 'imageR'.                                                                      */
DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation)));
                                        /* Translation horizontale ('dx') et verticale ('dy') de la montagne dans l'image            */
                                        /* Resultat exprimee en nombre de points de la matrice "imageR" ; on n'oubliera              */
                                        /* pas que cette translation est exprimee dans des unites telles que l'unite vaut            */
                                        /* respectivement [Xmin,Xmax] et [Ymin,Ymax].                                                */
DEFV(Argument,DEFV(Logical,ombres_portees));
                                        /* Les ombres portees doivent-elles etre presentes ('VRAI') ou non ('FAUX').                 */
DEFV(Argument,DEFV(Float,largeur_zone_penombre));
                                        /* Donne la largeur de la zone de penombre (valeur arbitraire, mais une valeur de            */
                                        /* l'ordre de la dizaine donne de bons resultats...).                                        */
DEFV(Argument,DEFV(pointF_2D,POINTERs(source_lumineuse)));
                                        /* Donne dans le plan de l'image Resultat ('imageR'), les coordonnees de                     */
                                        /* la source lumineuse ; ces coordonnees sont exprimees dans des unites                      */
                                        /* telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax].                        */
DEFV(Argument,DEFV(Logical,depth_cueing));
                                        /* Doit-on faire ('VRAI') ou pas ('FAUX') du depth-cueing ?                                  */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Float,min_depth_cueing));
                                        /* Ce parametre est inclus dans le segment [0,1] ; plus il est                               */
                                        /* proche de zero, plus, le "depth-cueing" est fort...                                       */
DEFV(Argument,DEFV(Logical,vue_d_avion));
                                        /* Definit le mode de representation : 'VRAI' donne une vue de dessus,                       */
                                        /* alors que 'FAUX' donne une vue de cote.                                                   */
DEFV(Argument,DEFV(Logical,anti_aliasing));
                                        /* Indique s'il faut faire ('VRAI') ou pas ('FAUX') de l'anti-aliasing                       */
                                        /* sur l'image Resultat.                                                                     */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     BDEFV(imageF,imageA_surface_flottante);
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface convertie en     */
                                        /* 'Float'...                                                                                */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

     /*..............................................................................................................................*/

#ifdef    TYPE_DE_imageA_surface_VERSION_01
     CALS(Imontagnes_precises(imageR
                             ,facteur_d_echelle,imageA_surface
                             ,imageA_texture
                             ,nettoyer
                             ,ARGUMENT_POINTERs(translation)
                             ,ombres_portees,largeur_zone_penombre
                             ,ARGUMENT_POINTERs(source_lumineuse)
                             ,depth_cueing,min_depth_cueing
                             ,vue_d_avion
                             ,anti_aliasing
                              )
          );
                                        /* Generation de la surface montagneuse...                                                   */
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     CALS(Istd_float(imageA_surface_flottante,NIVEAU_PRECIS_MINIMAL,NIVEAU_PRECIS_MAXIMAL,imageA_surface));
                                        /* Conversion flottante preliminaire...                                                      */
     CALS(Imontagnes_precises(imageR
                             ,facteur_d_echelle,imageA_surface_flottante
                             ,imageA_texture
                             ,nettoyer
                             ,ARGUMENT_POINTERs(translation)
                             ,ombres_portees,largeur_zone_penombre
                             ,ARGUMENT_POINTERs(source_lumineuse)
                             ,depth_cueing,min_depth_cueing
                             ,vue_d_avion
                             ,anti_aliasing
                              )
          );
                                        /* Generation de la surface montagneuse...                                                   */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     EDEFV(imageF,imageA_surface_flottante);
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface convertie en     */
                                        /* 'Float'...                                                                                */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

     RETI(imageR);
     Eblock

#ifdef    TYPE_DE_imageA_surface_VERSION_02
                                        /* ATTENTION, les deux dedefinitions qui suivent sont faites independamment pour les deux    */
                                        /* fonctions 'Imontagnes(...)' et 'Imontagnes_en_perspective(...)' afin qu'elles puissent    */
                                        /* prendre alors des valeurs differentes, ce qui n'est pas le cas actuellement...            */

#    undef     NIVEAU_PRECIS_MAXIMAL
#    undef     NIVEAU_PRECIS_MINIMAL
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

EFonctionP

_______________________________________________________________________________________________________________________________________
_______________________________________________________________________________________________________________________________________
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M I S E   E N   P E R S P E C T I V E   M O N T A G N E U S E   D ' U N E   I M A G E  :                                   */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Definition :                                                                                                               */
/*                                                                                                                                   */
/*                    Cette fonction genere une repre-                                                                               */
/*                  sentation 3D d'une image 2D, en                                                                                  */
/*                  utilisant la valeur de chaque point                                                                              */
/*                  comme troisieme dimension ; le calcul                                                                            */
/*                  est fait pour tout le champ {X,Y}.                                                                               */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                                                           *                                                                       */
/*                                                          ..@  .@                                                                  */
/*                                                        .* *.@ .@.@                                                                */
/*                                                      ...@ . ..*@@@@                                                               */
/*                              *@                  .. ..  ..   .**@@@*                                                              */
/*                  @ .**  .  .*.@*@               **.. .   .   *@@@@@.@  .@                                                         */
/*                  @****@.. @. **.*@    **..  .@.. .@..   ..   ...@*@*@.*.@*                                                        */
/*                  .*.@@@*. .**.*@@.@.  .*. . .@.  @... ....   . .@.** ..@@@*                                                       */
/*                  @.@@.@.  *..**** @@@   .. * ** **..   . . .. . *.@ *..@@@@*  .@                                                  */
/*                  @*.   @@.. @ @.@ ..@. .. .*@*@. ..@@@. ...*..****.. ...@*@@@****                                                 */
/*                  .  .**@..@@ @*.   *@@..*. * @.**@.@@. ** ..*@@.@**. .@@@.*@ *@@                                                  */
/*                  . .  ** ..@@*@. *@****@.   .***@..@@*....  @.*@ * .. .**.****@..                                                 */
/*                  .... **.@@@@*.  .*@**...  .@.*.@ .*@ .    .**@@....  **.@*@*@**                                                  */
/*                  *.... .@*@*...*.. @.@...   .**@.@*@. **..  ***@..    *   @*@.@                                                   */
/*                  *.... .***.*@.* ..**.@..@. @*.*@@ *.* ..... .*@@... ..* @. ...                                                   */
/*                  @..   .*.@.**** ..@***@@@* *@. *.@@.*..*.**. @*@@ .  * ** ...                                                    */
/*                  @@. . .@.* *.**. *.*@**@.*@@*@..@.@@@.*......@@.@..  .......   .                                                 */
/*                  @@ *. @.*@ **@.....@@*@.*@@*@*.@* *@  @@*.****.**.      ..... .*                                                 */
/*                  @.@ @@*.@@ .@ .* @ .@@*@**@@*@@* * *.**. . ..... ...      ....@.                                                 */
/*                  *@*..@*.**   @*  * *@@*@**@@@*.. .. .*....  ...  .. .  . . . .*.                                                 */
/*                  .@*@@**.    .*.**@*@@@@*.@@@**. ..  *@*.......   . .....      .                                                  */
/*                  @@@..*  **. .   @.**@*@@@.@@@...    *.**....  .@... . ... @...                                                   */
/*                  @**.  ** .   *.@@.@**@@ *.*@@* **  *.@.*.@@@. @***     .. @@*  .                                                 */
/*                  @. .   .     . @@..***@ @* ..@* *. *  .@*@*.  .*@* . ...  *@ .**                                                 */
/*                  @* .... ....  .** *@@*@ .. @.** *.*. @@*....   @@@@ @*..* .  @@*                                                 */
/*                  @  .**.   *@*@@..*@..**. . * *..@ @ * @...*... @@@*****.... .***                                                 */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   Y_to_Z(y)                                                                                                                     \
                    COZA(SOUS(COYR(y),COYR(SUCY(Ymax))))                                                                                \
                                        /* Procedure de permutation des axes 'Y' et 'Z', et qui de plus place l'image                */ \
                                        /* 'champ_de_cotes' derriere le plan (OX,OY). ATTENTION, on ne peut supprimer le             */ \
                                        /* 'SUCY(...)' sous peine de creer des defauts dans l'image...                               */
#define   Z_to_Y(z)                                                                                                                     \
                    COYA(ADD2(COZR(z),COZR(SUCZ(Zmax))))                                                                                \
                                        /* Procedure de permutation des axes 'Z' et 'Y'. ATTENTION, on ne peut supprimer le          */ \
                                        /* 'SUCZ(...)' sous peine de creer des defauts dans l'image...                               */

#define   IFEQ_a_peu_pres_sur_OX(x1,x2)                                                                                                 \
                    IFEQ_a_peu_pres_absolu(x1,x2,MOIT(_____lNORMALISE_OX(pasX)))                                                        \
                                        /* Procedure de test de l'egalite de deux abscisses a "epsilon" pres...                      */
#define   IFEQ_a_peu_pres_sur_OY(y1,y2)                                                                                                 \
                    IFEQ_a_peu_pres_absolu(y1,y2,MOIT(_____lNORMALISE_OY(pasY)))                                                        \
                                        /* Procedure de test de l'egalite de deux ordonnees a "epsilon" pres ; on notera avec        */ \
                                        /* ATTENTION que 'IFEQ_a_peu_pres_sur_OY()' est utilise sur des coordonnees de type 'Z'      */ \
                                        /* mais qui representent des 'Y' dans 'champ_de_cotes'...                                    */

#define   CALCUL_DES_DEUX_INTERSECTIONS(Xintersection,Zintersection)                                                                    \
                    Bblock                                                                                                              \
                    Test(EST_FAUX(on_a_trouve_le_premier_point))                                                                        \
                         Bblock                                                                                                         \
                         EGAL(ASD1(premier_point_d_intersection,x),Xintersection);                                                      \
                         EGAL(ASD1(premier_point_d_intersection,z),Zintersection);                                                      \
                                        /* Mise en place du premier point d'intersection.                                            */ \
                         EGAL(on_a_trouve_le_premier_point,VRAI);                                                                       \
                                        /* Ainsi, on sait qu'on connait le premier point d'intersection...                           */ \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Test(EST_FAUX(on_a_trouve_le_deuxieme_point))                                                                  \
                              Bblock                                                                                                    \
                              Test(IFET(IFEQ_a_peu_pres_sur_OX(Xintersection,ASD1(premier_point_d_intersection,x))                      \
                                       ,IFEQ_a_peu_pres_sur_OY(Zintersection,ASD1(premier_point_d_intersection,z))                      \
                                        )                                                                                               \
                                   )                                                                                                    \
                                   Bblock                                                                                               \
                                   EGAL(on_a_trouve_un_point_double,VRAI);                                                              \
                                        /* Cas des "points-doubles" : il ne s'agit pas d'erreur ; ils se rencontrent lorsque la      */ \
                                        /* ligne de visee passe, en projection, par l'un des coins de 'champ_de_cotes'...            */ \
                                   Eblock                                                                                               \
                              ATes                                                                                                      \
                                   Bblock                                                                                               \
                                   EGAL(ASD1(deuxieme_point_d_intersection,x),Xintersection);                                           \
                                   EGAL(ASD1(deuxieme_point_d_intersection,z),Zintersection);                                           \
                                        /* Mise en place du deuxieme point d'intersection.                                           */ \
                                   EGAL(on_a_trouve_le_deuxieme_point,VRAI);                                                            \
                                        /* Ainsi, on sait qu'on connait le deuxieme point d'intersection...                          */ \
                                   Eblock                                                                                               \
                              ETes                                                                                                      \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              Test(IFOU(IFET(IFEQ_a_peu_pres_sur_OX(Xintersection,ASD1(premier_point_d_intersection,x))                 \
                                            ,IFEQ_a_peu_pres_sur_OY(Zintersection,ASD1(premier_point_d_intersection,z))                 \
                                             )                                                                                          \
                                       ,IFET(IFEQ_a_peu_pres_sur_OX(Xintersection,ASD1(deuxieme_point_d_intersection,x))                \
                                            ,IFEQ_a_peu_pres_sur_OY(Zintersection,ASD1(deuxieme_point_d_intersection,z))                \
                                             )                                                                                          \
                                        )                                                                                               \
                                   )                                                                                                    \
                                   Bblock                                                                                               \
                                        /* Cas des "points-doubles" : il ne s'agit pas d'erreur ; ils se rencontrent lorsque la      */ \
                                        /* ligne de visee passe, en projection, par l'un des coins de 'champ_de_cotes'...            */ \
                                   Eblock                                                                                               \
                              ATes                                                                                                      \
                                   Bblock                                                                                               \
                                   PRINT_ERREUR("il y a plus de deux points distincts d'intersection");                                 \
                                   CAL1(Prer2(" intersection1=(%g,%g)"                                                                  \
                                             ,ASD1(premier_point_d_intersection,x)                                                      \
                                             ,ASD1(premier_point_d_intersection,z)                                                      \
                                              )                                                                                         \
                                        );                                                                                              \
                                   CAL1(Prer2("   intersection2=(%g,%g)"                                                                \
                                             ,ASD1(deuxieme_point_d_intersection,x)                                                     \
                                             ,ASD1(deuxieme_point_d_intersection,z)                                                     \
                                              )                                                                                         \
                                        );                                                                                              \
                                   CAL1(Prer2("   intersectionX=(%g,%g)"                                                                \
                                             ,Xintersection                                                                             \
                                             ,Zintersection                                                                             \
                                              )                                                                                         \
                                        );                                                                                              \
                                   CAL1(Prer0("\n"));                                                                                   \
                                   Eblock                                                                                               \
                              ETes                                                                                                      \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Calcul des points d'intersection de la ligne de visee avec un prisme de hauteur infinie   */ \
                                        /* et de base 'champ_de_cotes'.                                                              */

#ifdef    TYPE_DE_imageA_surface_VERSION_01
#    define    cote_courante(x,y)                                                                                                       \
                         MUL2(facteur_d_echelle,______NORMALISE_NIVEAU(load_point(champ_de_cotes,x,y)))                                 \
                                        /* Definition du champ de cote au point {x,y} du champ 'champ_de_cotes'.                     */
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
#    define    cote_courante(x,y)                                                                                                       \
                         MUL2(facteur_d_echelle,NIVR(loadF_point_valide(champ_de_cotes,x,y)))                                           \
                                        /* Definition du champ de cote au point {x,y} du champ 'champ_de_cotes'.                     */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

#define   texture_courante(x,y)                                                                                                         \
                    FLOT(NIVR(load_point_valide(champ_de_texture,x,y)))                                                                 \
                                        /* Definition de la texture a appliquer au point {x,y} de la montagne.                       */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N   D E   L A   S P E C U L A R I T E  :                                                                 */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
DEFV(Common,DEFV(Float,ZINT(Imontagnes_en_perspective_precises_____source_lumineuse_specularite,FU)));
                                        /* Definition de la specularite introduite le 20130101105228 en garantissant la              */
                                        /* compatibilite anterieure...                                                               */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M I S E   E N   P E R S P E C T I V E   M O N T A G N E U S E   " P R E C I S E "   D ' U N E   I M A G E  :               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
                                        /* ATTENTION, on introduit deux fonctions 'Imontagnes_en_perspective(...)' et                */
                                        /* 'Imontagnes_en_perspective_precises(...)' qui sont de toute evidence inutiles en          */
                                        /* 'TYPE_DE_imageA_surface_VERSION_01' mais dont la presence permet de simplifier            */
                                        /* considerablement la coexistence des deux versions...                                      */

#ifdef    TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_01'.    */

BFonctionP

DEFV(Common,DEFV(FonctionP,POINTERp(Imontagnes_en_perspective_precises(imageR
                                                                      ,facteur_d_echelle,imageA_surface
                                                                      ,imageA_texture
                                                                      ,ARGUMENT_POINTERs(translation)
                                                                      ,ARGUMENT_POINTERs(position_du_touriste_observateur)
                                                                      ,ombres_portees
                                                                      ,ARGUMENT_POINTERs(source_lumineuse)
                                                                      ,depth_cueing,min_depth_cueing
                                                                       )
                                    )
                 )
     )
DEFV(Argument,DEFV(image,imageR));
                                        /* Image Resultat, qui est une vue texturee de la surface.                                   */
DEFV(Argument,DEFV(Float,facteur_d_echelle));
                                        /* Facteur d'echelle permettant de moduler le champ contenu dans 'imageA_surface',           */
                                        /* et par exemple de l'inverser...                                                           */
DEFV(Argument,DEFV(image,imageA_surface));
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface,                 */
DEFV(Argument,DEFV(image,imageA_texture));
                                        /* Deuxieme image Argument, qui donne la texture de la surface.                              */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation)));
                                        /* Translation de l'ecran (c'est-a-dire du support de 'imageR') dans l'espace                */
                                        /* tridimensionnel ; on n'oubliera pas que cette translation est exprimee dans               */
                                        /* des unites telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax]...           */
DEFV(Argument,DEFV(pointF_3D,POINTERs(position_du_touriste_observateur)));
                                        /* Definition de la position de l'observateur.                                               */
                                        /*                                                                                           */
                                        /* 'position_de_l_observateur' fut remplace par 'position_du_touriste_observateur' le        */
                                        /* 20061113115240 pour prepaper l'execution de 'v $xau/LACT16.82$Z' qui fait la modification */
                                        /* 'v $xau/LACT16.61.modifier$sed position_de_l_observateur' et eviter ainsi une grosse      */
                                        /* ambiguite...                                                                              */
DEFV(Argument,DEFV(Logical,ombres_portees));
                                        /* Les ombres portees doivent-elles etre presentes ('VRAI') ou non ('FAUX').                 */
DEFV(Argument,DEFV(pointF_3D,POINTERs(source_lumineuse)));
                                        /* Donne dans le plan de l'image Resultat ('imageR'), les coordonnees de                     */
                                        /* la source lumineuse ; ces coordonnees sont exprimees dans des unites                      */
                                        /* telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax].                        */
DEFV(Argument,DEFV(Logical,depth_cueing));
                                        /* Doit-on faire ('VRAI') ou pas ('FAUX') du depth-cueing ?                                  */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Float,min_depth_cueing));
                                        /* Ce parametre est inclus dans le segment [0,1] ; plus il est                               */
                                        /* proche de zero, plus, le "depth-cueing" est fort...                                       */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
#Aifdef   TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_01'.    */
#Eifdef   TYPE_DE_imageA_surface_VERSION_01                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_01'.    */

#ifdef    TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_02'.    */

BFonctionP

DEFV(Common,DEFV(FonctionP,POINTERp(Imontagnes_en_perspective_precises(imageR
                                                                      ,facteur_d_echelle,imageA_surface
                                                                      ,imageA_texture
                                                                      ,ARGUMENT_POINTERs(translation)
                                                                      ,ARGUMENT_POINTERs(position_du_touriste_observateur)
                                                                      ,ombres_portees
                                                                      ,ARGUMENT_POINTERs(source_lumineuse)
                                                                      ,depth_cueing,min_depth_cueing
                                                                       )
                                    )
                 )
     )
DEFV(Argument,DEFV(image,imageR));
                                        /* Image Resultat, qui est une vue texturee de la surface.                                   */
DEFV(Argument,DEFV(Float,facteur_d_echelle));
                                        /* Facteur d'echelle permettant de moduler le champ contenu dans 'imageA_surface',           */
                                        /* et par exemple de l'inverser...                                                           */
DEFV(Argument,DEFV(imageF,imageA_surface));
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface,                 */
DEFV(Argument,DEFV(image,imageA_texture));
                                        /* Deuxieme image Argument, qui donne la texture de la surface.                              */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation)));
                                        /* Translation de l'ecran (c'est-a-dire du support de 'imageR') dans l'espace                */
                                        /* tridimensionnel ; on n'oubliera pas que cette translation est exprimee dans               */
                                        /* des unites telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax]...           */
DEFV(Argument,DEFV(pointF_3D,POINTERs(position_du_touriste_observateur)));
                                        /* Definition de la position de l'observateur.                                               */
                                        /*                                                                                           */
                                        /* 'position_de_l_observateur' fut remplace par 'position_du_touriste_observateur' le        */
                                        /* 20061113115240 pour prepaper l'execution de 'v $xau/LACT16.82$Z' qui fait la modification */
                                        /* 'v $xau/LACT16.61.modifier$sed position_de_l_observateur' et eviter ainsi une grosse      */
                                        /* ambiguite...                                                                              */
DEFV(Argument,DEFV(Logical,ombres_portees));
                                        /* Les ombres portees doivent-elles etre presentes ('VRAI') ou non ('FAUX').                 */
DEFV(Argument,DEFV(pointF_3D,POINTERs(source_lumineuse)));
                                        /* Donne dans le plan de l'image Resultat ('imageR'), les coordonnees de                     */
                                        /* la source lumineuse ; ces coordonnees sont exprimees dans des unites                      */
                                        /* telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax].                        */
DEFV(Argument,DEFV(Logical,depth_cueing));
                                        /* Doit-on faire ('VRAI') ou pas ('FAUX') du depth-cueing ?                                  */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Float,min_depth_cueing));
                                        /* Ce parametre est inclus dans le segment [0,1] ; plus il est                               */
                                        /* proche de zero, plus, le "depth-cueing" est fort...                                       */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
#Aifdef   TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_02'.    */
#Eifdef   TYPE_DE_imageA_surface_VERSION_02                                     /* Common,DEFV(Fonction,) : pour la 'VERSION_02'.    */

     Bblock

#ifdef    TYPE_DE_imageA_surface_VERSION_01
     BDEFV(image,champ_de_cotes);
                                        /* Cette image definie le champ de cote de la surface ; elle est obtenue par une             */
                                        /* symetrie d'axe 'OX' de l'image 'imageA_surface'. En effet, cette derniere est             */
                                        /* couchee dans le plan horizontal (OX,OZ), or l'axe 'OZ' vient vers l'observateur,          */
                                        /* ce qui fait que, par exemple, l'ancien 'Ymax' se trouve devant l'ancien 'Ymin', une       */
                                        /* fois sur le plan horizontal...                                                            */
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     BDEFV(imageF,champ_de_cotes);
                                        /* Cette image definie le champ de cote de la surface ; elle est obtenue par une             */
                                        /* symetrie d'axe 'OX' de l'image 'imageA_surface'. En effet, cette derniere est             */
                                        /* couchee dans le plan horizontal (OX,OZ), or l'axe 'OZ' vient vers l'observateur,          */
                                        /* ce qui fait que, par exemple, l'ancien 'Ymax' se trouve devant l'ancien 'Ymin', une       */
                                        /* fois sur le plan horizontal...                                                            */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

     BDEFV(image,champ_de_texture);
                                        /* Et il en est de meme pour la texture...                                                   */
     DEFV(pointF_3D,point_3D_courant_de_l_ecran);
                                        /* Definit le point courant sur l'ecran (c'est-a-dire dans 'imageR'), mais considere         */
                                        /* dans l'espace tridimensionnel, et que l'on va projeter, depuis l'observateur, sur         */
                                        /* la surface definie par le chmap 'champ_de_cotes'.                                         */
     DEFV(deltaF_3D,direction_de_visee_courante);
                                        /* Definit la ligne de visee courante (allant donc de l'observateur au point courant         */
                                        /* de l'ecran).                                                                              */
     DEFV(Float,INIT(distance_de_visee_courante,FLOT__UNDEF));
                                        /* Definit la norme du vecteur 'direction_de_visee_courante'.                                */
     DEFV(deltaF_3D,direction_image_observateur);
                                        /* Definit la ligne allant du centre de l'image a l'observateur, et qui est utilisee         */
                                        /* pour savoir si celui-ci ne "tourne pas le dos" a l'image 'champ_de_cotes'...              */
     DEFV(Float,INIT(X_pour_Zmin,FLOT__UNDEF));
                                        /* Pour definir l'intersection de la ligne de visee avec la droite Z=Y_to_Z(Ymin) dans       */
                                        /* le plan (OX,OZ),                                                                          */
     DEFV(Float,INIT(X_pour_Zmax,FLOT__UNDEF));
                                        /* Pour definir l'intersection de la ligne de visee avec la droite Z=Y_to_Z(Ymax) dans       */
                                        /* le plan (OX,OZ).                                                                          */
     DEFV(Float,INIT(Z_pour_Xmin,FLOT__UNDEF));
                                        /* Pour definir l'intersection de la ligne de visee avec la droite X=Xmin dans               */
                                        /* le plan (OX,OZ),                                                                          */
     DEFV(Float,INIT(Z_pour_Xmax,FLOT__UNDEF));
                                        /* Pour definir l'intersection de la ligne de visee avec la droite X=Xmax dans               */
                                        /* le plan (OX,OZ).                                                                          */
     DEFV(Logical,INIT(on_a_trouve_un_point_double,FAUX));
                                        /* Pour savoir si l'on a trouve un point double.                                             */
     DEFV(Logical,INIT(on_a_trouve_le_premier_point,FAUX));
                                        /* Pour savoir si l'on a trouve le premier point d'intersection.                             */
     DEFV(pointF_3D,premier_point_d_intersection);
                                        /* Definition du premier point d'intersection de la ligne de visee avec un prisme infini     */
                                        /* de base 'champ_de_cotes'.                                                                 */
     DEFV(Logical,INIT(on_a_trouve_le_deuxieme_point,FAUX));
                                        /* Pour savoir si l'on a trouve le deuxieme point d'intersection.                            */
     DEFV(pointF_3D,deuxieme_point_d_intersection);
                                        /* Definition du deuxieme point d'intersection de la ligne de visee avec un prisme infini    */
                                        /* de base 'champ_de_cotes'.                                                                 */
     DEFV(deltaI_3D,amplitude_de_traversee);
                                        /* Amplitude de passage du premier au deuxieme point d'intersection.                         */
     DEFV(Positive,INIT(nombre_de_points_entre_les_deux_points_d_intersection,UNDEF));
                                        /* Nombre de points a tester dans 'champ_de_cotes' pour aller du premier au deuxieme         */
                                        /* point d'intersection dans le plan (OX,OZ).                                                */
     DEFV(pointF_3D,point_courant_ligne_de_visee);
                                        /* Point courant allant du premier au deuxieme point d'intersection sur la ligne de visee... */
     DEFV(Logical,INIT(on_a_trouve_un_point_de_la_surface,FAUX));
                                        /* Pour savoir si l'on a trouve un point d'intersection entre la surface et la ligne         */
                                        /* de visee.                                                                                 */
     DEFV(deltaF_3D,normale);
                                        /* Vecteur normal a la facette courante ; il est definit comme un accroissement, et non      */
                                        /* comme un vrai vecteur, car seule sa direction nous importe...                             */
     DEFV(deltaF_3D,rayon_lumineux);
                                        /* Direction du rayon lumineux du point courant a la source lumineuse.                       */
     DEFV(Float,INIT(y_reduit,FLOT__UNDEF));
                                        /* Donne la coordonnee 'Y' reduite lors d'un depth-cueing dans [0,1[.                        */
     DEFV(Float,INIT(niveau_lumineux,MAX_NIVEAU_LUMINEUX));
                                        /* Donne le niveau lumineux courant ; il est initialise sur le                               */
                                        /* maximum, afin d'etre correct si l'ombrage n'est pas demande...                            */
     /*..............................................................................................................................*/
     Test(IFOU(IFNE(Zmin,Ymin)
              ,IFNE(Zmax,Ymax)
               )
          )
          Bblock
          PRINT_ATTENTION("les axes 'OY' et 'OZ' etant echanges en permanence, ils doivent etre definis de facon identique");
          CAL1(Prer2("OY=(%d,%d)\n",Ymin,Ymax));
          CAL1(Prer2("OZ=(%d,%d)\n",Zmin,Zmax));
          Eblock
     ATes
          Bblock
          Eblock
     ETes

#ifdef    TYPE_DE_imageA_surface_VERSION_01
     CALS(Ix_symetrie(champ_de_cotes,imageA_surface));
                                        /* Afin de prendre en compte le fait que ces deux images 'imageA_surface' et                 */
                                        /* 'imageA_texture' sont couchees sur le plan horizontal (OX,OZ), or l'axe 'OZ' vient        */
                                        /* vers l'observateurR...                                                                    */
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     CALS(IFx_symetrie(champ_de_cotes,imageA_surface));
                                        /* Afin de prendre en compte le fait que ces deux images 'imageA_surface' et                 */
                                        /* 'imageA_texture' sont couchees sur le plan horizontal (OX,OZ), or l'axe 'OZ' vient        */
                                        /* vers l'observateurR...                                                                    */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

     CALS(Ix_symetrie(champ_de_texture,imageA_texture));
                                        /* Afin de prendre en compte le fait que ces deux images 'imageA_surface' et                 */
                                        /* 'imageA_texture' sont couchees sur le plan horizontal (OX,OZ), or l'axe 'OZ' vient        */
                                        /* vers l'observateurR...                                                                    */
     INITIALISATION_TRANSFORMATION;
                                        /* Au cas ou la transformation geometrique tri-dimensionnelle ne serait                      */
                                        /* pas initialisee, on le fait sur la transformation unite.                                  */
     begin_image
          Bblock
                                        /*                                                                                           */
                                        /*                                                                   +                       */
                                        /*                                                                  +|                       */
                                        /*                                                                 + |                       */
                                        /*                    Ymax ==> -Zmax  ----------------------------+--|---------              */
                                        /*                                  /                            +   |        /              */
                                        /*                                 /                            +    |       /               */
                                        /*                                /                            +     |      /                */
                                        /*                               /                            +      |     /                 */
                                        /*                              /                            +       *    /                  */
                                        /*                             /    "image-surface"         +            /                   */
                                        /*                     Y^     /      (dans (OX,OZ))        +            /                    */
                                        /*                      |    /                            +            /                     */
                                        /*                      |   /                            +            /                      */
                                        /*          Ymin ==> -Zm|n  ----------------------------+------------                        */
                                        /*                      |                              +                                     */
                                        /*                      O--------->         |\        +                                      */
                                        /*                     /          X         | \      +                                       */
                                        /*                    /                     |  \    +                                        */
                                        /*                  Z/                      |   \  +                                         */
                                        /*                                          |    \+                                          */
                                        /*                                          |    .\                                          */
                                        /*                                          |   .  \                                         */
                                        /*                                          |  *P(Xp,Yp,Zp)                                  */
                                        /*                                           \+     |                                        */
                                        /*                                           +\     |                                        */
                                        /*                                 ligne de +  \    | ecran                                  */
                                        /*                                  visee  +    \   |                                        */
                                        /*                                        +      \  |                                        */
                                        /*                                       +        \ |                                        */
                                        /*                                      *          \|                                        */
                                        /*                                 O(Xo,Yo,Zo)                                               */
                                        /*                                                                                           */
          INITIALISATION_POINT_3D(point_3D_courant_de_l_ecran
                                 ,TRANSFORMATION_GEOMETRIQUE_3D_Fx(_____cNORMALISE_OX(X)
                                                                  ,_____cNORMALISE_OY(Y)
                                                                  ,_____cNORMALISE_OZ(Zorigine)
                                                                  ,ASI1(translation,dx)
                                                                   )
                                 ,TRANSFORMATION_GEOMETRIQUE_3D_Fy(_____cNORMALISE_OX(X)
                                                                  ,_____cNORMALISE_OY(Y)
                                                                  ,_____cNORMALISE_OZ(Zorigine)
                                                                  ,ASI1(translation,dy)
                                                                   )
                                 ,TRANSFORMATION_GEOMETRIQUE_3D_Fz(_____cNORMALISE_OX(X)
                                                                  ,_____cNORMALISE_OY(Y)
                                                                  ,_____cNORMALISE_OZ(Zorigine)
                                                                  ,ASI1(translation,dz)
                                                                   )
                                  );
                                        /* Definition du point courant sur l'ecran (c'est-a-dire dans 'imageR'), mais considere      */
                                        /* dans l'espace tridimensionnel, et que l'on va projeter, depuis l'observateur, sur         */
                                        /* la surface definie par le champ 'champ_de_cotes'.                                         */
          INITIALISATION_ACCROISSEMENT_3D(direction_de_visee_courante
                                         ,SOUS(ASD1(point_3D_courant_de_l_ecran,x)
                                              ,ASI1(position_du_touriste_observateur,x)
                                               )
                                         ,SOUS(ASD1(point_3D_courant_de_l_ecran,y)
                                              ,ASI1(position_du_touriste_observateur,y)
                                               )
                                         ,SOUS(ASD1(point_3D_courant_de_l_ecran,z)
                                              ,ASI1(position_du_touriste_observateur,z)
                                               )
                                          );
                                        /* Definition de la direction de visee, comme allant de l'observateur a l'ecran              */
          EGAL(distance_de_visee_courante,longF3D(direction_de_visee_courante));
                                        /* Puis de sa norme...                                                                       */
          Test(IZGT(distance_de_visee_courante))
               Bblock
               INITIALISATION_ACCROISSEMENT_3D(direction_de_visee_courante
                                              ,DIVI(ASD1(direction_de_visee_courante,dx)
                                                   ,distance_de_visee_courante
                                                    )
                                              ,DIVI(ASD1(direction_de_visee_courante,dy)
                                                   ,distance_de_visee_courante
                                                    )
                                              ,DIVI(ASD1(direction_de_visee_courante,dz)
                                                   ,distance_de_visee_courante
                                                    )
                                               );
                                        /* Enfin, on normalise la direction de visee (lorsqu'elle est definie...).                   */
               Test(IFOU(IFET(IZEQ(ASD1(direction_de_visee_courante,dx))
                             ,NINCff(ASI1(position_du_touriste_observateur,x)
                                    ,_____cNORMALISE_OX(Xmin)
                                    ,_____cNORMALISE_OX(Xmax)
                                     )
                              )
                        ,IFET(IZEQ(ASD1(direction_de_visee_courante,dz))
                             ,NINCff(ASI1(position_du_touriste_observateur,z)
                                    ,_____cNORMALISE_OZ(Y_to_Z(Ymin))
                                    ,_____cNORMALISE_OZ(Y_to_Z(Ymax))
                                     )
                              )
                         )
                    )
                    Bblock
                                        /* ATTENTION : la position en 'z' de l'observateur est comparee a des coordonnees de         */
                                        /* type 'y' ('Ymin' et 'Ymax'), ce qui est du au fait que l'image 'champ_de_cotes' est       */
                                        /* placee dans le plan (OX,OZ) ; enfin, on notera les 'Y_to_Z()' qui rappellent que l'axe    */
                                        /* 'OZ' vient vers nous, et que l'image 'champ_de_cotes' est placee derriere le plan         */
                                        /* (OX,OY)...                                                                                */
                    PRINT_ERREUR("l'observateur ne regarde pas dans la direction de l'image a visualiser");
                    Eblock
               ATes
                    Bblock
                    INITIALISATION_ACCROISSEMENT_3D(direction_image_observateur
                                                   ,SOUS(_____cNORMALISE_OX(Xcentre)
                                                        ,ASI1(position_du_touriste_observateur,x)
                                                         )
                                                   ,FZERO
                                                   ,SOUS(_____cNORMALISE_OZ(Y_to_Z(Ycentre))
                                                        ,ASI1(position_du_touriste_observateur,z)
                                                         )
                                                    );
                                        /* Definition de la ligne allant de l'observateur au centre de l'image et qui est utilisee   */
                                        /* pour savoir si celui-ci ne "tourne pas le dos" a l'image 'champ_de_cotes' ; on notera     */
                                        /* que la composante en 'dy' est mise a 0, et ce afin de simuler dans le test qui va suivre  */
                                        /* un produit scalaire entre 'direction_image_observateur' et 'direction_de_visee_courante'  */
                                        /* dans le plan (Ox,OZ)...                                                                   */
                    Test(IZGT(prdF3D(direction_image_observateur,direction_de_visee_courante)))
                         Bblock
                                        /* Il faut que les deux pseudo-vecteurs 'direction_image_observateur' et                     */
                                        /* 'direction_de_visee_courante' aillent a peu pres dans la meme direction pour avoir        */
                                        /* une chance de voir 'champ_de_cotes' depuis l'observateur...                               */
                                        /*                                                                                           */
                                        /* L'equation de la ligne de visee est :                                                     */
                                        /*                                                                                           */
                                        /*                    X - Xo       Y - Yo       Z - Zo                                       */
                                        /*                  ---------- = ---------- = ----------                                     */
                                        /*                   visee(X)     visee(Y)     visee(Z)                                      */
                                        /*                                                                                           */
                                        /* ou :                                                                                      */
                                        /*                                                                                           */
                                        /* {X,Y,Z} designe le point courant,                                                         */
                                        /* (Xo,Yo,Zo) designe l'observateur, et                                                      */
                                        /* (visee(X),visee(Y),visee(Z)) designe son vecteur directeur 'direction_de_visee_courante'. */
                                        /*                                                                                           */
                         EGAL(Z_pour_Xmin
                             ,COND(IZEQ(ASD1(direction_de_visee_courante,dx))
                                  ,F_INFINI
                                  ,AXPB(DIVI(ASD1(direction_de_visee_courante,dz),ASD1(direction_de_visee_courante,dx))
                                       ,SOUS(_____cNORMALISE_OX(Xmin),ASI1(position_du_touriste_observateur,x))
                                       ,ASI1(position_du_touriste_observateur,z)
                                        )
                                   )
                              );
                                        /* Calcul de l'intersection de la ligne de visee avec la droite X=Xmin dans                  */
                                        /* le plan (OX,OZ), qui est en general du type :                                             */
                                        /*                                                                                           */
                                        /*                            visee(Z)                                                       */
                                        /*                  Z = Zo + ----------.(Xmin-Xo).                                           */
                                        /*                            visee(X)                                                       */
                                        /*                                                                                           */
                         EGAL(Z_pour_Xmax
                             ,COND(IZEQ(ASD1(direction_de_visee_courante,dx))
                                  ,F_INFINI
                                  ,AXPB(DIVI(ASD1(direction_de_visee_courante,dz),ASD1(direction_de_visee_courante,dx))
                                       ,SOUS(_____cNORMALISE_OX(Xmax),ASI1(position_du_touriste_observateur,x))
                                       ,ASI1(position_du_touriste_observateur,z)
                                        )
                                   )
                              );
                                        /* Calcul de l'intersection de la ligne de visee avec la droite X=Xmax dans                  */
                                        /* le plan (OX,OZ), qui est en general du type :                                             */
                                        /*                                                                                           */
                                        /*                            visee(Z)                                                       */
                                        /*                  Z = Zo + ----------.(Xmax-Xo).                                           */
                                        /*                            visee(X)                                                       */
                                        /*                                                                                           */
                         EGAL(X_pour_Zmin
                             ,COND(IZEQ(ASD1(direction_de_visee_courante,dz))
                                  ,F_INFINI
                                  ,AXPB(DIVI(ASD1(direction_de_visee_courante,dx),ASD1(direction_de_visee_courante,dz))
                                       ,SOUS(_____cNORMALISE_OZ(Y_to_Z(Ymin)),ASI1(position_du_touriste_observateur,z))
                                       ,ASI1(position_du_touriste_observateur,x)
                                        )
                                   )
                              );
                                        /* Calcul de l'intersection de la ligne de visee avec la droite Z=Y_to_Z(Ymin) dans          */
                                        /* le plan (OX,OZ), qui est en general du type :                                             */
                                        /*                                                                                           */
                                        /*                            visee(X)                                                       */
                                        /*                  X = Xo + ----------.(Y_to_Z(Ymin)-Xo).                                   */
                                        /*                            visee(Z)                                                       */
                                        /*                                                                                           */
                         EGAL(X_pour_Zmax
                             ,COND(IZEQ(ASD1(direction_de_visee_courante,dz))
                                  ,F_INFINI
                                  ,AXPB(DIVI(ASD1(direction_de_visee_courante,dx),ASD1(direction_de_visee_courante,dz))
                                       ,SOUS(_____cNORMALISE_OZ(Y_to_Z(Ymax)),ASI1(position_du_touriste_observateur,z))
                                       ,ASI1(position_du_touriste_observateur,x)
                                        )
                                   )
                              );
                                        /* Calcul de l'intersection de la ligne de visee avec la droite Z=Y_to_Z(Ymax) dans          */
                                        /* le plan (OX,OZ), qui est en general du type :                                             */
                                        /*                                                                                           */
                                        /*                            visee(X)                                                       */
                                        /*                  X = Xo + ----------.(Y_to_Z(Ymax)-Xo).                                   */
                                        /*                            visee(Z)                                                       */
                                        /*                                                                                           */

                         Test(IFET(IFET(NINCff(Z_pour_Xmin,_____cNORMALISE_OZ(Y_to_Z(Ymin)),_____cNORMALISE_OZ(Y_to_Z(Ymax)))
                                       ,NINCff(Z_pour_Xmax,_____cNORMALISE_OZ(Y_to_Z(Ymin)),_____cNORMALISE_OZ(Y_to_Z(Ymax)))
                                        )
                                  ,IFET(NINCff(X_pour_Zmin,_____cNORMALISE_OX(Xmin),_____cNORMALISE_OX(Xmax))
                                       ,NINCff(X_pour_Zmax,_____cNORMALISE_OX(Xmin),_____cNORMALISE_OX(Xmax))
                                        )
                                   )
                              )
                              Bblock
                                        /* L'observateur ne voit pas l'image a visualiser dans cette direction, mais cela ne         */
                                        /* constitue pas une erreur (ce sera en general le cas aux bords de l'ecran).                */
                              Eblock
                         ATes
                              Bblock
                                        /* Calcul de l'intersection de la ligne de visee avec l'image dans le plan (OX,OZ) :         */
                                        /*                                                                                           */
                                        /*                 |         .                          .                                    */
                                        /*                 |  \      .                          .                                    */
                                        /*                 |   \     .                          .                                    */
                                        /*                 |    \    .                          .                                    */
                                        /*                 |     \   .                          .                                    */
                                        /*                 |      \  .                          .                                    */
                                        /*                 |       \ .                          .                                    */
                                        /*                 |        \.                          .                                    */
                                        /*                 |         +                          .                                    */
                                        /*                 |         .\                         .                                    */
                                        /*                 |         . \ deuxieme point         .                                    */
                                        /*    Y_to_Z(Ymax) |............+.......................................                     */
                                        /*                 |         .  |\ d'intersection       .                                    */
                                        /*                 |         .  | \                     .                                    */
                                        /*                 |         .  |  \                    .                                    */
                                        /*                 |         .  |   \                   .                                    */
                                        /*                 |         .  |    \                  .                                    */
                                        /*                 |         .  |     \                 .                                    */
                                        /*                 |         .  |      \                .                                    */
                                        /*                 |         .  |       \               .                                    */
                                        /*                 |         .  |        \              .                                    */
                                        /*                 |         .  |         \             .                                    */
                                        /*                 |         .  |          \            .                                    */
                                        /*                 |         .  |           \ premier point                                  */
                                        /*    Y_to_Z(Ymin) |............|------------+..........................                     */
                                        /*                 |         .   amplitude    \ d'intersection                               */
                                        /*                 |         .       de        \        .                                    */
                                        /*                 |         .   traversee      \_      .                                    */
                                        /*                 |         .                  |\ visee.                                    */
                                        /*                 |         .                    \     .                                    */
                                        /*                 |         .                     \    .                                    */
                                        /*                 |         .                      *Observateur                             */
                                        /*                 |         .                       \  .                                    */
                                        /*                 |         .                        \ .                                    */
                                        /*                 |         .                         \.                                    */
                                        /*                 |         .                          +                                    */
                                        /*                 |         .                          .\                                   */
                                        /*                 |         .                          . \                                  */
                                        /*                 |         .                          .  \                                 */
                                        /*                 |         .                          .                                    */
                                        /*                 O----------------------------------------------------->                   */
                                        /*                 |        Xmin                       Xmax              X                   */
                                        /*               Z |                                                                         */
                                        /*                                                                                           */
                              EGAL(on_a_trouve_un_point_double,FAUX);
                                        /* A priori, on n'a pas trouve de point double.                                              */
                              EGAL(on_a_trouve_le_premier_point,FAUX);
                              EGAL(on_a_trouve_le_deuxieme_point,FAUX);
                                        /* A priori, on n'a encore trouve aucun point d'intersection...                              */
                              EGAL(ASD1(premier_point_d_intersection,y),FZERO);
                              EGAL(ASD1(deuxieme_point_d_intersection,y),FZERO);
                                        /* A priori, on ne s'interesse pas a la troisieme coordonnee, qui est ici, il faut faire     */
                                        /* attention, la coordonnee 'Y'...                                                           */

                              Test(INCLff(Z_pour_Xmin,_____cNORMALISE_OZ(Y_to_Z(Ymin)),_____cNORMALISE_OZ(Y_to_Z(Ymax))))
                                   Bblock
                                   CALCUL_DES_DEUX_INTERSECTIONS(_____cNORMALISE_OX(Xmin),Z_pour_Xmin);
                                        /* Calcul des deux points d'intersections...                                                 */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              Test(INCLff(Z_pour_Xmax,_____cNORMALISE_OZ(Y_to_Z(Ymin)),_____cNORMALISE_OZ(Y_to_Z(Ymax))))
                                   Bblock
                                   CALCUL_DES_DEUX_INTERSECTIONS(_____cNORMALISE_OX(Xmax),Z_pour_Xmax);
                                        /* Calcul des deux points d'intersections...                                                 */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              Test(INCLff(X_pour_Zmin,_____cNORMALISE_OX(Xmin),_____cNORMALISE_OX(Xmax)))
                                   Bblock
                                   CALCUL_DES_DEUX_INTERSECTIONS(X_pour_Zmin,_____cNORMALISE_OZ(Y_to_Z(Ymin)));
                                        /* Calcul des deux points d'intersections...                                                 */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              Test(INCLff(X_pour_Zmax,_____cNORMALISE_OX(Xmin),_____cNORMALISE_OX(Xmax)))
                                   Bblock
                                   CALCUL_DES_DEUX_INTERSECTIONS(X_pour_Zmax,_____cNORMALISE_OZ(Y_to_Z(Ymax)));
                                        /* Calcul des deux points d'intersections...                                                 */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              Test(IFET(EST_VRAI(on_a_trouve_le_premier_point),EST_VRAI(on_a_trouve_le_deuxieme_point)))
                                   Bblock
                                   DEFV(Float,INIT(X_P,FLOT__UNDEF));
                                   DEFV(Float,INIT(Y_P,FLOT__UNDEF));
                                        /* Definition du point courant 'P'.                                                          */

                                   DEFV(Int,INIT(X_G,UNDEF));
                                   DEFV(Int,INIT(X_D,UNDEF));

                                   DEFV(Int,INIT(Y_B,UNDEF));
                                   DEFV(Int,INIT(Y_H,UNDEF));

                                        /* Definition de la maille entiere entourant le point courant 'P' :                          */
                                        /*                                                                                           */
                                        /*                          G                 D                                              */
                                        /*                                                                                           */
                                        /*                          |       |         |                                              */
                                        /*                                  |                                                        */
                                        /*               [Y]+1 ---- * ------+-------- * ----- H                                      */
                                        /*                                  |                                                        */
                                        /*                          |                 |                                              */
                                        /*                 Y   -----+------ P --------+------                                        */
                                        /*                          |                 |                                              */
                                        /*                          |       |         |                                              */
                                        /*                          |       |         |                                              */
                                        /*                          |       |         |                                              */
                                        /*                          |       |         |                                              */
                                        /*                                  |                                                        */
                                        /*                [Y]  ---- * ------+-------- * ----- B                                      */
                                        /*                                  |                                                        */
                                        /*                          |       |         |                                              */
                                        /*                                                                                           */
                                        /*                         [X]      X       [X]+1                                            */
                                        /*                                                                                           */
                                        /* ou '[x]' designe la partie entiere par defaut du nombre reel 'x', et ou {G,D,B,H}         */
                                        /* symbolisent {Gauche,Droite,Bas,Haut}.                                                     */

                                   DEFV(Float,INIT(ponderation_BG,FLOT__UNDEF));
                                   DEFV(Float,INIT(ponderation_BD,FLOT__UNDEF));
                                   DEFV(Float,INIT(ponderation_HG,FLOT__UNDEF));
                                   DEFV(Float,INIT(ponderation_HD,FLOT__UNDEF));
                                        /* Coefficients d'interpolation lineaire a l'interieur de la maille definie ci-dessus.       */

                                   Test(IFLT(gpdisF3D(position_du_touriste_observateur,ASI1
                                                     ,deuxieme_point_d_intersection,ASD1
                                                      )
                                            ,gpdisF3D(position_du_touriste_observateur,ASI1
                                                     ,premier_point_d_intersection,ASD1
                                                      )
                                             )
                                        )
                                        Bblock
                                        fSWAP(ASD1(premier_point_d_intersection,x),ASD1(deuxieme_point_d_intersection,x));
                                        fSWAP(ASD1(premier_point_d_intersection,y),ASD1(deuxieme_point_d_intersection,y));
                                        fSWAP(ASD1(premier_point_d_intersection,z),ASD1(deuxieme_point_d_intersection,z));
                                        /* Il faut que l'on trouve dans l'ordre sur 'direction_de_visee_courante' : l'observateur,   */
                                        /* le premier point d'intersection, et enfin le deuxieme point d'intersection...             */
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes

                                   Test(IZEQ(ASD1(direction_de_visee_courante,dy)))
                                        Bblock
                                        EGAL(ASD1(premier_point_d_intersection,y)
                                            ,ASI1(position_du_touriste_observateur,y)
                                             );
                                        EGAL(ASD1(deuxieme_point_d_intersection,y)
                                            ,ASI1(position_du_touriste_observateur,y)
                                             );
                                        /* Si la ligne de visee est horizontale, la coordonnee 'Yi' des points d'intersection est    */
                                        /* aussi celle de l'observateur...                                                           */

                                        Test(IFET(IZEQ(ASD1(direction_de_visee_courante,dx))
                                                 ,IZEQ(ASD1(direction_de_visee_courante,dz))
                                                  )
                                             )
                                             Bblock
                                             PRINT_ERREUR("les trois composantes de la visee sont nulles");
                                             Eblock
                                        ATes
                                             Bblock
                                             Eblock
                                        ETes
                                        Eblock
                                   ATes
                                        Bblock
                                        Test(IZNE(ASD1(direction_de_visee_courante,dz)))
                                             Bblock
                                             EGAL(ASD1(premier_point_d_intersection,y)
                                                 ,AXPB(DIVI(ASD1(direction_de_visee_courante,dy)
                                                           ,ASD1(direction_de_visee_courante,dz)
                                                            )
                                                      ,SOUS(ASD1(premier_point_d_intersection,z)
                                                           ,ASI1(position_du_touriste_observateur,z)
                                                            )
                                                      ,ASI1(position_du_touriste_observateur,y)
                                                       )
                                                  );
                                             EGAL(ASD1(deuxieme_point_d_intersection,y)
                                                 ,AXPB(DIVI(ASD1(direction_de_visee_courante,dy)
                                                           ,ASD1(direction_de_visee_courante,dz)
                                                            )
                                                      ,SOUS(ASD1(deuxieme_point_d_intersection,z)
                                                           ,ASI1(position_du_touriste_observateur,z)
                                                            )
                                                      ,ASI1(position_du_touriste_observateur,y)
                                                       )
                                                  );
                                        /* Sinon, on calcule la coordonnee 'Yi' des points d'intersection a partir de la ligne de    */
                                        /* visee et d'une composante non nulle (ici 'dz') :                                          */
                                        /*                                                                                           */
                                        /*                             visee(Y)                                                      */
                                        /*                  Yi = Yo + ----------.(Zi-Zo).                                            */
                                        /*                             visee(Z)                                                      */
                                        /*                                                                                           */
                                             Eblock
                                        ATes
                                             Bblock
                                             Test(IZNE(ASD1(direction_de_visee_courante,dx)))
                                                  Bblock
                                                  EGAL(ASD1(premier_point_d_intersection,y)
                                                      ,AXPB(DIVI(ASD1(direction_de_visee_courante,dy)
                                                                ,ASD1(direction_de_visee_courante,dx)
                                                                 )
                                                           ,SOUS(ASD1(premier_point_d_intersection,x)
                                                                ,ASI1(position_du_touriste_observateur,x)
                                                                 )
                                                           ,ASI1(position_du_touriste_observateur,y)
                                                            )
                                                       );
                                                  EGAL(ASD1(deuxieme_point_d_intersection,y)
                                                      ,AXPB(DIVI(ASD1(direction_de_visee_courante,dy)
                                                                ,ASD1(direction_de_visee_courante,dx)
                                                                 )
                                                           ,SOUS(ASD1(deuxieme_point_d_intersection,x)
                                                                ,ASI1(position_du_touriste_observateur,x)
                                                                 )
                                                           ,ASI1(position_du_touriste_observateur,y)
                                                            )
                                                       );
                                        /* Sinon, on calcule la coordonnee 'Yi' des points d'intersection a partir de la ligne de    */
                                        /* visee et d'une composante non nulle (ici 'dx') :                                          */
                                        /*                                                                                           */
                                        /*                             visee(Y)                                                      */
                                        /*                  Yi = Yo + ----------.(Xi-Xo).                                            */
                                        /*                             visee(X)                                                      */
                                        /*                                                                                           */
                                                  Eblock
                                             ATes
                                                  Bblock
                                                  PRINT_ERREUR("la visee a lieu perpendiculairement au plan de l'image");
                                                  EGAL(ASD1(premier_point_d_intersection,y),F_INFINI);
                                                  EGAL(ASD1(deuxieme_point_d_intersection,y),F_INFINI);
                                                  Eblock
                                             ETes
                                             Eblock
                                        ETes
                                        Eblock
                                   ETes

                                   INITIALISATION_ACCROISSEMENT_3D(amplitude_de_traversee
                                                                  ,SOUS(_cDENORMALISE_OX(ASD1(deuxieme_point_d_intersection,x))
                                                                       ,_cDENORMALISE_OX(ASD1(premier_point_d_intersection,x))
                                                                        )
                                                                  ,SOUS(_cDENORMALISE_OY(ASD1(deuxieme_point_d_intersection,y))
                                                                       ,_cDENORMALISE_OY(ASD1(premier_point_d_intersection,y))
                                                                        )
                                                                  ,SOUS(_cDENORMALISE_OZ(ASD1(deuxieme_point_d_intersection,z))
                                                                       ,_cDENORMALISE_OZ(ASD1(premier_point_d_intersection,z))
                                                                        )
                                                                   );
                                        /* Calul de l'amplitude de passage du premier au deuxieme point d'intersection.              */
                                   EGAL(nombre_de_points_entre_les_deux_points_d_intersection
                                       ,TRPU(MAX2(DIVI(ABSO(ASD1(amplitude_de_traversee,dx)),pasX)
                                                 ,DIVI(ABSO(ASD1(amplitude_de_traversee,dz)),pasY)
                                                  )
                                             )
                                        );
                                        /* Nombre de points a tester dans 'champ_de_cotes' pour aller du premier au deuxieme         */
                                        /* point d'intersection dans le plan (OX,OZ).                                                */
                                   TRANSFERT_POINT_3D(point_courant_ligne_de_visee,premier_point_d_intersection);
                                        /* Initialisation du point courant de balayage de la surface...                              */
                                   EGAL(on_a_trouve_un_point_de_la_surface,FAUX);
                                        /* Pour savoir si l'on a trouve un point d'intersection entre la surface et la ligne         */
                                        /* de visee.                                                                                 */

                                   Repe(nombre_de_points_entre_les_deux_points_d_intersection)
                                        Bblock
                                        Test(IFET(EST_FAUX(on_a_trouve_un_point_de_la_surface)
                                                 ,I3ET(INCLff(ASD1(point_courant_ligne_de_visee,x)
                                                             ,ASD1(premier_point_d_intersection,x)
                                                             ,ASD1(deuxieme_point_d_intersection,x)
                                                              )
                                                      ,INCLff(ASD1(point_courant_ligne_de_visee,y)
                                                             ,ASD1(premier_point_d_intersection,y)
                                                             ,ASD1(deuxieme_point_d_intersection,y)
                                                              )
                                                      ,INCLff(ASD1(point_courant_ligne_de_visee,z)
                                                             ,ASD1(premier_point_d_intersection,z)
                                                             ,ASD1(deuxieme_point_d_intersection,z)
                                                              )
                                                       )
                                                  )
                                             )
                                        /* On notera l'introduction du test d'inclusion (par 'INCLff(...)') des coordonnees du point */
                                        /* courant par rapport a celles des deux points d'intersection. En effet, a cause d'erreurs  */
                                        /* d'arrondi, il est possible, lors du deplacement par incrementation du point courant, de   */
                                        /* sortir (de tres peu...) du segment forme par les deux points d'intersection. Enfin, on    */
                                        /* utilise 'INCLff(...)', et non pas 'IFINff(...)', car on ne connait pas a priori l'ordre   */
                                        /* des bornes...                                                                             */
                                             Bblock
                                             EGAL(X_P,F__cDENORMALISE_OX(ASD1(point_courant_ligne_de_visee,x)));
                                             EGAL(Y_P,Z_to_Y(F__cDENORMALISE_OZ(ASD1(point_courant_ligne_de_visee,z))));
                                        /* Calcul du point courant 'P'.                                                              */
                                             EGAL(X_G,NEUT(INTE(X_P)));
                                             EGAL(X_D,SUCX(INTE(X_P)));
                                             EGAL(Y_B,NEUT(INTE(Y_P)));
                                             EGAL(Y_H,SUCY(INTE(Y_P)));
                                        /* Calcul de la maille entiere entourant le point courant 'P'.                               */
                                             EGAL(ponderation_BG,MUL2(SOUS(FLOT(X_D),NEUT(X_P)),SOUS(FLOT(Y_H),NEUT(Y_P))));
                                             EGAL(ponderation_BD,MUL2(SOUS(NEUT(X_P),FLOT(X_G)),SOUS(FLOT(Y_H),NEUT(Y_P))));
                                             EGAL(ponderation_HG,MUL2(SOUS(FLOT(X_D),NEUT(X_P)),SOUS(NEUT(Y_P),FLOT(Y_B))));
                                             EGAL(ponderation_HD,MUL2(SOUS(NEUT(X_P),FLOT(X_G)),SOUS(NEUT(Y_P),FLOT(Y_B))));
                                        /* Calcul des coefficients d'interpolation lineaire a l'interieur de la maille precedente.   */

                                             Test(IFOU(IFOU(IFEXff(ponderation_BG
                                                                  ,COORDONNEE_BARYCENTRIQUE_MINIMALE
                                                                  ,COORDONNEE_BARYCENTRIQUE_MAXIMALE
                                                                   )
                                                           ,IFEXff(ponderation_BD
                                                                  ,COORDONNEE_BARYCENTRIQUE_MINIMALE
                                                                  ,COORDONNEE_BARYCENTRIQUE_MAXIMALE
                                                                   )
                                                            )
                                                      ,IFOU(IFEXff(ponderation_HG
                                                                  ,COORDONNEE_BARYCENTRIQUE_MINIMALE
                                                                  ,COORDONNEE_BARYCENTRIQUE_MAXIMALE
                                                                   )
                                                           ,IFEXff(ponderation_HD
                                                                  ,COORDONNEE_BARYCENTRIQUE_MINIMALE
                                                                  ,COORDONNEE_BARYCENTRIQUE_MAXIMALE
                                                                   )
                                                            )
                                                       )
                                                  )
                                                  Bblock
                                                  PRINT_ERREUR("des coordonnees barycentriques sont hors de [0,1]");

                                                  CAL1(Prer2("(X,Y)........................=(%d,%d)\n",X,Y));

                                                  CAL1(Prer3("premier point d'intersection.=(%+.17f,%+.17f,%+.17f)\n"
                                                            ,ASD1(premier_point_d_intersection,x)
                                                            ,ASD1(premier_point_d_intersection,y)
                                                            ,ASD1(premier_point_d_intersection,z)
                                                             )
                                                       );
                                                  CAL1(Prer3("deuxieme point d'intersection=(%+.17f,%+.17f,%+.17f)\n"
                                                            ,ASD1(deuxieme_point_d_intersection,x)
                                                            ,ASD1(deuxieme_point_d_intersection,y)
                                                            ,ASD1(deuxieme_point_d_intersection,z)
                                                             )
                                                       );

                                                  CAL1(Prer3("ligne de visee...............=(%+.17f,%+.17f,%+.17f)\n"
                                                            ,ASD1(point_courant_ligne_de_visee,x)
                                                            ,ASD1(point_courant_ligne_de_visee,y)
                                                            ,ASD1(point_courant_ligne_de_visee,z)
                                                             )
                                                       );
                                                  CAL1(Prer2("point courant................=(%+.17f,%+.17f)\n",X_P,Y_P));

                                                  CAL1(Prer1("Gauche.......................=%d\n",X_G));
                                                  CAL1(Prer1("Droite.......................=%d\n",X_D));
                                                  CAL1(Prer1("Bas..........................=%d\n",Y_B));
                                                  CAL1(Prer1("Haut.........................=%d\n",Y_H));

                                                  CAL1(Prer1("ponderation BG...............=%+g\n",ponderation_BG));
                                                  CAL1(Prer1("ponderation BD...............=%+g\n",ponderation_BD));
                                                  CAL1(Prer1("ponderation HG...............=%+g\n",ponderation_HG));
                                                  CAL1(Prer1("ponderation HD...............=%+g\n",ponderation_HD));
                                                  Eblock
                                             ATes
                                                  Bblock
                                                  Eblock
                                             ETes

                                             Test(IFGT(ASD1(point_courant_ligne_de_visee,y)
                                                      ,LRZ4(ponderation_BG,cote_courante(X_G,Y_B)
                                                           ,ponderation_BD,cote_courante(X_D,Y_B)
                                                           ,ponderation_HD,cote_courante(X_D,Y_H)
                                                           ,ponderation_HG,cote_courante(X_G,Y_H)
                                                            )
                                                       )
                                                  )
                                                  Bblock
                                        /* Cas ou la ligne de visee passe au-dessus du point courant de la surface...                */
                                                  Test(IFGE(nombre_de_points_entre_les_deux_points_d_intersection,DEUX))
                                                       Bblock
                                                       INCR(ASD1(point_courant_ligne_de_visee,x)
                                                           ,DIVI(_____lNORMALISE_OX(ASD1(amplitude_de_traversee,dx))
                                                                ,FLOT(TRMU(nombre_de_points_entre_les_deux_points_d_intersection))
                                                                 )
                                                            );
                                                       INCR(ASD1(point_courant_ligne_de_visee,y)
                                                           ,DIVI(_____lNORMALISE_OY(ASD1(amplitude_de_traversee,dy))
                                                                ,FLOT(TRMU(nombre_de_points_entre_les_deux_points_d_intersection))
                                                                 )
                                                            );
                                                       INCR(ASD1(point_courant_ligne_de_visee,z)
                                                           ,DIVI(_____lNORMALISE_OZ(ASD1(amplitude_de_traversee,dz))
                                                                ,FLOT(TRMU(nombre_de_points_entre_les_deux_points_d_intersection))
                                                                 )
                                                            );
                                        /* Progression du point courant...                                                           */
                                                       Eblock
                                                  ATes
                                                       Bblock
                                                       Eblock
                                                  ETes
                                                  Eblock
                                             ATes
                                                  Bblock
                                        /* Cas ou la ligne de visee rentre en collision avec la surface...                           */
                                                  EGAL(on_a_trouve_un_point_de_la_surface,VRAI);
                                        /* Memorisons que l'on a trouve un point d'intersection avec la surface : on notera          */
                                        /* qu'a partir de maintenant, 'point_courant_ligne_de_visee' ne bouge plus...                */
                                                  Eblock
                                             ETes
                                             Eblock
                                        ATes
                                             Bblock
                                             Eblock
                                        ETes
                                        Eblock
                                   ERep

                                   Test(EST_VRAI(on_a_trouve_un_point_de_la_surface))
                                        Bblock
                                        /* On notera que pour des raisons diverses :                                                 */
                                        /*                                                                                           */
                                        /*                  X # _cDENORMALISE_OX(ASD1(point_courant_ligne_de_visee,x))               */
                                        /*                  Y # Z_to_Y(_cDENORMALISE_OZ(ASD1(point_courant_ligne_de_visee,z)))       */
                                        /*                                                                                           */
                                        /* la difference portant sur tres peu d'unites...                                            */

                                        DEFV(Int,INIT(X_AD,PREX(X_G)));
                                        DEFV(Int,INIT(X_BC,SUCX(X_G)));

                                        DEFV(Int,INIT(Y_AB,PREY(Y_B)));
                                        DEFV(Int,INIT(Y_DC,SUCY(Y_B)));

                                        DEFV(Float,INIT(Z__A,UNDEF));
                                        DEFV(Float,INIT(Z__B,UNDEF));
                                        DEFV(Float,INIT(Z__C,UNDEF));
                                        DEFV(Float,INIT(Z__D,UNDEF));

                                        /* Definition d'un quadrilatere {A,B,C,D} entourant le point courant 'P' :                   */
                                        /*                                                                                           */
                                        /*                          |       |         |                                              */
                                        /*                                  |                                                        */
                                        /*               [Y]+1 ---- D ------+-------- C -----                                        */
                                        /*                                  |                                                        */
                                        /*                          |       |         |                                              */
                                        /*                          |                 |                                              */
                                        /*                  Y  -----+------ P --------+------                                        */
                                        /*                          |                 |                                              */
                                        /*                          |       |         |                                              */
                                        /*                          |       |         |                                              */
                                        /*                          |       |         |                                              */
                                        /*                                  |                                                        */
                                        /*               [Y]-1 ---- A ------+-------- B -----                                        */
                                        /*                                  |                                                        */
                                        /*                          |       |         |                                              */
                                        /*                                                                                           */
                                        /*                        [X]-1     XX      [X]+1                                            */
                                        /*                                                                                           */
                                        /* ou '[x]' designe la partie entiere par defaut du nombre reel 'x'.                         */

                                        EGAL(Z__A,F__cDENORMALISE_OY(cote_courante(X_AD,Y_AB)));
                                        EGAL(Z__B,F__cDENORMALISE_OY(cote_courante(X_BC,Y_AB)));
                                        EGAL(Z__C,F__cDENORMALISE_OY(cote_courante(X_BC,Y_DC)));
                                        EGAL(Z__D,F__cDENORMALISE_OY(cote_courante(X_AD,Y_DC)));
                                        /* Ceci etant rendu necesaire parce que les niveaux (par exemple ceux qui sont transmis par  */
                                        /* 'Imontagnes_en_perspective(...)') sont dans {NIVEAU_PRECIS_MINIMAL,NIVEAU_PRECIS_MAXIMAL} */
                                        /* ce qui correspond en fait a [0,1]...                                                      */

                                        INITIALISATION_ACCROISSEMENT_3D(normale
                                                                       ,PvectX(SOUS(X_AD,X_BC)
                                                                              ,SOUS(Z__D,Z__B)
                                                                              ,SOUS(Y_to_Z(Y_DC),Y_to_Z(Y_AB))

                                                                              ,SOUS(X_BC,X_AD)
                                                                              ,SOUS(Z__C,Z__A)
                                                                              ,SOUS(Y_to_Z(Y_DC),Y_to_Z(Y_AB))
                                                                               )

                                                                       ,PvectY(SOUS(X_AD,X_BC)
                                                                              ,SOUS(Z__D,Z__B)
                                                                              ,SOUS(Y_to_Z(Y_DC),Y_to_Z(Y_AB))

                                                                              ,SOUS(X_BC,X_AD)
                                                                              ,SOUS(Z__C,Z__A)
                                                                              ,SOUS(Y_to_Z(Y_DC),Y_to_Z(Y_AB))
                                                                               )

                                                                       ,PvectZ(SOUS(X_AD,X_BC)
                                                                              ,SOUS(Z__D,Z__B)
                                                                              ,SOUS(Y_to_Z(Y_DC),Y_to_Z(Y_AB))

                                                                              ,SOUS(X_BC,X_AD)
                                                                              ,SOUS(Z__C,Z__A)
                                                                              ,SOUS(Y_to_Z(Y_DC),Y_to_Z(Y_AB))
                                                                               )
                                                                        );
                                        /* Approximation d'une normale possible au point 'P' par :                                   */
                                        /*                                                                                           */
                                        /*                 -->   --->    --->                                                        */
                                        /*                  N  =  BD  /\  AC                                                         */
                                        /*                                                                                           */
                                        /* (n'oublions pas que l'axe 'OY' de l'image est oriente dans le sens inverse de l'axe       */
                                        /* 'OZ' de l'espace).                                                                        */

                                        INITIALISATION_ACCROISSEMENT_3D(rayon_lumineux
                                                                       ,SOUS(F__cDENORMALISE_OX(ASI1(source_lumineuse,x))
                                                                            ,X_P
                                                                             )
                                                                       ,SOUS(F__cDENORMALISE_OY(ASI1(source_lumineuse,y))
                                                                            ,LRZ4(ponderation_BG,cote_courante(X_G,Y_B)
                                                                                 ,ponderation_BD,cote_courante(X_D,Y_B)
                                                                                 ,ponderation_HD,cote_courante(X_D,Y_H)
                                                                                 ,ponderation_HG,cote_courante(X_G,Y_H)
                                                                                  )
                                                                             )
                                                                       ,SOUS(F__cDENORMALISE_OZ(ASI1(source_lumineuse,z))
                                                                            ,Y_to_Z(Y_P)
                                                                             )
                                                                        );
                                        /* Calcul du rayon lumineux courant...                                                       */

                                        EGAL(niveau_lumineux,MAX_NIVEAU_LUMINEUX);
                                        /* A priori, on choisit le maximum...                                                        */

                                        EGAL(niveau_lumineux
                                            ,MUL2(HOMO(PUIX(DIVI(prdF3D(normale,rayon_lumineux)
                                                                ,RACX(MUL2(pytF3D(normale)
                                                                          ,pytF3D(rayon_lumineux)
                                                                           )
                                                                      )
                                                                 )
                                                           ,Imontagnes_en_perspective_precises_____source_lumineuse_specularite
                                                            )
                                                      ,COSINUS_DE_PI
                                                      ,COSINUS_DE_0
                                                      ,minimum_normalise_du_cosinus_d_une_normale
                                                      ,maximum_normalise_du_cosinus_d_une_normale
                                                       )
                                                 ,niveau_lumineux
                                                  )
                                             );
                                        /* Prise en compte de l'eclairage par la source lumineuse.                                   */
                                        /*                                                                                           */
                                        /* La specularite a ete introduite le 20130101105228...                                      */

                                        Test(IL_FAUT(depth_cueing))
                                             Bblock
                                             EGAL(y_reduit,__DENORMALISE_NIVEAU(_____cNORMALISE_OY(COYA(Y_P))));
                                        /* Ainsi, on convertit la coordonnee 'Y' en un niveau ; mais ATTENTION, la coordonnee 'Y'    */
                                        /* utilisee pour le "depth-cueing" n'est pas correcte, puisqu'en effet, la valeur ainsi      */
                                        /* obtenue est toujours la meme, quelle que soit la position de l'observateur par rapport    */
                                        /* a l'image...                                                                              */
                                             EGAL(y_reduit,______NORMALISE_NIVEAU(NIVA(MAX2(y_reduit,MIN_INTENSITE))));
                                        /* En effet, on ne peut tracer en noir...                                                    */
                                             EGAL(niveau_lumineux
                                                 ,MAX2(NIVA(MUL2(BARY(y_reduit
                                                                     ,______NORMALISE_NIVEAU(MAX_NIVEAU_LUMINEUX)
                                                                     ,min_depth_cueing
                                                                      )
                                                                ,NIVR(niveau_lumineux)
                                                                 )
                                                            )
                                                      ,MIN_INTENSITE
                                                       )
                                                  );
                                             Eblock
                                        ATes
                                             Bblock
                                             Eblock
                                        ETes

                                        EGAL(niveau_lumineux
                                            ,SCAL(niveau_lumineux
                                                 ,MAX_NIVEAU_LUMINEUX
                                                 ,LRZ4(ponderation_BG,texture_courante(X_G,Y_B)
                                                      ,ponderation_BD,texture_courante(X_D,Y_B)
                                                      ,ponderation_HD,texture_courante(X_D,Y_H)
                                                      ,ponderation_HG,texture_courante(X_G,Y_H)
                                                       )
                                                  )
                                             );
                                        /* Et on applique la texture donnee par "champ_de_texture".                                  */

                                        Test(INCLff(niveau_lumineux,FLOT__NOIR,FLOT__BLANC))
                                        /* ATTENTION : le test precedent :                                                           */
                                        /*                                                                                           */
                                        /*                  Test(INCLff(niveau,NOIR,BLANC))                                          */
                                        /*                                                                                           */
                                        /* implique l'evaluation des expressions 'MINI(NOIR,BLANC)' et 'MAXI(NOIR,BLANC)', et alors  */
                                        /* le compilateur de 'SYSTEME_ES9000_AIX_CC' sort le message de warning suivant :            */
                                        /*                                                                                           */
                                        /*                  w "..."....:      Unsigned compare with zero always true.                */
                                        /*                                                                                           */
                                        /* ce qui est intolerable. Plutot que de passer de 'INCLff(...)' a 'IFINff(...)', et parce   */
                                        /* qu'il est des cas ou je n'ai pu faire disparaitre ce message, j'ai introduit dans         */
                                        /* 'v $xcc/cb$Z' le fichier '$xcc/cb$D/sup.Mwarning$sed' qui elimine ces messages...         */
                                             Bblock
                                             store_point_3D(GENP(NIVA(niveau_lumineux))
                                                           ,imageR
                                                           ,X,Y,ASD1(point_courant_ligne_de_visee,z)
                                                            );
                                        /* ATTENTION : a la permutation des axes 'OY' et 'OZ'...                                     */
                                             Eblock
                                        ATes
                                             Bblock
                                             PRINT_ERREUR("le niveau du point courant est hors [NOIR,BLANC]");
                                             Eblock
                                        ETes
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                   Test(EST_FAUX(on_a_trouve_un_point_double))
                                        Bblock
                                        PRINT_ERREUR("moins de deux points d'intersection ont ete trouve");

                                        CAL1(Prer2("(X,Y)........................=(%d,%d)\n",X,Y));

                                        CAL1(Prer1("X_pour_Zmin..................=%+.17f\n",X_pour_Zmin));
                                        CAL1(Prer1("X_pour_Zmax..................=%+.17f\n",X_pour_Zmax));
                                        CAL1(Prer1("Z_pour_Xmin..................=%+.17f\n",Z_pour_Xmin));
                                        CAL1(Prer1("Z_pour_Xmax..................=%+.17f\n",Z_pour_Xmax));

                                        CAL1(Prer1("Xmin.........................=%+.17f\n",_____cNORMALISE_OX(Xmin)));
                                        CAL1(Prer1("Xmax.........................=%+.17f\n",_____cNORMALISE_OX(Xmax)));
                                        CAL1(Prer1("Ymin.........................=%+.17f\n",_____cNORMALISE_OZ(Y_to_Z(Ymin))));
                                        CAL1(Prer1("Ymax.........................=%+.17f\n",_____cNORMALISE_OZ(Y_to_Z(Ymax))));
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes
                                   Eblock
                              ETes
                              Eblock
                         ETes
                         Eblock
                    ATes
                         Bblock
                         PRINT_ERREUR("l'observateur tourne surement le dos a l'image a visualiser");
                         Eblock
                    ETes
                    Eblock
               ETes
               Eblock
          ATes
               Bblock
               PRINT_ERREUR("l'observateur est mal place par rapport au plan de l'ecran");
               Eblock
          ETes
          Eblock
     end_image

     EDEFV(image,champ_de_texture);
                                        /* Et il en est de meme pour la texture...                                                   */

#ifdef    TYPE_DE_imageA_surface_VERSION_01
     EDEFV(image,champ_de_cotes);
                                        /* Cette image definie le champ de cote de la surface ; elle est obtenue par une             */
                                        /* symetrie d'axe 'OX' de l'image 'imageA_surface'. En effet, cette derniere est             */
                                        /* couchee dans le plan horizontal (OX,OZ), or l'axe 'OZ' vient vers l'observateur,          */
                                        /* ce qui fait que, par exemple, l'ancien 'Ymax' se trouve devant l'ancien 'Ymin', une       */
                                        /* fois sur le plan horizontal...                                                            */
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     EDEFV(imageF,champ_de_cotes);
                                        /* Cette image definie le champ de cote de la surface ; elle est obtenue par une             */
                                        /* symetrie d'axe 'OX' de l'image 'imageA_surface'. En effet, cette derniere est             */
                                        /* couchee dans le plan horizontal (OX,OZ), or l'axe 'OZ' vient vers l'observateur,          */
                                        /* ce qui fait que, par exemple, l'ancien 'Ymax' se trouve devant l'ancien 'Ymin', une       */
                                        /* fois sur le plan horizontal...                                                            */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

     RETI(imageR);
     Eblock

EFonctionP

#undef    texture_courante

#ifdef    TYPE_DE_imageA_surface_VERSION_01
#    undef     cote_courante
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
#    undef     cote_courante
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

#undef    CALCUL_DES_DEUX_INTERSECTIONS
#undef    IFEQ_a_peu_pres_sur_OY
#undef    IFEQ_a_peu_pres_sur_OX

#undef    Y_to_Z
#undef    Z_to_Y

#undef    MAX_NIVEAU_LUMINEUX
#undef    MIN_INTENSITE
#undef    CLIPPING_INTENSITE

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M I S E   E N   P E R S P E C T I V E   M O N T A G N E U S E   D ' U N E   I M A G E   " S T A N D A R D "  :             */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

BFonctionP

                                        /* ATTENTION, on introduit deux fonctions 'Imontagnes_en_perspective(...)' et                */
                                        /* 'Imontagnes_en_perspective_precises(...)' qui sont de toute evidence inutiles en          */
                                        /* 'TYPE_DE_imageA_surface_VERSION_01' mais dont la presence permet de simplifier            */
                                        /* considerablement la coexistence des deux versions...                                      */

#ifdef    TYPE_DE_imageA_surface_VERSION_02
                                        /* ATTENTION, les deux definitions qui suivent sont faites independamment pour les deux      */
                                        /* fonctions 'Imontagnes(...)' et 'Imontagnes_en_perspective(...)' afin qu'elles puissent    */
                                        /* prendre alors des valeurs differentes, ce qui n'est pas le cas actuellement...            */

#    define    NIVEAU_PRECIS_MINIMAL                                                                                                    \
                         ______________NOIR_NORMALISE
#    define    NIVEAU_PRECIS_MAXIMAL                                                                                                    \
                         ______________BLANC_NORMALISE
                                        /* Niveaux minimal et maximal dans 'imageA_surface_flottante'.                               */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

DEFV(Common,DEFV(FonctionP,POINTERp(Imontagnes_en_perspective(imageR
                                                             ,facteur_d_echelle,imageA_surface
                                                             ,imageA_texture
                                                             ,ARGUMENT_POINTERs(translation)
                                                             ,ARGUMENT_POINTERs(position_du_touriste_observateur)
                                                             ,ombres_portees
                                                             ,ARGUMENT_POINTERs(source_lumineuse)
                                                             ,depth_cueing,min_depth_cueing
                                                              )
                                    )
                 )
     )
DEFV(Argument,DEFV(image,imageR));
                                        /* Image Resultat, qui est une vue texturee de la surface.                                   */
DEFV(Argument,DEFV(Float,facteur_d_echelle));
                                        /* Facteur d'echelle permettant de moduler le champ contenu dans 'imageA_surface',           */
                                        /* et par exemple de l'inverser...                                                           */
DEFV(Argument,DEFV(image,imageA_surface));
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface,                 */
DEFV(Argument,DEFV(image,imageA_texture));
                                        /* Deuxieme image Argument, qui donne la texture de la surface.                              */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation)));
                                        /* Translation de l'ecran (c'est-a-dire du support de 'imageR') dans l'espace                */
                                        /* tridimensionnel ; on n'oubliera pas que cette translation est exprimee dans               */
                                        /* des unites telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax]...           */
DEFV(Argument,DEFV(pointF_3D,POINTERs(position_du_touriste_observateur)));
                                        /* Definition de la position de l'observateur.                                               */
                                        /*                                                                                           */
                                        /* 'position_de_l_observateur' fut remplace par 'position_du_touriste_observateur' le        */
                                        /* 20061113115240 pour prepaper l'execution de 'v $xau/LACT16.82$Z' qui fait la modification */
                                        /* 'v $xau/LACT16.61.modifier$sed position_de_l_observateur' et eviter ainsi une grosse      */
                                        /* ambiguite...                                                                              */
DEFV(Argument,DEFV(Logical,ombres_portees));
                                        /* Les ombres portees doivent-elles etre presentes ('VRAI') ou non ('FAUX').                 */
DEFV(Argument,DEFV(pointF_3D,POINTERs(source_lumineuse)));
                                        /* Donne dans le plan de l'image Resultat ('imageR'), les coordonnees de                     */
                                        /* la source lumineuse ; ces coordonnees sont exprimees dans des unites                      */
                                        /* telles que l'unite vaut respectivement [Xmin,Xmax] et [Ymin,Ymax].                        */
DEFV(Argument,DEFV(Logical,depth_cueing));
                                        /* Doit-on faire ('VRAI') ou pas ('FAUX') du depth-cueing ?                                  */
                                        /* mais ATTENTION, cette option n'est effective que si les                                   */
                                        /* ombres portees ont ete demandees !!!                                                      */
DEFV(Argument,DEFV(Float,min_depth_cueing));
                                        /* Ce parametre est inclus dans le segment [0,1] ; plus il est                               */
                                        /* proche de zero, plus, le "depth-cueing" est fort...                                       */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     BDEFV(imageF,imageA_surface_flottante);
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface convertie en     */
                                        /* 'Float'...                                                                                */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

     /*..............................................................................................................................*/

#ifdef    TYPE_DE_imageA_surface_VERSION_01
     CALS(Imontagnes_en_perspective_precises(imageR
                                            ,facteur_d_echelle,imageA_surface
                                            ,imageA_texture
                                            ,ARGUMENT_POINTERs(translation)
                                            ,ARGUMENT_POINTERs(position_du_touriste_observateur)
                                            ,ombres_portees
                                            ,ARGUMENT_POINTERs(source_lumineuse)
                                            ,depth_cueing,min_depth_cueing
                                             )
          );
                                        /* Generation de la surface montagneuse...                                                   */
#Aifdef   TYPE_DE_imageA_surface_VERSION_01
#Eifdef   TYPE_DE_imageA_surface_VERSION_01

#ifdef    TYPE_DE_imageA_surface_VERSION_02
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     CALS(Istd_float(imageA_surface_flottante,NIVEAU_PRECIS_MINIMAL,NIVEAU_PRECIS_MAXIMAL,imageA_surface));
                                        /* Conversion flottante preliminaire...                                                      */
     CALS(Imontagnes_en_perspective_precises(imageR
                                            ,facteur_d_echelle,imageA_surface_flottante
                                            ,imageA_texture
                                            ,ARGUMENT_POINTERs(translation)
                                            ,ARGUMENT_POINTERs(position_du_touriste_observateur)
                                            ,ombres_portees
                                            ,ARGUMENT_POINTERs(source_lumineuse)
                                            ,depth_cueing,min_depth_cueing
                                             )
          );
                                        /* Generation de la surface montagneuse...                                                   */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

#ifdef    TYPE_DE_imageA_surface_VERSION_02
     EDEFV(imageF,imageA_surface_flottante);
                                        /* Premiere image Argument, qui donne la troisieme coordonnee de la surface convertie en     */
                                        /* 'Float'...                                                                                */
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

     RETI(imageR);
     Eblock

#ifdef    TYPE_DE_imageA_surface_VERSION_02
                                        /* ATTENTION, les deux dedefinitions qui suivent sont faites independamment pour les deux    */
                                        /* fonctions 'Imontagnes(...)' et 'Imontagnes_en_perspective(...)' afin qu'elles puissent    */
                                        /* prendre alors des valeurs differentes, ce qui n'est pas le cas actuellement...            */

#    undef     NIVEAU_PRECIS_MAXIMAL
#    undef     NIVEAU_PRECIS_MINIMAL
#Aifdef   TYPE_DE_imageA_surface_VERSION_02
#Eifdef   TYPE_DE_imageA_surface_VERSION_02

EFonctionP

_______________________________________________________________________________________________________________________________________



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.