/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E N E R A T I O N   D E S   S E R P E N T S   R E L A T I V E M E N T   R E C T I L I G N E S                            */
/*        A V E C   T E N T A T I V E   D ' E V I T E M E N T   D ' I N T E R - C O L L I S I O N S  :                               */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                      :            oo           oooo                             :                                                 */
/*                     :                                  oo    +              ...                                                   */
/*                    o   oo       o                        +++ oo    ++   ::  ...                                                   */
/*                     o     oo                  ...........    +    ++  +    ..                                                     */
/*                      o   :   oo  ::     ........ +  oo ........   o    +++..                                                      */
/*                        o:       o   .....    ++      :::    + ...o.     o...++++                                                  */
/*                         o         .o.  --......::    ++++oo o  o ....   ...                                                       */
/*                        :  o     ...  o  ..:   ..++     o    +oo     ......     o                                                  */
/*                        :    o ...  ::::.o    ++      o     +oo        ...  o                                                      */
/*                        :     o.:::    ..  oo       o       ooo      ...oo.                                                        */
/*                        :  ::..:o     ...+    o   o       o++ o     .o. + ...                                                      */
/*                    :::::   ..    o   ..        o+       o+o     oo..  +   ...                                                     */
/*                         : ..      +o..        +   o    o+ o ooo ...        ...                                                    */
/*                         :..     +    o       +      o o+  o o ...    +      ..                                                    */
/*                         ...  +       +oo    +        ooo   o ...    +       ...                                                   */
/*                        ... +          + o +         oo  oo ...     +         ..                                                   */
/*                        ..-               +o     oo +     o.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    oo                                                                       */
/*                       ..        -           +...           oo             :                                                       */
/*                       ..         - ..     ....               oo           :                                                       */
/*                       ..          -..   ....                   o          :                                                       */
/*                        ..         .-..... +                        :    --                                                        */
/*                         .....  ......     +                            -                                                          */
/*                            ......   o-   +                                                                                        */
/*                                       ooo                                                                                         */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xrk/serpents.03$K' :                                                                                           */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 1989??????????).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        I N T E R F A C E   ' listG '  :                                                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        :Debut_listG:                                                                                                              */
/*        :Fin_listG:                                                                                                                */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D I R E C T I V E S   S P E C I F I Q U E S   D E   C O M P I L A T I O N  :                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F I C H I E R S   D ' I N C L U D E S  :                                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#include  INCLUDES_BASE
#include  maths_fonct_COURBES_1_EXT

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        P A R A M E T R E S  :                                                                                                     */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   GRAINE    1789                                                                                                                \
                                        /* Graine initiale du generateur aleatoire (Vive le gland Plesident Mityrand... Mais         */ \
                                        /* pourquoi dis-je cela : est-ce a cause de la revolution, ou a cause de l'aleatoire ?).     */
#define   PAS_DE_LA_GRAINE                                                                                                              \
                    ZERO                                                                                                                \
                                        /* Afin de faire evoluer eventuellement  (s'il est different de 0) la GRAINE...              */

#define   XB_min    SOUS(Xmin,FRA4(dimX))                                                                                               \
                                        /* Pour definir l'espace tri-dimensionnel dans lequel doivent rester les points aleatoires.  */
#define   XB_max    ADD2(Xmax,FRA4(dimX))                                                                                               \
                                        /* Pour definir l'espace tri-dimensionnel dans lequel doivent rester les points aleatoires.  */
#define   YB_min    SOUS(Ymin,FRA4(dimY))                                                                                               \
                                        /* Pour definir l'espace tri-dimensionnel dans lequel doivent rester les points aleatoires.  */
#define   YB_max    ADD2(Ymax,FRA4(dimY))                                                                                               \
                                        /* Pour definir l'espace tri-dimensionnel dans lequel doivent rester les points aleatoires.  */
#define   FACTEUR_D_HOMOTHETIE_Z                                                                                                        \
                    DIVI(MdimXY,COULEURS)                                                                                               \
                                        /* Pour passer de l'axe des 'Z' aux couleurs du depth-cueing...                              */
#define   ZB_min    COZA(MUL2(FACTEUR_D_HOMOTHETIE_Z,NIVR(NIVEAU_ORIGINE)))                                                             \
                                        /* Pour definir l'espace tri-dimensionnel dans lequel doivent rester les points aleatoires.  */
#define   ZB_max    COZA(MUL2(FACTEUR_D_HOMOTHETIE_Z,NIVR(NIVEAU_EXTREMITE)))                                                           \
                                        /* Pour definir l'espace tri-dimensionnel dans lequel doivent rester les points aleatoires.  */

#define   NOMBRE_DE_TENTATIVES_SUR_UN_POINT                                                                                             \
                    DOUB(SEIZE)                                                                                                         \
                                        /* Nombre maximal de tentatives de generation d'un point aleatoire lorsqu'on                 */ \
                                        /* detecte des "recouvrements"...                                                            */
#define   NOMBRE_DE_TENTATIVES_SUR_UN_ARC                                                                                               \
                    SEIZE                                                                                                               \
                                        /* Nombre maximal de tentatives de generation d'un arc lorsqu'on detecte des                 */ \
                                        /* pseudo-collisions...                                                                      */
#define   NIVEAU_DE_MASQUAGE_DE_L_ARC_PRECEDENT                                                                                         \
                    BLANC                                                                                                               \
                                        /* Niveau destine a exclure par masquage l'arc genere precedemment...                        */
#define   TAUX_DE_REGRESSION                                                                                                            \
                    PARE(0.95)                                                                                                          \
                                        /* Donne la "vitesse" de retour de 'P3' vers 'P1' en cas de collisions...                    */

#define   PAS_DE_PARCOURS_DE_LA_SPIRALE                                                                                                 \
                    SUCC(SEIZE)                                                                                                         \
                                        /* On parcours la spirale en sautant des points...                                           */

#define   SPHERE_X  FRA2(dimX)                                                                                                          \
                                        /* Pour definir la distance maximale (P1,P2).                                                */
#define   SPHERE_Y  FRA2(dimY)                                                                                                          \
                                        /* Pour definir la distance maximale (P1,P2).                                                */
#define   SPHERE_Z  FRA2(MUL2(FACTEUR_D_HOMOTHETIE_Z,COULEURS))                                                                         \
                                        /* Pour definir la distance maximale (P1,P2).                                                */

#define   M_DELTA_X FRA2(SPHERE_X)                                                                                                      \
                                        /* "Ouverture" arriere du cone de generation des points aleatoires 'P3' et 'P4' ; plus       */ \
                                        /* cette valeur est proche de 0 (apres '_____lNORMALISE_OX'), moins le retour en arriere     */ \
                                        /* est possible...                                                                           */
#define   M_DELTA_Y FRA2(SPHERE_Y)                                                                                                      \
                                        /* "Ouverture" arriere du cone de generation des points aleatoires 'P3' et 'P4' ; plus       */ \
                                        /* cette valeur est proche de 0 (apres '_____lNORMALISE_OY'), moins le retour en arriere     */ \
                                        /* est possible...                                                                           */
