hutch@sdcsvax.UUCP (Jim Hutchison) (07/08/85)
fractal() For all of you folks out there with appetite for source, I have posted a copy of several routines which can draw Koch lakes, Gosper Curves, and a Monkey curve. If you don't know what these are, they are self avoiding curves well described in Benoit Mandelbrot's Book "The Fractal Geometry of Nature". If nothing else look at the pretty pictures ( Planet Rise!!! ). # -- strip top and signature -- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by gryphon!hutch on Mon Jul 8 01:23:24 PDT 1985 # Contents: plot.c gosper.c koch.c monkey.c g.h gen.h README echo x - plot.c sed 's/^@//' > "plot.c" <<'@//E*O*F plot.c//' /* * Plot_line() * * Draw a line by length and angle relative to current x,y * * Author: Jim Hutchison (hutch@sdcsvax) * (this is free, but credit me) */ #include <usercore.h> #include <math.h> #include "g.h" /* * Plot a line by length and angle from current position */ plot_line(length,angle) double length,angle; { double dx,dy; MOD(angle,TWOPI); dx = length * cos(angle); dy = length * sin(angle); line_rel_2( dx, dy); } @//E*O*F plot.c// chmod u=rw,g=r,o=r plot.c echo x - gosper.c sed 's/^@//' > "gosper.c" <<'@//E*O*F gosper.c//' /* * Gosper() * * Draw a Gosper curve according to Dr. Mandelbrot. * start with flip at 1 usually, but -1 is fine also. * * Author: Jim Hutchison (hutch@sdcsvax) * (this is free, but credit me) */ #include <usercore.h> #include <math.h> #include "g.h" #include "gen.h" #ifdef GEN_SIDES #undef GEN_SIDES #endif #define GEN_SIDES 7 #define GEN_MAX GEN_SIDES - 1L static GEN generator[GEN_SIDES] = { /* angle flip */ { 0.0, 1 }, { PIO3, -1 }, { PI, -1 }, { (2.0 * PIO3), 1 }, { 0.0, 1 }, { 0.0, 1 }, { (TWOPI - PIO3), -1 } }; gosper(len,angle,min_len,flip) double len,angle,min_len; int flip; { register int i; register GEN *gp; if (len > min_len) { /* draw generator */ angle += (TWOPI - PIO6);/* tilt */ gp = &generator[ (flip == 1)? 0 : GEN_MAX ]; for(i = 0 ; i < GEN_SIDES ; i++, gp += flip) gosper(len/2.0, angle + gp->angle, min_len, gp->flip * flip); } else /* draw side */ plot_line(len, angle); } @//E*O*F gosper.c// chmod u=rw,g=r,o=r gosper.c echo x - koch.c sed 's/^@//' > "koch.c" <<'@//E*O*F koch.c//' /* * koch() * * Draw a Koch lake according to Dr. Mandelbrot. * * Author: Jim Hutchison (hutch@sdcsvax) * (this is free, but credit me) */ #include <usercore.h> #include <math.h> #include "g.h" #include "gen.h" koch(len,angle,min_len) double len,angle,min_len; { int i; for (i = 0 ; i < 4 ; i++, angle += PIO2) /* square seed */ koch_side(len, angle, min_len); } #ifdef GEN_SIDES #undef GEN_SIDES #endif #define GEN_SIDES 8 GEN genkoch[GEN_SIDES] = { /* Angle */ { 0.0 }, { PIO2 }, { 0.0 }, { - PIO2 }, { - PIO2 }, { 0.0 }, { PIO2 }, { 0.0 } }; /* * Draw a side recursively. */ koch_side(len,angle,min_len) double len,angle,min_len; { register int i; GEN *gp; if (len > min_len) /* draw generator */ for(i = 0, gp = genkoch ; i < GEN_SIDES ; i++, gp++) koch_side(len/2.0, angle + gp->angle, min_len); else /* draw side */ plot_line(len, angle); } @//E*O*F koch.c// chmod u=rw,g=r,o=r koch.c echo x - monkey.c sed 's/^@//' > "monkey.c" <<'@//E*O*F monkey.c//' /* * Monkey() * * Draw a Monkey curve according to Dr. Mandelbrot. * * Author: Jim Hutchison (hutch@sdcsvax) * (this is free, but credit me) */ #include <usercore.h> #include <math.h> #include "g.h" #include "gen.h" #ifdef GEN_SIDES #undef GEN_SIDES #endif #define GEN_SIDES 11 #define GEN_MAX GEN_SIDES - 1 GEN genmonkey[GEN_SIDES] = { /* Angle Flip Scale */ { PIO3, -1, 1.0 }, /* R */ { PIO3, 1, 1.0 }, /* L */ { 0.0, 1, 1.0 }, /* L */ { (TWOPI - PIO3), 1, 1.0 }, /* L */ { (2.0 * PIO3 + PIO6), 1, 0.5 }, /* L */ { (2.0 * PIO3 + PIO6), -1, 0.5 }, /* R */ { (PI + PIO6), -1, 0.5 }, /* R */ { (TWOPI - PIO2), -1, 0.5 }, /* R */ { (TWOPI - PIO2), 1, 0.5 }, /* L */ { 0.0, -1, 1.0 }, /* R */ { 0.0, 1, 1.0 } /* L */ }; /* * Draw a monkey curve */ monkey(len,angle,min_len,scale,flip) double len,angle,min_len,scale; int flip; { register int i; GEN *gp; if (len > min_len) { /* draw generator */ gp = &genmonkey[ (flip == 1)? 0 : GEN_MAX ]; for(i = 0 ; i < GEN_SIDES ; i++, gp += flip) monkey(len/2.0, angle + gp->angle, min_len, scale * gp->scale, gp->flip * flip); } else /* draw side */ plot_line(len * scale, angle); } @//E*O*F monkey.c// chmod u=rw,g=r,o=r monkey.c echo x - g.h sed 's/^@//' > "g.h" <<'@//E*O*F g.h//' /* * G.h * * Constants for convenience when doing radial fractal work under SUNCORE * * Author: Jim Hutchison (hutch@sdcsvax) */ #define SQRT2 1.41421 #define PI 3.1415926536 #define PIO2 (PI / 2.0) #define PIO3 (PI / 3.0) #define PIO4 (PI / 4.0) #define PIO6 (PI / 6.0) #define TWOPIO3 (2.0 * PI / 3.0) #define TWOPI (2.0 * PI) #define MOD(a,b) while(a > b) a -= b /* sad but true */ @//E*O*F g.h// chmod u=rw,g=r,o=r g.h echo x - gen.h sed 's/^@//' > "gen.h" <<'@//E*O*F gen.h//' /* * Author: Jim Hutchison (hutch@sdcsvax) * Curve generators and initiators ( can be same structure ) * Various and sundry generators and a very general one. */ typedef struct gen { /* an initiator or generator */ double angle; /* next turtle turn */ int flip; /* Flip flop multiplier */ double scale; /* scale factor for sides */ double div; /* division factor for length */ } GEN; @//E*O*F gen.h// chmod u=rw,g=r,o=r gen.h echo x - README sed 's/^@//' > "README" <<'@//E*O*F README//' These files: g.ha few constants gen.h generator structure general.c a general curve generator gosper.c gosper curve generator koch.c koch curve generator monkey.c monkey curve generator (My favorite) plot.c plot a line relatively Comprise a collection of simple fractal curve generators. They do not generate nifty 3D dragons or towers or archs, but they are entertaining and probably good for tiling. All I ask is that you not (how incredibly unlikely) try to sell these for profit. I can ofcourse assume no respon- sibility for how these work out for you. They work fine for me on a SUN (TM) workstation under 4.2 Unix (TM) using SUN- core. Jim Hutchison hutch@sdcsvax {ihnp4,ucbvax}!sdcsvax!hutch @//E*O*F README// chmod u=rw,g=r,o=r README exit 0 -- /* Jim Hutchison UUCP: {dcdwest,ucbvax}!sdcsvax!hutch ARPA: hutch@sdcsvax < Ofcourse these statements are only mine, not my employers. > */