/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E T E R M I N A T I O N   D E   L ' E Q U A T I O N   D ' U N E   E L L I P S E  :                                       */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xtc/EquationEllipse.02$vv$c' :                                                                                 */
/*                                                                                                                                   */
/*                    Jean-Francois Colonna (LACTAMME, 20221011183131).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

#include  "INCLUDES.01.I"

extern    double    sqrt();

static    int       GenererImage=FAUX;
                                        /* Afin de pouvoir verifier qu'il s'agit bien d'une ellipse...                               */

#define   ZOOM                                                                                                                          \
                    2
#define   FACTEUR                                                                                                                       \
                    1

#define   REDUC(z)                                                                                                                      \
                    ((z)/FACTEUR)
#define   CARRE(z)                                                                                                                      \
                    ((z)*(z))
#define   CHECK(x,y)                                                                                                                    \
                    (CARRE(x)/CARRE(a))+(CARRE(y)/CARRE(b))

#define   INFINI                                                                                                                        \
                    1.0e100

#define   NOMBRE                                                                                                                        \
                    41

extern    void      *malloc();

static    int       dimX=0;
#define   Xmin      0
#define   Xmax      (Xmin + (dimX-1))
                                        /* Definition des abscisses.                                                                 */
static    int       dimY=0;
#define   Ymin      0
#define   Ymax      (Ymin + (dimY-1))
                                        /* Definition des ordonnees.                                                                 */

#define   IMAGE(x,y)                                                                                                                    \
                    (*(image + (((y-Ymin)*dimX) + (x-Xmin))))                                                                           \
                                        /* Acces a un point de l'image.                                                              */
#define   store(n,x,y)                                                                                                                  \
                    {                                                                                                                   \
                    IMAGE(x,y) = n;                                                                                                     \
                    }                                                                                                                   \
                                        /* Rangement d'un point valide d'une image.                                                  */
#define   ELLIPSE(Lx,Ly)                                                                                                                \
                    {                                                                                                                   \
                    int       cX=(((Lx[index]-minimum_2_X)/(maximum_2_X-minimum_2_X))*(Xmax-Xmin))+Xmin;                                \
                    int       cY=(((Ly[index]-minimum_2_Y)/(maximum_2_Y-minimum_2_Y))*(Ymax-Ymin))+Ymin;                                \
                                                                                                                                        \
                    cX = (((cX-Xmin)-((Xmax-Xmin)/2))/ZOOM)+(dimX/2)+Xmin;                                                              \
                    cY = (((cY-Ymin)-((Ymax-Ymin)/2))/ZOOM)+(dimY/2)+Ymin;                                                              \
                                                                                                                                        \
                    store(BLANC,cX,cY);                                                                                                 \
                    }                                                                                                                   \
                                        /* Trace de l'ellipse...                                                                     */

