ftp.nice.ch/pub/next/graphics/vector/MapMaker.0.9.N.bs.tar.gz#/MapMaker/fractal.c

This is fractal.c in view mode; [Download] [Up]

/*
** fractal.c 
** for project : MapMaker  
** using NeXTStep and mach Unix.
** CPSC 414 Assignment No. 4 Project
**  
** Programmed by Bradley Head and Thomas Burkholder 
** December 1990
*/

#import <math.h>
#import "pointdata.h"
#import "proj.h"
#import "fractal.h"


  float MinLen = 10*toRADS;	/* set global variable to initial value */
 
 FractValues fvalues;
 /****************************************************/ 
 
 int setFValues(int Fractalize, float H, float StdDev) {	/* set up constants for Fractalizing */
 	fvalues.Fractalize = Fractalize;
	fvalues.H = H;
	fvalues.StdDev = StdDev;
	}
	
float Gauss() {	 		/* returns a random number between -0.5 & 0.5  */
double intpart;					/* with  mean at 0.0 */
float g = 0.0;
int i;

for (i = 1;i <= 23;i++) 
	g += rand() /(RAND_MAX + 1.0);
	g = g/23.0 - 0.5; 		/* set mean to 0.0 */
return g;
}


void  Fract(Point a, Point b, float sdev, PointList *plist) 
{
/*  this function is used to fractalize
** line segments
*/
float r;
float Len;
Point n;
Len = sqrt((b.x - a.x)*(b.x - a.x) + (b.y - a.y)*(b.y - a.y));	/* compute length between points */
if  (Len  < (MinLen)) { 		/* terminating condition: don't fractalize less than this length */
	addToPointList(plist,&b);	/* add the point to list */
	}
	else {
		sdev *= fvalues.f;		/* scale Sdev by f */
		r = Gauss()*sdev;		/* get gaussian pseudo-random number */
		n.x = 0.5*(a.x + b.x) - r*(b.y - a.y);	/* compute the middle point */
		n.y = 0.5*(a.y + b.y) + r*(b.x - a.x);
		n.pen = DOWN;
		Fract(a,n,sdev,plist);	/* call Fract on segment between a and n */
		Fract(n,b,sdev,plist);	/* call Fract on segment between b and n */
	}
}


void insertFSegments(PointList *pin, PointList *pout, ProjParam *pparam)  {

/* This function segments the input list either using a parametric 
** insertion technique
** or by fractalizing the line segments of the input list
** the segmented list is returned as the point list pout 
** which can then be plotted
*/
float step,t;
float Len;
Point p;
Point *p1;
Point *p2;
int vertex = 0;
MinLen =10*toRADS*fabs(pparam->radius);  /* compute minimum length to decide if segmenting */
while (gotoPointInList(pin,vertex,&p1)) {	/* while there is a list to segment */
	addToPointList(pout,p1);			/* add the first point to the output list */
	vertex++;
 	if (gotoPointInList(pin,vertex,&p2))	/* if there is a next vertex then continue */
 		{
		Len = sqrt((p2->x - p1->x)*(p2->x - p1->x) + (p2->y - p1->y)*(p2->y - p1->y));
		if (fvalues.Fractalize) {
			fvalues.f  = exp((0.5 - fvalues.H)*log(2.0));	/* Fractalize stuff to get f */
			if (p1->pen == DOWN)															
				Fract(*p1, *p2, fvalues.StdDev, pout);	/* call the recursive function Fract */
			else 
				addToPointList(pout,p2);	/* if the pen command is up don't fractalize; just move and store */
			}
		else  {								/* else you don't want to Fractalize, so segment */
			if ((Len  > MinLen) && (p1->pen == DOWN))  {
				step = MinLen/Len;			/* step increment for parametric segmenting */
				for (t=step;t<1.0; t+=step) {
					p.x = p1->x + (p2->x - p1->x)*t;	/* calculate segment vertex position */
					p.y = p1->y + (p2->y - p1->y)*t; /* parametrically */
					p.pen = DOWN;
					addToPointList(pout,&p); 	/* add each segment vertex */
					}
				}
			addToPointList(pout,p2);	/* add the last point then carry on */
			}
		}
	}
}



These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.