/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        T R A C E   D ' U N E   E P Y C Y C L O I D E  :                                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xtc/epicycloide.03$c' :                                                                                        */
/*                                                                                                                                   */
/*                    Jean-Francois Colonna (LACTAMME, 20161212093719).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

#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                                                                                                                        \
                    (2*PI)
#define   PAST                                                                                                                          \
                    ((THETAn-THETA0)/320)
                                        /* Definition de l'angle 'theta' parametrant la courbe.                                      */

#define   PARAM_A                                                                                                                       \
                    8.0
#define   PARAM_a                                                                                                                       \
                    1.0
#define   PARAM_L                                                                                                                       \
                    4.0
                                        /* Parametrage de l'epicycloide.                                                             */

#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)/30
#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(FAUX,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    psi;

                              x = ((PARAM_A+PARAM_a)*cos(theta))-((PARAM_L*PARAM_a)*cos(((PARAM_A+PARAM_a)/PARAM_a)*theta));
                              y = ((PARAM_A+PARAM_a)*sin(theta))-((PARAM_L*PARAM_a)*sin(((PARAM_A+PARAM_a)/PARAM_a)*theta));
                                        /* Point courant {x,y}.                                                                      */

                              dx = ((PARAM_A+PARAM_a)*(-sin(theta)))-((PARAM_L*PARAM_a)*(-sin(((PARAM_A+PARAM_a)/PARAM_a)*theta)));
                              dy = ((PARAM_A+PARAM_a)*cos(theta))-((PARAM_L*PARAM_a)*cos(((PARAM_A+PARAM_a)/PARAM_a)*theta));
                                        /* 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.