/*	Area Under a Curve program.
	Approximates the area under curve by summing the area of a number 
	of trapezoids that represent the area under the curve. The user specifies
	the function, the endlimits, and the number of trapezoids.                           */

#include <iostream.h>
#include <conio.h>
#include <lvp\bool.h>
#include <math.h>
#include "utility.h"

//--------------------------------------------------------------------------------
void GiveDescription()
/*	Provides a description of the program
	Post: A description of the program displayed */
{
	cout << "This program approximates the area under a curve by" << endl; 
	cout << "numerical integration. Numerical integration calculates" << endl;
	cout << "the area under a curve by summing the areas of" << endl;
	cout << "a set of trapezoids that represent the curve." << endl;
	cout << "The user chooses the function, the endlimits, and" << endl;
	cout << "and the number of trapezoids." << endl;
	Pause();
}
//--------------------------------------------------------------------------------
int ChooseFunction()
/*	Allows user to choose a function from a menu.
	Post: The function number chosen by the user returned
	or 0 to quit returned                                                              */
{
	cout << "Function list" << endl;
	cout << "  0. QUIT" << endl;
	cout << "  1. x^2" << endl;
	cout << "  2. x^2 + 1" << endl;
	cout << "  3. sqrt(x)" << endl;
	cout << "  4. sin(x)" << endl;
	cout << "  5. log(x)" << endl;
	cout << "Enter your choice: ";
	int Choice = GetInt(0, 5);
	return (Choice);
}
//--------------------------------------------------------------------------------
double f(int FunctionNum, double x)
/*	Returns the value of the function at x
	Pre: FunctionNum represents a valid function
	f(x) is defined for the function
	Post: The value of the function at x is returned or 
	0 if FunctionNum is not valid.                                       */
{
	switch (FunctionNum) {
		case 1: return(x*x);
		case 2: return(x*x + 1);
		case 3: return(sqrt(x));
		case 4: return(sin(x));
		case 5: return(log(x));
		default: return(0);
	}
}
//--------------------------------------------------------------------------------
double Approximate(int FunctionNum, double LowLimit, 
						  double HighLimit, int NumTraps)
/*	Approximates the area under a curve using trapezoids
	Pre: FunctionNum is a defined function
	LowLimit..HighLimit values are defined for the function
	NumTraps >= 1
	Post: The area under the function between LowLimit and 
	HighLimit returned                                                                  */
{
	double TrapWidth = (HighLimit - LowLimit)/NumTraps;
	double x = LowLimit;
	double Area = 0;
	for (int TrapCount = 1; TrapCount <= NumTraps; TrapCount++) {
		Area += 0.5*(f(FunctionNum, x)+f(FunctionNum, x+TrapWidth))
					*TrapWidth;
		x += TrapWidth;
	}
	return(Area);
}
//--------------------------------------------------------------------------------
void FindArea(int FunctionNum)
/*	Prompts user for endlimits and the number of trapezoids to use, 
	and then calculates and displays the area under the curve
	FunctionNum using these values
	Post: area of selected function returned                                             */
{
	double LowLimit, HighLimit, Area;
	int NumTraps;
	cout << "Enter the low limit: ";
	cin >> LowLimit;
	cout << "Enter the high limit: ";
	cin >> HighLimit;
	cout << "Enter the number of trapezoids: ";
	cin >> NumTraps;
	Area = Approximate(FunctionNum, LowLimit, HighLimit, NumTraps);
	cout << "The area is approximately " << Area << endl;
	Pause();
}
//--------------------------------------------------------------------------------
int main()
{
	GiveDescription();
	while (true) {
		clrscr();
		int FunctionNum = ChooseFunction();
		if (FunctionNum == 0)
			break;
		FindArea(FunctionNum);
	}
	return(0);
}


