- // Project 1
- // CMSC 15200
- // Winter 2011
- // Miranda Seitz-McLeese
- // mseitzmcleese@uchicago.edu
- #include <math.h>
- #include <stdio.h>
- // Recursion boundaries
- #define max_levels 30
- #define min_levels 3
- // Global variable for accounting of evaluations
- int evaluations = 0;
- // Point struct definition
- struct point
- {
- double x;
- double y;
- };
- // Pointer to a function that takes a double and returns a point
- typedef struct point (*pcurve)(double);
- // Distance between two points.
- double distance (struct point p_one, struct point p_two);
- // Line
- struct point line(double t);
- // Parabola
- struct point parabola(double t);
- // Sqrt Sine
- struct point sine(double t);
- // Recursive function to find curve length
- double curve_length(double left, double right, pcurve curve, double tolerance);
- // Print a few test results of curve_length
- int main()
- {
- // Declarations
- double line_length, parabola_length, sine_length; // variables to hold the results of curve_length
- // Line results
- line_length = curve_length(0, 2, line, .01);
- printf("Line (tol = .01) : %f, %d evaluations \n", line_length, evaluations);
- evaluations = 0;
- line_length = curve_length(0, 2, line, .0001);
- printf(" (tol = .0001) : %f, %d evaluations \n", line_length, evaluations);
- evaluations = 0;
- // Parabola results
- parabola_length = curve_length(0, 1, parabola, .01);
- printf("Parabola (tol = .01) : %f, %d evaluations \n", parabola_length, evaluations);
- evaluations = 0;
- line_length = curve_length(0, 1, parabola, .0001);
- printf(" (tol = .0001) : %f, %d evaluations \n", parabola_length, evaluations);
- evaluations = 0;
- // Sine Results
- sine_length = curve_length(0, 1, sine, .01);
- printf("Sine (tol = .01) : %f, %d evaluations \n", sine_length, evaluations);
- evaluations = 0;
- sine_length = curve_length(0, 1, sine, .0001);
- printf(" (tol = .0001) : %f, %d evaluations \n", sine_length, evaluations);
- return 0;
- }
- double distance(struct point p_one, struct point p_two)
- {
- double dist = sqrt((p_one.x - p_two.x)*(p_one.x - p_two.x) + (p_one.y - p_two.y)*(p_one.y - p_two.y));
- return dist;
- }
- struct point line(double t)
- {
- struct point p;
- p.x = t;
- p.y = 2*t;
- return p;
- }
- struct point parabola(double t)
- {
- struct point p;
- p.x = t;
- p.y = t*t;
- return p;
- }
- struct point sine(double t)
- {
- struct point p;
- p.x = t;
- p.y = sqrt(sin(t));
- return p;
- }
- double curve_length(double left, double right, pcurve curve, double tolerance)
- {
- // Declarations
- static int levels = 0; // Keep track of levels of recursion
- double corse, fine; // Estimation variables
- double middle; // Mid point of interval
- double first_half, second_half; // To hold the results of the recursive call
- // Increment bookkeeping variables.
- levels++;
- evaluations++;
- // Calculate midpoint
- middle = left + fabs(right - left)/2;
- // Calculate corse and fine estimates
- corse = distance((curve(left)), (curve(right)));
- fine = distance(curve(left), curve(middle)) + distance(curve(middle), curve(right));
- // If precise enough, return the fine value, if not, recurse again.
- if (levels >= max_levels)
- {
- levels--;
- return fine;
- }
- if (levels < min_levels || fabs(fine-corse) > tolerance){
- first_half = curve_length(left, middle, curve, (tolerance/2));
- second_half = curve_length(middle, right, curve, (tolerance/2));
- levels--;
- return (first_half + second_half);
- }
- else {
- levels--;
- return fine;
- }
- }