#define   M_DELTA_Z FRA2(SPHERE_Z)                                                                                                      \
                                        /* "Ouverture" arriere du cone de generation des points aleatoires 'P3' et 'P4' ; plus       */ \
                                        /* cette valeur est proche de 0 (apres '_____lNORMALISE_OZ'), moins le retour en arriere     */ \
                                        /* est possible...                                                                           */
#define   P_DELTA_X FZERO                                                                                                               \
                                        /* "Ouverture" avant du cone de generation des points aleatoires 'P3' et 'P4' ; plus         */ \
                                        /* cette valeur est proche de 1 (apres '_____lNORMALISE_OX'), plus l'eloignement en avant    */ \
                                        /* est rapide...                                                                             */
#define   P_DELTA_Y FZERO                                                                                                               \
                                        /* "Ouverture" avant du cone de generation des points aleatoires 'P3' et 'P4' ; plus         */ \
                                        /* cette valeur est proche de 1 (apres '_____lNORMALISE_OY'), plus l'eloignement en avant    */ \
                                        /* est rapide...                                                                             */
#define   P_DELTA_Z FZERO                                                                                                               \
                                        /* "Ouverture" avant du cone de generation des points aleatoires 'P3' et 'P4' ; plus         */ \
                                        /* cette valeur est proche de 1 (apres '_____lNORMALISE_OZ'), plus l'eloignement en avant    */ \
                                        /* est rapide...                                                                             */

#define   NIVEAU_ORIGINE                                                                                                                \
                    NOIR_PLANCHER_1                                                                                                     \
                                        /* Niveau origine du trace (correspond grossierement au 'Z' ; je dit  "grossierement" car    */ \
                                        /* en effet pour les niveaux, l'interpolation est lineaire et non pas cubique puisqu'on      */ \
                                        /* ne connait pas les derivees).                                                             */
#define   NIVEAU_EXTREMITE                                                                                                              \
                    BLANC                                                                                                               \
                                        /* Niveau origine du trace (correspond grossierement au 'Z' ; je dit  "grossierement" car    */ \
                                        /* en effet pour les niveaux, l'interpolation est lineaire et non pas cubique puisqu'on      */ \
                                        /* ne connait pas les derivees).                                                             */
#define   AFFAIBLISSEMENT_AU_BORD                                                                                                       \
                    QUAR(FDU)                                                                                                           \
                                        /* Afin de faire un degrade du centre vers le bord...                                        */

#define   NOMBRE_D_ARCS_F1                                                                                                              \
                    DOUB(QUATRE)                                                                                                        \
                                        /* Nombre d'arcs pour la famille 'F1'.                                                       */
#define   NOMBRE_DE_POINTS_F1                                                                                                           \
                    SEIZE                                                                                                               \
                                        /* Nombre de points definissant le multi-arc de cubique (il y a un arc de moins que          */ \
                                        /* de points) de la famille 'F1'.                                                            */
#define   RAYON_DU_POINT_F1                                                                                                             \
                    DOUZE                                                                                                               \
                                        /* Rayon du point representatif de la famille 'F1'.                                          */
#define   COULEURS_F1                                                                                                                   \
                    L_SUBSTITUTION_11                                                                                                   \
                                        /* Liste de substitution de trace de la famille 'F1'.                                        */

#define   NOMBRE_D_ARCS_F2                                                                                                              \
                    NEUT(NOMBRE_D_ARCS_F1)                                                                                              \
                                        /* Nombre d'arcs pour la famille 'F2'.                                                       */
#define   NOMBRE_DE_POINTS_F2                                                                                                           \
                    NOMBRE_DE_POINTS_F1                                                                                                 \
                                        /* Nombre de points definissant le multi-arc de cubique (il y a un arc de moins que          */ \
                                        /* de points) de la famille 'F2'.                                                            */
#define   RAYON_DU_POINT_F2                                                                                                             \
                    TIER(RAYON_DU_POINT_F1)                                                                                             \
                                        /* Rayon du point representatif de la famille 'F2'.                                          */
#define   COULEURS_F2                                                                                                                   \
                    L_SUBSTITUTION_12                                                                                                   \
                                        /* Liste de substitution de trace de la famille 'F2'.                                        */

#define   NOMBRE_D_ARCS_F3                                                                                                              \
                    DOUB(NOMBRE_D_ARCS_F1)                                                                                              \
                                        /* Nombre d'arcs pour la famille 'F3'.                                                       */
#define   NOMBRE_DE_POINTS_F3                                                                                                           \
                    NOMBRE_DE_POINTS_F1                                                                                                 \
                                        /* Nombre de points definissant le multi-arc de cubique (il y a un arc de moins que          */ \
                                        /* de points) de la famille 'F3'.                                                            */
#define   RAYON_DU_POINT_F3                                                                                                             \
                    TIER(RAYON_DU_POINT_F1)                                                                                             \
                                        /* Rayon du point representatif de la famille 'F3'.                                          */
#define   COULEURS_F3                                                                                                                   \
                    L_SUBSTITUTION_13                                                                                                   \
                                        /* Liste de substitution de trace de la famille 'F3'.                                        */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M A C R O S   U T I L E S  :                                                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   EVITEMENT(rayon)                                                                                                              \
                    GRO1(rayon)                                                                                                         \
                                        /* Pour faire que les serpents s'evitent, on fait une premiere passe avec un rayon           */ \
                                        /* augmente dans les proportions indiquees ici (en fait 'GRO3' est plus physique...).        */
#define   SEUIL_AVANT(rayon)                                                                                                            \
                    EVITEMENT(CHOI(_____lNORMALISE_OX(rayon)                                                                            \
                                  ,_____lNORMALISE_OY(rayon)                                                                            \
                                   )                                                                                                    \
                              )                                                                                                         \
                                        /* Afin de simuler l'evitement des serpents...                                               */
#define   SEUIL_ARRIERE(rayon)                                                                                                          \
                    EVITEMENT(CHOI(_____lNORMALISE_OX(rayon)                                                                            \
                                  ,_____lNORMALISE_OY(rayon)                                                                            \
                                   )                                                                                                    \
                              )                                                                                                         \
                                        /* Afin de simuler l'evitement des serpents...                                               */
