struct Point double x, y struct Shape int n_points Point *points struct Transform double xx, xy, yx, yy, dx, dy Transform id_trans = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } int temporary_shape_points = 0 Shape temporary_shape = { 0, NULL } Shape *get_temporary_shape(int n_points) if n_points > temporary_shape_points temporary_shape_points *= 2 if temporary_shape_points < n_points temporary_shape_points = n_points Realloc(temporary_shape.points, sizeof(Point) * temporary_shape_points) temporary_shape.n_points = n_points return &temporary_shape int temporary_xpoints_points = 0 XPoint *temporary_xpoints = NULL XPoint *get_temporary_xpoints(int n_points) if n_points > temporary_xpoints_points temporary_xpoints_points *= 2 if temporary_xpoints_points < n_points temporary_xpoints_points = n_points Realloc(temporary_xpoints, sizeof(XPoint) * temporary_xpoints_points) return temporary_xpoints transform_point(Point *p0, Point *p1, Transform *trans) double p0x = p0->x, p0y = p0->y p1->x = p0x * trans->xx + p0y * trans->yx + trans->dx p1->y = p0x * trans->xy + p0y * trans->yy + trans->dy Shape *transform_shape(Shape *src, Shape *dest, Transform *trans) int n = src->n_points Point *p0 = src->points, *p1 if dest == NULL dest = get_temporary_shape(n) p1 = dest->points for ; n>0; --n, ++p0, ++p1 transform_point(p0, p1, trans) return dest round_point(Point *p0, XPoint *p1) p1->x = (int)(p0->x+0.5) p1->y = (int)(p0->y+0.5) XPoint *round_shape(Shape *src, XPoint *dest) int n = src->n_points Point *p0 = src->points XPoint *p1 if dest == NULL dest = get_temporary_xpoints(n+1) p1 = dest for ; n>0; --n, ++p0, ++p1 round_point(p0, p1) *p1 = *dest return dest scale_transform(Transform *src, Transform *dest, double mag) dest->xx = src->xx * mag dest->xy = src->xy * mag dest->yx = src->yx * mag dest->yy = src->yy * mag dest->dx = src->dx * mag dest->dy = src->dy * mag translate_transform(Transform *src, Transform *dest, double dx, double dy) dest->xx = src->xx dest->xy = src->xy dest->yx = src->yx dest->yy = src->yy dest->dx = src->dx + dx dest->dy = src->dy + dy make_rotate_transform(Transform *dest, double angle) double s = sin(angle), c = cos(angle) dest->xx = c dest->xy = s dest->yx = -s dest->yy = c dest->dx = 0 dest->dy = 0 make_transform(Transform *dest, double angle, double scale, double x, double y, boolean flip) make_rotate_transform(dest, angle) scale_transform(dest, dest, scale) translate_transform(dest, dest, x, y) if flip flip_transform(dest) make_inverse_transform(Transform *dest, double angle, double scale, double x, double y, boolean flip) Transform tmp tmp = id_trans if flip flip_transform(&tmp) translate_transform(&tmp, dest, -x, -y) scale_transform(dest, dest, 1.0/scale) make_rotate_transform(&tmp, -angle) compose_transform(&tmp, dest, dest) flip_transform(Transform *toflip) toflip->xy = -toflip->xy toflip->yy = -toflip->yy toflip->dy = -toflip->dy compose_transform(Transform *src0, Transform *src1, Transform *dest) double xx0 = src0->xx, xx1 = src1->xx, xy0 = src0->xy, xy1 = src1->xy, yx0 = src0->yx, yx1 = src1->yx, yy0 = src0->yy, yy1 = src1->yy, dx0 = src0->dx, dx1 = src1->dx, dy0 = src0->dy, dy1 = src1->dy dest->xx = xx0 * xx1 + yx0 * xy1 dest->xy = xy0 * xx1 + yy0 * xy1 dest->yx = xx0 * yx1 + yx0 * yy1 dest->yy = xy0 * yx1 + yy0 * yy1 dest->dx = xx0 * dx1 + yx0 * dy1 + dx0 dest->dy = xy0 * dx1 + yy0 * dy1 + dy0 print_transform(Transform *t) Sayf("%7.2f %7.2f", t->xx, t->xy) Sayf("%7.2f %7.2f", t->yx, t->yy) Sayf("%7.2f %7.2f", t->dx, t->dy) export gr use m io error alloc