/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        T R A C E   D ' U N   H U I T  :                                                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xtc/huit.03$c' :                                                                                               */
/*                                                                                                                                   */
/*                    Jean-Francois Colonna (LACTAMME, 20161201111423).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

#include  "INCLUDES.01.I"

int       tracer_tangente=VRAI;
int       tracer_normale_=VRAI;
int       tracer_ellipse_=VRAI;
int       tracer_courbe__=VRAI;
                                        /* Indicateurs divers de trace...                                                            */

#define   NOMBRE_MAXIMAL_DE_POINTS_DE_LA_COURBE                                                                                         \
                    10000

#define   THETA0                                                                                                                        \
                    0
#define   THETAn                                                                                                                        \
                    (4*PI)
#define   PAST                                                                                                                          \
                    ((THETAn-THETA0)/80)
                                        /* Definition de l'angle 'theta' parametrant la courbe.                                      */

#define   PHI0                                                                                                                          \
                    0
#define   PHIn                                                                                                                          \
                    (2*PI)
#define   PASP                                                                                                                          \
                    0.05
#define   RAYONa                                                                                                                        \
                    10
#define   RAYONb                                                                                                                        \
                    20
                                        /* Definition de l'angle 'phi' parametrant l'ellipse.                                        */

#define   RAYON                                                                                                                         \
                    MIN2(dimX,dimY)/2
#define   TRANSX                                                                                                                        \
                    (dimX/2)
#define   TRANSY                                                                                                                        \
                    (dimY/2)
#define   NORMX(x)                                                                                                                      \
                    (RAYON*(x)+TRANSX)
#define   NORMY(y)                                                                                                                      \
                    (RAYON*(y)+TRANSY)
                                        /* Definition de l'ellipse.                                                                  */

#define   LAMBDA0                                                                                                                       \
                    -0.13
#define   LAMBDAn                                                                                                                       \
                    +0.13
#define   PASL                                                                                                                          \
                    0.01
                                        /* Definition de l'interpolation lineaire de trace de la tangente et de la normale.          */

#define   GRIS_TANGENTE                                                                                                                 \
                    (BLANC/4)
#define   GRIS_NORMALE                                                                                                                  \
                    (BLANC/3)
#define   GRIS_ELLIPSE                                                                                                                  \
                    (BLANC/2)
#define   GRIS_COURBE                                                                                                                   \
                    (BLANC/1)
                                        /* Definition des couleurs.                                                                  */

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(tracer,niveau,x,y)                                                                                                      \
                    {                                                                                                                   \
                    if        (tracer == VRAI)                                                                                          \
                              {                                                                                                         \
                              int       xs=(int)x,ys=(int)y;                                                                            \
                                                                                                                                        \
                              if        (((xs >= Xmin) && (xs <= Xmax)) && ((ys >= Ymin) && (ys <= Ymax)))                              \
                                        {                                                                                               \
                                        IMAGE(xs,ys) = niveau;                                                                          \
                                        }                                                                                               \
                              else                                                                                                      \
                                        {                                                                                               \
                                        }                                                                                               \
                              }                                                                                                         \
                    else                                                                                                                \
                              {                                                                                                         \
                              }                                                                                                         \
                    }                                                                                                                   \
                                        /* Rangement d'un point valide d'une image.                                                  */