#define   GENERE_COORDONNEE_ALEATOIRE(coordonnee,borne_inferieure,borne_superieure,_____cNORMALISE_OXYZ,V_min,V_max)                    \
                    Bblock                                                                                                              \
                    DEFV(Float,INIT(inferieur,borne_inferieure));                                                                       \
                    DEFV(Float,INIT(superieur,borne_superieure));                                                                       \
                    DEFV(Float,INIT(amplitude,FLOT__UNDEF));                                                                            \
                                        /* Ces variables intermediaires sont uniquement creees afin d'accelerer la compilation...    */ \
                    EGAL(amplitude,TRMU(LENG(inferieur,superieur)));                                                                    \
                                        /* Le 'LENG' n'est pas fait dans 'INIT' afin d'accelerer la compilation ; d'autre part,      */ \
                                        /* le 'TRMU' est la afin que 'amplitude' soit nul, si 'inferieur' et 'superieur' sont egaux. */ \
                    EGAL(inferieur,TRON(inferieur,V_min,V_max));                                                                        \
                    EGAL(superieur,TRON(superieur,V_min,V_max));                                                                        \
                                        /* Le 'TRON' n'est pas fait dans 'INIT' afin d'accelerer la compilation...                   */ \
                    Test(IFLT(V_min,V_max))                                                                                             \
                         Bblock                                                                                                         \
                         Test(IFET(IFEQ(inferieur,V_min),IFEQ(superieur,V_min)))                                                        \
                              Bblock                                                                                                    \
                              EGAL(inferieur,V_min);                                                                                    \
                              EGAL(superieur,ADD2(V_min,amplitude));                                                                    \
                                        /* Reinitialisation arbitraire lorsque les deux bornes sont egales...                        */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Test(IFET(IFEQ(inferieur,V_max),IFEQ(superieur,V_max)))                                                        \
                              Bblock                                                                                                    \
                              EGAL(inferieur,SOUS(V_max,amplitude));                                                                    \
                              EGAL(superieur,V_max);                                                                                    \
                                        /* Reinitialisation arbitraire lorsque les deux bornes sont egales...                        */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Test(IL_NE_FAUT_PAS(couper_l_arc_courant))                                                                          \
                         Bblock                                                                                                         \
                         CALS(rdnI2D(ADRESSE(pointI_spirale)                                                                            \
                                    ,UNDEF                                                                                              \
                                    ,RDN_INIT                                                                                           \
                                    ,inferieur                                                                                          \
                                    ,superieur                                                                                          \
                                     )                                                                                                  \
                              );                                                                                                        \
                                        /* Initialisation du generateur aleatoire.                                                   */ \
                         EGAL(coordonnee                                                                                                \
                             ,_____cNORMALISE_OXYZ(INTE(rdnI2D(ADRESSE(pointI_spirale)                                                  \
                                                              ,graine_courante                                                          \
                                                              ,RDN_GENERE                                                               \
                                                              ,FLOT__ARGUMENT_ABSENT,FLOT__ARGUMENT_ABSENT                              \
                                                               )                                                                        \
                                                        )                                                                               \
                                                   )                                                                                    \
                              );                                                                                                        \
                         Repe(PAS_DE_PARCOURS_DE_LA_SPIRALE)                                                                            \
                              Bblock                                                                                                    \
                              SPIRALE_INITIALISATION;                                                                                   \
                                        /* Initialisation dynamique de 'spirale_nombre_de_points_a_traiter'.                         */ \
                              SPIRALE_DEPLACEMENT(ASD1(pointI_spirale,x),ASD1(pointI_spirale,y));                                       \
                                        /* Deplacement du point courant de la spirale...                                             */ \
                              SPIRALE_PARCOURS;                                                                                         \
                                        /* Parcours de la spirale avec rotation eventuelle de PI/2 du bras courant...                */ \
                              INCR(graine_courante,pas_de_la_graine);                                                                   \
                                        /* Et enfin, modification eventuelle de la graine du generateur aleatoire...                 */ \
                              Eblock                                                                                                    \
                         ERep                                                                                                           \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Generation d'une coordonnee aleatoire avec restriction a la boite [V_min,V_max].          */
#define   GENERE_POINT_ALEATOIRE(point,X_min,X_max,Y_min,Y_max,Z_min,Z_max,VX_min,VX_max,VY_min,VY_max,VZ_min,VZ_max)                   \
                    Bblock                                                                                                              \
                    DEFV(Logical,INIT(generer_un_point,VRAI));                                                                          \
                                        /* Indique s'il faut ou pas generer un point (on en genere au moins un, le premier).         */ \
                    DEFV(Positive,INIT(nombre_de_tentatives_sur_un_point,NOMBRE_DE_TENTATIVES_SUR_UN_POINT));                           \
                                        /* Donne le nombre de tentatives restant a faire pour generer un point aleatoire             */ \
                                        /* lorsqu'il y a "recouvrement"...                                                           */ \
                    Tant(IFET(IL_FAUT(generer_un_point),IZGT(nombre_de_tentatives_sur_un_point)))                                       \
                         Bblock                                                                                                         \
                         GENERE_COORDONNEE_ALEATOIRE(ASD1(point,x),X_min,X_max,_____cNORMALISE_OX,VX_min,VX_max);                       \
                         GENERE_COORDONNEE_ALEATOIRE(ASD1(point,y),Y_min,Y_max,_____cNORMALISE_OY,VY_min,VY_max);                       \
                         GENERE_COORDONNEE_ALEATOIRE(ASD1(point,z),Z_min,Z_max,_____cNORMALISE_OZ,VZ_min,VZ_max);                       \
                         Test(IFEQ(load_point_valide(ImageR                                                                             \
                                                    ,INTE(COXA(PROJECTION_OX(COXR(_cDENORMALISE_OX(ASD1(point,x)))                      \
                                                                            ,COYR(_cDENORMALISE_OY(ASD1(point,y)))                      \
                                                                            ,COZR(_cDENORMALISE_OZ(ASD1(point,z)))                      \
                                                                             )                                                          \
                                                               )                                                                        \
                                                          )                                                                             \
                                                    ,INTE(COYA(PROJECTION_OY(COXR(_cDENORMALISE_OX(ASD1(point,x)))                      \
                                                                            ,COYR(_cDENORMALISE_OY(ASD1(point,y)))                      \
                                                                            ,COZR(_cDENORMALISE_OZ(ASD1(point,z)))                      \
                                                                             )                                                          \
                                                               )                                                                        \
                                                          )                                                                             \
                                                     )                                                                                  \
                                  ,NOIR                                                                                                 \
                                   )                                                                                                    \
                              )                                                                                                         \
                              Bblock                                                                                                    \
                              EGAL(generer_un_point,FAUX);                                                                              \
                                        /* Si le point aleatoire genere tombe dans le "vide", on le prend ; sinon, on le refuse      */ \
                                        /* et on en genere un autre, et ce afin d'eviter des problemes de detection de collisions :  */ \
                                        /* en effet, si le point (dit "de controle") d'un arc tombe sur un point deja occupe apres   */ \
                                        /* projection, etant donne qu'on masque les extremites des arcs afin de ne pas trouver       */ \
                                        /* de fausses collisions, les points de l'arc anterieur seront eux-aussi masques, et il      */ \
                                        /* n'y aura pas de collisions detectees...                                                   */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              DECR(nombre_de_tentatives_sur_un_point,I);                                                                \
                                        /* Malgre tout, on empeche les bouclages a l'infini...                                       */ \
                              Test(IZEQ(nombre_de_tentatives_sur_un_point))                                                             \
                                   Bblock                                                                                               \
                                   EGAL(couper_l_arc_courant,VRAI);                                                                     \
                                        /* On a fait trop de tentatives : on arrete la...                                            */ \
                                   Eblock                                                                                               \
                              ATes                                                                                                      \
                                   Bblock                                                                                               \
                                   Eblock                                                                                               \
                              ETes                                                                                                      \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ETan                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Generation d'un point aleatoire avec restriction a la boite [VXYZ_min,VXYZ_max].          */
