/* ACM North Central Region, 1993-94 Problem F, PostScript Emulation Ed Karrels, March 1996 */ #include #include typedef float matrix[3][3]; char *cmds[7] = {"rotate", "translate", "scale", "moveto", "rmoveto", "lineto", "rlineto"}; int ReadMove(float *x, float *y) { char cmd[20]; int i; scanf("%f %f", x, y); scanf("%s", cmd); for (i=0; i<7; i++) { if (!strcmp(cmd, cmds[i])) return i+1; } return 0; } void Xlate(float *x, float *y, matrix m) { float nx, ny; nx = m[0][0] * *x + m[0][1] * *y + m[0][2]; ny = m[1][0] * *x + m[1][1] * *y + m[1][2]; *x = nx; *y = ny; } void PrintMatrix(matrix a) { int i, j; for (i=0; i<3; i++) { for (j=0; j<3; j++) { printf("%7.2f", a[i][j]); } putchar('\n'); } putchar('\n'); } /* b <- a * b */ void MatrixMult(matrix a, matrix b) { matrix c; int i, j, k; for (i=0; i<3; i++) for (j=0; j<3; j++) { c[i][j] = 0; for (k=0; k<3; k++) c[i][j] += a[i][k] * b[k][j]; } for (i=0; i<3; i++) for (j=0; j<3; j++) a[i][j] = c[i][j]; } void IdentMatrix(matrix a) { int i, j; for (i=0; i<3; i++) for (j=0; j<3; j++) a[i][j] = 0; for (i=0; i<3; i++) a[i][i] = 1; } int main() { int movetype; float x, y, cur_x=0, cur_y=0, tx, ty; matrix xform_matrix, mx; IdentMatrix(xform_matrix); while (movetype = ReadMove(&x, &y)) { if (movetype < 4) { IdentMatrix(mx); switch (movetype) { case 1: x *= 3.141592653 / 180.0; tx = cur_x * cos(-x) - cur_y * sin(-x); cur_y = cur_x * sin(-x) + cur_y * cos(-x); cur_x = tx; mx[0][0] = cos(x); mx[0][1] = -sin(x); mx[1][0] = sin(x); mx[1][1] = cos(x); break; case 2: cur_x -= x; cur_y -= y; mx[0][2] = x; mx[1][2] = y; break; case 3: cur_x /= x; cur_y /= y; mx[0][0] = x; mx[1][1] = y; break; } MatrixMult(xform_matrix, mx); } else { switch (movetype) { case 4: cur_x = x; cur_y = y; Xlate(&x, &y, xform_matrix); printf("%g %g moveto\n", x, y); break; case 5: tx = cur_x; ty = cur_y; cur_x += x; x = cur_x; cur_y += y; y = cur_y; Xlate(&x, &y, xform_matrix); Xlate(&tx, &ty, xform_matrix); printf("%g %g rmoveto\n", x-tx, y-ty); break; case 6: cur_x = x; cur_y = y; Xlate(&x, &y, xform_matrix); printf("%g %g lineto\n", x, y); break; case 7: tx = cur_x; ty = cur_y; cur_x += x; x = cur_x; cur_y += y; y = cur_y; Xlate(&x, &y, xform_matrix); Xlate(&tx, &ty, xform_matrix); printf("%g %g rlineto\n", x-tx, y-ty); break; } } } return 0; }