/*************************************************************************************************************************************/
/* */
/* C O N S T R U C T I O N D ' U N E C O U R B E F R A C T A L E A L E A T O I R E D A N S L E P L A N : */
/* */
/* */
/* Author of '$xtc/FracCurve.11$c' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, AAAAMMJJhhmmss). */
/* */
/*************************************************************************************************************************************/
#include "INCLUDES.01.I"
/* Introduit le 20051116094022... */
extern void *malloc();
extern int atoi();
extern char *getenv();
extern double sqrt();
extern double cos();
extern double sin();
extern double drand48();
#define AVEUGLE 5646
#define RANDOM(minimum,maximum) \
((minimum) + (((maximum)-(minimum))*drand48())) \
/* Generation d'une valeur aleatoire dans [minimum,maximum]. */
#define XG (0.00)
#define XD (1.00)
/* Extremites Gauche et Droite sur l'axe des 'X'. */
#define YB (0.00)
#define YH (1.00)
/* Extremites Bas et Haut sur l'axe des 'Y'. */
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. */
unsigned char *image;
/* Definition de l'image a generer... */
#define Xnormalise(x) \
((int)((x-XG)/(XD-XG)*dimX))
#define Ynormalise(y) \
((int)((y-YB)/(YH-YB)*dimY))
/* Mise des coordonnees {x,y} dans [Xmin,Xmax]x[Ymin,Ymax]. */
#define IMAGE(x,y) \
(*(image + ((int)(((y-Ymin)*dimX) + (x-Xmin))))) \
/* Acces a un point de l'image. */
#define NIVEAU_MINIMAL \
(NOIR+1)
#define NIVEAU_MAXIMAL \
(BLANC)
/* Definition des niveaux aleatoires. */
#define store(n,x,y) \
{ \
if (((x>=Xmin) && (x<=Xmax)) && ((y>=Ymin) && (y<=Ymax))) \
{ \
IMAGE(x,y) = (int)(n); \
} \
else \
{ \
} \
} \
/* Rangement d'un point valide d'une image. */
#define PRECIS double \
/* Precision des calculs. */
typedef struct complexe {
PRECIS reelle;
PRECIS imaginaire;
} complexe;
#define Reelle(z) (z.reelle)
#define Imaginaire(z) (z.imaginaire)
/* Definition et acces aux composantes d'un nombre complexe... */
#define Cinit(z,x1,y1) \
{ \
Reelle(z) = x1; \
Imaginaire(z) = y1; \
}
#define Cegal(z,z1) \
{ \
Cinit(z,Reelle(z1),Imaginaire(z1)); \
}
#define Csomme(z,z1,z2) \
{ \
complexe zT; \
Reelle(zT) = Reelle(z1) + Reelle(z2); \
Imaginaire(zT) = Imaginaire(z1) + Imaginaire(z2); \
Cegal(z,zT); \
}
#define Cdifference(z,z1,z2) \
{ \
complexe zT; \
Reelle(zT) = Reelle(z1) - Reelle(z2); \
Imaginaire(zT) = Imaginaire(z1) - Imaginaire(z2); \
Cegal(z,zT); \
}
#define Cproduit(z,z1,z2) \
{ \
complexe zT; \
Reelle(zT) = (Reelle(z1)*Reelle(z2)) - (Imaginaire(z1)*Imaginaire(z2)); \
Imaginaire(zT) = (Reelle(z2)*Imaginaire(z1)) + (Reelle(z1)*Imaginaire(z2)); \
Cegal(z,zT); \
}
#define Crotation(z,z1,rho,theta) \
{ \
complexe zR; \
Cinit(zR,rho*cos(theta),rho*sin(theta)); \
Cproduit(z,z1,zR); \
}
#define Cmodule2(z) \
((Reelle(z)*Reelle(z)) + (Imaginaire(z)*Imaginaire(z)))
#define NOMBRE_MINIMAL_D_ANGLES \
4
#define NOMBRE_MAXIMAL_D_ANGLES \
8
#define ANGLE_MINIMAL \
(-PI/2)
#define ANGLE_MAXIMAL \
(+PI/2)
int nombre_d_angles;
PRECIS *angles;
/* Definition de la liste des angles aleatoires. */
PRECIS seuil=0.002;
/* Definition du seuil d'arret. */
#define RAPPORT_MINIMAL \
2.0
#define RAPPORT_MAXIMAL \
3.0
PRECIS rapport=4.0;
/* Definition du rapport de reduction aleatoire. */
#define rotation_et_construction(theta) \
{ \
Cegal(zGs3,zDs3); \
Crotation(difference_reduite,difference_reduite,1.0,theta); \
Csomme(zDs3,zGs3,difference_reduite); \
construction(zGs3,zDs3); \
}
construction(zG,zD)
complexe zG,zD;
{
complexe difference;
Cdifference(difference,zD,zG);
if (sqrt(Cmodule2(difference)) < seuil)
{
store(RANDOM(NIVEAU_MINIMAL,NIVEAU_MAXIMAL),Xnormalise(Reelle(zG)),Ynormalise(Imaginaire(zG)));
store(RANDOM(NIVEAU_MINIMAL,NIVEAU_MAXIMAL),Xnormalise(Reelle(zD)),Ynormalise(Imaginaire(zD)));
/* Marquage et arret de la recursivite... */
}
else
{
int angle;
complexe zGs3,zDs3;
complexe difference_reduite;
Cegal(zDs3,zG);
Crotation(difference_reduite,difference,1.0/rapport,0.0);
for (angle=0 ; angle<nombre_d_angles ; angle++)
{
rotation_et_construction(*(angles+angle));
}
}
return(OK);
}
main()
{
complexe zG,zD;
/* Definition des extremites de la courbe. */
int x,y;
/* Definition des coordonnees d'initialisation de l'image. */
int aveugle;
int angle;
/* Index de la liste des angles. */
for (aveugle=0 ; aveugle<AVEUGLE ; aveugle++)
{
PRECIS random=drand48();
/* Pour faire comme s'il on injectait une graine dans le generateur aleatoire... */
}
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(NOIR,x,y);
/* Initialisation de l'image finale... */
}
}
rapport = RANDOM(RAPPORT_MINIMAL,RAPPORT_MAXIMAL);
/* Generation du rapport de reduction aleatoire. */
nombre_d_angles = RANDOM(NOMBRE_MINIMAL_D_ANGLES,NOMBRE_MAXIMAL_D_ANGLES);
angles = malloc(nombre_d_angles*sizeof(PRECIS));
for (angle=0 ; angle<nombre_d_angles ; angle++)
{
*(angles+angle) = RANDOM(ANGLE_MINIMAL,ANGLE_MAXIMAL);
/* Generation de la liste des angles aleatoires. */
}
Cinit(zG,XG,(YB+YH)/2);
Cinit(zD,XD,(YB+YH)/2);
/* Initialisation des extremites de la courbe. */
construction(zG,zD);
/* Construction de la courbe. */
write(1,image,dimX*dimY);
/* Sortie de l'image... */
fprintf(stderr,"\n rapport de reduction=%f",rapport);
fprintf(stderr,"\n nombre d'angles utilises=%d",nombre_d_angles);
for (angle=0 ; angle<nombre_d_angles ; angle++)
{
fprintf(stderr,"\n angle(%d)=%+f",angle,*(angles+angle));
/* Edition des angles utilises... */
}
fprintf(stderr,"\n");
fprintf(stderr,"\nrapport=%f ",rapport);
for (angle=0 ; angle<nombre_d_angles ; angle++)
{
fprintf(stderr,"c%02d=VRAI a%02d=%+f ",angle,angle,*(angles+angle));
/* Edition des angles utilises... */
}
fprintf(stderr,"\n");
}