/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        I N T E R S E C T I O N   D ' U N   E N S E M B L E   D E   S E G M E N T S  :                                             */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xrv/intersection.11$K' :                                                                                       */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 20150703141059).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

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

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        V A L E U R S   I M P L I C I T E S   D E S   P A R A M E T R E S  :                                                       */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   RECHERCHER_LES_INTERSECTIONS                                                                                                  \
                    VRAI                                                                                                                \
                                        /* Doit-on rechercher les intersections ('VRAI') ou pas ('FAUX') ce qui permet alors un      */ \
                                        /* comportement neutre. Ceci fut introduit le 20150730134540...                              */

#define   EPSILON_DE_TEST_DES_DETERMINANTS                                                                                              \
                    FZERO                                                                                                               \
                                        /* Doit-on tester exactement la nullite des determinants ('FZERO') ou de facon approchee ?   */ \
                                        /* Ceci fut introduit le 20150703210300...                                                   */
#define   EPSILON_DE_TEST_DES_PRODUITS_VECTORIELS                                                                                       \
                    FZERO                                                                                                               \
                                        /* Doit-on tester exactement la nullite des produits vectoriels ('FZERO') ou de facon        */ \
                                        /* approchee ? Ceci fut introduit le 20150804161420...                                       */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N   D E S   F I C H I E R S  :                                                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#include  xrv/ARITHMET.1d.I"
#include  xrv/ARITHMET.21.I"
#include  xrv/champs_5.41.I"

#define   S_Xorg_IMPLICITE                                                                                                              \
                    FZERO
#define   S_Yorg_IMPLICITE                                                                                                              \
                    FZERO
#define   S_Zorg_IMPLICITE                                                                                                              \
                    FZERO

#define   S_Xext_IMPLICITE                                                                                                              \
                    FZERO
#define   S_Yext_IMPLICITE                                                                                                              \
                    FZERO
#define   S_Zext_IMPLICITE                                                                                                              \
                    FZERO

gGENERATION_D_UN_FICHIER(fichier_LISTE_S_Xorg,liste_initiale_des_S_Xorg);
gGENERATION_D_UN_FICHIER(fichier_LISTE_S_Yorg,liste_initiale_des_S_Yorg);
gGENERATION_D_UN_FICHIER(fichier_LISTE_S_Zorg,liste_initiale_des_S_Zorg);

gGENERATION_D_UN_FICHIER(fichier_LISTE_S_Xext,liste_initiale_des_S_Xext);
gGENERATION_D_UN_FICHIER(fichier_LISTE_S_Yext,liste_initiale_des_S_Yext);
gGENERATION_D_UN_FICHIER(fichier_LISTE_S_Zext,liste_initiale_des_S_Zext);
                                        /* Definition en memoire des fichiers de coordonnees cartesiennes des segments.              */

#define   ELEMENT_DU_FICHIER_LISTE_S_Xorg(index)                                                                                        \
                    gELEMENT_DU_FICHIER(liste_initiale_des_S_Xorg,index)
#define   ELEMENT_DU_FICHIER_LISTE_S_Yorg(index)                                                                                        \
                    gELEMENT_DU_FICHIER(liste_initiale_des_S_Yorg,index)
#define   ELEMENT_DU_FICHIER_LISTE_S_Zorg(index)                                                                                        \
                    gELEMENT_DU_FICHIER(liste_initiale_des_S_Zorg,index)

#define   ELEMENT_DU_FICHIER_LISTE_S_Xext(index)                                                                                        \
                    gELEMENT_DU_FICHIER(liste_initiale_des_S_Xext,index)
#define   ELEMENT_DU_FICHIER_LISTE_S_Yext(index)                                                                                        \
                    gELEMENT_DU_FICHIER(liste_initiale_des_S_Yext,index)
