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