davidk@dartvax.UUCP (David C. Kovar) (08/04/85)
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@csnet-relay CSNET: davidk%amber@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@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@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@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@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@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@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@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@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@sdcsvax.UUCP (Jim Hutchison) Newsgroups: net.graphics Subject: Fractal Plot (BUG) Message-ID: <980@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@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@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@csnet-relay CSNET: davidk%amber@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