main()
          {
          int       compteur_des_points_de_la_courbe=0;
          double    x,y,z=0;
          double    theta;
          double    phi;

          unsigned  char      *image;
                                        /* Definition de l'image a generer...                                                        */

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

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

          for       (y=Ymin ; y<=Ymax ; y++)
                    {
                    for       (x=Xmin ; x<=Xmax ; x++)
                              {
                              store(VRAI,NOIR,x,y);
                              }
                    }

          for       (theta=THETA0 ; theta<THETAn ; theta=theta+PAST)
                    {
                    if        (compteur_des_points_de_la_courbe < NOMBRE_MAXIMAL_DE_POINTS_DE_LA_COURBE)
                              {
                              double    dx,dy;
                              double    lambda;
                              double    signe=COND(theta<(THETAn/2),+1,-1);
                              double    psi;

                              if        ((1+cos(theta)) < 1.0e-6)
                                        {
                                        theta=theta-1.0e-6;
                                        /* Ceci a ete introduit le 20161204093720 car, en effet :                                    */
                                        /*                                                                                           */
                                        /*                  cos(theta)=-1   ==> dx=infini et dy=-1/2                                 */
                                        /*                                                                                           */
                                        /* et alors, cela donne :                                                                    */
                                        /*                                                                                           */
                                        /*                  atan2=-0.500000 ==> psi=pi/2                                             */
                                        /*                                                                                           */
                                        /* d'ou une petite perturbation de 'theta' pour eviter ce qui donne une anomalie importante  */
                                        /* de direction ('psi' anormal)...                                                           */
                                        }
                              else
                                        {
                                        }

                              x = signe*sqrt((1+cos(theta))/2);
                              y = sin(theta)/2;
                                        /* Point courant {x,y}.                                                                      */
                                        /*                                                                                           */
                                        /* Ce parametrage vient de l'equation cartesienne du '8' dans le plan :                      */
                                        /*                                                                                           */
                                        /*                   2    2      2                                                           */
                                        /*                  y  = x (1 - x )                                                          */
                                        /*                                                                                           */
                                        /* En faisant le changement de variable :                                                    */
                                        /*                                                                                           */
                                        /*                   2                                                                       */
                                        /*                  x  = z + 1/2                                                             */
                                        /*                                                                                           */
                                        /* on obtient l'equation :                                                                   */
                                        /*                                                                                           */
                                        /*                   2   2                                                                   */
                                        /*                  y + z  = 1/4                                                             */
                                        /*                                                                                           */
                                        /* qui est donc l'equation d'un cercle que l'on peut parametrer en {rho=1/2,theta}, d'ou     */
                                        /* le parametrage ci-dessus en revenant a {x,y}...                                           */
                                        /*                                                                                           */

                              dx = signe*(1/(2*sqrt((1+cos(theta))/2)))*((-sin(theta))/2);
                              dy = cos(theta)/2;
                                        /* Derivee au point courant {dx,dy}. Elle definit la tangente {dx,dy}.                       */

                              psi = COND(atan2(-dx,+dy) >= 0,atan2(-dx,+dy),atan2(-dx,+dy)+2*PI);
                                        /* Angle de la normale (+dy,-dx} avec l'axe 'x'.                                             */
                                        /*                                                                                           */
                                        /*                  psi = ATAN(DY,DX) = arctg(DY/DX)                                         */
                                        /*                                                                                           */
                                        /* avec :                                                                                    */
                                        /*                                                                                           */
                                        /*                  DX = +dy                                                                 */
                                        /*                  DY = -dx                                                                 */
                                        /*                                                                                           */

                                        /* Le plan P de la courbe C et le plan H orthogonal a C en {x,y} definissent un referentiel  */
                                        /* {X,Y,Z} dont les vecteurs unites sont :                                                   */
                                        /*                                                                                           */
                                        /*                  X = {+dx/L,+dy/L,0}           (parallele a la tangente)                  */
                                        /*                  Y = {-dy/L,+dx/L,0}           (parallele a la normale)                   */
                                        /*                  Z = {0,    0,    1}           (orthogonal a la tangente et a la normale) */
                                        /*                                                                                           */
                                        /* avec :                                                                                    */
                                        /*                                                                                           */
                                        /*                  L = sqrt((dx^2)+(dy^2))       (afin de normaliser...)                    */
                                        /*                                                                                           */
                                        /* et c'est dans le plan {X,Z} qu'il faut construire un cercle "epaississant" la courbe C    */
                                        /* en un tore a deux trous...                                                                */

                              for       (lambda=LAMBDA0 ; lambda<=LAMBDAn ; lambda=lambda+PASL)
                                        {
                                        double    xt,yt;
                                        double    xn,yn;

                                        double    X,Y,Z;

                                        double    phi;

                                        xt = BARY(+x,+x+dx,lambda);
                                        yt = BARY(+y,+y+dy,lambda);

                                        store(tracer_tangente,GRIS_TANGENTE,NORMX(xt),NORMY(yt));
                                        /* Trace de la tangente.                                                                     */

                                        xn = BARY(+x,+x-dy,lambda);
                                        yn = BARY(+y,+y+dx,lambda);

                                        store(tracer_normale_,GRIS_NORMALE,NORMX(xn),NORMY(yn));
                                        /* Trace de la normale (soit la tangente {dx,dy} multipliee par 'i', soit {-dy,+dx}).        */
                                        }

                              for       (phi=PHI0 ; phi<PHIn ; phi=phi+PASP)
                                        {
                                        double    Xc,Yc,Zc;
                                        double    xc,yc,zc;

                                        Xc = RAYONa*cos(phi);
                                        Yc = 0;
                                        Zc = RAYONb*sin(phi);
                                        /* Definition d'une ellipse dans le plan {x,z}.                                              */

                                        xc = (Xc*cos(psi)) - (Yc*sin(psi)) + NORMX(x);
                                        yc = (Xc*sin(psi)) + (Yc*cos(psi)) + NORMY(y);
                                        zc = Zc;
                                        /* Rotation amenant l'ellipse dans le plan defini par la normale et l'axe 'z' orthogonal     */
                                        /* au plan {x,y} de la courbe C.                                                             */

                                        store(tracer_ellipse_,GRIS_ELLIPSE,xc,yc);
                                        }

                              store(tracer_courbe__,GRIS_COURBE,NORMX(x),NORMY(y));

                              compteur_des_points_de_la_courbe++;
                              }
                    else
                              {
                              }
                    }

          write(1,image,dimX*dimY);
                                        /* Sortie de l'image...                                                                      */
          }



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