/*************************************************************************************************************************************/ /* */ /* I N T E R S E C T I O N D E C O U P L E S D E S E G M E N T S : */ /* */ /* */ /* Definition : */ /* */ /* Pour chaque couple de segments {S1,S2}, on */ /* renvoie la valeur '$EXIST' ou '$NEXIST' suivant */ /* que S1 intersecte S2 ou pas respectivement. On */ /* notera que l'intersection concerne effectivement */ /* les segments et non pas les droites qui les */ /* portent... */ /* */ /* */ /* Author of '$xrv/intersection.01$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20150701090752). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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 EPSILON_DE_TEST_DES_DETERMINANTS \ FZERO \ /* Doit-on tester exactement la nullite des determinants ('FZERO') ou de facon approchee ? */ \ /* Ceci fut introduit le 20150703210250... */ #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 20150805163707... */ #define EDITER_LES_POINTS_D_INTERSECTION \ FAUX \ /* Faut-il editer les points d'intersection ('VRAI') ou pas ('FAUX') ? */ #define TRACER_LE_CALCUL_DES_INTERSECTIONS \ FAUX \ /* Faut-il tracer le calcul des points d'intersection ('VRAI') ou pas ('FAUX') ? */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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 S1_Xorg_IMPLICITE \ FZERO #define S1_Yorg_IMPLICITE \ FZERO #define S1_Zorg_IMPLICITE \ FZERO #define S1_Xext_IMPLICITE \ FZERO #define S1_Yext_IMPLICITE \ FZERO #define S1_Zext_IMPLICITE \ FZERO gGENERATION_D_UN_FICHIER(fichier_LISTE_S1_Xorg,liste_initiale_des_S1_Xorg); gGENERATION_D_UN_FICHIER(fichier_LISTE_S1_Yorg,liste_initiale_des_S1_Yorg); gGENERATION_D_UN_FICHIER(fichier_LISTE_S1_Zorg,liste_initiale_des_S1_Zorg); gGENERATION_D_UN_FICHIER(fichier_LISTE_S1_Xext,liste_initiale_des_S1_Xext); gGENERATION_D_UN_FICHIER(fichier_LISTE_S1_Yext,liste_initiale_des_S1_Yext); gGENERATION_D_UN_FICHIER(fichier_LISTE_S1_Zext,liste_initiale_des_S1_Zext); /* Definition en memoire des fichiers de coordonnees cartesiennes des segments 'S1'. */ #define ELEMENT_DU_FICHIER_LISTE_S1_Xorg(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S1_Xorg,index) #define ELEMENT_DU_FICHIER_LISTE_S1_Yorg(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S1_Yorg,index) #define ELEMENT_DU_FICHIER_LISTE_S1_Zorg(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S1_Zorg,index) #define ELEMENT_DU_FICHIER_LISTE_S1_Xext(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S1_Xext,index) #define ELEMENT_DU_FICHIER_LISTE_S1_Yext(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S1_Yext,index) #define ELEMENT_DU_FICHIER_LISTE_S1_Zext(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S1_Zext,index) /* Acces a un element courant des fichiers de coordonnees cartesiennes des segments 'S1'. */ #define S2_Xorg_IMPLICITE \ FZERO #define S2_Yorg_IMPLICITE \ FZERO #define S2_Zorg_IMPLICITE \ FZERO #define S2_Xext_IMPLICITE \ FZERO #define S2_Yext_IMPLICITE \ FZERO #define S2_Zext_IMPLICITE \ FZERO gGENERATION_D_UN_FICHIER(fichier_LISTE_S2_Xorg,liste_initiale_des_S2_Xorg); gGENERATION_D_UN_FICHIER(fichier_LISTE_S2_Yorg,liste_initiale_des_S2_Yorg); gGENERATION_D_UN_FICHIER(fichier_LISTE_S2_Zorg,liste_initiale_des_S2_Zorg); gGENERATION_D_UN_FICHIER(fichier_LISTE_S2_Xext,liste_initiale_des_S2_Xext); gGENERATION_D_UN_FICHIER(fichier_LISTE_S2_Yext,liste_initiale_des_S2_Yext); gGENERATION_D_UN_FICHIER(fichier_LISTE_S2_Zext,liste_initiale_des_S2_Zext); /* Definition en memoire des fichiers de coordonnees cartesiennes des segments 'S2'. */ #define ELEMENT_DU_FICHIER_LISTE_S2_Xorg(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S2_Xorg,index) #define ELEMENT_DU_FICHIER_LISTE_S2_Yorg(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S2_Yorg,index) #define ELEMENT_DU_FICHIER_LISTE_S2_Zorg(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S2_Zorg,index) #define ELEMENT_DU_FICHIER_LISTE_S2_Xext(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S2_Xext,index) #define ELEMENT_DU_FICHIER_LISTE_S2_Yext(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S2_Yext,index) #define ELEMENT_DU_FICHIER_LISTE_S2_Zext(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_S2_Zext,index) /* Acces a un element courant des fichiers de coordonnees cartesiennes des segments 'S2'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A C R O S U T I L E S : */ /* */ /*************************************************************************************************************************************/ #define TRACE_DU_CALCUL_DES_INTERSECTIONS(impression) \ Bblock \ Test(IL_FAUT(tracer_le_calcul_des_intersections)) \ Bblock \ Test(EST_VRAI(une_valeur_courante_au_moins_a_ete_editee)) \ Bblock \ CAL2(Prin0("\n")); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ CAL2(Prin1("TRACE DU CALCUL DES INTERSECTIONS (index=%d) : ",index)); \ BLOC(impression); \ \ Test(EST_FAUX(une_valeur_courante_au_moins_a_ete_editee)) \ Bblock \ CAL2(Prin0("\n")); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock #define RESOLUTION_D_UN_SYSTEME_LINEAIRE(coordonnee1,coordonnee2,coordonnee3,message_determinant_non_nul,message_determinant_nul) \ 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... */ \ \ TRACE_DU_CALCUL_DES_INTERSECTIONS(BLOC(Bblock \ CAL2(Prin1("%s",message_determinant_non_nul)); \ Eblock \ ) \ ); \ \ 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 \ TRACE_DU_CALCUL_DES_INTERSECTIONS(BLOC(Bblock \ CAL2(Prin2("T1=%f T2=%f" \ ,coordonnee_S1_T \ ,coordonnee_S2_T \ ) \ ); \ Eblock \ ) \ ); \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ TRACE_DU_CALCUL_DES_INTERSECTIONS(BLOC(Bblock \ CAL2(Prin1("%s",message_determinant_nul)); \ Eblock \ ) \ ); \ 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 E C O U P L E S D E S E G M E N T S : */ /* */ /*************************************************************************************************************************************/ BCommande(nombre_d_arguments,arguments) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock 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 20150703210250... */ 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 20150805163707... */ DEFV(Logical,INIT(editer_les_points_d_intersection,EDITER_LES_POINTS_D_INTERSECTION)); /* Faut-il editer les points d'intersection ('VRAI') ou pas ('FAUX') ? */ DEFV(Logical,INIT(tracer_le_calcul_des_intersections,TRACER_LE_CALCUL_DES_INTERSECTIONS)); /* Faut-il tracer le calcul des points d'intersection ('VRAI') ou pas ('FAUX') ? */ #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_S1_Xorg=" ,fichier_LISTE_S1_Xorg ,liste_initiale_des_S1_Xorg ,S1_Xorg_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S1_Yorg=" ,fichier_LISTE_S1_Yorg ,liste_initiale_des_S1_Yorg ,S1_Yorg_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S1_Zorg=" ,fichier_LISTE_S1_Zorg ,liste_initiale_des_S1_Zorg ,S1_Zorg_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S1_Xext=" ,fichier_LISTE_S1_Xext ,liste_initiale_des_S1_Xext ,S1_Xext_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S1_Yext=" ,fichier_LISTE_S1_Yext ,liste_initiale_des_S1_Yext ,S1_Yext_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S1_Zext=" ,fichier_LISTE_S1_Zext ,liste_initiale_des_S1_Zext ,S1_Zext_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S2_Xorg=" ,fichier_LISTE_S2_Xorg ,liste_initiale_des_S2_Xorg ,S2_Xorg_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S2_Yorg=" ,fichier_LISTE_S2_Yorg ,liste_initiale_des_S2_Yorg ,S2_Yorg_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S2_Zorg=" ,fichier_LISTE_S2_Zorg ,liste_initiale_des_S2_Zorg ,S2_Zorg_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S2_Xext=" ,fichier_LISTE_S2_Xext ,liste_initiale_des_S2_Xext ,S2_Xext_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S2_Yext=" ,fichier_LISTE_S2_Yext ,liste_initiale_des_S2_Yext ,S2_Yext_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_S2_Zext=" ,fichier_LISTE_S2_Zext ,liste_initiale_des_S2_Zext ,S2_Zext_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); GET_ARGUMENT_F("epsilon_determinants=""epsdet=",epsilon_de_test_des_determinants); /* Argument introduit le 20150703210250... */ GET_ARGUMENT_F("epsilon_produits_vectoriels=""epspv=",epsilon_de_test_des_produits_vectoriels); /* Argument introduit le 20150805163707... */ GET_ARGUMENT_L("editer_points_intersection=""editer=""epi=",editer_les_points_d_intersection); GET_ARGUMENT_L("tracer_intersections=""tracer=""ti=",tracer_le_calcul_des_intersections); PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_3; PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_1; PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_5; /* Cette procedure fut introduite le 20211005105629... */ ) ); gOPERATION_SUR_LES_FICHIERS(BLOC( DEFV(Float,INIT(coordonnee_S1_Xorg,ELEMENT_DU_FICHIER_LISTE_S1_Xorg(index))); DEFV(Float,INIT(coordonnee_S1_Yorg,ELEMENT_DU_FICHIER_LISTE_S1_Yorg(index))); DEFV(Float,INIT(coordonnee_S1_Zorg,ELEMENT_DU_FICHIER_LISTE_S1_Zorg(index))); /* Recuperation des coordonnees {S1_Xorg,S1_Yorg,S1_Zorg} courantes dans les fichiers. */ DEFV(Float,INIT(coordonnee_S1_Xext,ELEMENT_DU_FICHIER_LISTE_S1_Xext(index))); DEFV(Float,INIT(coordonnee_S1_Yext,ELEMENT_DU_FICHIER_LISTE_S1_Yext(index))); DEFV(Float,INIT(coordonnee_S1_Zext,ELEMENT_DU_FICHIER_LISTE_S1_Zext(index))); /* Recuperation des coordonnees {S1_Xext,S1_Yext,S1_Zext} courantes dans les fichiers. */ DEFV(Float,INIT(coordonnee_S2_Xorg,ELEMENT_DU_FICHIER_LISTE_S2_Xorg(index))); DEFV(Float,INIT(coordonnee_S2_Yorg,ELEMENT_DU_FICHIER_LISTE_S2_Yorg(index))); DEFV(Float,INIT(coordonnee_S2_Zorg,ELEMENT_DU_FICHIER_LISTE_S2_Zorg(index))); /* Recuperation des coordonnees {S2_Xorg,S2_Yorg,S2_Zorg} courantes dans les fichiers. */ DEFV(Float,INIT(coordonnee_S2_Xext,ELEMENT_DU_FICHIER_LISTE_S2_Xext(index))); DEFV(Float,INIT(coordonnee_S2_Yext,ELEMENT_DU_FICHIER_LISTE_S2_Yext(index))); DEFV(Float,INIT(coordonnee_S2_Zext,ELEMENT_DU_FICHIER_LISTE_S2_Zext(index))); /* 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)); DEFV(Logical,INIT(les_segments_S1_et_S2_ont_un_point_commun,FAUX)); /* Les segments '1' et '2' ont-ils un point commun ? */ 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 des parametres de l'equation parametrique de la droite du segment */ /* */ /* 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 ,"determinant_XY # 0" ,"determinant_XY = 0" ); RESOLUTION_D_UN_SYSTEME_LINEAIRE(Y,Z,X ,"determinant_YZ # 0" ,"determinant_YZ = 0" ); RESOLUTION_D_UN_SYSTEME_LINEAIRE(Z,X,Y ,"determinant_ZX # 0" ,"determinant_ZX = 0" ); /* 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(les_segments_S1_et_S2_ont_un_point_commun,VRAI); /* Le point d'intersection {X,Y,Z} appartient aux segments '1' et '2'... */ Test(IL_FAUT(editer_les_points_d_intersection)) Bblock EDITION_DES_POINTS_D_INTERSECTION; Eblock ATes Bblock Eblock ETes Eblock ATes Bblock TRACE_DU_CALCUL_DES_INTERSECTIONS(BLOC(Bblock CAL2(Prin0("intersection hors segment")); EDITION_DES_POINTS_D_INTERSECTION; Eblock ) ); 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(les_segments_S1_et_S2_ont_un_point_commun,VRAI); /* On fait alors comme s'il y avait intersection (introduit le 20150805162711...). */ Test(IL_FAUT(editer_les_points_d_intersection)) Bblock EDITION_DES_POINTS_D_INTERSECTION; Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock ATes Bblock /* Voir a ce propos 'v $xrv/intersection.11$K .xiirv.CARB.51'... */ Eblock ETes Eblock ETes ) ,FLOT(les_segments_S1_et_S2_ont_un_point_commun) ,EDITER_LA_VALEUR_RESULTANTE_DANS_gOPERATION_SUR_LES_FICHIERS ,nombre_d_exemplaires_du_resultat_de_l_operation_sur_les_valeurs_courantes ); /* Intersection des sgments 'S1' et 'S2' : */ /* */ /* S1 intersecte S2 ==> $EXIST */ /* S1 n'intersecte pas S2 ==> $NEXIST */ /* */ /* en rappelant qu'il s'agit bien des segments eux-memes et non pas des droites qui les */ /* contiennent... */ lGENERATION_D_UN_FICHIER(liste_initiale_des_S2_Zext,S2_Zext_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S2_Yext,S2_Yext_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S2_Xext,S2_Xext_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S2_Zorg,S2_Zorg_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S2_Yorg,S2_Yorg_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S2_Xorg,S2_Xorg_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S1_Zext,S1_Zext_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S1_Yext,S1_Yext_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S1_Xext,S1_Xext_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S1_Zorg,S1_Zorg_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S1_Yorg,S1_Yorg_IMPLICITE); lGENERATION_D_UN_FICHIER(liste_initiale_des_S1_Xorg,S1_Xorg_IMPLICITE); RETU_Commande; Eblock ECommande