#define   GENERE_VECTEUR_ALEATOIRE(origine,extremite)                                                                                   \
                    Bblock                                                                                                              \
                    Test(IL_NE_FAUT_PAS(couper_l_arc_courant))                                                                          \
                         Bblock                                                                                                         \
                         DEFV(deltaI_3D,vecteur_aleatoire_courant);                                                                     \
                                        /* Donne en permanence le vecteur aleatoire de type (P1,P2) ou (P2,P3).                      */ \
                         INITIALISATION_ACCROISSEMENT_3D(vecteur_aleatoire_courant                                                      \
                                                        ,SOUS(_cDENORMALISE_OX(ASD1(extremite,x)),_cDENORMALISE_OX(ASD1(origine,x)))    \
                                                        ,SOUS(_cDENORMALISE_OY(ASD1(extremite,y)),_cDENORMALISE_OY(ASD1(origine,y)))    \
                                                        ,SOUS(_cDENORMALISE_OZ(ASD1(extremite,z)),_cDENORMALISE_OZ(ASD1(origine,z)))    \
                                                         );                                                                             \
                         EGAL(rayon_courant,RACX(FLOT(pytI3D(vecteur_aleatoire_courant))));                                             \
                         Test(IZEQ(rayon_courant))                                                                                      \
                              Bblock                                                                                                    \
                              PRINT_ERREUR("le rayon courant est nul, il va y avoir des divisions par 0");                              \
                              EGAL(rayon_courant,FU);                                                                                   \
                                        /* Pour les eviter malgre tout...                                                            */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         EGAL(rayon_courant,FU);                                                                                        \
                                        /* Pour eviter d'ulterieures divisions par 0...                                              */ \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Calcul du vecteur aleatoire (P1,P2) ou (P2,P3), et son module.                            */
#define   SET_P1(X0,Y0,Z0)                                                                                                              \
                    Bblock                                                                                                              \
                    INITIALISATION_POINT_3D(pointF_P1,_____cNORMALISE_OX(X0),_____cNORMALISE_OY(Y0),_____cNORMALISE_OZ(Z0));            \
                    Eblock                                                                                                              \
                                        /* Definition du point P1.                                                                   */
#define   SET_P2(X0,Y0,Z0)                                                                                                              \
                    Bblock                                                                                                              \
                    INITIALISATION_POINT_3D(pointF_P2,_____cNORMALISE_OX(X0),_____cNORMALISE_OY(Y0),_____cNORMALISE_OZ(Z0));            \
                    Eblock                                                                                                              \
                                        /* Definition du point P2.                                                                   */
#define   SET_P3(X0,Y0,Z0)                                                                                                              \
                    Bblock                                                                                                              \
                    INITIALISATION_POINT_3D(pointF_P3,_____cNORMALISE_OX(X0),_____cNORMALISE_OY(Y0),_____cNORMALISE_OZ(Z0))             \
                    Eblock                                                                                                              \
                                        /* Definition du point P3.                                                                   */
#define   SET_P4(X0,Y0,Z0)                                                                                                              \
                    Bblock                                                                                                              \
                    INITIALISATION_POINT_3D(pointF_P4,_____cNORMALISE_OX(X0),_____cNORMALISE_OY(Y0),_____cNORMALISE_OZ(Z0));            \
                    Eblock                                                                                                              \
                                        /* Definition du point P4.                                                                   */
#define   MOVE_POINTS                                                                                                                   \
                    Bblock                                                                                                              \
                    SET_P1(_cDENORMALISE_OX(ASD1(pointF_P2,x))                                                                          \
                          ,_cDENORMALISE_OY(ASD1(pointF_P2,y))                                                                          \
                          ,_cDENORMALISE_OZ(ASD1(pointF_P2,z))                                                                          \
                           );                                                                                                           \
                    SET_P2(_cDENORMALISE_OX(ASD1(pointF_P3,x))                                                                          \
                          ,_cDENORMALISE_OY(ASD1(pointF_P3,y))                                                                          \
                          ,_cDENORMALISE_OZ(ASD1(pointF_P3,z))                                                                          \
                           );                                                                                                           \
                    SET_P3(_cDENORMALISE_OX(ASD1(pointF_P4,x))                                                                          \
                          ,_cDENORMALISE_OY(ASD1(pointF_P4,y))                                                                          \
                          ,_cDENORMALISE_OZ(ASD1(pointF_P4,z))                                                                          \
                           );                                                                                                           \
                    Eblock                                                                                                              \
                                        /* Decalage des points (P1,P2,P3,P4) --> (P2,P3,P4,P4).                                      */
#define   DRAW_CUBIQUE_4(image,rayon_du_point,niveau_a_l_origine,niveau_a_l_extremite)                                                  \
                    Bblock                                                                                                              \
                    Test(IL_NE_FAUT_PAS(couper_l_arc_courant))                                                                          \
                         Bblock                                                                                                         \
                         Test(IFID(image,Masque))                                                                                       \
                              Bblock                                                                                                    \
                              CALS(Ivisualisation_arc_de_cubique_4P(Masque                                                              \
                                                                   ,ADRESSE(pointF_P3)                                                  \
                                                                   ,ADRESSE(pointF_P3)                                                  \
                                                                   ,niveau_a_l_extremite                                                \
                                                                   ,ADRESSE(pointF_P3)                                                  \
                                                                   ,niveau_a_l_extremite                                                \
                                                                   ,ADRESSE(pointF_P3)                                                  \
                                                                   ,CHOI(_____lNORMALISE_OX(rayon_du_point)                             \
                                                                        ,_____lNORMALISE_OY(rayon_du_point)                             \
                                                                         )                                                              \
                                                                   ,FU                                                                  \
                                                                   ,BI_DIMENSIONNEL                                                     \
                                                                    )                                                                   \
                                   );                                                                                                   \
                                        /* Trace du point extremite uniquement dans le cas du 'Masque'...                            */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              CALS(Ivisualisation_arc_de_cubique_4P(image                                                               \
                                                                   ,ADRESSE(pointF_P1)                                                  \
                                                                   ,ADRESSE(pointF_P2)                                                  \
                                                                   ,niveau_a_l_origine                                                  \
                                                                   ,ADRESSE(pointF_P3)                                                  \
                                                                   ,niveau_a_l_extremite                                                \
                                                                   ,ADRESSE(pointF_P4)                                                  \
                                                                   ,CHOI(_____lNORMALISE_OX(rayon_du_point)                             \
                                                                        ,_____lNORMALISE_OY(rayon_du_point)                             \
                                                                         )                                                              \
                                                                   ,affaiblissement_au_bord                                             \
                                                                   ,TRI_DIMENSIONNEL                                                    \
                                                                    )                                                                   \
                                   );                                                                                                   \
                                        /* Trace de l'arc de cubique pour une image quelconque ; attention, pour le 'Masque',        */ \
                                        /* il ne faut surtout pas modifier le 'Z-Buffer' car en effet, la generation de              */ \
                                        /* l'image 'ImageR' s'en trouverait perturbee...                                             */ \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Trace de l'arc de cubique...                                                              */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D O N N E E S   C O M M U N E S  :                                                                                         */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
DEFV(Local,DEFV(Int,INIT(graine_courante,GRAINE)));
                                        /* Graine variable de generation des nombres aleatoires,                                     */
