/*************************************************************************************************************************************/
/* */
/* C A L C U L D E L ' I N E R T I E D E L ' I M A G E A R G U M E N T : */
/* */
/* */
/* Definition : */
/* */
/* Cette commande calcule les moments */
/* d'inertie locaux de l'image Argument. */
/* et les renvoie sous forme (Vx,Vy). */
/* */
/* */
/* Author of '$xci/inertie.01$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 1993??????????). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 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 : */
/* */
/*************************************************************************************************************************************/
#include xci/inertie.01.I"
#define SEUIL_DE_FAUX_VRAI_POUR_LES_NIVEAUX_A_TRAITER \
GRIS_4 \
/* Seuil de discrimination {FAUX,VRAI} introduit le 20060306092808 lors de l'entree de la */ \
/* liste des niveaux a traiter via une palette de couleur. */
#define EXCLURE_UN_NIVEAU_DE_LA_CONVOLUTION \
FAUX
#define NIVEAU_A_EXCLURE_DE_LA_CONVOLUTION \
NOIR
/* Faut-il ('VRAI') ou pas ('FAUX') exclure un niveau de la convolution (par defaut le */
/* NOIR) ? Cela fut introduit le 20060306092808... */
#define FAIRE_TOURNER_LES_VECTEURS_PROPRES \
VRAI \
/* Faut-il faire tourner de pi/4 la base de vecteurs propres ? Cette rotation a ete */ \
/* introduite, car, en effet, contrairement a l'intuition, sur une image du type de */ \
/* 'v $xiio/MIRE' (voir 'v $xtc/inertie.01$c'), les vecteurs propres ne sont pas horizontaux */ \
/* et verticaux, mais orientes a pi/4 par rapport a l'horizontale... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#include xci/convol.01.I"
#include xci/inertie.02.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C A L C U L D E L ' I N E R T I E D E L ' I M A G E A R G U M E N T : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(CHAR,INIC(POINTERc(nom_imageRs1),NOM_PIPE));
DEFV(CHAR,INIC(POINTERc(nom_imageRs2),NOM_PIPE));
DEFV(CHAR,INIC(POINTERc(nom_imageRX1),NOM_PIPE));
DEFV(CHAR,INIC(POINTERc(nom_imageRY1),NOM_PIPE));
DEFV(CHAR,INIC(POINTERc(nom_imageRX2),NOM_PIPE));
DEFV(CHAR,INIC(POINTERc(nom_imageRY2),NOM_PIPE));
DEFV(CHAR,INIC(POINTERc(nom_imageA),NOM_PIPE));
DEFV(genere_p,INIT(seuil_de_FAUX_VRAI_pour_les_niveaux_a_traiter,SEUIL_DE_FAUX_VRAI_POUR_LES_NIVEAUX_A_TRAITER));
DEFV(CHAR,INIC(POINTERc(nom_paletteA),NOM_PIPE));
/* Nom de la palette a utiliser eventuellement et seuil de discrimination {FAUX,VRAI} */
/* introduits le 20060306092808... */
DEFV(Logical,INIT(exclure_un_niveau_de_la_convolution,EXCLURE_UN_NIVEAU_DE_LA_CONVOLUTION));
DEFV(genere_p,INIT(niveau_a_exclure_de_la_convolution,NIVEAU_A_EXCLURE_DE_LA_CONVOLUTION));
/* Faut-il ('VRAI') ou pas ('FAUX') exclure un niveau de la convolution (par defaut le */
/* NOIR) ? Cela fut introduit le 20060306092808... */
DEFV(Logical,DTb1(niveaux_a_traiter,COULEURS));
/* Definit les niveaux sur lesquels on doit faire la convolution par 'Pconvolution()'. */
DEFV(Logical,DTb1(niveaux_cumulables,COULEURS));
/* Definit les niveaux cumulables lors du calcul de 'Pconvolution_____cumul_courant'. */
DEFV(Logical,INIT(le_noyau_de_convolution_est_carre,LE_NOYAU_DE_CONVOLUTION_EST_CARRE));
/* Indique si le noyau de convolution est carre ('VRAI') ou circulaire ('FAUX'). */
DEFV(Float,INIT(facteur_multiplicatif,FACTEUR_MULTIPLICATIF_DE_CONVOLUTION));
/* Facteur multiplicatif du produit de convolution en chaque point {X,Y}. */
DEFV(Int,INIT(nombre_de_points,NOMBRE_DE_POINTS_DU_NOYAU));
/* Nombre de points du noyau. */
DEFV(Float,DTb1(noyau,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION));
/* Noyau de la convolution, */
DEFV(Float,INIT(noyau_01,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_02,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_03,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_04,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_05,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_06,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_07,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_08,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_09,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_10,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_11,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_12,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_13,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_14,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_15,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_16,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_17,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_18,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_19,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_20,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_21,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_22,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_23,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_24,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
DEFV(Float,INIT(noyau_25,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION));
/* Definition des 9 premiers elements du noyau (meme si le noyau fait moins de 9 points), */
/* et qui sont redefinissables. A titre d'exemple : */
/* */
/* p=9 n1=0 n2=+1 n3=0 n4=0 n5=0 n6=-1 n7=0 n8=0 n9=0 normaliser=FAUX renormaliser=VRAI */
/* */
/* donne la derivee de 'ImageR' par rapport a 'OX', alors que : */
/* */
/* p=9 n1=0 n2=0 n3=0 n4=+1 n5=0 n6=0 n7=0 n8=-1 n9=0 normaliser=FAUX renormaliser=VRAI */
/* */
/* donne la derivee de 'ImageR' par rapport a 'OY'. */
/* */
/* Le passage de 9 a 25 a ete introduit le 20210308132551... */
DEFV(Logical,DTb1(inhibition_du_noyau,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION));
/* Et sa liste d'activite. */
DEFV(Logical,INIT(editer_les_situations_impossibles,EDITER_LES_SITUATIONS_IMPOSSIBLES));
/* Faut-il editer tous les cas d'impossibilite de calculer les vecteurs propres ? */
DEFV(Logical,INIT(faire_tourner_les_vecteurs_propres,FAIRE_TOURNER_LES_VECTEURS_PROPRES));
/* Faut-il faire tourner de pi/4 la base de vecteurs propres ? Cette rotation a ete */
/* introduite, car, en effet, contrairement a l'intuition, sur une image du type de */
/* 'v $xiio/MIRE' (voir 'v $xtc/inertie.01$c'), les vecteurs propres ne sont pas horizontaux */
/* et verticaux, mais orientes a pi/4 par rapport a l'horizontale... */
DEFV(Int,INIT(index,UNDEF));
/* Index d'initialisation du noyau. */
/*..............................................................................................................................*/
EGAL(Pconvolution_____normaliser_le_cumul_pondere,FAUX);
/* Voir les commentaires relatifs au calcul des moments d'inertie lors de la definition de */
/* 'Pconvolution(...)' dans 'v $xiii/di_image$FON'... */
GET_ARGUMENTSi(nombre_d_arguments
,BLOC(GET_ARGUMENT_C("imageA=""A=",nom_imageA);
GET_ARGUMENT_C("imageRs1=""Rs1=",nom_imageRs1);
GET_ARGUMENT_C("imageRs2=""Rs2=",nom_imageRs2);
GET_ARGUMENT_C("imageRX1=""RX1=",nom_imageRX1);
GET_ARGUMENT_C("imageRY1=""RY1=",nom_imageRY1);
GET_ARGUMENT_C("imageRX2=""RX2=",nom_imageRX2);
GET_ARGUMENT_C("imageRY2=""RY2=",nom_imageRY2);
GET_ARGUMENT_C("paletteA=""palette=""pA=",nom_paletteA);
/* ATTENTION : le parametre "p=" ne peut etre defini ici a cause de 'nombre_de_points'... */
GET_ARGUMENT_P("sp=""seuil_palette=",seuil_de_FAUX_VRAI_pour_les_niveaux_a_traiter);
GET_ARGUMENT_L("exclure=",exclure_un_niveau_de_la_convolution);
GET_ARGUMENT_P("niveau_a_exclure=""ne=",niveau_a_exclure_de_la_convolution);
GET_ARGUMENT_L("noyau_carre=""ncarre=",le_noyau_de_convolution_est_carre);
/* Le 20060118092753, "carre=" a ete remplace par "noyau_carre=" et "ncarre=" (risque de */
/* double definition...). */
GET_ARGUMENT_N("noyau_circulaire=""ncirculaire=",le_noyau_de_convolution_est_carre);
/* Ces deux parametres furent introduits le 20071003113934... */
GET_ARGUMENT_F("facteur=""f=",facteur_multiplicatif);
GET_ARGUMENT_I("pmX=",Pconvolution_____pasX_de_la_mosaique_de_convolution);
GET_ARGUMENT_I("pmY=",Pconvolution_____pasY_de_la_mosaique_de_convolution);
GET_ARGUMENT_I("tmX=",Pconvolution_____translationX_de_la_mosaique_de_convolution);
GET_ARGUMENT_I("tmY=",Pconvolution_____translationY_de_la_mosaique_de_convolution);
GET_ARGUMENT_I("saut=",Pconvolution_____nombre_de_points_sautes);
GET_ARGUMENT_L("circulaire=",Pconvolution_____parcourir_circulairement_les_spirales_carrees);
/* Option introduite le 20040703110246... */
GET_ARGUMENT_L("circulaire_optimale="
,Pconvolution_____adapter_le_nombre_de_points_lors_du_parcours_circulaire_des_spirales_carrees
);
/* Option introduite le 20061224122501... */
GET_ARGUMENT_L("normaliser=",Pconvolution_____normaliser_le_cumul_pondere);
GET_ARGUMENT_I("points=""p=",nombre_de_points);
GET_ARGUMENT_F("n1=",noyau_01);
GET_ARGUMENT_F("n2=",noyau_02);
GET_ARGUMENT_F("n3=",noyau_03);
GET_ARGUMENT_F("n4=",noyau_04);
GET_ARGUMENT_F("n5=",noyau_05);
GET_ARGUMENT_F("n6=",noyau_06);
GET_ARGUMENT_F("n7=",noyau_07);
GET_ARGUMENT_F("n8=",noyau_08);
GET_ARGUMENT_F("n9=",noyau_09);
GET_ARGUMENT_F("n10=",noyau_10);
GET_ARGUMENT_F("n11=",noyau_11);
GET_ARGUMENT_F("n12=",noyau_12);
GET_ARGUMENT_F("n13=",noyau_13);
GET_ARGUMENT_F("n14=",noyau_14);
GET_ARGUMENT_F("n15=",noyau_15);
GET_ARGUMENT_F("n16=",noyau_16);
GET_ARGUMENT_F("n17=",noyau_17);
GET_ARGUMENT_F("n18=",noyau_18);
GET_ARGUMENT_F("n19=",noyau_19);
GET_ARGUMENT_F("n20=",noyau_20);
GET_ARGUMENT_F("n21=",noyau_21);
GET_ARGUMENT_F("n22=",noyau_22);
GET_ARGUMENT_F("n23=",noyau_23);
GET_ARGUMENT_F("n24=",noyau_24);
GET_ARGUMENT_F("n25=",noyau_25);
/* Le passage de 9 a 25 a ete introduit le 20210308132551... */
/* */
/* Disposition des 25 premiers points du noyau sur la spirale : */
/* */
/* */
/* 17---16---15---14---13 */
/* | | */
/* | | */
/* 18 5----4----3 12 */
/* | | | | */
/* | | | | */
/* 19 6 1----2 11 */
/* | | | */
/* | | | */
/* 20 7----8----9---10 */
/* | */
/* | */
/* 21---22---23---24---25 */
/* */
GET_ARGUMENT_L("editer_noyau_convolution=""enc=",Pconvolution_____editer_le_noyau_de_convolution);
GET_ARGUMENT_I("Xedition_noyau_convolution=""Xenc="
,Pconvolution_____coordonnee_X_d_edition_du_noyau_de_convolution
);
GET_ARGUMENT_I("Yedition_noyau_convolution=""Yenc="
,Pconvolution_____coordonnee_Y_d_edition_du_noyau_de_convolution
);
/* Possibilite introduite le 20210309110304... */
GET_ARGUMENT_I("spirale_horizontal=",SPIRALE_DEFINITION_____facteur_delta_horizontal);
GET_ARGUMENT_I("spirale_vertical=",SPIRALE_DEFINITION_____facteur_delta_vertical);
GET_ARGUMENT_L("editer=",editer_les_situations_impossibles);
GET_ARGUMENT_L("rotation=",faire_tourner_les_vecteurs_propres);
)
);
CALi(Inoir(ImageA1));
CALi(Inoir(ImageA2));
CALi(Inoir(ImageA3));
CALi(Inoir(ImageA4));
CALi(Inoir(ImageA5));
CALi(Inoir(ImageA6));
/* Initialisation des images Resultats. */
SELECTION_DES_NIVEAUX(nom_paletteA,niveaux_a_traiter,niveaux_cumulables);
/* Introduit sous cette forme le 20060306092808... */
Test(IFLE(NOMBRE_DE_POINTS_EFFECTIF_D_UN_NOYAU_DE_CONVOLUTION_PARCOURU_CIRCULAIREMENT(nombre_de_points)
,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION
)
)
Bblock
DoIn(index
,PREMIER_POINT
,LSTX(PREMIER_POINT,NOMBRE_DE_POINTS_EFFECTIF_D_UN_NOYAU_DE_CONVOLUTION_PARCOURU_CIRCULAIREMENT(nombre_de_points))
,I
)
Bblock
NOYAU(index,VALEUR_INITIALE_DU_NOYAU_DE_CONVOLUTION);
/* Initialisation du noyau de convolution. */
Eblock
EDoI
Eblock
ATes
Bblock
PRINT_ERREUR("la taille demandee pour le noyau de convolution est incompatible avec les definitions");
EGAL(nombre_de_points,NOMBRE_DE_POINTS_DU_NOYAU);
CAL1(Prer1("(la valeur %d par defaut est forcee)\n",nombre_de_points));
/* Introduit le 20111031141217 car, en effet, manquait cruellement... */
Eblock
ETes
NOYAU(ADD2(PREMIER_POINT,ZERO),noyau_01);
NOYAU(ADD2(PREMIER_POINT,UN),noyau_02);
NOYAU(ADD2(PREMIER_POINT,DEUX),noyau_03);
NOYAU(ADD2(PREMIER_POINT,TROIS),noyau_04);
NOYAU(ADD2(PREMIER_POINT,QUATRE),noyau_05);
NOYAU(ADD2(PREMIER_POINT,CINQ),noyau_06);
NOYAU(ADD2(PREMIER_POINT,SIX),noyau_07);
NOYAU(ADD2(PREMIER_POINT,SEPT),noyau_08);
NOYAU(ADD2(PREMIER_POINT,HUIT),noyau_09);
NOYAU(ADD2(PREMIER_POINT,NEUF),noyau_10);
NOYAU(ADD2(PREMIER_POINT,DIX),noyau_11);
NOYAU(ADD2(PREMIER_POINT,ONZE),noyau_12);
NOYAU(ADD2(PREMIER_POINT,DOUZE),noyau_13);
NOYAU(ADD2(PREMIER_POINT,TREIZE),noyau_14);
NOYAU(ADD2(PREMIER_POINT,QUATORZE),noyau_15);
NOYAU(ADD2(PREMIER_POINT,QUINZE),noyau_16);
NOYAU(ADD2(PREMIER_POINT,SEIZE),noyau_17);
NOYAU(ADD2(PREMIER_POINT,DIX_SEPT),noyau_18);
NOYAU(ADD2(PREMIER_POINT,DIX_HUIT),noyau_19);
NOYAU(ADD2(PREMIER_POINT,DIX_NEUF),noyau_20);
NOYAU(ADD2(PREMIER_POINT,VINGT),noyau_21);
NOYAU(ADD2(PREMIER_POINT,VINGT_ET_UN),noyau_22);
NOYAU(ADD2(PREMIER_POINT,VINGT_DEUX),noyau_23);
NOYAU(ADD2(PREMIER_POINT,VINGT_TROIS),noyau_24);
NOYAU(ADD2(PREMIER_POINT,VINGT_QUATRE),noyau_25);
/* Initialisation des 9 premiers elements du noyau de convolution (meme si la taille */
/* demandee est inferieure a 9) avec des valeurs eventuellement arguments d'appel... */
/* On notera que l'on ecrase ainsi une partie de l'initialisation faite ci-dessus dans la */
/* boucle 'DoIn(...)' que l'on ne modifie pas pour simplifier... */
/* */
/* Le passage de 9 a 25 a ete introduit le 20210308132551... */
Test(PAS_D_ERREUR(CODE_ERROR(Iload_image(ImageA,nom_imageA))))
/* Chargement de l'image a transformer. */
Bblock
DEFV(genere_Float,INIT(minimum_de_s1,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_s1,FLOT__UNDEF));
/* Donnent le minimum et le maximum de la premiere valeur propre. */
DEFV(genere_Float,INIT(minimum_de_s2,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_s2,FLOT__UNDEF));
/* Donnent le minimum et le maximum de la deuxieme valeur propre. */
DEFV(genere_Float,INIT(minimum_de_s1_et_s2,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_s1_et_s2,FLOT__UNDEF));
/* Donnent le minimum et le maximum des deux valeurs propres. */
DEFV(genere_Float,INIT(minimum_de_X1,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_X1,FLOT__UNDEF));
/* Donnent le minimum et le maximum de la composante en 'X' du premier vecteur propre, */
DEFV(genere_Float,INIT(minimum_de_Y1,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_Y1,FLOT__UNDEF));
/* Donnent le minimum et le maximum de la composante en 'Y' du premier vecteur propre. */
DEFV(genere_Float,INIT(minimum_de_X2,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_X2,FLOT__UNDEF));
/* Donnent le minimum et le maximum de la composante en 'X' du deuxieme vecteur propre, */
DEFV(genere_Float,INIT(minimum_de_Y2,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_Y2,FLOT__UNDEF));
/* Donnent le minimum et le maximum de la composante en 'Y' du deuxieme vecteur propre. */
DEFV(genere_Float,INIT(minimum_de_X1_et_Y1,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_X1_et_Y1,FLOT__UNDEF));
/* Donnent le minimum et le maximum des deux composantes du premier vecteur propre. */
DEFV(genere_Float,INIT(minimum_de_X2_et_Y2,FLOT__UNDEF));
DEFV(genere_Float,INIT(maximum_de_X2_et_Y2,FLOT__UNDEF));
/* Donnent le minimum et le maximum des deux composantes du deuxieme vecteur propre. */
BDEFV(imageF,moment_d_inertie_Ixx);
BDEFV(imageF,moment_d_inertie_Ixyx);
BDEFV(imageF,moment_d_inertie_Iyy);
/* Images flottantes dans lesquelles on trouve les trois moments d'inertie locaux de */
/* l'image Argument (Ixx,Ixyx=Ixy=Iyx,Iyy). */
BDEFV(imageF,valeurs_propres_1);
BDEFV(imageF,valeurs_propres_2);
/* Images flottantes dans lesquelles on trouve les deux valeurs propres locales des */
/* matrices d'inertie locales... */
BDEFV(imageF,vecteurs_propres_1_X);
BDEFV(imageF,vecteurs_propres_1_Y);
BDEFV(imageF,vecteurs_propres_2_X);
BDEFV(imageF,vecteurs_propres_2_Y);
/* Images flottantes dans lesquelles on trouve les coordonnees des deux vecteurs propres. */
CALCUL_DE_L_INERTIE_Ixx_D_UNE_IMAGE;
CALS(IFconvolution(moment_d_inertie_Ixx
,facteur_multiplicatif
,ImageA
,niveaux_a_traiter,niveaux_cumulables
,nombre_de_points,noyau,inhibition_du_noyau
)
);
/* Calcul du moment d'inertie Ixx. */
CALCUL_DE_L_INERTIE_Ixyx_D_UNE_IMAGE;
CALS(IFconvolution(moment_d_inertie_Ixyx
,facteur_multiplicatif
,ImageA
,niveaux_a_traiter,niveaux_cumulables
,nombre_de_points,noyau,inhibition_du_noyau
)
);
/* Calcul du moment d'inertie Ixyx=Ixy=Iyx. */
CALCUL_DE_L_INERTIE_Iyy_D_UNE_IMAGE;
CALS(IFconvolution(moment_d_inertie_Iyy
,facteur_multiplicatif
,ImageA
,niveaux_a_traiter,niveaux_cumulables
,nombre_de_points,noyau,inhibition_du_noyau
)
);
/* Calcul du moment d'inertie Iyy. */
begin_image
Bblock
DEFV(Logical,INIT(corriger_les_vecteurs_propres,FAUX));
/* Cet indicateur est positionne en cas d'impossibilite de calcul des vecteurs propres, */
/* auquel cas on force la base naturelle [(1,0),(0,1)]... */
DEFV(Float,INIT(discriminant,DISCRIMINANT2(cA,cB,cC)));
/* En chaque point {X,Y}, on dispose d'une matrice : */
/* */
/* | | */
/* | Ixx Ixy | */
/* M = | | */
/* | Iyx Iyy | */
/* | | */
/* */
/* ses valeurs propres s'obtiennent en resolvant l'equation : */
/* */
/* det(M - s.I) = 0 */
/* */
/* (ou 's' represente les valeurs propres) soit : */
/* */
/* (Ixx-s).(Iyy-s) - Ixy.Iyx = 0 */
/* */
/* ou encore : */
/* */
/* 2 */
/* (Ixx-s).(Iyy-s) - Ixyx = 0 */
/* */
/* ou encore : */
/* */
/* 2 2 */
/* s -(Ixx+Iyy).s + (Ixx.Iyy - Ixyx ) = 0. */
/* */
/* Les vecteurs propres 'V' s'obtiennent en resolvant l'equation : */
/* */
/* M.V = s.I.V */
/* */
/* soit : */
/* */
/* Ixx.Vx + Ixy.Vy = s.Vx */
/* Iyx.Vx + Iyy.Vy = s.Vy */
/* */
/* d'ou : */
/* */
/* (Ixx-s).Vx + Ixy.Vy = 0 */
/* Iyx.Vx + (Iyy-s).Vy = 0 */
/* */
/* Le determinant de ce systeme etant nul, il y a indetermination ; on peut donc fixer */
/* arbitrairement l'une des deux composantes... */
/* */
/* L'operateur 'DISCRIMINANT2(...)' fut introduit le 20110325113208... */
DEFV(Float,INIT(s1,FZERO));
DEFV(Float,INIT(s2,FZERO));
/* Definition des deux valeurs propres ; l'initialisation est faite avec 'FZERO', et non */
/* pas avec 'FLOT__UNDEF', afin de prendre en cas la valeur a donner aux valeurs propres */
/* en cas de degenerescence... */
Test(IZGE(discriminant))
Bblock
EGAL(s1,DIVI(ADD2(NEGA(cB),RACX(discriminant)),GRO2(cA)));
EGAL(s2,DIVI(SOUS(NEGA(cB),RACX(discriminant)),GRO2(cA)));
/* Calcul des valeurs propres 's1' et 's2'... */
Eblock
ATes
Bblock
EGAL(corriger_les_vecteurs_propres,VRAI);
/* Memorisation de la degenerescence... */
Eblock
ETes
storeF_point(s1,valeurs_propres_1,X,Y);
storeF_point(s2,valeurs_propres_2,X,Y);
/* Memorisation des deux valeurs propres (eventuellement degenerees...). */
Test(IZNE(Ixyx))
Bblock
DEFV(deltaF_2D,vecteur_1);
DEFV(Float,INIT(longueur_vecteur_1,FLOT__UNDEF));
DEFV(deltaF_2D,vecteur_2);
DEFV(Float,INIT(longueur_vecteur_2,FLOT__UNDEF));
DEFV(deltaF_2D,vecteur_1_prime);
DEFV(Float,INIT(longueur_vecteur_1_prime,FLOT__UNDEF));
DEFV(deltaF_2D,vecteur_2_prime);
DEFV(Float,INIT(longueur_vecteur_2_prime,FLOT__UNDEF));
INITIALISATION_ACCROISSEMENT_2D(vecteur_1,FU,NEGA(DIVI(SOUS(Ixx,s1),Ixyx)));
/* Calcul du premier vecteur propre, en fixant arbitrairement a 1 la composante en 'X'. */
/* On notera bien que par definition des vecteurs propres, dont le le calcul est fait */
/* avec : */
/* */
/* INITIALISATION_ACCROISSEMENT_2D(vecteur_1,FU,NEGA(DIVI(SOUS(Ixx,s1),Ixyx))); */
/* */
/* on a : */
/* */
/* theta E [0,pi] */
/* */
/* et les vecteurs propres etant normalises, on a : */
/* */
/* module E [0,1] */
/* */
/* d'ou eventuellement des problemes lors de l'utilisation de '$xci/XY_RT$K' pour lequel */
/* la phase 'tete' ne balayera pas l'integralite du cercle trigonometrique... */
NORMALISATION_VECTEUR_PROPRE(vecteur_1
,longueur_vecteur_1
,BLOC(CAL1(Prer3("v1=(%g,%g) longueur=%g\n"
,ASD1(vecteur_1,dx),ASD1(vecteur_1,dy)
,longueur_vecteur_1
)
);
)
);
INITIALISATION_ACCROISSEMENT_2D(vecteur_2,FU,NEGA(DIVI(SOUS(Ixx,s2),Ixyx)));
/* Calcul du deuxieme vecteur propre, en fixant arbitrairement a 1 la composante en 'X'. */
/* On notera bien que par definition des vecteurs propres, dont le le calcul est fait */
/* avec : */
/* */
/* INITIALISATION_ACCROISSEMENT_2D(vecteur_2,FU,NEGA(DIVI(SOUS(Ixx,s2),Ixyx))); */
/* */
/* on a : */
/* */
/* theta E [0,pi] */
/* */
/* et les vecteurs propres etant normalises, on a : */
/* */
/* module E [0,1] */
/* */
/* d'ou eventuellement des problemes lors de l'utilisation de '$xci/XY_RT$K' pour lequel */
/* la phase 'tete' ne balayera pas l'integralite du cercle trigonometrique... */
NORMALISATION_VECTEUR_PROPRE(vecteur_2
,longueur_vecteur_2
,BLOC(CAL1(Prer3("v2=(%g,%g) longueur=%g\n"
,ASD1(vecteur_2,dx),ASD1(vecteur_2,dy)
,longueur_vecteur_2
)
);
)
);
Test(IFET(IFEQ(ASD1(vecteur_1,dx),ASD1(vecteur_2,dx)),IFEQ(ASD1(vecteur_1,dy),ASD1(vecteur_2,dy))))
Bblock
Test(IL_FAUT(editer_les_situations_impossibles))
Bblock
PRINT_ERREUR("les deux vecteurs propres sont identiques");
CAL1(Prer3("v1=(%g,%g) longueur=%g\n"
,ASD1(vecteur_1,dx),ASD1(vecteur_1,dy)
,longueur_vecteur_1
)
);
CAL1(Prer3("v2=(%g,%g) longueur=%g\n"
,ASD1(vecteur_2,dx),ASD1(vecteur_2,dy)
,longueur_vecteur_2
)
);
CAL1(Prer2("point courant : (%d,%d)\n",X,Y));
CAL1(Prer2("valeurs propres : s1=%g s2=%g\n",s1,s2));
CAL1(Prer3("moments d'inertie : Ixx=%g Ixy=Iyx=%g Iyy=%g\n",Ixx,Ixyx,Iyy));
Eblock
ATes
Bblock
Eblock
ETes
EGAL(corriger_les_vecteurs_propres,VRAI);
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(faire_tourner_les_vecteurs_propres))
Bblock
INITIALISATION_ACCROISSEMENT_2D(vecteur_1_prime
,ADD2(ASD1(vecteur_1,dx),ASD1(vecteur_2,dx))
,ADD2(ASD1(vecteur_1,dy),ASD1(vecteur_2,dy))
);
INITIALISATION_ACCROISSEMENT_2D(vecteur_2_prime
,SOUS(ASD1(vecteur_1,dx),ASD1(vecteur_2,dx))
,SOUS(ASD1(vecteur_1,dy),ASD1(vecteur_2,dy))
);
/* Cas ou l'on fait tourner de pi/4 la base de vecteurs propres... */
Eblock
ATes
Bblock
TRANSFERT_ACCROISSEMENT_2D(vecteur_1_prime,vecteur_1);
TRANSFERT_ACCROISSEMENT_2D(vecteur_2_prime,vecteur_2);
/* Cas ou l'on conserve la base orthogonale de vecteurs propres. */
Eblock
ETes
NORMALISATION_VECTEUR_PROPRE(vecteur_1_prime
,longueur_vecteur_1_prime
,BLOC(CAL1(Prer2("v1=(%g,%g)\n"
,ASD1(vecteur_1,dx),ASD1(vecteur_1,dy)
)
);
CAL1(Prer2("v2=(%g,%g)\n"
,ASD1(vecteur_2,dx),ASD1(vecteur_2,dy)
)
);
CAL1(Prer3("v1'=(%g,%g) longueur=%g\n"
,ASD1(vecteur_1_prime,dx),ASD1(vecteur_1_prime,dy)
,longueur_vecteur_1_prime
)
);
)
);
NORMALISATION_VECTEUR_PROPRE(vecteur_2_prime
,longueur_vecteur_2_prime
,BLOC(CAL1(Prer2("v1=(%g,%g)\n"
,ASD1(vecteur_1,dx),ASD1(vecteur_1,dy)
)
);
CAL1(Prer2("v2=(%g,%g)\n"
,ASD1(vecteur_2,dx),ASD1(vecteur_2,dy)
)
);
CAL1(Prer3("v2'=(%g,%g) longueur=%g\n"
,ASD1(vecteur_2_prime,dx),ASD1(vecteur_2_prime,dy)
,longueur_vecteur_2_prime
)
);
)
);
storeF_point(ASD1(vecteur_1_prime,dx),vecteurs_propres_1_X,X,Y);
storeF_point(ASD1(vecteur_1_prime,dy),vecteurs_propres_1_Y,X,Y);
storeF_point(ASD1(vecteur_2_prime,dx),vecteurs_propres_2_X,X,Y);
storeF_point(ASD1(vecteur_2_prime,dy),vecteurs_propres_2_Y,X,Y);
/* Et enfin rangement de la base orthonormee choisie... */
Eblock
ATes
Bblock
EGAL(corriger_les_vecteurs_propres,VRAI);
Eblock
ETes
Test(IL_FAUT(corriger_les_vecteurs_propres))
Bblock
storeF_point(NEUT(FDU),vecteurs_propres_1_X,X,Y);
storeF_point(NEUT(FDU),vecteurs_propres_1_Y,X,Y);
storeF_point(NEUT(FDU),vecteurs_propres_2_X,X,Y);
storeF_point(NEUT(FDU),vecteurs_propres_2_Y,X,Y);
/* Dans le cas de l'impossibilite de calcul des vecteurs propres, on force une fausse */
/* base du type : */
/* */
/* 1 1 1 1 */
/* [(+ --- , + ---),(+ --- , + ---)] */
/* 2 2 2 2 */
/* */
/* On notera que l'on n'utilise pas la base [(1,0),(0,1)] afin de perturber le moins */
/* possible la recherche des extrema par la suite (en forcant ainsi '0' et '1'...). */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
end_image
CALS(IFnivo_extrema(valeurs_propres_1,ADRESSE(minimum_de_s1),ADRESSE(maximum_de_s1)));
/* Recherche du minimum et du maximum de la premiere valeur propre. */
CALS(IFnivo_extrema(valeurs_propres_2,ADRESSE(minimum_de_s2),ADRESSE(maximum_de_s2)));
/* Recherche du minimum et du maximum de la deuxieme valeur propre. */
EGAL(minimum_de_s1_et_s2,MIN2(minimum_de_s1,minimum_de_s2));
EGAL(maximum_de_s1_et_s2,MAX2(maximum_de_s1,maximum_de_s2));
/* Recherche du minimum et du maximum des deux valeurs propres. */
CALS(Ifloat_std(ImageA1
,valeurs_propres_1
,minimum_de_s1_et_s2
,maximum_de_s1_et_s2
)
);
CALS(Ifloat_std(ImageA2
,valeurs_propres_2
,minimum_de_s1_et_s2
,maximum_de_s1_et_s2
)
);
/* Conversion des valeurs propres... */
CALS(IFnivo_extrema(vecteurs_propres_1_X,ADRESSE(minimum_de_X1),ADRESSE(maximum_de_X1)));
/* Recherche du minimum et du maximum de la composante en 'X' du premier vecteur propre, */
CALS(IFnivo_extrema(vecteurs_propres_1_Y,ADRESSE(minimum_de_Y1),ADRESSE(maximum_de_Y1)));
/* Recherche du minimum et du maximum de la composante en 'Y' du premier vecteur propre. */
CALS(IFnivo_extrema(vecteurs_propres_2_X,ADRESSE(minimum_de_X2),ADRESSE(maximum_de_X2)));
/* Recherche du minimum et du maximum de la composante en 'X' du deuxieme vecteur propre, */
CALS(IFnivo_extrema(vecteurs_propres_2_Y,ADRESSE(minimum_de_Y2),ADRESSE(maximum_de_Y2)));
/* Recherche du minimum et du maximum de la composante en 'Y' du deuxieme vecteur propre. */
EGAL(minimum_de_X1_et_Y1,MIN2(minimum_de_X1,minimum_de_Y1));
EGAL(maximum_de_X1_et_Y1,MAX2(maximum_de_X1,maximum_de_Y1));
/* Recherche du minimum et du maximum des deux composantes du premier vecteur propre. */
EGAL(minimum_de_X2_et_Y2,MIN2(minimum_de_X2,minimum_de_Y2));
EGAL(maximum_de_X2_et_Y2,MAX2(maximum_de_X2,maximum_de_Y2));
/* Recherche du minimum et du maximum des deux composantes du deuxieme vecteur propre. */
CALS(Ifloat_std(ImageA3
,vecteurs_propres_1_X
,minimum_de_X1_et_Y1
,maximum_de_X1_et_Y1
)
);
CALS(Ifloat_std(ImageA4
,vecteurs_propres_1_Y
,minimum_de_X1_et_Y1
,maximum_de_X1_et_Y1
)
);
/* Conversion du premier vecteur propre... */
CALS(Ifloat_std(ImageA5
,vecteurs_propres_2_X
,minimum_de_X2_et_Y2
,maximum_de_X2_et_Y2
)
);
CALS(Ifloat_std(ImageA6
,vecteurs_propres_2_Y
,minimum_de_X2_et_Y2
,maximum_de_X2_et_Y2
)
);
/* Conversion du deuxieme vecteur propre. */
CALi(Iupdate_image(nom_imageRs1,ImageA1));
CALi(Iupdate_image(nom_imageRs2,ImageA2));
CALi(Iupdate_image(nom_imageRX1,ImageA3));
CALi(Iupdate_image(nom_imageRY1,ImageA4));
CALi(Iupdate_image(nom_imageRX2,ImageA5));
CALi(Iupdate_image(nom_imageRY2,ImageA6));
EDEFV(imageF,vecteurs_propres_2_Y);
EDEFV(imageF,vecteurs_propres_2_X);
EDEFV(imageF,vecteurs_propres_1_Y);
EDEFV(imageF,vecteurs_propres_1_X);
/* Images flottantes dans lesquelles on trouve les coordonnees des deux vecteurs propres. */
EDEFV(imageF,valeurs_propres_2);
EDEFV(imageF,valeurs_propres_1);
/* Images flottantes dans lesquelles on trouve les deux valeurs propres locales des */
/* matrices d'inertie locales... */
EDEFV(imageF,moment_d_inertie_Iyy);
EDEFV(imageF,moment_d_inertie_Ixyx);
EDEFV(imageF,moment_d_inertie_Ixx);
/* Images flottantes dans lesquelles on trouve les trois moments d'inertie locaux de */
/* l'image Argument (Ixx,Ixyx=Ixy=Iyx,Iyy). */
Eblock
ATes
Bblock
Test__CODE_ERREUR__ERREUR07;
Eblock
ETes
RETU_Commande;
Eblock
ECommande