#define   ELEMENT_DU_FICHIER_LISTE_S_Zext(index)                                                                                        \
                    gELEMENT_DU_FICHIER(liste_initiale_des_S_Zext,index)
                                        /* Acces a un element courant des fichiers de coordonnees cartesiennes des segments.         */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M A C R O S   U T I L E S  :                                                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   RESOLUTION_D_UN_SYSTEME_LINEAIRE(coordonnee1,coordonnee2,coordonnee3)                                                         \
                    Bblock                                                                                                              \
                    Test(EST_FAUX(le_systeme_lineaire_est_resolu))                                                                      \
                         Bblock                                                                                                         \
                         DEFV(Float,INIT(determinant`coordonnee1`coordonnee2                                                            \
                                        ,DET2(NEUT(A_S1`coordonnee1),NEGA(A_S2`coordonnee1)                                             \
                                             ,NEUT(A_S1`coordonnee2),NEGA(A_S2`coordonnee2)                                             \
                                              )                                                                                         \
                                         )                                                                                              \
                              );                                                                                                        \
                                        /* Calcul du determinant du systeme lineaire courant (deux des trois equations...).          */ \
                                                                                                                                        \
                         Test(IZNE_a_peu_pres(determinant`coordonnee1`coordonnee2,epsilon_de_test_des_determinants))                    \
                              Bblock                                                                                                    \
                                        /* Cas ou le determinant du systeme lineaire courant n'est pas nul :                         */ \
                              DEFV(Float,INIT(determinant`coordonnee1`coordonnee2_T1                                                    \
                                             ,DET2(SOUS(B_S2`coordonnee1,B_S1`coordonnee1),NEGA(A_S2`coordonnee1)                       \
                                                  ,SOUS(B_S2`coordonnee2,B_S1`coordonnee2),NEGA(A_S2`coordonnee2)                       \
                                                   )                                                                                    \
                                              )                                                                                         \
                                   );                                                                                                   \
                              DEFV(Float,INIT(determinant`coordonnee1`coordonnee2_T2                                                    \
                                             ,DET2(NEUT(A_S1`coordonnee1),SOUS(B_S2`coordonnee1,B_S1`coordonnee1)                       \
                                                  ,NEUT(A_S1`coordonnee2),SOUS(B_S2`coordonnee2,B_S1`coordonnee2)                       \
                                                   )                                                                                    \
                                              )                                                                                         \
                                   );                                                                                                   \
                                        /* On peut donc le resoudre...                                                               */ \
                                                                                                                                        \
                              EGAL(coordonnee_S1_T,DIVI(determinant`coordonnee1`coordonnee2_T1,determinant`coordonnee1`coordonnee2));   \
                              EGAL(coordonnee_S2_T,DIVI(determinant`coordonnee1`coordonnee2_T2,determinant`coordonnee1`coordonnee2));   \
                                        /* Calcul des deux solutions {T1,T2}.                                                        */ \
                                                                                                                                        \
                              Test(IFEQ(AXPB(A_S1`coordonnee3,coordonnee_S1_T,B_S1`coordonnee3)                                         \
                                       ,AXPB(A_S2`coordonnee3,coordonnee_S2_T,B_S2`coordonnee3)                                         \
                                        )                                                                                               \
                                   )                                                                                                    \
                                   Bblock                                                                                               \
                                        /* Cas ou les deux solutions {T1,T2} verifient la troisieme equation lineaire :              */ \
                                   EGAL(le_systeme_lineaire_est_resolu,VRAI);                                                           \
                                        /* On a trouve une intersection...                                                           */ \
                                   Eblock                                                                                               \
                              ATes                                                                                                      \
                                   Bblock                                                                                               \
                                   Eblock                                                                                               \
                              ETes                                                                                                      \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock

#define   EDITION_DES_POINTS_D_INTERSECTION                                                                                             \
                    Bblock                                                                                                              \
                    Test(EST_VRAI(une_valeur_courante_au_moins_a_ete_editee))                                                           \
                         Bblock                                                                                                         \
                         CAL2(Prin0("\n"));                                                                                             \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                                                                                                                                        \
                    CAL2(Prin0(" X="));                                                                                                 \
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(intersection_X);                                                           \
                    CAL2(Prin0(" Y="));                                                                                                 \
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(intersection_Y);                                                           \
                    CAL2(Prin0(" Z="));                                                                                                 \
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(intersection_Z);                                                           \
                                        /* Edition du triplet {X,Y,Z}.                                                               */ \
                                                                                                                                        \
                    Test(EST_FAUX(une_valeur_courante_au_moins_a_ete_editee))                                                           \
                         Bblock                                                                                                         \
                         CAL2(Prin0("\n"));                                                                                             \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        I N T E R S E C T I O N   D ' U N   E N S E M B L E   D E   S E G M E N T S  :                                             */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     DEFV(Logical,INIT(rechercher_les_intersections,RECHERCHER_LES_INTERSECTIONS));
                                        /* Doit-on rechercher les intersections ('VRAI') ou pas ('FAUX') ce qui permet alors un      */
                                        /* comportement neutre. Ceci fut introduit le 20150730134540...                              */

     DEFV(Float,INIT(epsilon_de_test_des_determinants,EPSILON_DE_TEST_DES_DETERMINANTS));
                                        /* Doit-on tester exactement la nullite des determinants ('FZERO') ou de facon approchee ?   */
                                        /* Ceci fut introduit le 20150703210300...                                                   */
     DEFV(Float,INIT(epsilon_de_test_des_produits_vectoriels,EPSILON_DE_TEST_DES_PRODUITS_VECTORIELS));
                                        /* Doit-on tester exactement la nullite des produits vectoriels ('FZERO') ou de facon        */
                                        /* approchee ? Ceci fut introduit le 20150804161420...                                       */