DEFV(Local,DEFV(Int,INIT(pas_de_la_graine,PAS_DE_LA_GRAINE)));
                                        /* Et son pas de variation eventuel...                                                       */
DEFV(Local,DEFV(Float,INIT(sphere_X,FLOT__UNDEF)));
DEFV(Local,DEFV(Float,INIT(sphere_Y,FLOT__UNDEF)));
DEFV(Local,DEFV(Float,INIT(sphere_Z,FLOT__UNDEF)));
                                        /* Definition de la sphere de proximite (P1,P2), (P2,P3) et (P3,P4).                         */
DEFV(Local,DEFV(Float,INIT(M_delta_X,FLOT__UNDEF)));
DEFV(Local,DEFV(Float,INIT(M_delta_Y,FLOT__UNDEF)));
DEFV(Local,DEFV(Float,INIT(M_delta_Z,FLOT__UNDEF)));
                                        /* "Ouverture" arriere du cone de generation des points aleatoires 'P3' et 'P4' ; plus       */
                                        /* cette valeur est proche de 0, moins le retour en arriere est possible...                  */
DEFV(Local,DEFV(Float,INIT(P_delta_X,FLOT__UNDEF)));
DEFV(Local,DEFV(Float,INIT(P_delta_Y,FLOT__UNDEF)));
DEFV(Local,DEFV(Float,INIT(P_delta_Z,FLOT__UNDEF)));
                                        /* "Ouverture" avant du cone de generation des points aleatoires 'P3' et 'P4' ; plus         */
                                        /* cette valeur est proche de 1, plus l'eloignement en avant est rapide...                   */
DEFV(Local,DEFV(Float,INIT(affaiblissement_au_bord,AFFAIBLISSEMENT_AU_BORD)));
                                        /* Afin de faire le degrade du centre vers le bord pour les disques.                         */
DEFV(Local,DEFV(Float,INIT(taux_de_regression,TAUX_DE_REGRESSION)));
                                        /* Donne la "vitesse" de retour de 'P3' vers 'P1' en cas de collisions...                    */
DEFV(Local,DEFV(pointI_2D,pointI_spirale));
                                        /* Point d'un espace en spirale destinee a generer des nombres aleatoires.                   */
SPIRALE_DEFINITION_GENERALE(SE12(PasX,PasY),ZERO)
                                        /* Donnees de generation d'une spirale de parcours d'une image.                              */

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

BFonctionI

DEFV(Local,DEFV(FonctionI,genere_une_famille_de_serpents(nombre_d_arcs
                                                        ,nombre_de_points
                                                        ,liste_de_substitution
                                                        ,rayon_du_point
                                                         )
                )
     )
DEFV(Argument,DEFV(Positive,nombre_d_arcs));
                                        /* Nombre d'arcs a generer pour cette famille.                                               */
DEFV(Argument,DEFV(Positive,nombre_de_points));
                                        /* Nombre de points definissant chaque arc (en fait, on en genere 2 de plus...).             */
DEFV(Argument,DEFV(Int,liste_de_substitution));
                                        /* Definition de la liste de substitution a utiliser pour cette generation.                  */
