/*************************************************************************************************************************************/
/* */
/* 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... */
}