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