Fractal routines (slightly hacked over)
David C. Kovar
davidk at dartvax.UUCP
Sun Aug 4 09:38:59 AEST 1985
This is a reposting of Jim Hutchison's fractal routines. I just made them
work under pixrect instead of suncore and added a trivial driver to run them
all. This may be of little interest to most, but it made life easier for me.
(Was having problems getting it running under SunCore ...) Hope it helps
someone out there....
Oh yea, some of the initialization stuff was taken from somewhere else,
but I can't remember where. Hope I did not offend anyone. (I *do* know that
it was not a commercial package....)
David C. Kovar
USNET: {linus|decvax|cornell|astrovax}!dartvax!davidk%amber
ARPA: davidk%amber%dartmouth at csnet-relay
CSNET: davidk%amber at dartmouth
-------------------------------- cut here ----------------------------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
all=FALSE
if [ $1x = -ax ]; then
all=TRUE
fi
/bin/echo 'Extracting Makefile'
sed 's/^X//' <<'//go.sysin dd *' >Makefile
GENOBJ = init.o sqrt.o plot.o
FRACTOBJ = general.o koch.o monkey.o gosper.o
LIB = -lm -lpixrect
fractals: main.o $(FRACTOBJ) $(GENOBJ)
cc -o fractals -O main.o $(FRACTOBJ) $(GENOBJ) $(LIB)
koch.o: koch.c gen.h g.h
cc -c koch.c
monkey.o: monkey.o gen.h g.h
cc -c monkey.c
gosper.o: gosper.c gen.h g.h
cc -c gosper.c
general.o: general.c gen.h g.h
cc -c general.c
plot.o: plot.c g.h pix.h
cc -c plot.c
sqrt.o: sqrt.c
cc -c sqrt.c
init.o: init.c defs.h
cc -c init.c
clean:
rm *.o fractals
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 Makefile
/bin/echo -n ' '; /bin/ls -ld Makefile
fi
/bin/echo 'Extracting README'
sed 's/^X//' <<'//go.sysin dd *' >README
These files:
defs.h random definitions
pix.h pixrect definitions
g.h 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
main.c trivial driver for all the routines
init.c routines to setup screen under pixrect
sqrt.c somehow the sqrt function got lost here ...
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. [Now under pixrect ... -David Kovar]
Jim Hutchison
hutch at sdcsvax
{ihnp4,ucbvax}!sdcsvax!hutch
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 README
/bin/echo -n ' '; /bin/ls -ld README
fi
/bin/echo 'Extracting defs.h'
sed 's/^X//' <<'//go.sysin dd *' >defs.h
#define LEFT 01
#define RIGHT 02
#define MINXPOS 50
#define MAXXPOS (SCREEN_WIDTH-50)
#define MINYPOS 100
#define MAXYPOS (SCREEN_HEIGHT-100)
#ifndef CTRL
# define CTRL(c) ('c' & 037)
#endif
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define ABS(d) ((d) < 0 ? -(d) : (d))
extern int errno, sys_nerr;
extern char *sys_errlist[];
#define ERRSTR (errno < sys_nerr ? sys_errlist[errno] : "Unknown Error")
#define MEM_WIDTH 32
#define MEM_HEIGHT 32
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 defs.h
/bin/echo -n ' '; /bin/ls -ld defs.h
fi
/bin/echo 'Extracting g.h'
sed 's/^X//' <<'//go.sysin dd *' >g.h
X/*
* G.h
*
* Constants for convenience when doing radial fractal work under SUNCORE
*
* Author: Jim Hutchison (hutch at 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 D_X 5.0
#define D_Y 5.0
#define GEN_SIDES 10
#define MOD(a,b) while(a > b) a -= b /* sad but true */
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 g.h
/bin/echo -n ' '; /bin/ls -ld g.h
fi
/bin/echo 'Extracting gen.h'
sed 's/^X//' <<'//go.sysin dd *' >gen.h
X/*
* Author: Jim Hutchison (hutch at 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;
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 gen.h
/bin/echo -n ' '; /bin/ls -ld gen.h
fi
/bin/echo 'Extracting general.c'
sed 's/^X//' <<'//go.sysin dd *' >general.c
X/*
* general()
*
* Draw a Generic Fractal curve.
*
* Author: Jim Hutchison (hutch at sdcsvax)
* (this is free, but credit me)
*/
#include <usercore.h>
#include <math.h>
#include "g.h"
#include "gen.h"
general(len,angle,min_len,scale,flip,shape,size)
double len,angle,min_len,scale;
int flip;
GEN *shape;
int size;
{
register int i;
GEN *gp;
if (len > min_len) { /* draw generator */
gp = shape + ((flip == 1)? 0 : size );
for(i = 0 ; i < GEN_SIDES ; i++, gp += flip)
general(len/gp->div,
angle + gp->angle,
min_len,
scale * gp->scale,
gp->flip * flip);
} else /* draw side */
plot_line(len * scale, angle);
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 general.c
/bin/echo -n ' '; /bin/ls -ld general.c
fi
/bin/echo 'Extracting gosper.c'
sed 's/^X//' <<'//go.sysin dd *' >gosper.c
X/*
* Gosper()
*
* Draw a Gosper curve according to Dr. Mandelbrot.
* start with flip at 1 usually, but -1 is fine also.
*
* Author: Jim Hutchison (hutch at 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);
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 gosper.c
/bin/echo -n ' '; /bin/ls -ld gosper.c
fi
/bin/echo 'Extracting init.c'
sed 's/^X//' <<'//go.sysin dd *' >init.c
#include <stdio.h>
#include <pixrect/pixrect_hs.h>
#include <sys/ioctl.h>
#include <sun/fbio.h>
#include <sys/file.h>
#include "defs.h"
char *PR_DEVICE = "/dev/fb"; /* for console frame buffer */
struct pixrect *px_screen; /* console screen pixrect */
int SCREEN_WIDTH, SCREEN_HEIGHT;
X/*
* Set up the screen for the subsequent screen graphics mmanipulations.
* All operations are done with the pixrect facilities of the SUN
* workstation 1.1 release.
*/
initpix()
{
char *getenv();
if (init_screen())
return(-1);
pr_rop(px_screen, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, PIX_SET,
(struct pixrect *)NULL, 0, 0);
return(0);
}
X/*
* Initialize the pixrect from the whole screen.
*/
init_screen()
{
int fd;
if ( (fd = open(PR_DEVICE, O_RDWR)) < 0 ) {
fprintf(stderr, "Cannot open \"%s\": %s\n", PR_DEVICE, ERRSTR);
return(-1);
}
if ( getsize(fd) )
return(-1);
close(fd);
if ((px_screen = pr_open(PR_DEVICE)) == NULL) {
fputs("Cannot open ", stderr);
perror(PR_DEVICE);
return(-1);
}
return(0);
}
X/*
* Get the number of pixels of the screen size. If the size
* is zero, we assume an error.
*/
getsize(fd)
{
struct fbtype fbt;
if (ioctl(fd, FBIOGTYPE, (char *)&fbt) < 0) {
perror("FBIOGTYPE ioctl");
return(-1);
}
SCREEN_WIDTH = fbt.fb_width;
SCREEN_HEIGHT = fbt.fb_height;
if ( SCREEN_WIDTH <= 0 || SCREEN_HEIGHT <= 0 ) {
fprintf(stderr, "Can't get the window size.\n");
return(-1);
}
return(0);
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 init.c
/bin/echo -n ' '; /bin/ls -ld init.c
fi
/bin/echo 'Extracting koch.c'
sed 's/^X//' <<'//go.sysin dd *' >koch.c
X/*
* koch()
*
* Draw a Koch lake according to Dr. Mandelbrot.
*
* Author: Jim Hutchison (hutch at 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 }
};
X/*
* 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);
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 koch.c
/bin/echo -n ' '; /bin/ls -ld koch.c
fi
/bin/echo 'Extracting main.c'
sed 's/^X//' <<'//go.sysin dd *' >main.c
#include <stdio.h>
main()
{
int choice = 0;
double len, angle, min_len, scale;
int flip;
while(choice < 1 || choice > 4) {
printf("Choose a fractal: \n");
printf("\t1) Monkey \n");
printf("\t2) Koch lakes \n");
printf("\t3) General (not handled yet)\n");
printf("\t4) Gosper\n");
printf("\nChoice? ");
scanf("%d", &choice);
}
printf("All values should be doubles (xxx.x) save for 'flip', an int.\n");
printf("Reasonable values for monkey are: 10.0 0.0 1.0 1.0 1 \n");
switch (choice) {
case 1: /* Monkey */
printf ("Length, angle, min. length, scale, flip: ");
scanf ("%lf %lf %lf %lf %d",
&len, &angle, &min_len, &scale, &flip);
initpix();
monkey (len, angle, min_len, scale, flip);
break;
case 2: /* Koch lakes */
printf ("Length, angle, minimum length: ");
scanf ("%lf %lf %lf", &len, &angle, &min_len);
initpix();
koch (len, angle, min_len);
break;
case 3: /* General. Not handled yet */
printf ("Not handled.\n");
break;
case 4:
printf ("Length, angle, minimum length, flip: ");
scanf ("%lf %lf %lf %", &len, &angle, &min_len, &flip);
initpix();
gosper (len, angle, min_len, flip);
break;
}
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 main.c
/bin/echo -n ' '; /bin/ls -ld main.c
fi
/bin/echo 'Extracting monkey.c'
sed 's/^X//' <<'//go.sysin dd *' >monkey.c
X/*
* Monkey()
*
* Draw a Monkey curve according to Dr. Mandelbrot.
*
* Author: Jim Hutchison (hutch at 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 */
};
X/*
* 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);
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 monkey.c
/bin/echo -n ' '; /bin/ls -ld monkey.c
fi
/bin/echo 'Extracting pix.h'
sed 's/^X//' <<'//go.sysin dd *' >pix.h
X/*
* Basic operations on the screen as a whole pixrect.
*/
#include <pixrect/pixrect_hs.h>
extern struct pixrect *px_screen;
#define OP_CLEAR PIX_CLR
#define OP_SET PIX_SET
#define OP_PAINT (PIX_SRC|PIX_DST)
#define OP_WRITE PIX_SRC
#define OP_MASK (PIX_SRC&PIX_DST)
#define OP_ERASE (PIX_NOT(PIX_SRC)&PIX_DST)
#define OP_INVERT (PIX_NOT(PIX_SRC^PIX_DST))
#define OP_NOT(op) PIX_NOT(op)
#define WHITE CLEAR
#define BLACK SET
extern int SCREEN_WIDTH, SCREEN_HEIGHT;
#define point(x,y,op) pr_put(px_screen, x, y, (op == PIX_CLR) ? 0 : 1)
#define line(x1,y1,x2,y2,op) pr_vector(px_screen, x1, y1, x2, y2, op, 0)
#define block(x,y,w,h,op) pr_rop(px_screen, x, y, w, h, op, \
(struct pixrect *)0, 0, 0)
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 pix.h
/bin/echo -n ' '; /bin/ls -ld pix.h
fi
/bin/echo 'Extracting plot.c'
sed 's/^X//' <<'//go.sysin dd *' >plot.c
X/*
* Plot_line()
*
* Draw a line by length and angle relative to current x,y
*
* Author: Jim Hutchison (hutch at sdcsvax)
* (this is free, but dis/credit me)
*/
#include <math.h>
#include "g.h"
#include "pix.h"
static double crntx = D_X, crnty = D_Y; /* or global for presetting */
set_coord(x,y)
double x,y;
{
crntx = x;
crnty = y;
}
X/*
* 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((int)(crntx * 10.0), (int)(crnty * 10.0),
(int)((crntx + dx) * 10.0), (int)((crnty + dy) * 10.0), OP_WRITE);
crntx += dx;
crnty += dy;
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 plot.c
/bin/echo -n ' '; /bin/ls -ld plot.c
fi
/bin/echo 'Extracting plot.fix'
sed 's/^X//' <<'//go.sysin dd *' >plot.fix
Relay-Version: version B 2.10.2 9/18/84; site dartvax.UUCP
Posting-Version: version B 2.10.2 9/18/84; site sdcsvax.UUCP
Path: dartvax!decvax!tektronix!hplabs!sdcrdcf!sdcsvax!hutch
From: hutch at sdcsvax.UUCP (Jim Hutchison)
Newsgroups: net.graphics
Subject: Fractal Plot (BUG)
Message-ID: <980 at sdcsvax.UUCP>
Date: 11 Jul 85 21:19:38 GMT
Article-I.D.: sdcsvax.980
Posted: Thu Jul 11 17:19:38 1985
Date-Received: 15 Jul 85 11:02:17 GMT
Organization: UCSD EMU Project (Educational Microcomputer Unix)
Lines: 65
*** These Bugs do seem to creep in... ***
Plot.c had a small bug in it, i.e. it looked neat, but not right
for most normal cases. For all those of you with headaches over
it, pardon.
in your main routine:
openpl();
space(-500,-500,500,500);
set_coord(D_X, D_Y); /* initial position */
monkey(10.0, 0.0, 1.0, 1.0, 1); /* for example */
closepl();
The earlier version ran fine in atleast one particular case, so
if it works for you this fix is still a good idea.
X/*
* Plot_line()
*
* Draw a line by length and angle relative to current x,y
*
* Author: Jim Hutchison (hutch at sdcsvax)
* (this is free, but dis/credit me)
*/
#include <math.h>
#include "g.h"
static double crntx = 0.0, crnty = 0.0; /* or global for presetting */
set_coord(x,y)
double x,y;
{
crntx = x;
crnty = y;
}
X/*
* 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((int)(crntx * 10.0), (int)(crnty * 10.0),
(int)((crntx + dx) * 10.0), (int)((crnty + dy) * 10.0));
crntx += dx;
crnty += dy;
}
--
X/*
Jim Hutchison UUCP: {dcdwest,ucbvax}!sdcsvax!hutch
ARPA: hutch at sdcsvax
< Ofcourse these statements are only mine, not my employers. >
*/
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 plot.fix
/bin/echo -n ' '; /bin/ls -ld plot.fix
fi
/bin/echo 'Extracting sqrt.c'
sed 's/^X//' <<'//go.sysin dd *' >sqrt.c
double sqrt()
{
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 sqrt.c
/bin/echo -n ' '; /bin/ls -ld sqrt.c
fi
--
David C. Kovar
USNET: {linus|decvax|cornell|astrovax}!dartvax!davidk%amber
ARPA: davidk%amber%dartmouth at csnet-relay
CSNET: davidk%amber at dartmouth
"I felt like a punk who'd gone out for a switchblade and come back
with a tactical nuke.
'Shit', I thought. 'Screwed again. What good's a tactical nuke in a
street fight?'"
"Burning Chrome" by William Gibson
More information about the Comp.sources.unix
mailing list