DEFV(Argument,DEFV(Positive,rayon_du_point));
                                        /* Rayon du disque materialisant un point.                                                   */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     DEFV(pointF_3D,pointF_P1);
     DEFV(pointF_3D,pointF_P2);
     DEFV(pointF_3D,pointF_P3);
     DEFV(pointF_3D,pointF_P4);
                                        /* Definition des quatre points definissant l'arc de cubique.                                */
     DEFV(Float,INIT(rayon_courant,FLOT__UNDEF));
                                        /* Module du vecteur aleatoire (P1,P2) ou (P2,P3).                                           */
     DEFV(Logical,INIT(couper_l_arc_courant,LUNDEF));
                                        /* Indique s'il faut ou pas arreter la generation de l'arc courant (cas des sorties...).     */
     DEFV(Positive,INIT(nombre_de_tentatives_sur_un_arc,UNDEF));
                                        /* Donne le nombre de tentatives restant a faire pour generer un arc lorsqu'il               */
                                        /* y a des pseudo-collisions...                                                              */
     DEFV(Positive,INIT(nombre_de_pseudo_collisions,INFINI));
                                        /* Donne le nombre de pseudo-collisions ; il est initialise de facon a ce que le             */
                                        /* comptage soit fait au moins une fois...                                                   */

     INIT_ERROR;
     /*..............................................................................................................................*/
     SUBSTITUTION(liste_de_substitution);
                                        /* Mise en place des bonnes couleurs...                                                      */
     Komp(numero_de_l_arc,nombre_d_arcs)
          Bblock
          EGAL(couper_l_arc_courant,FAUX);
                                        /* A priori, on ne va pas couper, puisqu'on commence...                                      */
          PUSH_FILTRAGE;
          SET_FILTRAGE(INACTIF);
                                        /* On inhibe temporairement le filtrage afin de generer correctement le masque...            */
          CALS(Iinitialisation(Masque,NIVEAU_DE_MASQUAGE_DE_L_ARC_PRECEDENT));
                                        /* A priori, on ne masque rien...                                                            */
          PULL_FILTRAGE;
          Komp(numero_du_point,SUCC(SUCC(nombre_de_points)))
               Bblock
               Choi(numero_du_point)
                    Bblock
                    Ca1e(UN)
                         Bblock
                         GENERE_POINT_ALEATOIRE(pointF_P1
                                               ,XB_min,XB_max
                                               ,YB_min,YB_max
                                               ,ZB_min,ZB_min
                                               ,XB_min,XB_max
                                               ,YB_min,YB_max
                                               ,ZB_min,ZB_min
                                                );
                                        /* Initialisation du point 'P1' (tout a fait aleatoire mais dans le carre                    */
                                        /* [XB_min,XB_max]x[YB_min,YB_max] et sur le plan du "fond" 'ZB_min').                       */
                         Eblock
                    ECa1

                    Ca1e(DEUX)
                         Bblock
                         GENERE_POINT_ALEATOIRE(pointF_P2
                                               ,SOUS(_cDENORMALISE_OX(ASD1(pointF_P1,x)),_lDENORMALISE_OX(sphere_X))
                                               ,ADD2(_cDENORMALISE_OX(ASD1(pointF_P1,x)),_lDENORMALISE_OX(sphere_X))
                                               ,SOUS(_cDENORMALISE_OY(ASD1(pointF_P1,y)),_lDENORMALISE_OY(sphere_Y))
                                               ,ADD2(_cDENORMALISE_OY(ASD1(pointF_P1,y)),_lDENORMALISE_OY(sphere_Y))
                                               ,SOUS(_cDENORMALISE_OZ(ASD1(pointF_P1,z)),_lDENORMALISE_OZ(sphere_Z))
                                               ,ADD2(_cDENORMALISE_OZ(ASD1(pointF_P1,z)),_lDENORMALISE_OZ(sphere_Z))
                                               ,XB_min,XB_max
                                               ,YB_min,YB_max
                                               ,ZB_min,ZB_max
                                                );
                                        /* Initialisation du point 'P2' (a l'interieur d'une sphere centree sur P1).                 */
                         Eblock
                    ECa1

                    Ca1e(TROIS)
                         Bblock
                         GENERE_VECTEUR_ALEATOIRE(pointF_P1,pointF_P2);
                         GENERE_POINT_ALEATOIRE(pointF_P3
                                               ,COXA(SOUS(BARY(COXR(_cDENORMALISE_OX(ASD1(pointF_P2,x)))
                                                              ,COXR(_cDENORMALISE_OX(ASD1(pointF_P1,x)))
                                                              ,NEGA(DIVI(_lDENORMALISE_OX(sphere_X),rayon_courant))
                                                               )
                                                         ,_lDENORMALISE_OX(M_delta_X)
                                                          )
                                                     )
                                               ,NEUT(ADD2(BARY(COXR(_cDENORMALISE_OX(ASD1(pointF_P2,x)))
                                                              ,COXR(_cDENORMALISE_OX(ASD1(pointF_P1,x)))
                                                              ,NEGA(DIVI(_lDENORMALISE_OX(sphere_X),rayon_courant))
                                                               )
                                                         ,_lDENORMALISE_OX(P_delta_X)
                                                          )
                                                     )
                                               ,COYA(SOUS(BARY(COYR(_cDENORMALISE_OY(ASD1(pointF_P2,y)))
                                                              ,COYR(_cDENORMALISE_OY(ASD1(pointF_P1,y)))
                                                              ,NEGA(DIVI(_lDENORMALISE_OY(sphere_Y),rayon_courant))
                                                               )
                                                         ,_lDENORMALISE_OY(M_delta_Y)
                                                          )
                                                     )
                                               ,NEUT(ADD2(BARY(COYR(_cDENORMALISE_OY(ASD1(pointF_P2,y)))
                                                              ,COYR(_cDENORMALISE_OY(ASD1(pointF_P1,y)))
                                                              ,NEGA(DIVI(_lDENORMALISE_OY(sphere_Y),rayon_courant))
                                                               )
                                                         ,_lDENORMALISE_OY(P_delta_Y)
                                                          )
                                                     )
                                               ,COZA(SOUS(BARY(COZR(_cDENORMALISE_OZ(ASD1(pointF_P2,z)))
                                                              ,COZR(_cDENORMALISE_OZ(ASD1(pointF_P1,z)))
                                                              ,NEGA(DIVI(_lDENORMALISE_OZ(sphere_Z),rayon_courant))
                                                               )
                                                         ,_lDENORMALISE_OZ(M_delta_Z)
                                                          )
                                                     )
                                               ,NEUT(ADD2(BARY(COZR(_cDENORMALISE_OZ(ASD1(pointF_P2,z)))
                                                              ,COZR(_cDENORMALISE_OZ(ASD1(pointF_P1,z)))
                                                              ,NEGA(DIVI(_lDENORMALISE_OZ(sphere_Z),rayon_courant))
                                                               )
                                                         ,_lDENORMALISE_OZ(P_delta_Z)
                                                          )
                                                     )
                                               ,XB_min,XB_max
                                               ,YB_min,YB_max
                                               ,ZB_min,ZB_max
                                                );
                                        /* Initialisation du point 'P3' (dans la direction P1 --> P2, on definit un point PP3        */
                                        /* a distance 'sphere_XYZ' de 'P2' ; autour de 'PP3', on construit une sphere a l'interieur  */
                                        /* de laquelle on choisit aleatoirement le point 'P3'). Donnons precisemment la facon        */
                                        /* de calculer le minimum et le maximum communique au generateur aleatoire :                 */
                                        /*                                                                                           */
                                        /*                                  P2 - P1                                                  */
                                        /*                  minimum = P2 + ---------.S - M                                           */
                                        /*                                     R                                                     */
                                        /*                                                                                           */
                                        /*                                  P2 - P1                                                  */
                                        /*                  maximum = P2 + ---------.S + P                                           */
                                        /*                                     R                                                     */
                                        /*                                                                                           */
                                        /* ou :                                                                                      */
                                        /*                                                                                           */
                                        /* 'R' : designe 'rayon_courant', c'est-a-dire la norme du vecteur (P1,P2),                  */
                                        /* 'S' : designe 'S_delta_X', 'S_delta_Y' ou encore 'S_delta_Z',                             */
                                        /* 'M' : designe 'M_delta_X', 'M_delta_Y' ou encore 'M_delta_Z',                             */
                                        /* 'P' : designe 'P_delta_X', 'P_delta_Y' ou encore 'P_delta_Z',                             */
                                        /*                                                                                           */
                                        /* ce qui donne sur un diagramme mono-dimensionnel :                                         */
                                        /*                                                                                           */
                                        /*                            P1                 P2                                          */
                                        /*                  ..........*..................*.......X------------------X...........     */
                                        /*                                                       |                  |                */
                                        /*                                                       |                  |                */
                                        /*                                                    minimum            maximum             */
                                        /*                                                                                           */
                                        /* le point aleatoire desire ne pouvant qu'etre dans [minimum,maximum].                      */
                                        /*                                                                                           */
                         Eblock
                    ECa1

                    Defo
                         Bblock
                                        /* On notera que le point 'P4' peut etre recalcule plusieurs fois, en cas de collisions.     */
                         EGAL(nombre_de_tentatives_sur_un_arc,NOMBRE_DE_TENTATIVES_SUR_UN_ARC);
                                        /* Donne le nombre de tentatives restant a faire pour generer un point de l'arc              */
                                        /* courant lorsqu'il y a pseudo-collisions...                                                */
                         EGAL(nombre_de_pseudo_collisions,INFINI);
                                        /* L'initialisation est faite de telle facon que les points de type 'P4' soit toujours       */
                                        /* calcule au moins une fois en mode de detection des pseudo-collsions...                    */
                         Tant(IFET(IZNE(nombre_de_pseudo_collisions),IZGT(nombre_de_tentatives_sur_un_arc)))
                              Bblock
                              GENERE_VECTEUR_ALEATOIRE(pointF_P2,pointF_P3);
                              GENERE_POINT_ALEATOIRE(pointF_P4
                                                    ,COXA(SOUS(BARY(COXR(_cDENORMALISE_OX(ASD1(pointF_P3,x)))
                                                                   ,COXR(_cDENORMALISE_OX(ASD1(pointF_P2,x)))
                                                                   ,NEGA(DIVI(_lDENORMALISE_OX(sphere_X),rayon_courant))
                                                                    )
                                                              ,_lDENORMALISE_OX(M_delta_X)
                                                               )
                                                          )
                                                    ,NEUT(ADD2(BARY(COXR(_cDENORMALISE_OX(ASD1(pointF_P3,x)))
                                                                   ,COXR(_cDENORMALISE_OX(ASD1(pointF_P2,x)))
                                                                   ,NEGA(DIVI(_lDENORMALISE_OX(sphere_X),rayon_courant))
                                                                    )
                                                              ,_lDENORMALISE_OX(P_delta_X)
                                                               )
                                                          )
                                                    ,COYA(SOUS(BARY(COYR(_cDENORMALISE_OY(ASD1(pointF_P3,y)))
                                                                   ,COYR(_cDENORMALISE_OY(ASD1(pointF_P2,y)))
                                                                   ,NEGA(DIVI(_lDENORMALISE_OY(sphere_Y),rayon_courant))
                                                                    )
                                                              ,_lDENORMALISE_OY(M_delta_Y)
                                                               )
                                                          )
                                                    ,NEUT(ADD2(BARY(COYR(_cDENORMALISE_OY(ASD1(pointF_P3,y)))
                                                                   ,COYR(_cDENORMALISE_OY(ASD1(pointF_P2,y)))
                                                                   ,NEGA(DIVI(_lDENORMALISE_OY(sphere_Y),rayon_courant))
                                                                    )
                                                              ,_lDENORMALISE_OY(P_delta_Y)
                                                               )
                                                          )
                                                    ,COZA(SOUS(BARY(COZR(_cDENORMALISE_OZ(ASD1(pointF_P3,z)))
                                                                   ,COZR(_cDENORMALISE_OZ(ASD1(pointF_P2,z)))
                                                                   ,NEGA(DIVI(_lDENORMALISE_OZ(sphere_Z),rayon_courant))
                                                                    )
                                                              ,_lDENORMALISE_OZ(M_delta_Z)
                                                               )
                                                          )
                                                    ,NEUT(ADD2(BARY(COZR(_cDENORMALISE_OZ(ASD1(pointF_P3,z)))
                                                                   ,COZR(_cDENORMALISE_OZ(ASD1(pointF_P2,z)))
                                                                   ,NEGA(DIVI(_lDENORMALISE_OZ(sphere_Z),rayon_courant))
                                                                    )
                                                              ,_lDENORMALISE_OZ(P_delta_Z)
                                                               )
                                                          )
                                                    ,XB_min,XB_max
                                                    ,YB_min,YB_max
                                                    ,ZB_min,ZB_max
                                                     );
                                        /* Initialisation du point 'P4' (dans la direction P2 --> P3, on definit un point PP4        */
                                        /* a distance 'sphere_XYZ' de 'P3' ; autour de 'PP4', on construit une sphere a l'interieur  */
                                        /* de laquelle on choisit aleatoirement le point 'P4'). Voir le commentaire ci-dessus.       */
                              DEMARRAGE_DU_COMPTAGE_DES_PSEUDO_COLLISIONS(SEUIL_AVANT(rayon_du_point)
                                                                         ,SEUIL_ARRIERE(rayon_du_point)
                                                                          );
                              MASQUE_IMAGES(NIVEAU_DE_MASQUAGE_DE_L_ARC_PRECEDENT);
                                        /* Ce masquage a pour effet de ne faire le comptage que la ou il n'y a pas masquage ; or     */
                                        /* celui-ci correspond a toute l'image sauf l'extremite de l'arc precedent, et ce afin de    */
                                        /* resoudre le probleme du recouvrement des points extremite de l'arc precedent et           */
                                        /* origine ('P2') de l'arc courant...                                                        */
                              DRAW_CUBIQUE_4(ImageR
                                            ,rayon_du_point
                                            ,NIVA(DIVI(COZR(_cDENORMALISE_OZ(ASD1(pointF_P2,z)))
                                                      ,FACTEUR_D_HOMOTHETIE_Z
                                                       )
                                                  )
                                            ,NIVA(DIVI(COZR(_cDENORMALISE_OZ(ASD1(pointF_P3,z)))
                                                      ,FACTEUR_D_HOMOTHETIE_Z
                                                       )
                                                  )
                                             );
                                        /* Trace virtuel de l'arc de cubique (P2,P3) a l'aide des points (P1,P2,P3,P4).              */
                              DEMASQUE_IMAGES;
                              ARRET_DU_COMPTAGE_DES_PSEUDO_COLLISIONS(nombre_de_pseudo_collisions);
                                        /* En fait, on va changer le point 'P4' tant qu'il a des collisions...                       */
                              DECR(nombre_de_tentatives_sur_un_arc,I);
                                        /* Malgre tout, on empeche les bouclages a l'infini...                                       */
                              Test(IZNE(nombre_de_pseudo_collisions))
                                   Bblock
                                   Test(IZEQ(nombre_de_tentatives_sur_un_arc))
                                        Bblock
                                        EGAL(couper_l_arc_courant,VRAI);
                                        /* On a fait trop de tentative : on arrete la...                                             */
                                        Eblock
                                   ATes
                                        Bblock
                                        /* Lorsqu'on a encore le droit de retenter, on deplace le point 'P3'...                      */
                                        INITIALISATION_POINT_3D(pointF_P3
                                                               ,BARY(ASD1(pointF_P1,x),ASD1(pointF_P3,x),taux_de_regression)
                                                               ,BARY(ASD1(pointF_P1,y),ASD1(pointF_P3,y),taux_de_regression)
                                                               ,BARY(ASD1(pointF_P1,z),ASD1(pointF_P3,z),taux_de_regression)
                                                                );
                                        /* En cas de collisions, on deplace le point 'P3' ; afin de ne pas perturber le              */
                                        /* raccordement des arcs au niveau des tangentes, le point 'P3' doit etre rapproche          */
                                        /* de 'P1' en se deplacant sur la droite (P1,P3) ; rappelons qu'en effet la tangente         */
                                        /* en 'P2' est donnee par la direction (P1,P3)...                                            */
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes
                              Eblock
                         ETan
                         DRAW_CUBIQUE_4(ImageR
                                       ,rayon_du_point
                                       ,NIVA(DIVI(COZR(_cDENORMALISE_OZ(ASD1(pointF_P2,z)))
                                                 ,FACTEUR_D_HOMOTHETIE_Z
                                                  )
                                             )
                                       ,NIVA(DIVI(COZR(_cDENORMALISE_OZ(ASD1(pointF_P3,z)))
                                                 ,FACTEUR_D_HOMOTHETIE_Z
                                                  )
                                             )
                                        );
                                        /* Trace reel de l'arc de cubique (P2,P3) a l'aide des points (P1,P2,P3,P4).                 */
                         PUSH_FILTRAGE;
                         SET_FILTRAGE(INACTIF);
                                        /* On inhibe temporairement le filtrage afin de generer correctement le masque...            */
                         CALS(Iinitialisation(Masque,NIVEAU_DE_MASQUAGE_DE_L_ARC_PRECEDENT));
                         DRAW_CUBIQUE_4(Masque
                                       ,SUCC(rayon_du_point)
                                       ,VCOMP(NIVEAU_DE_MASQUAGE_DE_L_ARC_PRECEDENT)
                                       ,VCOMP(NIVEAU_DE_MASQUAGE_DE_L_ARC_PRECEDENT)
                                        );
                                        /* Et generation d'un masque correspondant au complement de l'extremite                      */
                                        /* de l'arc que l'on vient de generer ; le 'SUCC' est la pour corriger d'eventuelles         */
                                        /* erreurs d'arrondis qui rendrait le masque trop etroit...                                  */
                         PULL_FILTRAGE;
                         MOVE_POINTS;
                                        /* Et "rotation" des points : (P1,P2,P3,P4) --> (P2,P3,P4,P4).                               */
                         Eblock
                    EDef
                    Eblock
               ECho
               Eblock
          EKom
          Eblock
     EKom
     RETU_ERROR;
     Eblock

