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