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