/*	Tesselmeer.m - Tesselated plane model.
 *	Copyright (C) 1993 Corona Design, Inc. All rights reserved.
 *
 *	Abstract
 *		Creates a hexagon tesselated with colored equilateral triangles.
 *
 *	RCS path: 
 *		$Source: /Users/pkron/Projects/voxel/Pyramid/RCS/Tesselmeer.m,v $
 *	Modified: $Date: 93/09/15 12:35:21 $ by $Author: pkron $
 *	Current State: $State: Exp $ locked by $Locker:  $
 */

#import		"Tesselmeer.h"

#define	SQRT3	1.732051
static void	subdivideTriangle( struct _meer *, int index, int depth);

@implementation	Tesselmeer

- init
	{
	int		depth = 2;

	[super init];
	
								// define initial hexagon
								// six triangles
	meer3D.count = 6;
	meer3D.triangles[0].apex[0] = -.5;
	meer3D.triangles[0].apex[1] = SQRT3/2;
	meer3D.triangles[0].height  = -SQRT3/2;
	meer3D.triangles[0].color  = G;
	
	meer3D.triangles[1].apex[0] = 0;
	meer3D.triangles[1].apex[1] = 0;
	meer3D.triangles[1].height  = SQRT3/2;
	meer3D.triangles[1].color  = Y;
	
	meer3D.triangles[2].apex[0] = .5;
	meer3D.triangles[2].apex[1] = SQRT3/2;
	meer3D.triangles[2].height  = -SQRT3/2;
	meer3D.triangles[2].color  = B;
	
	meer3D.triangles[3].apex[0] = -.5;
	meer3D.triangles[3].apex[1] = -SQRT3/2;
	meer3D.triangles[3].height  = SQRT3/2;
	meer3D.triangles[3].color  = B;
	
	meer3D.triangles[4].apex[0] = 0;
	meer3D.triangles[4].apex[1] = 0;
	meer3D.triangles[4].height  = -SQRT3/2;
	meer3D.triangles[4].color  = Y;
	
	meer3D.triangles[5].apex[0] = .5;
	meer3D.triangles[5].apex[1] = -SQRT3/2;
	meer3D.triangles[5].height  = SQRT3/2;
	meer3D.triangles[5].color  = G;

									// recursively divide triangles	
	if ( depth GT 0 )
		{
		subdivideTriangle( &meer3D, 0, depth);
		subdivideTriangle( &meer3D, 1, depth);
		subdivideTriangle( &meer3D, 2, depth);
		subdivideTriangle( &meer3D, 3, depth);
		subdivideTriangle( &meer3D, 4, depth);
		subdivideTriangle( &meer3D, 5, depth);
		}
	
	return( self);
	}
	

								// draw the tesslated plane	
- drawModel: (MATRIX)transform : (NXRect *)clip
	{
	int		i;
	
	for ( i=0; i LT meer3D.count; ++i)
		{
		POINT	corners[3];
		float	height = meer3D.triangles[i].height;
		float	deltaX = height*(.5/(SQRT3/2));
		
		corners[0][2] = corners[1][2] = corners[2][2] = 0;
		corners[0][3] = corners[1][3] = corners[2][3] = 1;
		corners[0][0] = meer3D.triangles[i].apex[0];
		corners[0][1] = meer3D.triangles[i].apex[1];

								// compute corners from apex		
		corners[1][0] = corners[0][0] - deltaX;
		corners[1][1] = corners[0][1] + height;

		corners[2][0] = corners[1][0] + 2*deltaX;
		corners[2][1] = corners[1][1];

								// map and project vertices		
		map( transform, &corners[0]);
		map( transform, &corners[1]);
		map( transform, &corners[2]);
		project(&corners[0]);
		project(&corners[1]);
		project(&corners[2]);

								// draw
		PSmoveto( corners[0][0], corners[0][1]);
		PSlineto( corners[1][0], corners[1][1]);
		PSlineto( corners[2][0], corners[2][1]);
		PSclosepath();
		switch( meer3D.triangles[i].color )
			{
			case R:
				PSsetrgbcolor( 1, 0, 0);
				break;
			case G:
				PSsetrgbcolor( 0, 1, 0);
				break;
			case B:
				PSsetrgbcolor( 0, 0, 1);
				break;
			case Y:
				PSsetrgbcolor( 1, 1, 0);
				break;
			}
		PSfill();
		}
		
	return( self);
	}


@end


								// recursively subdivide
static void	
subdivideTriangle( struct _meer *meer, int index, int depth)
	{
	int		new;
	float	apex[2];
	float	height	= meer->triangles[ index].height/2;

								// cut this triangle in half and paint tip red	
	apex[0] = meer->triangles[ index].apex[0];
	apex[1] = meer->triangles[ index].apex[1];
	meer->triangles[ index].height = height;
	meer->triangles[ index].color  = R;
	
								// create 3 new triangles to
								// subdivide base of original triangle
	new = meer->count++;
	meer->triangles[ new].apex[0] 	= apex[0] + (height*.5)/(SQRT3/2);
	meer->triangles[ new].apex[1] 	= apex[1] + height;
	meer->triangles[ new].height 	= height;
	meer->triangles[ new].color 	= G;
	
	new = meer->count++;
	meer->triangles[ new].apex[0] 	= apex[0];
	meer->triangles[ new].apex[1] 	= apex[1] + 2*height;
	meer->triangles[ new].height 	= -height;
	meer->triangles[ new].color 	= Y;
	
	new = meer->count++;
	meer->triangles[ new].apex[0] 	= apex[0] - (height*.5)/(SQRT3/2);
	meer->triangles[ new].apex[1] 	= apex[1] + height;
	meer->triangles[ new].height 	= height;
	meer->triangles[ new].color 	= B;
	
									// recurse
	if ( depth GT 1 )
		{
		subdivideTriangle( meer, index, depth-1);
		subdivideTriangle( meer, new--, depth-1);
		subdivideTriangle( meer, new--, depth-1);
		subdivideTriangle( meer, new--, depth-1);
		}
	}


#ifdef	_LOG
/*
 *	$Log:	Tesselmeer.m,v $
Revision 1.1  93/09/15  12:35:21  pkron
Created.

 */
#endif		