void      main()
          {
          int       index;

          double    Lx1[NOMBRE]={-800000000000
                                ,-799166000064.454468
                                ,-796663511901.509888
                                ,-792491283632.184937
                                ,-786647243443.405396
                                ,-779128521231.340820
                                ,-769931489097.738647
                                ,-759051804715.996460
                                ,-746484479038.770020
                                ,-732223953778.206543
                                ,-716264213954.533447
                                ,-698598919432.062622
                                ,-679221575849.836548
                                ,-658125753714.453125
                                ,-635305359835.672241
                                ,-610754984887.974731
                                ,-584470346608.554565
                                ,-556448846633.977905
                                ,-526690275857.960571
                                ,-495197717087.342590
                                ,-461978695533.236389
                                ,-427046653020.436279
                                ,-390422834068.982605
                                ,-352138716161.846497
                                ,-312239139907.355164
                                ,-270786351349.391632
                                ,-227865229686.255005
                                ,-183590042709.856995
                                ,-138113159832.700897
                                ,-91636235028.870025
                                ,-44424416024.877166
                                ,+3175900065.465378
                                ,+50715503185.226310
                                ,+97617427472.923400
                                ,+143150528185.577606
                                ,+186406172868.677582
                                ,+226286945182.115662
                                ,+261521714723.657501
                                ,+290725629051.373169
                                ,+312520841585.724304
                                ,+325716668536.934021
                                 };
          double    Ly1[NOMBRE]={+1000
                                ,+27989568947.760650
                                ,+55921375246.897300
                                ,+83735923255.243881
                                ,+111373744767.720016
                                ,+138774353113.066803
                                ,+165875883044.374756
                                ,+192614711478.117554
                                ,+218925054332.794769
                                ,+244738533244.007599
                                ,+269983706706.834137
                                ,+294585557945.559204
                                ,+318464929193.731323
                                ,+341537896320.715393
                                ,+363715071637.104004
                                ,+384900821220.337158
                                ,+404992390454.005859
                                ,+423878913452.105347
                                ,+441440297714.340515
                                ,+457545961486.339233
                                ,+472053411434.564392
                                ,+484806639343.538879
                                ,+495634329810.908386
                                ,+504347874400.330322
                                ,+510739199645.671082
                                ,+514578458131.797607
                                ,+515611666175.225647
                                ,+513558468956.451233
                                ,+508110328739.113464
                                ,+498929666769.876892
                                ,+485650807662.503113
                                ,+467884075341.501648
                                ,+445225103997.960083
                                ,+417272362288.405457
                                ,+383656913569.580444
                                ,+344089133453.590576
                                ,+298426404636.323669
                                ,+246761858210.234467
                                ,+189524738428.388153
                                ,+127567417275.454803
                                ,+62198223006.654739
                                 };
          double    Lx2[NOMBRE]={+329515043551.962524
                                ,+323674532868.917603
                                ,+308564150133.509460
                                ,+285081892772.509705
                                ,+254475501947.702972
                                ,+218137658787.323669
                                ,+177436906761.184479
                                ,+133610597143.845917
                                ,+87716052194.003341
                                ,+40622578393.841774
                                ,-6973667863.918034
                                ,-54525136275.164947
                                ,-101606497534.667068
                                ,-147890330250.330505
                                ,-193126365338.586426
                                ,-237124520192.660980
                                ,-279741380978.299683
                                ,-320869592701.490845
                                ,-360429601866.614075
                                ,-398363259766.155457
                                ,-434628874995.758789
                                ,-469197382259.000793
                                ,-502049380352.338501
                                ,-533172829268.901184
                                ,-562561259638.667480
                                ,-590212378315.997192
                                ,-616126969700.465210
                                ,-640308042395.343994
                                ,-662760159839.397949
                                ,-683488909924.952026
                                ,-702500482089.756958
                                ,-719801340182.548706
                                ,-735397962263.524780
                                ,-749296632401.443970
                                ,-761503277891.523193
                                ,-772023340802.756470
                                ,-780861679188.498535
                                ,-788022488122.065308
                                ,-793509238390.982666
                                ,-797324630363.287231
                                ,-799470563564.701050
                                 };
          double    Ly2[NOMBRE]={-4882226246.836296
                                ,-71755092708.735641
                                ,-136528805597.224564
                                ,-197575237592.599060
                                ,-253681601590.071869
                                ,-304090926985.294800
                                ,-348453819930.926392
                                ,-386735626516.374207
                                ,-419117050514.681030
                                ,-445909525249.911804
                                ,-467492196848.978088
                                ,-484269211220.109741
                                ,-496642941958.444824
                                ,-504998521330.766052
                                ,-509695854117.710144
                                ,-511066339505.118835
                                ,-509412401795.952881
                                ,-505008611894.748901
                                ,-498103619840.776733
                                ,-488922441210.968323
                                ,-477668816546.808472
                                ,-464527498768.808533
                                ,-449666385627.008789
                                ,-433238466668.945557
                                ,-415383573394.559753
                                ,-396229942333.709900
                                ,-375895603252.519348
                                ,-354489608547.058411
                                ,-332113120234.844666
                                ,-308860374532.823303
                                ,-284819536244.112122
                                ,-260073461792.595642
                                ,-234700379460.007568
                                ,-208774502202.248444
                                ,-182366580523.182190
                                ,-155544404924.997314
                                ,-128373267044.422150
                                ,-100916386548.792847
                                ,-73235308198.392166
                                ,-45390273860.971466
                                ,-17440583527.914199
                                 };
                                        /* Ces listes {x1,y1} et {x2,Y2} sont des points "diametralement opposes" d'une ellipse      */
                                        /* obtenue par integration des equations de Newton ('v $xiirk/NCOS_81' et aussi              */
                                        /* 'v $xiirk/$Fnota Debut_listG_NCOS_81_coordonnees_XY')...                                  */

          double    minimum_1_X=+INFINI,maximum_1_X=-INFINI;
          double    minimum_1_Y=+INFINI,maximum_1_Y=-INFINI;

          double    Translation_X;
          double    Translation_Y;


          for       (index=0 ; index<NOMBRE ; index++)
                    {
                    minimum_1_X = MIN2(Lx1[index],minimum_1_X);
                    minimum_1_X = MIN2(Lx2[index],minimum_1_X);

                    maximum_1_X = MAX2(Lx1[index],maximum_1_X);
                    maximum_1_X = MAX2(Lx2[index],maximum_1_X);

                    minimum_1_Y = MIN2(Ly1[index],minimum_1_Y);
                    minimum_1_Y = MIN2(Ly2[index],minimum_1_Y);

                    maximum_1_Y = MAX2(Ly1[index],maximum_1_Y);
                    maximum_1_Y = MAX2(Ly2[index],maximum_1_Y);
                                        /* Premier calcul des extrema des coordonnees afin de centrer l'ellipse...                   */
                    }

          Translation_X = (maximum_1_X+minimum_1_X)/2;
          Translation_Y = (maximum_1_Y+minimum_1_Y)/2;

          for       (index=0 ; index<NOMBRE ; index++)
                    {
                    Lx1[index]=Lx1[index]-Translation_X;
                    Ly1[index]=Ly1[index]-Translation_Y;

                    Lx2[index]=Lx2[index]-Translation_X;
                    Ly2[index]=Ly2[index]-Translation_Y;
                                        /* Operation de centrage de l'ellipse afin que son equation soit "canonique"...              */
                    }

          if        (GenererImage == FAUX)
                    {
                    double    moyenne_a=0;
                    double    moyenne_b=0;

                    int       nombre=0;

                    for       (index=0 ; index<NOMBRE ; index++)
                              {
                              Lx1[index]=REDUC(Lx1[index]);
                              Ly1[index]=REDUC(Ly1[index]);

                              Lx2[index]=REDUC(Lx2[index]);
                              Ly2[index]=REDUC(Ly2[index]);
                                        /* Operation eventuelle de reduction des coordonnees au cas ou elles seraient vraiment       */
                                        /* trop grandes...                                                                           */
                              }

                    for       (index=0 ; index<NOMBRE ; index++)
                              {
                              double    x1=Lx1[index];
                              double    y1=Ly1[index];

                              double    x2=Lx2[index];
                              double    y2=Ly2[index];
                                        /* Les points {x1,y1} et {x2,Y2} sont deux points quasiment "diametralement opposes"...      */

                              double    X1=CARRE(x1);
                              double    Y1=CARRE(y1);

                              double    X2=CARRE(x2);
                              double    Y2=CARRE(y2);

                              if        ((X1 != X2) && (Y1 != Y2))
                                        /* Ce test est necessaire car, en effet, les coordonnees sont recentrees par rapport a       */
                                        /* leurs extrema. Il peut donc y avoir deux points "opposees" dont les coordonnees sont      */
                                        /* opposees et donc leurs carres sont egaux. Cela donnerait donc des 'iA's et/ou des 'iB's   */
                                        /* nuls...                                                                                   */
                                        {
                                        double    a,A,iA;
                                        double    b,B,iB;

                                        double    determinant=((Y2*X1)-(Y1*X2));

                                        /* Les coordonnees ayant ete "centrees", on peut utiliser l'equation "canonique" de          */
                                        /* l'ellipse...                                                                              */
                                        /*                                                                                           */
                                        /* On va travailler simplement sur les carres en passant de :                                */
                                        /*                                                                                           */
                                        /*                     2       2                     2       2                               */
                                        /*                   x1      y1                    x2      y2                                */
                                        /*                  ----- + ----- = 1             ----- + ----- = 1                          */
                                        /*                    2       2                     2       2                                */
                                        /*                   a       b                     a       b                                 */
                                        /*                                                                                           */
                                        /* a :                                                                                       */
                                        /*                                                                                           */
                                        /*                   X1      Y1                    X2      Y2                                */
                                        /*                  ----  + ----  = 1             ----  + ----  = 1                          */
                                        /*                   A       B                     A       B                                 */
                                        /*                                                                                           */
                                        /* puis a :                                                                                  */
                                        /*                                                                                           */
                                        /*                  iA.X1 + iB.Y1 = 1             iA.X2 + iB.Y2 = 1                          */
                                        /*                                                                                           */
                                        /* {iA,iB} etant les inverses de {A,B}. On est donc en presence d'un systeme lineaire de     */
                                        /* deux equations a deux inconnues trivial a resoudre...                                     */

                                        iB = (X1-X2)/determinant;
                                        iA = (Y2-Y1)/determinant;

                                        A = 1/iA;
                                        B = 1/iB;

                                        a = sqrt(A);
                                        b = sqrt(B);

                                        moyenne_a = moyenne_a+a;
                                        moyenne_b = moyenne_b+b;

                                        printf("{{%+f,%+f},{%+f,%+f}}     a=%+f b=%+f",x1,y1,x2,y2,a,b);

                                        printf("     Check=(%+f,%+f)\n"
                                              ,CHECK(x1,y1)
                                              ,CHECK(x2,y2)
                                               );

                                        nombre++;
                                        }
                              else
                                        {
                                        }
                              }

                    moyenne_a = moyenne_a/nombre;
                    moyenne_b = moyenne_b/nombre;

                    printf("\n");
                    printf("Moyenne : a=%+f b=%+f sur %d couples de points.\n",moyenne_a,moyenne_b,nombre);
                    }
          else
                    {
                    int                 x,y;
                                        /* Definition des coordonnees des points de l'image.                                         */
                    unsigned  char      *image;
                                        /* Definition de l'image a generer...                                                        */

                    double    minimum_2_X=+INFINI,maximum_2_X=-INFINI;
                    double    minimum_2_Y=+INFINI,maximum_2_Y=-INFINI;

                    Get(dimX,"dimX");
                    Get(dimY,"dimY");
                                        /* Recuperation des dimensions en 'X' et en 'Y' de l'image a generer.                        */

                    image=(unsigned char*)malloc(dimY*dimX);
                                        /* Definition de l'image a generer...                                                        */

                    for       (y=Ymin ; y<=Ymax ; y++)
                              {
                              for       (x=Xmin ; x<=Xmax ; x++)
                                        {
                                        store(NOIR,x,y);
                                        /* Initialisation de l'image finale...                                                       */
                                        }
                              }

                    for       (index=0 ; index<NOMBRE ; index++)
                              {
                              minimum_2_X = MIN2(Lx1[index],minimum_2_X);
                              minimum_2_X = MIN2(Lx2[index],minimum_2_X);

                              maximum_2_X = MAX2(Lx1[index],maximum_2_X);
                              maximum_2_X = MAX2(Lx2[index],maximum_2_X);

                              minimum_2_Y = MIN2(Ly1[index],minimum_2_Y);
                              minimum_2_Y = MIN2(Ly2[index],minimum_2_Y);

                              maximum_2_Y = MAX2(Ly1[index],maximum_2_Y);
                              maximum_2_Y = MAX2(Ly2[index],maximum_2_Y);
                                        /* Deuxieme calcul des extrema des coordonnees afin de centrer l'image...                    */
                              }

                    for       (index=0 ; index<NOMBRE ; index++)
                              {
                              ELLIPSE(Lx1,Ly1);
                              ELLIPSE(Lx2,Ly2);
                              }

                    write(1,image,dimX*dimY);
                                        /* Sortie de l'image afin de verifier qu'il s'agit bien d'une ellipse...                     */
                    }
          }



Copyright © Jean-François Colonna, 2022-2023.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2022-2023.