#include  xrv/ARITHMET.22.I"
#include  xci/valeurs.03.I"

     /*..............................................................................................................................*/
#include  xrv/champs_5.1A.I"

     GET_ARGUMENTS_(nombre_d_arguments
                   ,BLOC(PROCESS_ARGUMENT_I("nombre_elements=""ne=",nombre_d_elements
                                           ,BLOC(VIDE;)
                                           ,BLOC(Bblock
                                                 PRINT_AVERTISSEMENT("'ne=' doit etre defini avant toute entree de fichiers");
                                                 Eblock
                                                 )
                                            );

                         PROCESS_ARGUMENTS_DE_DEFINITION_DES_FICHIERS_01;

                         PROKESF_ARGUMENT_FICHIER("LISTE_S_Xorg="
                                                 ,fichier_LISTE_S_Xorg
                                                 ,liste_initiale_des_S_Xorg
                                                 ,S_Xorg_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );
                         PROKESF_ARGUMENT_FICHIER("LISTE_S_Yorg="
                                                 ,fichier_LISTE_S_Yorg
                                                 ,liste_initiale_des_S_Yorg
                                                 ,S_Yorg_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );
                         PROKESF_ARGUMENT_FICHIER("LISTE_S_Zorg="
                                                 ,fichier_LISTE_S_Zorg
                                                 ,liste_initiale_des_S_Zorg
                                                 ,S_Zorg_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );

                         PROKESF_ARGUMENT_FICHIER("LISTE_S_Xext="
                                                 ,fichier_LISTE_S_Xext
                                                 ,liste_initiale_des_S_Xext
                                                 ,S_Xext_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );
                         PROKESF_ARGUMENT_FICHIER("LISTE_S_Yext="
                                                 ,fichier_LISTE_S_Yext
                                                 ,liste_initiale_des_S_Yext
                                                 ,S_Yext_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );
                         PROKESF_ARGUMENT_FICHIER("LISTE_S_Zext="
                                                 ,fichier_LISTE_S_Zext
                                                 ,liste_initiale_des_S_Zext
                                                 ,S_Zext_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );

                         GET_ARGUMENT_L("intersections=""inter=",rechercher_les_intersections);
                         GET_ARGUMENT_N("neutre=",rechercher_les_intersections);
                                        /* Arguments introduits le 20150730134540...                                                 */

                         GET_ARGUMENT_F("epsilon_determinants=""epsdet=",epsilon_de_test_des_determinants);
                                        /* Argument introduit le 20150703210300...                                                   */
                         GET_ARGUMENT_F("epsilon_produits_vectoriels=""epspv=",epsilon_de_test_des_produits_vectoriels);
                                        /* Argument introduit le 20150804161420...                                                   */

                         PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_3;

                         PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_1;

                         GET_ARGUMENT_I("exemplaires=",nombre_d_exemplaires_du_resultat_de_l_operation_sur_les_valeurs_courantes);
                         )
                    );

     begin_nouveau_block
          Bblock
          DEFV(Int,INIT(indexS1,UNDEF));
                                        /* Index des segments 'S1'.                                                                  */

          DoIn(indexS1,PREMIER_ELEMENT_D_UN_FICHIER,DERNIER_ELEMENT_D_UN_FICHIER,I)
               Bblock
               DEFV(Logical,INIT(le_segment_S1_intersecte_au_moins_un_segment_S2,FAUX));
                                        /* A priori, le segment courant 'S1' n'intersecte aucun autre segment (dit 'S2').            */
               DEFV(Int,INIT(indexS2,UNDEF));
                                        /* Index des segments 'S2'.                                                                  */

               DEFV(Float,INIT(coordonnee_S1_Xorg,ELEMENT_DU_FICHIER_LISTE_S_Xorg(indexS1)));
               DEFV(Float,INIT(coordonnee_S1_Yorg,ELEMENT_DU_FICHIER_LISTE_S_Yorg(indexS1)));
               DEFV(Float,INIT(coordonnee_S1_Zorg,ELEMENT_DU_FICHIER_LISTE_S_Zorg(indexS1)));
                                        /* Recuperation des coordonnees {S1_Xorg,S1_Yorg,S1_Zorg} courantes dans les fichiers.       */
               DEFV(Float,INIT(coordonnee_S1_Xext,ELEMENT_DU_FICHIER_LISTE_S_Xext(indexS1)));
               DEFV(Float,INIT(coordonnee_S1_Yext,ELEMENT_DU_FICHIER_LISTE_S_Yext(indexS1)));
               DEFV(Float,INIT(coordonnee_S1_Zext,ELEMENT_DU_FICHIER_LISTE_S_Zext(indexS1)));
                                        /* Recuperation des coordonnees {S1_Xext,S1_Yext,S1_Zext} courantes dans les fichiers.       */

               Test(IL_FAUT(rechercher_les_intersections))
                                        /* Possibilite introduite le 20150730134540 afin de pouvoir rendre "neutre" ce '$K' lors     */
                                        /* de tests...                                                                               */
                    Bblock
                    DoIn(indexS2,SUCC(indexS1),DERNIER_ELEMENT_D_UN_FICHIER,I)
                         Bblock
                         DEFV(Float,INIT(coordonnee_S2_Xorg,ELEMENT_DU_FICHIER_LISTE_S_Xorg(indexS2)));
                         DEFV(Float,INIT(coordonnee_S2_Yorg,ELEMENT_DU_FICHIER_LISTE_S_Yorg(indexS2)));
                         DEFV(Float,INIT(coordonnee_S2_Zorg,ELEMENT_DU_FICHIER_LISTE_S_Zorg(indexS2)));
                                        /* Recuperation des coordonnees {S2_Xorg,S2_Yorg,S2_Zorg} courantes dans les fichiers.       */
                         DEFV(Float,INIT(coordonnee_S2_Xext,ELEMENT_DU_FICHIER_LISTE_S_Xext(indexS2)));
                         DEFV(Float,INIT(coordonnee_S2_Yext,ELEMENT_DU_FICHIER_LISTE_S_Yext(indexS2)));
                         DEFV(Float,INIT(coordonnee_S2_Zext,ELEMENT_DU_FICHIER_LISTE_S_Zext(indexS2)));
                                        /* Recuperation des coordonnees {S2_Xext,S2_Yext,S2_Zext} courantes dans les fichiers.       */

                         DEFV(Logical,INIT(le_systeme_lineaire_est_resolu,FAUX));
                         DEFV(Float,INIT(intersection_X,FLOT__UNDEF));
                         DEFV(Float,INIT(intersection_Y,FLOT__UNDEF));
                         DEFV(Float,INIT(intersection_Z,FLOT__UNDEF));
                                        /* Intersection eventuelle entre les segments 'S1' et 'S2' (avec evidemment S1#S2...).       */

                         DEFV(Float,INIT(A_S1_X,FLOT__UNDEF));
                         DEFV(Float,INIT(B_S1_X,FLOT__UNDEF));
                         DEFV(Float,INIT(A_S1_Y,FLOT__UNDEF));
                         DEFV(Float,INIT(B_S1_Y,FLOT__UNDEF));
                         DEFV(Float,INIT(A_S1_Z,FLOT__UNDEF));
                         DEFV(Float,INIT(B_S1_Z,FLOT__UNDEF));
                         DEFV(Float,INIT(coordonnee_S1_T,FLOT__UNDEF));
                                        /* Definition de l'equation parametrique de la droite du segment 'S1'.                       */

                         DEFV(Float,INIT(A_S2_X,FLOT__UNDEF));
                         DEFV(Float,INIT(B_S2_X,FLOT__UNDEF));
                         DEFV(Float,INIT(A_S2_Y,FLOT__UNDEF));
                         DEFV(Float,INIT(B_S2_Y,FLOT__UNDEF));
                         DEFV(Float,INIT(A_S2_Z,FLOT__UNDEF));
                         DEFV(Float,INIT(B_S2_Z,FLOT__UNDEF));
                         DEFV(Float,INIT(coordonnee_S2_T,FLOT__UNDEF));
                                        /* Definition de l'equation parametrique de la droite du segment 'S2'.                       */

                         EGAL(A_S1_X,SOUS(coordonnee_S1_Xext,coordonnee_S1_Xorg));
                         EGAL(B_S1_X,coordonnee_S1_Xorg);
                         EGAL(A_S1_Y,SOUS(coordonnee_S1_Yext,coordonnee_S1_Yorg));
                         EGAL(B_S1_Y,coordonnee_S1_Yorg);
                         EGAL(A_S1_Z,SOUS(coordonnee_S1_Zext,coordonnee_S1_Zorg));
                         EGAL(B_S1_Z,coordonnee_S1_Zorg);
                                        /* Calcul de l'equation parametrique de la droite du segment 'S1' :                          */
                                        /*                                                                                           */
                                        /*                  S1_X = A_S1_X.T1 + B_S1_X                                                */
                                        /*                  S1_Y = A_S1_Y.T1 + B_S1_Y                                                */
                                        /*                  S1_Z = A_S1_Z.T1 + B_S1_Z                                                */
                                        /*                                                                                           */
                                        /* ou 'T1' est le parametre.                                                                 */

                         EGAL(A_S2_X,SOUS(coordonnee_S2_Xext,coordonnee_S2_Xorg));
                         EGAL(B_S2_X,coordonnee_S2_Xorg);
                         EGAL(A_S2_Y,SOUS(coordonnee_S2_Yext,coordonnee_S2_Yorg));
                         EGAL(B_S2_Y,coordonnee_S2_Yorg);
                         EGAL(A_S2_Z,SOUS(coordonnee_S2_Zext,coordonnee_S2_Zorg));
                         EGAL(B_S2_Z,coordonnee_S2_Zorg);
                                        /* Calcul de l'equation parametrique de la droite du segment 'S2' :                          */
                                        /*                                                                                           */
                                        /*                  S2_X = A_S2_X.T2 + B_S2_X                                                */
                                        /*                  S2_Y = A_S2_Y.T2 + B_S2_Y                                                */
                                        /*                  S2_Z = A_S2_Z.T2 + B_S2_Z                                                */
                                        /*                                                                                           */
                                        /* ou 'T2' est le parametre.                                                                 */

                         begin_nouveau_block
                              Bblock
                              RESOLUTION_D_UN_SYSTEME_LINEAIRE(X,Y,Z);
                              RESOLUTION_D_UN_SYSTEME_LINEAIRE(Y,Z,X);
                              RESOLUTION_D_UN_SYSTEME_LINEAIRE(Z,X,Y);
                                        /* D'une facon generale, pour trouver l'eventuelle intersection de 'S1' et de 'S2',          */
                                        /* il convient de resoudre le systeme :                                                      */
                                        /*                                                                                           */
                                        /*                  S1_X = S2_X                                                              */
                                        /*                  S1_Y = S2_Y                                                              */
                                        /*                  S1_Z = S2_Z                                                              */
                                        /*                                                                                           */
                                        /* soit :                                                                                    */
                                        /*                                                                                           */
                                        /*                  A_S1_X.T1 + B_S1_X = A_S2_X.T2 + B_S2_X                                  */
                                        /*                  A_S1_Y.T1 + B_S1_Y = A_S2_Y.T2 + B_S2_Y                                  */
                                        /*                  A_S1_Z.T1 + B_S1_Z = A_S2_Z.T2 + B_S2_Z                                  */
                                        /*                                                                                           */
                                        /* ou encore :                                                                               */
                                        /*                                                                                           */
                                        /*                  A_S1_X.T1 - A_S2_X.T2 = B_S2_X - B_S1_X                                  */
                                        /*                  A_S1_Y.T1 - A_S2_Y.T2 = B_S2_Y - B_S1_Y                                  */
                                        /*                  A_S1_Z.T1 - A_S2_Z.T2 = B_S2_Z - B_S1_Z                                  */
                                        /*                                                                                           */
                                        /* qui est surdetermine puiqu'il y a 3 equations et deux inconnues {T1,T2}. On va donc       */
                                        /* resoudre successivement et si besoin est trois systemes lineaires en {X,Y}, {Y,Z) et      */
                                        /* {Z,X}...                                                                                  */
                                        /*                                                                                           */
                                        /* Si aucun des trois systemes n'a de solution, cela signifie en general que 'S1'            */
                                        /* n'intersecte pas 'S2'. Malgre tout, il restera a voir si, par hasard, les deux            */
                                        /* segments 'S1' et 'S2' ne sont pas colineaires et si oui, si l'un ('S2') n'est             */
                                        /* pas inclus dans l'autre ('S1') ; cela se fera plus loin a l'aide du produit vectoriel     */
                                        /* de 'S1' et de 'S2'...                                                                     */
                              Eblock
                         end_nouveau_block

                         Test(EST_VRAI(le_systeme_lineaire_est_resolu))
                              Bblock
                              DEFV(Float,INIT(intersection_S1_X,AXPB(A_S1_X,coordonnee_S1_T,B_S1_X)));
                              DEFV(Float,INIT(intersection_S1_Y,AXPB(A_S1_Y,coordonnee_S1_T,B_S1_Y)));
                              DEFV(Float,INIT(intersection_S1_Z,AXPB(A_S1_Z,coordonnee_S1_T,B_S1_Z)));
                              DEFV(Float,INIT(intersection_S2_X,AXPB(A_S2_X,coordonnee_S2_T,B_S2_X)));
                              DEFV(Float,INIT(intersection_S2_Y,AXPB(A_S2_Y,coordonnee_S2_T,B_S2_Y)));
                              DEFV(Float,INIT(intersection_S2_Z,AXPB(A_S2_Z,coordonnee_S2_T,B_S2_Z)));

                              Test(I3ET(IFEQ(intersection_S1_X,intersection_S2_X)
                                       ,IFEQ(intersection_S1_Y,intersection_S2_Y)
                                       ,IFEQ(intersection_S1_Z,intersection_S2_Z)
                                        )
                                   )
                                   Bblock
                                   EGAL(intersection_X,CHOI(intersection_S1_X,intersection_S2_X));
                                   EGAL(intersection_Y,CHOI(intersection_S1_Y,intersection_S2_Y));
                                   EGAL(intersection_Z,CHOI(intersection_S1_Z,intersection_S2_Z));

                                   Test(IFET(I3ET(IFOU(IFET(IFEQ(intersection_X,coordonnee_S1_Xorg)
                                                           ,IFEQ(intersection_X,coordonnee_S1_Xext)
                                                            )
                                                      ,INCLoo(intersection_X,coordonnee_S1_Xorg,coordonnee_S1_Xext)
                                                       )
                                                 ,IFOU(IFET(IFEQ(intersection_Y,coordonnee_S1_Yorg)
                                                           ,IFEQ(intersection_Y,coordonnee_S1_Yext)
                                                            )
                                                      ,INCLoo(intersection_Y,coordonnee_S1_Yorg,coordonnee_S1_Yext)
                                                       )
                                                 ,IFOU(IFET(IFEQ(intersection_Z,coordonnee_S1_Zorg)
                                                           ,IFEQ(intersection_Z,coordonnee_S1_Zext)
                                                            )
                                                      ,INCLoo(intersection_Z,coordonnee_S1_Zorg,coordonnee_S1_Zext)
                                                       )
                                                  )
                                            ,I3ET(IFOU(IFET(IFEQ(intersection_X,coordonnee_S2_Xorg)
                                                           ,IFEQ(intersection_X,coordonnee_S2_Xext)
                                                            )
                                                      ,INCLoo(intersection_X,coordonnee_S2_Xorg,coordonnee_S2_Xext)
                                                       )
                                                 ,IFOU(IFET(IFEQ(intersection_Y,coordonnee_S2_Yorg)
                                                           ,IFEQ(intersection_Y,coordonnee_S2_Yext)
                                                            )
                                                      ,INCLoo(intersection_Y,coordonnee_S2_Yorg,coordonnee_S2_Yext)
                                                       )
                                                 ,IFOU(IFET(IFEQ(intersection_Z,coordonnee_S2_Zorg)
                                                           ,IFEQ(intersection_Z,coordonnee_S2_Zext)
                                                            )
                                                      ,INCLoo(intersection_Z,coordonnee_S2_Zorg,coordonnee_S2_Zext)
                                                       )
                                                  )
                                             )
                                        )
                                        Bblock
                                        /* Ce test assez complique teste si une coordonnee d'intersection est dans l'ouvert          */
                                        /* correspondant au segment courant projete sur l'un des axes. Mais il prend aussi en        */
                                        /* compte le cas ou cette projection est de longueur nulle et que l'intersection y est       */
                                        /* malgre tout presente...                                                                   */

                                        EGAL(le_segment_S1_intersecte_au_moins_un_segment_S2,VRAI);
                                        /* Le point d'intersection {X,Y,Z} appartient aux segments 'S1' et 'S2'...                   */
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes
                              Eblock
                         ATes
                              Bblock
                                        /* Dans le cas ou aucun des trois systemes lineaires n'a pu etre resolu (les experiences     */
                                        /* ont montre que cela correspondait systematiquement a un determinant nul lors des          */
                                        /* trois calculs 'RESOLUTION_D_UN_SYSTEME_LINEAIRE(...)'. Cela signifie certainement que     */
                                        /* les deux segments 'S1' et 'S2' sont colineaires, ce que l'on va verifier ci-apres :       */
                              DEFV(Float,INIT(produit_vectoriel_X
                                             ,PvectX(SOUS(coordonnee_S1_Xext,coordonnee_S1_Xorg)
                                                    ,SOUS(coordonnee_S1_Yext,coordonnee_S1_Yorg)
                                                    ,SOUS(coordonnee_S1_Zext,coordonnee_S1_Zorg)
                                                    ,SOUS(coordonnee_S2_Xext,coordonnee_S2_Xorg)
                                                    ,SOUS(coordonnee_S2_Yext,coordonnee_S2_Yorg)
                                                    ,SOUS(coordonnee_S2_Zext,coordonnee_S2_Zorg)
                                                     )
                                              )
                                   );
                              DEFV(Float,INIT(produit_vectoriel_Y
                                             ,PvectY(SOUS(coordonnee_S1_Xext,coordonnee_S1_Xorg)
                                                    ,SOUS(coordonnee_S1_Yext,coordonnee_S1_Yorg)
                                                    ,SOUS(coordonnee_S1_Zext,coordonnee_S1_Zorg)
                                                    ,SOUS(coordonnee_S2_Xext,coordonnee_S2_Xorg)
                                                    ,SOUS(coordonnee_S2_Yext,coordonnee_S2_Yorg)
                                                    ,SOUS(coordonnee_S2_Zext,coordonnee_S2_Zorg)
                                                     )
                                              )
                                   );
                              DEFV(Float,INIT(produit_vectoriel_Z
                                             ,PvectZ(SOUS(coordonnee_S1_Xext,coordonnee_S1_Xorg)
                                                    ,SOUS(coordonnee_S1_Yext,coordonnee_S1_Yorg)
                                                    ,SOUS(coordonnee_S1_Zext,coordonnee_S1_Zorg)
                                                    ,SOUS(coordonnee_S2_Xext,coordonnee_S2_Xorg)
                                                    ,SOUS(coordonnee_S2_Yext,coordonnee_S2_Yorg)
                                                    ,SOUS(coordonnee_S2_Zext,coordonnee_S2_Zorg)
                                                     )
                                              )
                                   );
                                        /* Produit vectoriel des segments 'S1' et 'S2' ramenes a l'origine...                        */

                              Test(I3ET(IZEQ_a_peu_pres(produit_vectoriel_X,epsilon_de_test_des_produits_vectoriels)
                                       ,IZEQ_a_peu_pres(produit_vectoriel_Y,epsilon_de_test_des_produits_vectoriels)
                                       ,IZEQ_a_peu_pres(produit_vectoriel_Z,epsilon_de_test_des_produits_vectoriels)
                                        )
                                   )
                                   Bblock
                                        /* Cas ou les segments 'S1' et 'S2' sont colineaires :                                       */
                                   Test(IFET(I3ET(INCLff(coordonnee_S2_Xorg,coordonnee_S1_Xorg,coordonnee_S1_Xext)
                                                 ,INCLff(coordonnee_S2_Yorg,coordonnee_S1_Yorg,coordonnee_S1_Yext)
                                                 ,INCLff(coordonnee_S2_Zorg,coordonnee_S1_Zorg,coordonnee_S1_Zext)
                                                  )
                                            ,I3ET(INCLff(coordonnee_S2_Xext,coordonnee_S1_Xorg,coordonnee_S1_Xext)
                                                 ,INCLff(coordonnee_S2_Yext,coordonnee_S1_Yorg,coordonnee_S1_Yext)
                                                 ,INCLff(coordonnee_S2_Zext,coordonnee_S1_Zorg,coordonnee_S1_Zext)
                                                  )
                                             )
                                        )
                                        Bblock
                                        /* Cas ou le segment 'S2' est "inclus" dans le segment 'S1' (avec eventuellement             */
                                        /* coincidence de l'une ou des deux extremite(s) de 'S1' et de 'S2') :                       */
                                        EGAL(le_segment_S1_intersecte_au_moins_un_segment_S2,VRAI);
                                        /* On fait alors comme s'il y avait intersection (introduit le 20150804142249...).           */
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                        /* J'ai remarque le 20150804161420 que l'on passait ici pour 'v $xiirv/CARB.51'. La          */
                                        /* raison est simple : c'est la premiere image de type 'CARB' dont les segments sont         */
                                        /* tridimensionnels. Pour les autres images de type 'CARB' calculees avant cette date,       */
                                        /* les segments etaient bidimensionnels : etant donc dans le meme plan, la probabilite       */
                                        /* pour que les droites les supportant se coupent est tres grande et ainsi l'un des trois    */
                                        /* systemes lineaires a ete resolu et donc on ne passe pas par ici...                        */
                                   Eblock
                              ETes
                              Eblock
                         ETes
                         Eblock
                    EDoI
                    Eblock
               ATes
                    Bblock
                                        /* Cas du fonctionnement "neutre"...                                                         */
                    Eblock
               ETes

               Test(IFOU(EST_FAUX(le_segment_S1_intersecte_au_moins_un_segment_S2)
                        ,IFET(EST_VRAI(le_segment_S1_intersecte_au_moins_un_segment_S2)
                             ,IFEQ(SUCC(indexS1),DERNIER_ELEMENT_D_UN_FICHIER)
                              )
                         )
                    )
                                        /* Le test est un peu plus complique que l'on pourrait le souhaiter a cause du cas           */
                                        /* suivant :                                                                                 */
                                        /*                                                                                           */
                                        /*                  'S1' est l'avant-dernier segment,                                        */
                                        /*                  'S2' est donc le dernier segment,                                        */
                                        /*                                                                                           */
                                        /*                  'S1' intersecte 'S2'.                                                    */
                                        /*                                                                                           */
                                        /* Si alors on se contentait de tester 'le_segment_S1_intersecte_au_moins_un_segment_S2',    */
                                        /* 'S1' ne serait pas edite. Mais malheureusement, 'S2' ne serait jamais edite puisque       */
                                        /* toutes les boucles 'DoIn(...)'s sont terminees...                                         */
                    Bblock
                    CAL2(Prin0(" X1="));
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(coordonnee_S1_Xorg);
                    CAL2(Prin0(" Y1="));
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(coordonnee_S1_Yorg);
                    CAL2(Prin0(" Z1="));
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(coordonnee_S1_Zorg);
                    CAL2(Prin0(" X2="));
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(coordonnee_S1_Xext);
                    CAL2(Prin0(" Y2="));
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(coordonnee_S1_Yext);
                    CAL2(Prin0(" Z2="));
                    EDITION_DANS_gOPERATION_SUR_LES_FICHIERS(coordonnee_S1_Zext);
                                        /* Edition du segment courant 'S1' qui n'intersecte aucun segment 'S2'...                    */

                    CAL2(Prin0("\n"));
                    Eblock
               ATes
                    Bblock
                                        /* Par contre, si le segment courant 'S1' intersecte au moins un segment 'S2', alors il      */
                                        /* n'est pas edite (sauf s'il s'agit de l'avant-dernier).                                    */
                    Eblock
               ETes
               Eblock
          EDoI
          Eblock
     end_nouveau_block

     lGENERATION_D_UN_FICHIER(liste_initiale_des_S_Zext,S_Zext_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_S_Yext,S_Yext_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_S_Xext,S_Xext_IMPLICITE);

     lGENERATION_D_UN_FICHIER(liste_initiale_des_S_Zorg,S_Zorg_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_S_Yorg,S_Yorg_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_S_Xorg,S_Xorg_IMPLICITE);

     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.