[net.sources] Fractal curves

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