//	Turtle.cxx#include "Turtle.h"#include "PixelMap.h"#include <math.h>const double PI = 3.14157;#define ABS(x) ( x<0? (-(x)) : (x) )void Turtle::VLine( const int pY1, const int pY2, const int pX ){	if (!itsPixelMap) return;	// draw a vertical line, with our current thickness and color	int from,to;	if (pY1<pY2) {		from=pY1;		to=pY2;	} else {		from=pY2;		to=pY1;	}	if (itsWidth==1 && itsHeight==1) {		itsPixelMap->VLine( from, to, pX, itsColor );		return;	}	double halfw=(double)itsWidth/2;	double halfh=(double)itsHeight/2;	itsPixelMap->FillBox( (int)((double)pX-halfw), (int)((double)pX+halfw),		(int)((double)from-halfh), (int)((double)to+halfh), itsColor);}void Turtle::HLine( const int pX1, const int pX2, const int pY ){	if (!itsPixelMap) return;	// draw a horizontal line, with our current thickness and color	int from,to;	if (pX1<pX2) {		from=pX1;		to=pX2;	} else {		from=pX2;		to=pX1;	}	if (itsWidth==1 && itsHeight==1) {		itsPixelMap->HLine( from, to, pY, itsColor );		return;	}	double halfw=(double)itsWidth/2;	double halfh=(double)itsHeight/2;	itsPixelMap->FillBox( (int)((double)from-halfw), (int)((double)to+halfw),		(int)((double)pY-halfh), (int)((double)pY+halfh), itsColor);}void Turtle::Line( const int pDX, const int pDY ){	if (!itsPixelMap) return;	// draw a line from the current position		// if it's true vertical or horizontal, use a quicker method	if (pDX==0) {		VLine( (int)itsY, (int)itsY+pDY, (int)itsX );		return;	}	if (pDY==0) {		HLine( (int)itsX, (int)itsX+pDX, (int)itsY );		return;	}	int	step;		// if it's mostly-vertical, iterating over X makes sense	if ( ABS(pDY) > ABS(pDX) ) {		int newY, lastY = (int)itsY;		double dydx = pDY/(double)pDX;		step = (pDX > 0 ? 1 : -1);		for (int dx=0; dx!=pDX+step; dx+=step) {					// x is the column we're working on... find the y-intercept			newY = (int)( itsY + dydx*(dx+(double)step/2) );						// clip, if necessary to stay within target			if (ABS(newY-itsY) > ABS(pDY)) newY = (int)itsY+pDY;						// now draw a vertical line from lastY to newY			VLine( lastY, newY, (int)itsX+dx );						// and remember this position for next time			lastY = newY;				}	}	else {	// if it's mostly horizontal, iterate over Y instead			int newX, lastX=(int)itsX;		double dxdy = pDX/(double)pDY;		step = (pDY > 0 ? 1 : -1);		for (int dy=0; dy!=pDY+step; dy+=step) {			// find the x-intercept for the given Y			newX = (int)( itsX + dxdy*(dy+(double)step/2) );						// clip, if necessary to stay within target			if (ABS(newX-itsX) > ABS(pDX)) newX = (int)itsX+pDX;						// now draw a horizontal line...			HLine( lastX, newX, (int)itsY+dy );						// and update the X			lastX = newX;		}	}	// update the turtle position	Move( pDX, pDY );//	Dot();	// all done!}void Turtle::Move( const int pDist ){	// decompose angle,dist into x,y components	double dy = sin(itsAngle*PI/180.0) * pDist;	double dx = cos(itsAngle*PI/180.0) * pDist;	// do the move (here, to avoid truncation)	itsX += dx;	itsY += dy;}void Turtle::Line( const int pDist ){	// decompose angle,dist into x,y components	double dy = sin(itsAngle*PI/180.0) * pDist;	double dx = cos(itsAngle*PI/180.0) * pDist;	// do the line -- and remember coordinates, to avoid truncation	double newX = itsX+dx;	double newY = itsY+dy;	Line( (int)dx, (int)dy );	itsX = newX;	itsY = newY;}
