/*	File: Triangle.cpp
 *
 *	Design and Implementation Description:
 *		For i = 0 .. 2: delta [i] == point [(i + 1) % 3] - point [i].
 *	History:
 *		Date:		 Author:	 Change:
 *		97-05-14	 KHU		 Creation.
 */

#include "Triangle.h"

#include <assert.h>
#include <graphics.h>
#include <iostream.h>
#include <math.h>							// For fabs (), sqrt ().

#include "Arith.h"						// For Sqr ().

	void Triangle::Draw ()
	{
		moveto (refPoint.x, refPoint.y);
		for (int i = 0; i < triangleNbrOfPoints; i++)
		{
			linerel (delta [i].x, delta [i].y);
		};
	}; // Draw

	Float Triangle::Extent () const
	{
		Float result = 0.0;
		for (int i = 0; i < triangleNbrOfPoints; i++)
		{
			result += sqrt (Sqr (delta [i].x) + Sqr (delta [i].y));
		};
		assert(result >= 0.0);
		return result;
	}; // Extent

	Float Triangle::Area () const
	{
		Float result =
			0.5 * fabs
				(             - refPoint.x  * delta [1].y +
				 (delta [0].x + refPoint.x) * delta [2].y +
				 (delta [2].x - refPoint.x) * delta [0].y);
		assert(result >= 0.0);
		return result;
	}; // Area

	CoordinatePair Triangle::Point (int nbr) const
	{
		assert(nbr >= 0);
		assert(nbr < triangleNbrOfPoints);
		CoordinatePair point = refPoint;
		for (int i = 0; i < nbr; i++)
		{
			point.x += delta [i].x;
			point.y += delta [i].y;
		};
		return point;
	}; // Point

	void Triangle::Stretch (const CoordinatePair & factor)
	{
		FigureState s = state;
		if (s == shown)
		{
			Hide ();
		};
		refPoint.x *= factor.x;
		refPoint.y *= factor.y;
		for (int i = 0; i < triangleNbrOfPoints; i++)
		{
			delta [i].x *= factor.x;
			delta [i].y *= factor.y;
		};
		if (s == shown)
		{
			Show ();
		};
		CheckInvariant ();
		assert(s == state);
	}; // Stretch

	Triangle::Triangle
		(const CoordinatePair & point0,
		 const CoordinatePair & point1,
		 const CoordinatePair & point2)
	{
		refPoint    = point0;
		delta [0].x = point1.x - point0.x;
		delta [0].y = point1.y - point0.y;
		delta [1].x = point2.x - point1.x;
		delta [1].y = point2.y - point1.y;
		delta [2].x = point0.x - point2.x;
		delta [2].y = point0.y - point2.y;
		CheckInvariant ();
	}; // Triangle

	void Triangle::CheckInvariant ()
	{
		ClosedStretchableFigure::CheckInvariant ();
		for (int i = 0; i < triangleNbrOfPoints; i++)
		{
			assert(coordinateMin <= delta [i].x);
			assert(delta [i].x <= coordinateMax);
			assert(coordinateMin <= delta [i].y);
			assert(delta [i].y <= coordinateMax);
		}
	}; // CheckInvariant

// End of Triangle.

