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