/*	koch.c -- nach Beispiel aus Buch "C-Programmierung unter Linux			*/
/*	Programm zeichnet das Koch-Dreieck als Fraktal mithilfe der Rekursion		*/

#include <graphics.h>
#include <math.h>

/* ------------------ Makros für die Symbole der Produktionsregeln -------------------- */
#define		F	f(t-1);							/* F */
#define		M	phi=phi-delta;						/* - */
#define		P	phi=phi+delta;						/* + */

/* --- Makros, die Zeichenregeln beschreiben; müssen für neue Bilder gesetzt werden --- */
#define		ANFWINKEL	0		/* Winkel zum Zeichnen der 1. Gerade	*/
#define		DREHWINKEL	60		/* Drehwinkel (Schrittweite)		*/
#define		LFAKTOR		0.333		/* Verkleinerungsfaktor der Länge	*/
#define		STARTX		(getmaxx()/4)	/* x-Koordinate zu Beginn		*/
#define		STARTY		(getmaxy()/3.5)	/* y-Koordinate zu Beginn		*/
#define		STARTLAENGE	(getmaxy()/4)	/* Ausgangslaenge			*/
#define		REKTIEFE	7		/* Rekursionstiefe			*/


double x, y, laenge, phi, delta;


void f(int t);

/* ----------------------------------- main() ----------------------------------------- */
int main(int argc, char* argv[]){
	const double	PI = 4*atan(1);
	int		t, i;

	delta = (DREHWINKEL*PI)/180;		/* Umrechnung Winkel -> Bogenmass	*/
	initgraph(640, 480);
	laenge=STARTLAENGE;

	for(t=1; t<=REKTIEFE; ++t){
		cleardevice(LIGHTBLUE);
		phi=(ANFWINKEL*PI)/180;		/* Umrechnung Winkel -> Bogenmass	*/
		x=STARTX; y=STARTY;
		moveto((int)x, (int)y);
		for(i=1; i<=3; ++i) {
			f(t);
			M M
		}
		laenge*=LFAKTOR;
		getch();
	}

	closegraph();
	return 0;
}

/* ---------------------------------------- f() --------------------------------------- */
void f(int t){
	if(t>0) {
		F P F M M F P F
	}
	else {
		x += laenge*cos(-phi);
		y += laenge*sin(-phi);
		lineto((int)x, (int)y);
	}
}