EFonctionI

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E N E R A T I O N   D E S   S E R P E N T S   R E L A T I V E M E N T   R E C T I L I G N E S  :                         */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     DEFV(CHAR,INIC(POINTERc(nom_imageR),NOM_PIPE));
     DEFV(Positive,INIT(nombre_d_arcs_F1,NOMBRE_D_ARCS_F1));
     DEFV(Positive,INIT(nombre_de_points_F1,NOMBRE_DE_POINTS_F1));
     DEFV(genere_p,INIT(couleurs_F1,COULEURS_F1));
     DEFV(Positive,INIT(rayon_du_point_F1,RAYON_DU_POINT_F1));
                                        /* Parametres de definition de la famille 'F1'.                                              */
     DEFV(Positive,INIT(nombre_d_arcs_F2,NOMBRE_D_ARCS_F2));
     DEFV(Positive,INIT(nombre_de_points_F2,NOMBRE_DE_POINTS_F2));
     DEFV(genere_p,INIT(couleurs_F2,COULEURS_F2));
     DEFV(Positive,INIT(rayon_du_point_F2,RAYON_DU_POINT_F2));
                                        /* Parametres de definition de la famille 'F2'.                                              */
     DEFV(Positive,INIT(nombre_d_arcs_F3,NOMBRE_D_ARCS_F3));
     DEFV(Positive,INIT(nombre_de_points_F3,NOMBRE_DE_POINTS_F3));
     DEFV(genere_p,INIT(couleurs_F3,COULEURS_F3));
     DEFV(Positive,INIT(rayon_du_point_F3,RAYON_DU_POINT_F3));
                                        /* Parametres de definition de la famille 'F3'.                                              */
     /*..............................................................................................................................*/
     GET_ARGUMENTSv(nombre_d_arguments
                   ,BLOC(GET_ARGUMENT_C("imageR=""R=",nom_imageR);
                         GET_ARGUMENT_I("methode=",gen_ft_____methode_standard);
                         GET_ARGUMENT_I("graine=""g=",graine_courante);
                         GET_ARGUMENT_L("affiner_rdn=",rdnIFnD_____affiner_la_generation);
                         GET_ARGUMENT_L("iterer_rdn=",rdnIFnD_____iterer_la_generation);
                         GET_ARGUMENT_I("pg=""pas=",pas_de_la_graine);
                         GET_ARGUMENT_F("regression=",taux_de_regression);
                         GIT_ARGUMENT_F("sx=""sX=",sphere_X,_____lNORMALISE_OX(I_lHOMOTHETIE_Std_OX(SPHERE_X)));
                         GIT_ARGUMENT_F("sy=""sY=",sphere_Y,_____lNORMALISE_OY(I_lHOMOTHETIE_Std_OY(SPHERE_Y)));
                         GIT_ARGUMENT_F("sz=""sZ=",sphere_Z,_____lNORMALISE_OZ(I_lHOMOTHETIE_Std_OZ(SPHERE_Z)));
                         GIT_ARGUMENT_F("Mx=""MX=",M_delta_X,_____lNORMALISE_OX(I_lHOMOTHETIE_Std_OX(M_DELTA_X)));
                         GIT_ARGUMENT_F("My=""MY=",M_delta_Y,_____lNORMALISE_OY(I_lHOMOTHETIE_Std_OY(M_DELTA_Y)));
                         GIT_ARGUMENT_F("Mz=""MZ=",M_delta_Z,_____lNORMALISE_OZ(I_lHOMOTHETIE_Std_OZ(M_DELTA_Z)));
                         GIT_ARGUMENT_F("Px=""PX=",P_delta_X,_____lNORMALISE_OX(I_lHOMOTHETIE_Std_OX(P_DELTA_X)));
                         GIT_ARGUMENT_F("Py=""PY=",P_delta_Y,_____lNORMALISE_OY(I_lHOMOTHETIE_Std_OY(P_DELTA_Y)));
                         GIT_ARGUMENT_F("Pz=""PZ=",P_delta_Z,_____lNORMALISE_OZ(I_lHOMOTHETIE_Std_OZ(P_DELTA_Z)));
                                        /* Le 20120210211727, les 'I_lHOMOTHETIE_Std_O?(...)'s  furent introduits...                 */
                         GET_ARGUMENT_F("affaiblissement=",affaiblissement_au_bord);
                         GET_ARGUMENT_I("a1=",nombre_d_arcs_F1);
                         GET_ARGUMENT_I("p1=",nombre_de_points_F1);
                         GET_ARGUMENT_P("c1=",couleurs_F1);
                         GET_ARGUMENT_I("r1=",rayon_du_point_F1);
                         GET_ARGUMENT_I("a2=",nombre_d_arcs_F2);
                         GET_ARGUMENT_I("p2=",nombre_de_points_F2);
                         GET_ARGUMENT_P("c2=",couleurs_F2);
                         GET_ARGUMENT_I("r2=",rayon_du_point_F2);
                         GET_ARGUMENT_I("a3=",nombre_d_arcs_F3);
                         GET_ARGUMENT_I("p3=",nombre_de_points_F3);
                         GET_ARGUMENT_P("c3=",couleurs_F3);
                         GET_ARGUMENT_I("r3=",rayon_du_point_F3);
                         )
                    );

     Test(IFNE(NIVEAU_HORS_ECRAN,NOIR))
          Bblock
          PRINT_ERREUR("le niveau hors-ecran doit etre NOIR");
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     CALi(Inoir(ImageR));
                                        /* R  : futur resultat (avant la mise en place des pas).                                     */

     EGAL(projecteur_OX,FZERO);
     EGAL(projecteur_OY,FZERO);
                                        /* On inhibe completement la projection (pour tout voir...).                                 */

     SPIRALE_VALIDATION;
                                        /* Validation des pas de parcours (pasX,pasY) des images.                                    */

     SET_FILTRAGE(ACTIF);

     INITIALISATION_POINT_2D(pointI_spirale,Xcentre,Ycentre);
     SPIRALE_REINITIALISATION_BRAS_ET_DELTAS;
                                        /* Initialisation de la spirale.                                                             */

     CALS(Iinit_Z_Buffer());

     CALS(genere_une_famille_de_serpents(nombre_d_arcs_F1
                                        ,nombre_de_points_F1
                                        ,couleurs_F1
                                        ,rayon_du_point_F1
                                         )
          );
                                        /* Generation de la premiere famille de serpents,                                            */
     CALS(genere_une_famille_de_serpents(nombre_d_arcs_F2
                                        ,nombre_de_points_F2
                                        ,couleurs_F2
                                        ,rayon_du_point_F2
                                         )
          );
                                        /* Generation de la seconde famille de serpents,                                             */
     CALS(genere_une_famille_de_serpents(nombre_d_arcs_F3
                                        ,nombre_de_points_F3
                                        ,couleurs_F3
                                        ,rayon_du_point_F3
                                         )
          );
                                        /* Generation de la troisieme famille de serpents.                                           */

     CALi(Iupdate_image(nom_imageR,ImageR));

     RETU_Commande;
     Eblock
ECommande



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.