/* ----------------------------------------------------------------------------- // Figure 14.17: Main program for points in a rectangle. // Figure 14.19: Testing points. // Figure 14.20: Reading a rectangle. // Figure 14.21: Comparing structured data (two points). // Figure 14.22: Point location. // Figure 12.8: Swap. // ----------------------------------------------------------------------------- */ #include "tools.h" typedef struct POINT { double x, y; } point_type ; typedef struct RECTANGLE { point_type lo, hi; } rect_type ; typedef enum { P_IN, P_SIDE, P_CORNER, P_OUT } in_type; const string answer[4] = {"inside", "on a side of", "at a corner of", "outside"}; void test_points( void ); rect_type get_rect ( void ); bool equal( point_type p1, point_type p2 ); in_type in_or_out ( point_type P, rect_type R ) ; void swap( double* fp1, double* fp2 ); /* ----------------------------------------------------------------------------- */ void main( void ) { char again; /* For user response in test_points loop. */ banner(); puts( " Given a rectangle with a side parallel to the x axis \n" " and a series of points on the xy plane,\n" " say where each point lies in relation to the rectangle." ); do { test_points(); printf( "\n Do you want to test another rectangle (y/n)? " ); scanf( " %c", &again ); } while (tolower( again ) != 'n'); bye(); } /* ----------------------------------------------------------------------------- // Analyze the position of a point with respect to a rectangle in the xy plane. */ void test_points( void ) { rect_type R; /* The rectangle. */ point_type pt; /* The points we will test. */ in_type where; /* Position of point relative to rectangle. */ R = get_rect(); puts( " Please enter a series of points when prompted." ); do { printf( "\n Enter x and y (%g %g to quit): ", R.lo.x, R.lo.y ); scanf( "%lg%lg", &pt.x, &pt.y ); where = in_or_out( pt, R ); printf( " The point (%g, %g) is %s the rectangle.\n", pt.x, pt.y, answer[where] ); } while (! equal( pt, R.lo )); } /* ----------------------------------------------------------------------------- // Test whether two points are sufficiently close to equal. */ #define epsilon .000001 bool equal( point_type p1, point_type p2 ) { bool answer = true; if (fabs( p1.x - p2.x ) > epsilon || fabs( p1.y - p2.y ) > epsilon) answer = false; return answer; } /* ----------------------------------------------------------------------------- // Read, validate, and return the coordinates of a rectangle. */ rect_type get_rect( void ) { rect_type R; printf( "\n Enter x and y for lower left corner: " ); scanf( "%lg%lg", &R.lo.x, &R.lo.y ); printf( " Enter x and y for upper right corner: " ); scanf( "%lg%lg", &R.hi.x, &R.hi.y ); /* If corners were not entered correctly, swap coordinates. */ if (R.lo.x > R.hi.x) swap( &R.lo.x, &R.hi.x ); if (R.lo.y > R.hi.y) swap( &R.lo.y, &R.hi.y ); printf( "\n Using lower left = (%g, %g), " "upper right = (%g, %g).\n", R.lo.x, R.lo.y, R.hi.x, R.hi.y ); return R; } /* ----------------------------------------------------------------------------- // Given a point and a rectangle, return a code for the position of the point // relative to the rectangle. */ in_type /* Where is P with respect to R? */ in_or_out ( point_type P, rect_type R ) { in_type place; /* Set to out, in, corner, or side. */ if (P.x < R.lo.x || P.x > R.hi.x || P.y < R.lo.y || P.y > R.hi.y) place = P_OUT; /* Point is outside rectangle. */ else if (P.x > R.lo.x && P.x < R.hi.x && P.y > R.lo.y && P.y < R.hi.y) place = P_IN; /* Point is inside rectangle. */ else if ((fabs( P.x - R.lo.x )