/*************************************************************************************************************************************/
/* */
/* G E N E R A T I O N D ' U N P A V A G E D U D I S Q U E D E P O I N C A R E : */
/* */
/* */
/* Author of '$xci/valeurs_DPoincare.01$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20120522141653). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 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
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define COMPATIBILITE_2012060510 \
FAUX \
/* Permet de generer des segments {A,B} identiques a celles qui auraient pu etre generes */ \
/* anterieurement au 20120605104020... */
#define COMPATIBILITE_2012060512 \
FAUX \
/* Permet de generer l'ensemble des polygones (meme redondants) identiques a ceux qui */ \
/* auraient pu etre generes anterieurement au 20120605121054... */
#define EDITER_LES_COORDONNEES_DES_POINTS \
VRAI
#define EDITER_LES_COORDONNEES_NORMALISEES_DES_POINTS \
VRAI
/* Faut-il editer les coordonnees des points ('VRAI') ou pas ('FAUX') et doivent-elles */
/* normalisees ('VRAI') ou denormalisees ('FAUX') ? */
#define EDITER_LES_POINTS_SOUS_LA_FORME_DE_SEGMENTS_AB \
VRAI \
/* Faut-il editer des segments 'AB' ('VRAI') ou des points isoles ('FAUX') ? */
#define SUPPRIMER_LES_SEGMENTS_AB_REDONDANTS \
VRAI \
/* Faut-il supprimer les segments 'AB' redondants ('VRAI') ou les conserver ('FAUX') ? Ceci */ \
/* fut introduit le 20120609093349... */
#define INTERPOLER_CIRCULAIREMENT_ENTRE_LES_SOMMETS \
FAUX
#define FACTEUR_DE_CALCUL_DU_NOMBRE_DE_PAS_ANGULAIRES \
FLOT(VINGT)
/* Dans le cas ou 'IL_NE_FAUT_PAS(editer_les_points_sous_la_forme_de_segments_AB)', doit-on */
/* interpoler circulairement entre les sommets ('VRAI') ou pas ('FAUX') ? */
#define AVERTIR_DANS_LE_CAS_DE_RAYONS_NEGATIFS_OU_NULS \
FAUX \
/* Faut-il avertir ('VRAI') ou pas lors en acs de rayons negatifs ou nuls ('FAUX') ? */
#define NOMBRE_DE_COTES_DU_POLYGONE_FONDAMENTAL \
SIX \
/* Nombre de cotes 'N' du polygone fondamental. */
#define ANGLE_AU_SOMMET_EN_FRACTION_DU_CERCLE_TRIGONOMETRIQUE \
QUATRE \
/* Mesure des angles au sommet du polygone fondamental exprimee en fraction 'P' de 2.pi. */
#define PROFONDEUR_DU_DISQUE_DE_POINCARE \
DEUX \
/* Profondeur de la generation... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
/* On notera que l'on ne peut pas mettre ici : */
/* */
/* #include xci/valeurs.02.I" */
/* */
/* a cause du message : */
/* */
/* error: initializer element is not constant */
/* */
/* provoque par la fonction 'Finitialisation_d_une_constante_chaine_de_caracteres(...)'. */
/* On notera que l'on ne met pas ici : */
/* */
/* #include xci/valeurs.03.I" */
/* */
/* parce que l'on ne peut inclure '$xci/valeurs.02$I' ci-avant... */
DEFV(Local,DEFV(Logical,INIT(editer_les_coordonnees_des_points,EDITER_LES_COORDONNEES_DES_POINTS)));
DEFV(Local,DEFV(Logical,INIT(editer_les_coordonnees_normalisees_des_points,EDITER_LES_COORDONNEES_NORMALISEES_DES_POINTS)));
/* Faut-il editer les coordonnees des points ('VRAI') ou pas ('FAUX') et doivent-elles */
/* normalisees ('VRAI') ou denormalisees ('FAUX') ? */
DEFV(Local,DEFV(Logical,INIT(editer_les_points_sous_la_forme_de_segments_AB,EDITER_LES_POINTS_SOUS_LA_FORME_DE_SEGMENTS_AB)));
/* Faut-il editer des segments 'AB' ('VRAI') ou des points isoles ('FAUX') ? */
DEFV(Local,DEFV(Logical,INIT(supprimer_les_segments_AB_redondants,SUPPRIMER_LES_SEGMENTS_AB_REDONDANTS)));
/* Faut-il supprimer les segments 'AB' redondants ('VRAI') ou les conserver ('FAUX') ? Ceci */
/* fut introduit le 20120609093349... */
DEFV(Local,DEFV(Logical,INIT(interpoler_circulairement_entre_les_sommets,INTERPOLER_CIRCULAIREMENT_ENTRE_LES_SOMMETS)));
DEFV(Local,DEFV(Float,INIT(facteur_de_calcul_du_nombre_de_pas_angulaires,FACTEUR_DE_CALCUL_DU_NOMBRE_DE_PAS_ANGULAIRES)));
/* Dans le cas ou 'IL_NE_FAUT_PAS(editer_les_points_sous_la_forme_de_segments_AB)', doit-on */
/* interpoler circulairement entre les sommets ('VRAI') ou pas ('FAUX') ? */
#define INCLINAISON_GENERALE_DU_POLYGONE_FONDAMENTAL \
FZERO \
/* Donne l'inclinaison par rapport a l'horizontale du centre du cercle du premier cote du */ \
/* polygone fondamental. */
#define EDITION_DES_COORDONNEES(coord_X,coord_Y,editer,format_XY_normalisees,format_XY_denormalisees,format_numero_polygone) \
Bblock \
Test(IL_FAUT(editer_les_coordonnees_des_points)) \
Bblock \
Test(IL_FAUT(editer)) \
Bblock \
Test(IL_FAUT(editer_les_coordonnees_normalisees_des_points)) \
Bblock \
CAL2(Prin2(format_XY_normalisees \
,coord_X \
,coord_Y \
) \
); \
/* On notera que l'on ne peut utiliser 'NOMBRE_DE_DECIMALES_EFFECTIF(...)' ou encore */ \
/* 'valeurs_signees' et 'format_d_edition' tels qu'il sont definis d'une part dans */ \
/* 'v $xci/valeurs.02$I' et d'autre part dans '$xci/valeurs.03$I' pour des problemes */ \
/* de references en avant... */ \
/* */ \
/* Grace a ce format d'edition, on peut assurer les conversions : */ \
/* */ \
/* {X,Y} <--> CoordonneeCurviligne */ \
/* */ \
/* si besoin est... */ \
Eblock \
ATes \
Bblock \
CAL2(Prin2(format_XY_denormalisees \
,_cDENORMALISE_OX(coord_X) \
,_cDENORMALISE_OY(coord_Y) \
) \
); \
Eblock \
ETes \
\
CAL2(Prin2(format_numero_polygone \
,numero_du_polygone_courant \
,profondeur_courante \
) \
); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Edition des coordonnees. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S G E N E R A L E S R E L A T I V E S A U X P O L Y G O N E S */
/* D ' U N P A V A G E D U D I S Q U E D E P O I N C A R E : */
/* */
/*************************************************************************************************************************************/
DEFV(Int,INIT(profondeur_du_disque_de_Poincare,PROFONDEUR_DU_DISQUE_DE_POINCARE));
/* Profondeur de la generation... */
DEFV(Local,DEFV(Int,INIT(nombre_de_cotes_du_polygone_fondamental,NOMBRE_DE_COTES_DU_POLYGONE_FONDAMENTAL)));
/* Nombre de cotes 'N' du polygone fondamental. */
DEFV(Local,DEFV(Int,INIT(angle_au_sommet_en_fraction_du_cercle_trigonometrique,ANGLE_AU_SOMMET_EN_FRACTION_DU_CERCLE_TRIGONOMETRIQUE)));
/* Mesure des angles au sommet du polygone fondamental exprimee en fraction 'P' de 2.pi. */
DEFV(Local,DEFV(Float,INIT(demi_angle_au_sommet_du_polygone_fondamental,FLOT__UNDEF)));
DEFV(Local,DEFV(Float,INIT(demi_angle_au_centre_du_polygone_fondamental,FLOT__UNDEF)));
/* Definition de deux angles tres utiles... */
#define PREMIER_COTE_D_UN_POLYGONE \
PREMIER_POINT
#define sommet_de_reference_du_polygone_fondamental \
ACCES_SOMMET(polygone_fondamental,PREMIER_COTE_D_UN_POLYGONE)
/* Premier sommet du polygone fondamental. */
#define C_EST_LE_POLYGONE_FONDAMENTAL \
IFEQ(profondeur,PRED(profondeur_du_disque_de_Poincare)) \
/* Introduit le 20120609093349 afin de savoir si l'on est sur le polygone fondamental... */
#define sITb0(vecteur,index,dimension) \
ITb0(vecteur,index) \
/* Introduit afin que 'sITb0(...)' ait le meme nombre d'arguments (trois) que 'IdTb1(...)', */ \
/* ce qui n'est pas le cas de 'ITb0(...)' qui n'en a que deux... */
#define ACCES_SOMMET(nom_du_polygone,numero_du_cote_courant_du_polygone,ACCES) \
ACCES(liste_des_sommets_du`nom_du_polygone \
,INDX(numero_du_cote_courant_du_polygone,PREMIER_COTE_D_UN_POLYGONE) \
,nombre_de_cotes_du_polygone_fondamental \
)
#define ACCES_CENTRE(nom_du_polygone,numero_du_cote_courant_du_polygone,ACCES) \
ACCES(liste_des_centres_des_cercles_des_cotes_du`nom_du_polygone \
,INDX(numero_du_cote_courant_du_polygone,PREMIER_COTE_D_UN_POLYGONE) \
,nombre_de_cotes_du_polygone_fondamental \
) \
/* Procedure d'acces a un sommet du polygone fondamental. */
#define ACCES_RAYON_(nom_du_polygone,numero_du_cote_courant_du_polygone,ACCES) \
ACCES(liste_des_rayons_des_cercles_des_cotes_du`nom_du_polygone \
,INDX(numero_du_cote_courant_du_polygone,PREMIER_COTE_D_UN_POLYGONE) \
,nombre_de_cotes_du_polygone_fondamental \
)
#define DEBUT_DE_DEFINITION_D_UN_POLYGONE(nom_du_polygone) \
DEFV(pointF_2D,DdTb1(POINTERs \
,liste_des_sommets_du`nom_du_polygone \
,nombre_de_cotes_du_polygone_fondamental \
,tMalo(MUL2(nombre_de_cotes_du_polygone_fondamental,SIZE(pointF_2D)),pointF_2D) \
) \
); \
DEFV(pointF_2D,DdTb1(POINTERs \
,liste_des_centres_des_cercles_des_cotes_du`nom_du_polygone \
,nombre_de_cotes_du_polygone_fondamental \
,tMalo(MUL2(nombre_de_cotes_du_polygone_fondamental,SIZE(pointF_2D)),pointF_2D) \
) \
); \
DEFV(Float,DdTb1(POINTERf \
,liste_des_rayons_des_cercles_des_cotes_du`nom_du_polygone \
,nombre_de_cotes_du_polygone_fondamental \
,fMalo(MUL2(nombre_de_cotes_du_polygone_fondamental,size_Float)) \
) \
);
#define FIN_DE_DEFINITION_D_UN_POLYGONE(nom_du_polygone) \
FdTb1(liste_des_rayons_des_cercles_des_cotes_du`nom_du_polygone \
,nombre_de_cotes_du_polygone_fondamental \
,Float \
,ADRESSE_PLUS_DEFINIE \
); \
FdTb1(liste_des_centres_des_cercles_des_cotes_du`nom_du_polygone \
,nombre_de_cotes_du_polygone_fondamental \
,pointF_2D \
,ADRESSE_PLUS_DEFINIE \
); \
FdTb1(liste_des_sommets_du`nom_du_polygone \
,nombre_de_cotes_du_polygone_fondamental \
,pointF_2D \
,ADRESSE_PLUS_DEFINIE \
);
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F O N C T I O N S R E C U R S I V E S D E G E N E R A T I O N */
/* D ' U N P A V A G E D U D I S Q U E D E P O I N C A R E : */
/* */
/*************************************************************************************************************************************/
#define INVERSION_D_UNE_COORDONNEE_D_UN_POINT(oordonnee_2,coordonnee_1,centre_inversion,rayon_inversion) \
EGAL(oordonnee_2 \
,ADD2(centre_inversion \
,SCAL(SOUS(coordonnee_1,centre_inversion),longueur_1_au_carre,EXP2(rayon_inversion)) \
) \
) \
/* Procedure d'inversion d'une coordonnee d'un point. */
#define INVERSION_D_UN_POINT(point_2,point_1,centre_inversion,rayon_inversion) \
Bblock \
DEFV(Float,INIT(longueur_1_au_carre,FLOT__UNDEF)); \
\
EGAL(longueur_1_au_carre \
,pdisF2D(point_1,centre_inversion) \
); \
\
INVERSION_D_UNE_COORDONNEE_D_UN_POINT(ASD1(point_2,x) \
,ASD1(point_1,x) \
,ASD1(centre_inversion,x) \
,rayon_inversion \
); \
INVERSION_D_UNE_COORDONNEE_D_UN_POINT(ASD1(point_2,y) \
,ASD1(point_1,y) \
,ASD1(centre_inversion,y) \
,rayon_inversion \
); \
\
Test(IFGE(Rho_2D(ASD1(point_2,x),ASD1(point_2,y)),RAYON_DU_CERCLE_TRIGONOMETRIQUE)) \
Bblock \
PRINT_ERREUR("apres inversion, un point est sur la frontiere ou est a l'exterieur du disque"); \
CAL1(Prer7("(CentreInversion={%f,%f} RayonInversion=%f PointAvant={%f,%f} PointApres={%f,%f})\n" \
,ASD1(centre_inversion,x),ASD1(centre_inversion,y) \
,rayon_inversion \
,ASD1(point_1,x),ASD1(point_1,y) \
,ASD1(point_2,x),ASD1(point_2,y) \
) \
); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Procedure d'inversion d'un point suivant la definition : */ \
/* */ \
/* Soient : */ \
/* */ \
/* C : le centre d'inversion, */ \
/* R : la puissance d'inversion, */ \
/* P1 : un point quelconque, */ \
/* */ \
/* Le point P2 est l'inverse de P1 selon : */ \
/* */ \
/* ----> ----> 2 */ \
/* CP . CP = R */ \
/* 1 2 */ \
/* */
DEFV(Local,DEFV(Logical,INIT(avertir_dans_le_cas_de_rayons_negatifs_ou_nuls,AVERTIR_DANS_LE_CAS_DE_RAYONS_NEGATIFS_OU_NULS)));
/* Faut-il avertir ('VRAI') ou pas lors en acs de rayons negatifs ou nuls ('FAUX') ? */
#define INVERSION_DU_RAYON_D_UN_CERCLE(rayon_2,centre_cercle_1,rayon_1,centre_inversion,rayon_inversion) \
Bblock \
EGAL(rayon_2 \
,SCAL(rayon_1 \
,SOUS(pdisF2D(centre_inversion,centre_cercle_1) \
,EXP2(rayon_1) \
) \
,EXP2(rayon_inversion) \
) \
); \
/* Alors : 'SOUS(...)' ou 'SOUA(...)' ? En fait, il apparait qu'effectivement ce "rayon" */ \
/* ('rayon_2') peut etre negatif ! Il y a deux solutions : soit on utilise ici 'SOUA(...)', */ \
/* soit lorsque l'on utilise un rayon, on lui applique systematiquement 'ABSO(...)' comme */ \
/* cela est fait avec 'RAYON_DU_CERCLE' et 'RAYON_COURANT'. Enfin, on peut remplacer */ \
/* ci-apres 'NEUT(...)' par 'ABSO(...)'... */ \
\
Test(IZLE(rayon_2)) \
Bblock \
Test(IL_FAUT(avertir_dans_le_cas_de_rayons_negatifs_ou_nuls)) \
Bblock \
PRINT_ERREUR("apres inversion, un rayon est negatif ou nul"); \
CAL1(Prer7("(CentreInversion={%f,%f} RayonInversion=%f CentreCercle={%f,%f} Rayon1=%f Rayon2=%f)\n" \
,ASD1(centre_inversion,x),ASD1(centre_inversion,y) \
,rayon_inversion \
,ASD1(centre_cercle_1,x),ASD1(centre_cercle_1,y) \
,rayon_1 \
,rayon_2 \
) \
); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
EGAL(rayon_2,NEUT(rayon_2)); \
/* On peut remplacer 'NEUT(...)' par 'ABSO(...)'... */ \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Procedure d'inversion du rayon d'un cercle. */
#define INVERSION_D_UNE_COORDONNEE_DU_CENTRE_D_UN_CERCLE(coordonnee_2,rayon_2,coordonnee_1,rayon_1,centre_inversion,rayon_inversion) \
EGAL(coordonnee_2 \
,ADD2(centre_inversion \
,SCAL(SOUS(coordonnee_1,centre_inversion),rayon_1,rayon_2) \
) \
) \
/* Procedure d'inversion d'une coordonnee du centre d'un cercle. */
#define INVERSION_DU_CENTRE_D_UN_CERCLE(centre_cercle_2,rayon_2,centre_cercle_1,rayon_1,centre_inversion,rayon_inversion) \
Bblock \
Test(IFET(IFEQ(ASD1(centre_cercle_1,x),ASD1(centre_inversion,x)) \
,IFEQ(ASD1(centre_cercle_1,y),ASD1(centre_inversion,y)) \
) \
) \
Bblock \
EGAL(ASD1(centre_cercle_2,x),ASD1(centre_cercle_1,x)); \
EGAL(ASD1(centre_cercle_2,y),ASD1(centre_cercle_1,y)); \
EGAL(rayon_2,rayon_1); \
/* Cas ou le cercle a inverser est lui-meme le cercle d'inversion : on le conserve... */ \
Eblock \
ATes \
Bblock \
INVERSION_DU_RAYON_D_UN_CERCLE(rayon_2 \
,centre_cercle_1 \
,rayon_1 \
,centre_inversion \
,rayon_inversion \
); \
INVERSION_D_UNE_COORDONNEE_DU_CENTRE_D_UN_CERCLE(ASD1(centre_cercle_2,x) \
,rayon_2 \
,ASD1(centre_cercle_1,x) \
,rayon_1 \
,ASD1(centre_inversion,x) \
,rayon_inversion \
); \
INVERSION_D_UNE_COORDONNEE_DU_CENTRE_D_UN_CERCLE(ASD1(centre_cercle_2,y) \
,rayon_2 \
,ASD1(centre_cercle_1,y) \
,rayon_1 \
,ASD1(centre_inversion,y) \
,rayon_inversion \
); \
Eblock \
ETes \
Eblock \
/* Procedure d'inversion du centre d'un cercle suivant la definition : */ \
/* */ \
/* Soient : */ \
/* */ \
/* C : le centre d'inversion, */ \
/* R : la puissance d'inversion, */ \
/* K1 : un cercle de rayon R1 et de centre C1, */ \
/* A1 : l'un des deux points de tangence a K1 d'une droite */ \
/* issue de 'C'. */ \
/* */ \
/* L'inverse K2 du cercle K1 est tel que : */ \
/* */ \
/* Soient : */ \
/* */ \
/* C2 : le centre de K2, */ \
/* R2 : le rayon de K2, */ \
/* A2 : le points de tangence a K2 de la droite CA1. */ \
/* */ \
/* Les triangles {C,C2,A2} et {C,C1,A1} sont semblables et donc : */ \
/* */ \
/* CC CA C A R */ \
/* 2 2 2 2 2 */ \
/* ----- = ----- = ------ = ---- */ \
/* CC CA C A R */ \
/* 1 1 1 1 1 */ \
/* */ \
/* Le point A2 etant l'inverse de A1 (par definition de K2 inverse de K1), on a : */ \
/* */ \
/* 2 */ \
/* |CA |.|CA | = R */ \
/* 1 2 */ \
/* */ \
/* On deduit alors les deux formules (via le theoreme de Pythagore) : */ \
/* */ \
/* 2 */ \
/* R */ \
/* R = R .---------- */ \
/* 2 1 2 2 */ \
/* CC - R */ \
/* 1 1 */ \
/* */ \
/* */ \
/* R */ \
/* 2 */ \
/* CC = CC .---- */ \
/* 2 1 R */ \
/* 1 */ \
/* */ \
/* On notera au passage que C2 (centre de K2) n'est pas l'inverse de C1 (centre de K1)... */
DEFV(Local,DEFV(Int,INIT(numero_du_polygone_courant,ZERO)));
DEFV(Local,DEFV(Int,INIT(profondeur_courante,ZERO)));
/* Afin de donner une identite au polygone courant et sa profondeur... */
DEFV(Local,DEFV(Logical,INIT(compatibilite_2012060510,COMPATIBILITE_2012060510)));
/* Permet de generer des segments {A,B} identiques a celles qui auraient pu etre generes */
/* anterieurement au 20120605104020... */
DEFV(Local,DEFV(Logical,INIT(compatibilite_2012060512,COMPATIBILITE_2012060512)));
/* Permet de generer l'ensemble des polygones (meme redondants) identiques a ceux qui */
/* auraient pu etre generes anterieurement au 20120605121054... */
BFonctionI
DEFV(LoF,DEFV(FonctionI,InversionDUnPolygone(profondeur
,liste_des_centres_des_cercles_du_polygone_1
,liste_des_rayons_des_cercles_du_polygone_1
,liste_des_sommets_du_polygone_1
)
)
)
DEFV(Argument,DEFV(Int,profondeur));
/* Profondeur de la generation courante... */
DEFV(Argument,DEFV(pointF_2D,DTb0(liste_des_centres_des_cercles_des_cotes_du_polygone_1)));
DEFV(Argument,DEFV(Float,DTb0(liste_des_rayons_des_cercles_des_cotes_du_polygone_1)));
DEFV(Argument,DEFV(pointF_2D,DTb0(liste_des_sommets_du_polygone_1)));
/* Definition du polygone a inverser. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Int,INIT(numero_du_cote_courant_du_polygone_1,UNDEF));
DEFV(Float,INIT(longueur_du_plus_grand_cote_du_polygone_1,F_MOINS_L_INFINI));
INIT_ERROR;
/*..............................................................................................................................*/
INCR(numero_du_polygone_courant,I);
INCR(profondeur_courante,I);
Test(IFOU(C_EST_LE_POLYGONE_FONDAMENTAL
,IL_NE_FAUT_PAS(supprimer_les_segments_AB_redondants)
)
)
/* Test introduit le 20120609093349... */
Bblock
/* Cas ou l'on est sur le polygone fondamental ou bien les segments redondants doivent */
/* etre conserves... */
Eblock
ATes
Bblock
/* Cas ou les segments redondants peuvent etre elimines : */
DoIn(numero_du_cote_courant_du_polygone_1
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
DEFV(Int,INIT(numero_du_cote_suivant_du_polygone_1
,MODU(SUCC(numero_du_cote_courant_du_polygone_1)
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
)
)
);
EGAL(longueur_du_plus_grand_cote_du_polygone_1
,MAX2(RpdisF2D(ACCES_SOMMET(polygone_1,numero_du_cote_courant_du_polygone_1,IdTb1)
,ACCES_SOMMET(polygone_1,numero_du_cote_suivant_du_polygone_1,IdTb1)
)
,longueur_du_plus_grand_cote_du_polygone_1
)
);
/* Calcul introduit le 20120606183015... */
/* */
/* On notera que pour les polygones autres que le polygone fondamental, leur plus long cote */
/* (par le fait que l'inversion est ici une transformation "contractante") est aussi celui */
/* qui est commun avec leur polygone "pere" (de niveau superieur). Il est donc inutile de */
/* l'editer une seconde fois, d'ou ce test de longueur que l'on fera ci-apres pour */
/* l'eliminer (grace a 'longueur_du_plus_grand_cote_du_polygone_1'...). */
Eblock
EDoI
Eblock
ETes
DoIn(numero_du_cote_courant_du_polygone_1
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
Test(IL_NE_FAUT_PAS(interpoler_circulairement_entre_les_sommets))
Bblock
DEFV(Float,INIT(X1,ASD1(ACCES_SOMMET(polygone_1,numero_du_cote_courant_du_polygone_1,sITb0),x)));
DEFV(Float,INIT(Y1,ASD1(ACCES_SOMMET(polygone_1,numero_du_cote_courant_du_polygone_1,sITb0),y)));
DEFV(Float,INIT(X1_effectif,FLOT__UNDEF));
DEFV(Float,INIT(Y1_effectif,FLOT__UNDEF));
EGAL(X1_effectif,X1);
EGAL(Y1_effectif,Y1);
Test(IL_NE_FAUT_PAS(editer_les_points_sous_la_forme_de_segments_AB))
Bblock
EDITION_DES_COORDONNEES(X1_effectif
,Y1_effectif
,TOUJOURS_VRAI
,"xA=%+.^^^ yA=%+.^^^"
,"xA=%d yA=%d"
," NumeroPolygone=%d Profondeur=%d"
);
CAL2(Prin0("\n"));
Eblock
ATes
Bblock
DEFV(Int,INIT(numero_du_cote_suivant_du_polygone_1
,MODU(SUCC(numero_du_cote_courant_du_polygone_1)
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
)
)
);
DEFV(Float,INIT(X2,FLOT__UNDEF));
DEFV(Float,INIT(Y2,FLOT__UNDEF));
DEFV(Float,INIT(X2_effectif,FLOT__UNDEF));
DEFV(Float,INIT(Y2_effectif,FLOT__UNDEF));
EGAL(X2,ASD1(ACCES_SOMMET(polygone_1,numero_du_cote_suivant_du_polygone_1,sITb0),x));
EGAL(Y2,ASD1(ACCES_SOMMET(polygone_1,numero_du_cote_suivant_du_polygone_1,sITb0),y));
EGAL(X2_effectif,X2);
EGAL(Y2_effectif,Y2);
Test(IL_FAUT(compatibilite_2012060510))
Bblock
Eblock
ATes
Bblock
/* La sequence de tri qui suit a ete introduite le 20120605104020... */
Test(IFLT(X1,X2))
Bblock
/* Dans le cas ou X1<X2, l'ordre {1,2} est conserve... */
Eblock
ATes
Bblock
Test(IFGT(X1,X2))
Bblock
EGAL(X1_effectif,X2);
EGAL(Y1_effectif,Y2);
EGAL(X2_effectif,X1);
EGAL(Y2_effectif,Y1);
/* Dans le cas ou X1>X2, l'ordre {1,2} est inverse... */
Eblock
ATes
Bblock
Test(IFLT(Y1,Y2))
Bblock
/* Dans le cas ou X1=X2 et Y1<Y2, l'ordre {1,2} est conserve... */
Eblock
ATes
Bblock
Test(IFGT(Y1,Y2))
Bblock
EGAL(X1_effectif,X2);
EGAL(Y1_effectif,Y2);
EGAL(X2_effectif,X1);
EGAL(Y2_effectif,Y1);
/* Dans le cas ou X1=X2 et Y1>Y2, l'ordre {1,2} est inverse... */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Eblock
ETes
Eblock
ETes
Eblock
ETes
Test(I3OU(C_EST_LE_POLYGONE_FONDAMENTAL
,IL_NE_FAUT_PAS(supprimer_les_segments_AB_redondants)
,IFLT(RdisF2D(X1_effectif,Y1_effectif,X2_effectif,Y2_effectif)
,longueur_du_plus_grand_cote_du_polygone_1
)
)
)
/* Test introduit le 20120606183015... */
/* */
/* On regarde donc soit si nous sommes en train de traiter le polygone fondamental (via */
/* le test de 'profondeur'), soit pour les autres polygones s'il s'agit de cotes non */
/* encore edites (via le test de 'longueur_du_plus_grand_cote_du_polygone_1')... */
Bblock
EDITION_DES_COORDONNEES(X1_effectif
,Y1_effectif
,TOUJOURS_VRAI
,"xA=%+.^^^ yA=%+.^^^"
,"xA=%d yA=%d"
," NumeroPolygone=%d Profondeur=%d"
);
CAL2(Prin0(" "));
EDITION_DES_COORDONNEES(X2_effectif
,Y2_effectif
,TOUJOURS_VRAI
,"xB=%+.^^^ yB=%+.^^^"
,"xB=%d yB=%d"
," NumeroPolygone=%d Profondeur=%d"
);
/* Edition du segment courant {{X1,Y1},{X2,Y2}} systematiquement lorsque l'on traite le */
/* polygone fondamental, ou pour les polygones suivants, si ce segment n'est pas le plus */
/* long de ce polygone (auquel cas, il a deja ete traite a un niveau superieur...). On */
/* notera que j'avais essaye au prealable un test plus "leger" consistant a tester la */
/* valeur de 'numero_du_cote_courant_du_polygone_1, mais malheureusement, contrairement */
/* a mon espoir, cet indice n'est pas le meme (le premier, le dernier,...) d'un polygone */
/* a l'autre ; il y a en fait une sorte de permutation circulaire d'un cran a chaque */
/* nouveau polygone... */
CAL2(Prin0("\n"));
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Eblock
ATes
Bblock
DEFV(Int,INIT(nombre_de_pas,UNDEF));
/* Nombre de pas d'interpolation circulaire... */
DEFV(pointF_2D,centre);
DEFV(Float,INIT(rayon_du_cercle,FLOT__UNDEF));
/* Centre et rayon du cercle sur lequel se fait l'interpolation. */
DEFV(pointF_2D,sommet_1);
DEFV(Float,INIT(Rho__relatif_au_centre_du_sommet_1,FLOT__UNDEF));
DEFV(Float,INIT(Theta_relatif_au_centre_du_sommet_1,FLOT__UNDEF));
/* Origine (1) de l'interpolation circulaire. */
DEFV(pointF_2D,sommet_2);
DEFV(Float,INIT(Rho__relatif_au_centre_du_sommet_2,FLOT__UNDEF));
DEFV(Float,INIT(Theta_relatif_au_centre_du_sommet_2,FLOT__UNDEF));
/* Extremite (2) de l'interpolation circulaire. */
TRANSFERT_POINT_2D(centre,ACCES_CENTRE(polygone_1,NEUT(numero_du_cote_courant_du_polygone_1),sITb0));
EGAL(rayon_du_cercle,ACCES_RAYON_(polygone_1,numero_du_cote_courant_du_polygone_1,sITb0));
/* Definition du cercle sur lequel se fait l'interpolation. */
TRANSFERT_POINT_2D(sommet_1
,ACCES_SOMMET(polygone_1
,MODU(PRED(numero_du_cote_courant_du_polygone_1)
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
)
,sITb0
)
);
/* Definition de l'origine (1) de l'interpolation circulaire. */
TRANSFERT_POINT_2D(sommet_2
,ACCES_SOMMET(polygone_1,NEUT(numero_du_cote_courant_du_polygone_1),sITb0)
);
/* Definition de l'extremite (2) de l'interpolation circulaire. */
EGAL(Rho__relatif_au_centre_du_sommet_1
,Rho_2D(SOUS(ASD1(sommet_1,x),ASD1(centre,x)),SOUS(ASD1(sommet_1,y),ASD1(centre,y)))
);
EGAL(Theta_relatif_au_centre_du_sommet_1
,Theta_2D(SOUS(ASD1(sommet_1,x),ASD1(centre,x)),SOUS(ASD1(sommet_1,y),ASD1(centre,y)))
);
EGAL(Rho__relatif_au_centre_du_sommet_2
,Rho_2D(SOUS(ASD1(sommet_2,x),ASD1(centre,x)),SOUS(ASD1(sommet_2,y),ASD1(centre,y)))
);
EGAL(Theta_relatif_au_centre_du_sommet_2
,Theta_2D(SOUS(ASD1(sommet_2,x),ASD1(centre,x)),SOUS(ASD1(sommet_2,y),ASD1(centre,y)))
);
/* Determination des deux bornes extremes de 'Rho' et de 'Theta' lors de l'interpolation... */
Test(IFGT(SOUA(Theta_relatif_au_centre_du_sommet_1,Theta_relatif_au_centre_du_sommet_2),PI))
Bblock
/* Cas ou l'on passe par dessus '2.pi' : */
Test(IFLT(Theta_relatif_au_centre_du_sommet_1,Theta_relatif_au_centre_du_sommet_2))
Bblock
INCR(Theta_relatif_au_centre_du_sommet_1,CERCLE_TRIGONOMETRIQUE);
Eblock
ATes
Bblock
INCR(Theta_relatif_au_centre_du_sommet_2,CERCLE_TRIGONOMETRIQUE);
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
#define RAYON_DU_CERCLE \
ABSO(rayon_du_cercle)
Test(IFET(IFEQ_a_peu_pres_absolu(Rho__relatif_au_centre_du_sommet_1,RAYON_DU_CERCLE,igEPSILON)
,IFEQ_a_peu_pres_absolu(Rho__relatif_au_centre_du_sommet_2,RAYON_DU_CERCLE,igEPSILON)
)
)
Bblock
Eblock
ATes
Bblock
PRINT_ERREUR("incompatibilite entre les rayons extremes d'interpolation et celui d'inversion en valeur absolue");
CAL1(Prer3("(Rayon=%f Rho1=%f Rho2=%f)\n"
,rayon_du_cercle
,Rho__relatif_au_centre_du_sommet_1
,Rho__relatif_au_centre_du_sommet_2
)
);
Eblock
ETes
EGAL(nombre_de_pas
,INTE(MUL3(facteur_de_calcul_du_nombre_de_pas_angulaires
,RAYON_DU_CERCLE
,SOUA(Theta_relatif_au_centre_du_sommet_2,Theta_relatif_au_centre_du_sommet_1)
)
)
);
/* Le nombre de pas est donc proportionnel a la longueur de l'arc de cercle sur lequel on */
/* doit interpoler... */
/* */
/* Le 20161115152426, je note que si 'facteur_de_calcul_du_nombre_de_pas_angulaires' est */
/* trop petit, les arcs de cercle ont une apparence polyonale et ce d'autant plus qu'ils */
/* sont petits ('v $xiirv/POIN.13' ou en effet, les points ici generes sont joints les */
/* uns aux autres : 'v $xiirv/.POIN.21.$U isoles=FAUX.chainer=FAUX' ce qui donne des */
/* segments de plus en plus visibles...). */
EGAL(nombre_de_pas,MAX2(nombre_de_pas,DEUX));
/* Afin d'eviter une division par zero dans le 'BARY(...)' a venir... */
Repe(nombre_de_pas)
Bblock
DEFV(Float,INIT(lambda
,DIVI(FLOT(SOUS(compteur_des_repetitions_du_Repe,PREMIERE_ITERATION_D_UN_Repe))
,FLOT(SOUS(nombre_de_pas,PREMIERE_ITERATION_D_UN_Repe))
)
)
);
/* Parametre d'interpolation afin de balayer le cote du polygone du sommet 1 au sommet 2... */
DEFV(Float,INIT(Rho__courant,FLOT__UNDEF));
DEFV(Float,INIT(Theta_courant,FLOT__UNDEF));
DEFV(pointF_2D,point_intermediaire_interpole);
EGAL(Rho__courant
,BARY(Rho__relatif_au_centre_du_sommet_1
,Rho__relatif_au_centre_du_sommet_2
,lambda
)
);
EGAL(Theta_courant
,BARY(Theta_relatif_au_centre_du_sommet_1
,Theta_relatif_au_centre_du_sommet_2
,lambda
)
);
Test(IFEQ_a_peu_pres_absolu(Rho__courant,RAYON_DU_CERCLE,mgEPSILON))
Bblock
Eblock
ATes
Bblock
PRINT_ERREUR("le rayon interpole est incorrect en valeur absolue");
CAL1(Prer2("(Rayon=%f RayonInterpole=%f)\n"
,rayon_du_cercle
,Rho__courant
)
);
Eblock
ETes
#undef RAYON_DU_CERCLE
INITIALISATION_POINT_2D(point_intermediaire_interpole
,ADD2(ASD1(centre,x),Xcartesienne_2D(Rho__courant,Theta_courant))
,ADD2(ASD1(centre,y),Ycartesienne_2D(Rho__courant,Theta_courant))
);
Test(IFEQ(compteur_des_repetitions_du_Repe,PREMIERE_ITERATION_D_UN_Repe))
Bblock
Test(IFET(IFEQ_a_peu_pres_absolu(ASD1(point_intermediaire_interpole,x),ASD1(sommet_1,x),gEPSILON)
,IFEQ_a_peu_pres_absolu(ASD1(point_intermediaire_interpole,y),ASD1(sommet_1,y),gEPSILON)
)
)
Bblock
Eblock
ATes
Bblock
PRINT_ERREUR("le premier point d'une chaine d'interpolation est incorrect");
CAL1(Prer4("(Sommet1={%f,%f} PremierPoint={%f,%f})\n"
,ASD1(sommet_1,x),ASD1(sommet_1,y)
,ASD1(point_intermediaire_interpole,x),ASD1(point_intermediaire_interpole,y)
)
);
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Test(IFEQ(compteur_des_repetitions_du_Repe,nombre_de_pas))
Bblock
Test(IFET(IFEQ_a_peu_pres_absolu(ASD1(point_intermediaire_interpole,x),ASD1(sommet_2,x),gEPSILON)
,IFEQ_a_peu_pres_absolu(ASD1(point_intermediaire_interpole,y),ASD1(sommet_2,y),gEPSILON)
)
)
Bblock
Eblock
ATes
Bblock
PRINT_ERREUR("le dernier point d'une chaine d'interpolation est incorrect");
CAL1(Prer4("(Sommet2={%f,%f} DernierPoint={%f,%f})\n"
,ASD1(sommet_2,x),ASD1(sommet_2,y)
,ASD1(point_intermediaire_interpole,x),ASD1(point_intermediaire_interpole,y)
)
);
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(editer_les_points_sous_la_forme_de_segments_AB))
Bblock
Test(IFGT(compteur_des_repetitions_du_Repe,PREMIERE_ITERATION_D_UN_Repe))
Bblock
CAL2(Prin0(" "));
EDITION_DES_COORDONNEES(ASD1(point_intermediaire_interpole,x)
,ASD1(point_intermediaire_interpole,y)
,TOUJOURS_VRAI
,"xB=%+.^^^ yB=%+.^^^"
,"xB=%d yB=%d"
," NumeroPolygone=%d Profondeur=%d"
);
CAL2(Prin0("\n"));
Eblock
ATes
Bblock
Eblock
ETes
Test(IFLT(compteur_des_repetitions_du_Repe,nombre_de_pas))
Bblock
EDITION_DES_COORDONNEES(ASD1(point_intermediaire_interpole,x)
,ASD1(point_intermediaire_interpole,y)
,TOUJOURS_VRAI
,"xA=%+.^^^ yA=%+.^^^"
,"xA=%d yA=%d"
," NumeroPolygone=%d Profondeur=%d"
);
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
EDITION_DES_COORDONNEES(ASD1(point_intermediaire_interpole,x)
,ASD1(point_intermediaire_interpole,y)
,TOUJOURS_VRAI
,"xA=%+.^^^ yA=%+.^^^"
,"xA=%d yA=%d"
," NumeroPolygone=%d Profondeur=%d"
);
CAL2(Prin0("\n"));
Eblock
ETes
Eblock
ERep
Eblock
ETes
Eblock
EDoI
Test(IZGT(profondeur))
Bblock
DEFV(Float,INIT(diametre_du_polygone_1,F_MOINS_L_INFINI));
Test(IL_FAUT(compatibilite_2012060512))
/* Test introduit le 20120605121054... */
Bblock
Eblock
ATes
Bblock
DEFV(Int,INIT(numero_du_cote_courant_1_du_polygone_1,UNDEF));
DEFV(Int,INIT(numero_du_cote_courant_2_du_polygone_1,UNDEF));
DoIn(numero_du_cote_courant_1_du_polygone_1
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
DoIn(numero_du_cote_courant_2_du_polygone_1
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
EGAL(diametre_du_polygone_1
,MAX2(RpdisF2D(ACCES_SOMMET(polygone_1,numero_du_cote_courant_1_du_polygone_1,IdTb1)
,ACCES_SOMMET(polygone_1,numero_du_cote_courant_2_du_polygone_1,IdTb1)
)
,diametre_du_polygone_1
)
);
Eblock
EDoI
Eblock
EDoI
Eblock
ETes
DoIn(numero_du_cote_courant_du_polygone_1
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
DEFV(Int,INIT(numero_du_cote_courant_du_polygone_2,UNDEF));
DEBUT_DE_DEFINITION_D_UN_POLYGONE(polygone_2);
DoIn(numero_du_cote_courant_du_polygone_2
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
INVERSION_DU_CENTRE_D_UN_CERCLE(ACCES_CENTRE(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1)
,ACCES_RAYON_(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1)
,ACCES_CENTRE(polygone_1,numero_du_cote_courant_du_polygone_2,sITb0)
,ACCES_RAYON_(polygone_1,numero_du_cote_courant_du_polygone_2,sITb0)
,ACCES_CENTRE(polygone_1,numero_du_cote_courant_du_polygone_1,sITb0)
,ACCES_RAYON_(polygone_1,numero_du_cote_courant_du_polygone_1,sITb0)
);
INVERSION_D_UN_POINT(ACCES_SOMMET(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1)
,ACCES_SOMMET(polygone_1,numero_du_cote_courant_du_polygone_2,sITb0)
,ACCES_CENTRE(polygone_1,numero_du_cote_courant_du_polygone_1,sITb0)
,ACCES_RAYON_(polygone_1,numero_du_cote_courant_du_polygone_1,sITb0)
);
/* Generation d'un "polygone_2" par inversion du "polygone_1" par rapport a l'un de ses */
/* cotes de numero 'numero_du_cote_courant_du_polygone_1'. */
/* */
/* On notera que l'un de ses polygones "polygone_2" a ete deja ete genere mais, a un */
/* niveau 'profondeur_courante' inferieur (d'une unite...). */
Eblock
EDoI
DoIn(numero_du_cote_courant_du_polygone_2
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
DEFV(Float,INIT(distance_au_centre
,RpdisF2D(ACCES_SOMMET(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1)
,ACCES_CENTRE(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1)
)
)
);
#define RAYON_COURANT \
ABSO(rayon_courant)
DEFV(Float,INIT(rayon_courant,ACCES_RAYON_(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1)));
/* Afin de verifier que l'inversion des cercles et des sommets s'est bien passee... */
Test(IFEQ_a_peu_pres_absolu(distance_au_centre,RAYON_COURANT,mgEPSILON))
Bblock
Eblock
ATes
Bblock
PRINT_ERREUR("une inversion des cercles et des sommets est incoherente en valeur absolue");
CAL1(Prer6("(Centre=(%f,%f) Rayon=%f Sommet=(%f,%f) DistanceAuCentre=%f)\n"
,ASD1(ACCES_CENTRE(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1),x)
,ASD1(ACCES_CENTRE(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1),y)
,rayon_courant
,ASD1(ACCES_SOMMET(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1),x)
,ASD1(ACCES_SOMMET(polygone_2,numero_du_cote_courant_du_polygone_2,IdTb1),y)
,distance_au_centre
)
);
Eblock
ETes
#undef RAYON_COURANT
Eblock
EDoI
begin_nouveau_block
Bblock
DEFV(Float,INIT(diametre_du_polygone_2,F_MOINS_L_INFINI));
Test(IL_FAUT(compatibilite_2012060512))
/* Test introduit le 20120605121054... */
Bblock
Eblock
ATes
Bblock
DEFV(Int,INIT(numero_du_cote_courant_1_du_polygone_2,UNDEF));
DEFV(Int,INIT(numero_du_cote_courant_2_du_polygone_2,UNDEF));
DoIn(numero_du_cote_courant_1_du_polygone_2
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
DoIn(numero_du_cote_courant_2_du_polygone_2
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
EGAL(diametre_du_polygone_2
,MAX2(RpdisF2D(ACCES_SOMMET(polygone_2,numero_du_cote_courant_1_du_polygone_2,IdTb1)
,ACCES_SOMMET(polygone_2,numero_du_cote_courant_2_du_polygone_2,IdTb1)
)
,diametre_du_polygone_2
)
);
Eblock
EDoI
Eblock
EDoI
Eblock
ETes
Test(IFOU(IL_FAUT(compatibilite_2012060512)
,IFLT(diametre_du_polygone_2,diametre_du_polygone_1)
)
)
Bblock
/* Cas ou le 'polygone_2' est plus petit que le 'polygone_1' : on va le traiter.. */
CALS(InversionDUnPolygone(PRED(profondeur)
,liste_des_centres_des_cercles_des_cotes_du_polygone_2
,liste_des_rayons_des_cercles_des_cotes_du_polygone_2
,liste_des_sommets_du_polygone_2
)
);
/* Et cette operation est repetee recursivement. */
Eblock
ATes
Bblock
/* Cas ou le 'polygone_2' est plus grand que le 'polygone_1' : on va l'ignorer car, */
/* en effet, l'inversion que reduire les polygones sauf dans le cas d'un 'polygone_2' */
/* appartenant a la generation precedente (et donc deja traite...). */
Eblock
ETes
Eblock
end_nouveau_block
FIN_DE_DEFINITION_D_UN_POLYGONE(polygone_2);
Eblock
EDoI
Eblock
ATes
Bblock
Eblock
ETes
DECR(profondeur_courante,I);
RETU_ERROR;
Eblock
EFonctionI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* G E N E R A T I O N D ' U N P A V A G E D U D I S Q U E D E P O I N C A R E : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
/*..............................................................................................................................*/
GET_ARGUMENTSi(nombre_d_arguments
,BLOC(GET_ARGUMENT_L("compatibilite_2012060510=",compatibilite_2012060510);
GET_ARGUMENT_L("compatibilite_2012060512=",compatibilite_2012060512);
GET_ARGUMENT_L("editer_coordonnees=""coordonnees=",editer_les_coordonnees_des_points);
GET_ARGUMENT_L("coordonnees_normalisees=""normalisees=""norm="
,editer_les_coordonnees_normalisees_des_points
);
GET_ARGUMENT_N("coordonnees_denormalisees=""denormalisees=""denorm="
,editer_les_coordonnees_normalisees_des_points
);
GET_ARGUMENT_L("segments_AB=""segments=""AB="
,editer_les_points_sous_la_forme_de_segments_AB
);
GET_ARGUMENT_N("points_isoles=""points="
,editer_les_points_sous_la_forme_de_segments_AB
);
GET_ARGUMENT_L("supprimer_segments_AB_redondants=""supprimer_redondants=""sr="
,supprimer_les_segments_AB_redondants
);
GET_ARGUMENT_N("conserver_segments_AB_redondants=""conserver_redondants=""cr="
,supprimer_les_segments_AB_redondants
);
/* Arguments introduits le 20120609093349... */
GET_ARGUMENT_L("interpoler_circulairement=""circulaire=""ic="
,interpoler_circulairement_entre_les_sommets
);
GET_ARGUMENT_N("ne_pas_interpoler_circulairement=""nic="
,interpoler_circulairement_entre_les_sommets
);
GET_ARGUMENT_F("facteur_nombre_pas=""fnp=",facteur_de_calcul_du_nombre_de_pas_angulaires);
GET_ARGUMENT_L("rayons_negatifs_ou_nuls=""negatifs=""rnn=",avertir_dans_le_cas_de_rayons_negatifs_ou_nuls);
GET_ARGUMENT_I("nombre_cotes=""cotes=""nc=""N=",nombre_de_cotes_du_polygone_fondamental);
GET_ARGUMENT_I("angle_sommet=""angle=""as=""P=",angle_au_sommet_en_fraction_du_cercle_trigonometrique);
GET_ARGUMENT_I("profondeur=""recursivite=",profondeur_du_disque_de_Poincare);
)
);
Test(IFET(IL_FAUT(supprimer_les_segments_AB_redondants)
,IL_FAUT(interpoler_circulairement_entre_les_sommets)
)
)
/* Test introduit le 20120609095528... */
Bblock
PRINT_ERREUR("la suppression des segments 'AB' redondants est incompatible avec l'interpolation circulaire");
Eblock
ATes
Bblock
Eblock
ETes
Test(IFLT(ADD2(INVE(nombre_de_cotes_du_polygone_fondamental),INVE(angle_au_sommet_en_fraction_du_cercle_trigonometrique)),FDU))
/* Ce test provient de la contrainte suivante. Soient : */
/* */
/* O : l'origine du plan, */
/* A : le centre du cercle dont un arc est l'un des cotes du polygone */
/* fondamental, */
/* B : l'un des deux sommets du cote evoque ci-dessus. */
/* */
/* On a alors : */
/* */
/* / \ pi */
/* AOB = ---- */
/* N */
/* */
/* / \ pi pi */
/* ABO = ---- + ---- */
/* 2 P */
/* */
/* d'ou : */
/* */
/* / \ / \ / \ pi pi pi 1 1 1 */
/* OAB = pi - (AOB + ABO) = pi -(---- + ---- + ----) = pi.(--- - --- - ---) */
/* N 2 P 2 N P */
/* */
/* cet angle ne pouvant qu'etre strictement positif, on a : */
/* */
/* 1 1 1 */
/* --- + --- < --- */
/* N P 2 */
/* */
Bblock
DEFV(Float,INIT(rapportK,FLOT__UNDEF));
DEFV(Float,INIT(rayon_du_cercle_definissant_les_cotes_du_polygone_fondamental,FLOT__UNDEF));
DEFV(Float,INIT(longueur_du_cote_OA,FLOT__UNDEF));
DEFV(Float,INIT(longueur_du_cote_OB,FLOT__UNDEF));
DEFV(Int,INIT(numero_du_cote_courant_du_polygone_fondamental,UNDEF));
DEBUT_DE_DEFINITION_D_UN_POLYGONE(polygone_fondamental);
EGAL(demi_angle_au_centre_du_polygone_fondamental,DIVI(PI,nombre_de_cotes_du_polygone_fondamental));
EGAL(demi_angle_au_sommet_du_polygone_fondamental,DIVI(PI,angle_au_sommet_en_fraction_du_cercle_trigonometrique));
EGAL(rapportK
,EXP2(DIVI(SINX(demi_angle_au_centre_du_polygone_fondamental)
,COSX(demi_angle_au_sommet_du_polygone_fondamental)
)
)
);
EGAL(rayon_du_cercle_definissant_les_cotes_du_polygone_fondamental,RACX(DIVI(rapportK,COMP(rapportK))));
/* Le cercle de centre A (de rayon R) est orthogonal au cercle trigonometrique (de rayon 1). */
/* Ces deux cercles se coupent en deux points dont C. Le theoreme de Pythagore donne : */
/* */
/* 2 2 2 */
/* OA = OC + CA */
/* */
/* 2 2 2 */
/* OA = 1 + R */
/* */
/* La resolution du triangle OAB donne : */
/* */
/* / \ */
/* OA.sin(AOB) */
/* AB = -------------- */
/* / \ / \ */
/* sin(AOB+OAB) */
/* */
/* or : */
/* */
/* AB = R */
/* */
/* d'ou : */
/* */
/* _______ */
/* / 2 pi */
/* \/ 1 + R .sin(----) */
/* N */
/* R = ---------------------- */
/* pi pi */
/* sin(---- - ----) */
/* 2 P */
/* */
/* d'ou finalement : */
/* */
/* ______ */
/* / K */
/* R = \/ ----- */
/* 1-K */
/* */
/* avec : */
/* */
/* / pi \2 */
/* | sin(----) | */
/* | N | */
/* K =| -----------| */
/* | pi | */
/* | cos(----) | */
/* \ P / */
/* */
EGAL(longueur_du_cote_OA
,GpytF2D(RAYON_DU_CERCLE_TRIGONOMETRIQUE,rayon_du_cercle_definissant_les_cotes_du_polygone_fondamental)
);
EGAL(longueur_du_cote_OB
,MUL2(longueur_du_cote_OA
,DIVI(COSX(ADD2(demi_angle_au_centre_du_polygone_fondamental
,demi_angle_au_sommet_du_polygone_fondamental
)
)
,COSX(demi_angle_au_sommet_du_polygone_fondamental)
)
)
);
DoIn(numero_du_cote_courant_du_polygone_fondamental
,PREMIER_COTE_D_UN_POLYGONE
,LSTX(PREMIER_COTE_D_UN_POLYGONE,nombre_de_cotes_du_polygone_fondamental)
,I
)
Bblock
INITIALISATION_POINT_2D(ACCES_SOMMET(polygone_fondamental,numero_du_cote_courant_du_polygone_fondamental,IdTb1)
,Xcartesienne_2D(longueur_du_cote_OB
,ADD2(ADD2(demi_angle_au_centre_du_polygone_fondamental
,INCLINAISON_GENERALE_DU_POLYGONE_FONDAMENTAL
)
,MUL2(SOUS(numero_du_cote_courant_du_polygone_fondamental
,PREMIER_COTE_D_UN_POLYGONE
)
,DOUB(demi_angle_au_centre_du_polygone_fondamental)
)
)
)
,Ycartesienne_2D(longueur_du_cote_OB
,ADD2(ADD2(demi_angle_au_centre_du_polygone_fondamental
,INCLINAISON_GENERALE_DU_POLYGONE_FONDAMENTAL
)
,MUL2(SOUS(numero_du_cote_courant_du_polygone_fondamental
,PREMIER_COTE_D_UN_POLYGONE
)
,DOUB(demi_angle_au_centre_du_polygone_fondamental)
)
)
)
);
INITIALISATION_POINT_2D(ACCES_CENTRE(polygone_fondamental,numero_du_cote_courant_du_polygone_fondamental,IdTb1)
,Xcartesienne_2D(longueur_du_cote_OA
,ADD2(INCLINAISON_GENERALE_DU_POLYGONE_FONDAMENTAL
,MUL2(SOUS(numero_du_cote_courant_du_polygone_fondamental
,PREMIER_COTE_D_UN_POLYGONE
)
,DOUB(demi_angle_au_centre_du_polygone_fondamental)
)
)
)
,Ycartesienne_2D(longueur_du_cote_OA
,ADD2(INCLINAISON_GENERALE_DU_POLYGONE_FONDAMENTAL
,MUL2(SOUS(numero_du_cote_courant_du_polygone_fondamental
,PREMIER_COTE_D_UN_POLYGONE
)
,DOUB(demi_angle_au_centre_du_polygone_fondamental)
)
)
)
);
EGAL(ACCES_RAYON_(polygone_fondamental,numero_du_cote_courant_du_polygone_fondamental,IdTb1)
,rayon_du_cercle_definissant_les_cotes_du_polygone_fondamental
);
Eblock
EDoI
Test(IZGT(profondeur_du_disque_de_Poincare))
Bblock
CALS(InversionDUnPolygone(PRED(profondeur_du_disque_de_Poincare)
,liste_des_centres_des_cercles_des_cotes_du_polygone_fondamental
,liste_des_rayons_des_cercles_des_cotes_du_polygone_fondamental
,liste_des_sommets_du_polygone_fondamental
)
);
/* Inversion du polygone fondamental. */
/* */
/* Le 'PRED(profondeur_du_disque_de_Poincare)' peut paraitre inutile mais il est fait par */
/* "symetrie" avec ce qui est fait dans 'v $xci/valeurs_Hilbert2D$K REGLE_LEFT___', par */
/* exemple... */
Eblock
ATes
Bblock
Eblock
ETes
FIN_DE_DEFINITION_D_UN_POLYGONE(polygone_fondamental);
Eblock
ATes
Bblock
PRINT_ERREUR("la definition du polygone fondamental est impossible");
CAL1(Prer4("((1/(N=%d))+(1/(P=%d))=%f >= %f)\n"
,nombre_de_cotes_du_polygone_fondamental
,angle_au_sommet_en_fraction_du_cercle_trigonometrique
,ADD2(INVE(nombre_de_cotes_du_polygone_fondamental),INVE(angle_au_sommet_en_fraction_du_cercle_trigonometrique))
,FDU
)
);
Eblock
ETes
RETU_Commande;
Eblock
ECommande