/* --------------------------------------------------------------------- ** Figure 17.13: 2D point transformation - main program. ** Figure 17.14: Reading and displaying the data. ** Figure 17.15: The transformation. ** --------------------------------------------------------------------- */ #include "tools.h" #define MAXPOINTS 10 /* maximum number of points */ #define DIM 2 /* points are 2D */ typedef double point [DIM]; /* type point is 2D array */ typedef point object [MAXPOINTS]; /* an object is many points */ typedef double vector [DIM]; /* vector is for translation */ typedef double matrix [DIM][DIM]; /* matrix is for rotation */ int read_points( object obj ); void display_points( object obj1, object obj2, int numpts ); void get_transform( matrix R, vector t ); void transform_point( point p, matrix R, vector t, point newp ); void main( void ) { object old_obj, new_obj; /* points sets before and after */ vector translation; /* transformation movement */ matrix rotation; /* transformation rotation matrix */ int num_points; /* actual number of points */ int k; /* loop counter */ banner(); puts( "Welcome to the 2D point transformation program" ); num_points = read_points( old_obj ); /* input points and transform */ get_transform( rotation, translation ); /* rotate and translate pts */ for (k = 0; k < num_points; k++) transform_point( old_obj[k], rotation, translation, new_obj[k] ); display_points( old_obj, new_obj, num_points ); /* print result table */ bye(); } /* --------------------------------------------------------------------- ** Read (x,y) coordinates of point set from indicated data file. Read as ** many points as are in file or until data array is full. */ int read_points ( object obj ) { char filename[80]; /* name of data file */ stream f_in; /* input stream to read data */ int count; /* number of data values read */ int k; /* loop counter */ printf( "\nPlease enter name of file containing object points: " ); scanf( "%79s", filename); f_in = fopen( filename, "r" ); /* open file in read mode */ if (f_in == NULL) fatal( "Cannot open file %s for input.", filename ); /* read data points until array is full, end of file or error occurs */ for ( k = 0; k < MAXPOINTS; k++ ) { count = fscanf( f_in, "%lg %lg", &obj[k][0], &obj[k][1] ); if (count != 2) /* if bad read */ if (feof( f_in )) break; /* End of file -- leave loop. */ else fatal( "Error reading file %s", filename ); } fclose(f_in); return k; } /* --------------------------------------------------------------------- ** Print out old point and new point coordinates in a table. */ void display_points ( object obj1, object obj2, int numpts ) { int k; /* loop counter */ puts ( "\n\t Transformation of coordinates \n"); puts ( "Pt\t Old X\t Old Y\t\t New X\t New Y" ); for ( k = 0; k < numpts; k++ ) /* put both points on one line */ printf( "%2i \t%7.2f %7.2f \t%7.2f %7.2f\n", k+1, obj1[k][0], obj1[k][1], obj2[k][0], obj2[k][1] ); } /* --------------------------------------------------------------------- ** Input rotation angle and translation vector for transform from user. ** Compute components of rotation matrix assuming ccw rotation angle. */ void get_transform ( matrix R, vector t ) { double theta; /* rotation angle */ for (;;) { /* read rotation angle */ printf( "Please enter number of degrees to rotate object counterclockwise: " ); scanf( "%lg", &theta ); if (theta >= 0 && theta <= 360) break; puts( "Error: Angle must be in the range 0 - 360 degrees" ); } theta = PI * theta / 180.0; /* convert angle to radians for math */ R[0][0] = cos( theta ); /* compute rotation matrix elements */ R[0][1] = -sin( theta ); R[1][0] = sin( theta ); R[1][1] = cos( theta ); printf ( "Please enter the translation amount ( X, Y ): " ); scanf( "%lg %lg", &t[0], &t[1] ); } /* --------------------------------------------------------------------- ** Apply rotation and translation transforms to p and return new point. */ void transform_point ( point p, matrix R, vector t, point newp ) { int r, c; /* loop counters */ for (r = 0; r < DIM; ++r) { /* multiply each row by point for new */ for (newp[r] = 0, c = 0; c < DIM; ++c) /* do dot product */ newp[r] += R[r][c] * p[c]; } for (r = 0; r < DIM; ++r) /* add translation vector to point */ newp[r] += t[r]; }