bvol_t *transform_bin_volume_2D(bvol_t *b, trans2D_t *T) { /* Test each point in the plane for inclusion in the new * (transformed) binary image */ bvol_t *Tb = new_bin_volume(b->w, b->h, b->d, BVOL_BITS); /* Compute the inverse of T */ trans2D_t *Tinv = transform_invert(T); int x, y, z; int xc, yc, zc; for (z = 0; z < (int) b->d; z++) { for (y = 0; y < (int) b->h; y++) { for (x = 0; x < (int) b->w; x++) { double out[3]; transform_point(Tinv, (double) x, (double) y, out + 0, out + 1); out[2] = z; /* Check if the point lies in the set */ xc = iround(out[0]); yc = iround(out[1]); zc = iround(out[2]); if (bvol_getbit(b, xc, yc, zc)) bvol_setbit(Tb, x, y, z); } } } transform_free(Tinv); return Tb; }
/* Create a new image by applying transformation T to img and * resampling */ img_t *img_resample(img_t *img, trans2D_t *T) { int w = img->w, h = img->h; int x, y; trans2D_t *Tinv = transform_invert(T); img_t *Timg = img_new(w, h); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { double Tp[2]; fcolor_t c; /* Invert the point (x, y) */ transform_point(Tinv, x, y, &Tp[0], &Tp[1]); #if 1 /* Check if the result is in range */ if (Tp[0] < 0.0 || Tp[1] < 0.0 || Tp[0] > w - 1 || Tp[1] > h - 1) { img_set_pixel(Timg, x, y, background_color.r, background_color.g, background_color.b); /* img_nullify_pixel(Timg, x, y); */ } else { /* Apply bilinear interpolation */ c = pixel_lerp(img, Tp[0], Tp[1]); img_set_pixel(Timg, x, y, iround(c.r), iround(c.g), iround(c.b)); } #else if (Tp[0] < 0.0) Tp[0] = 0.0; else if (Tp[0] > w - 1) Tp[0] = w - 1; if (Tp[1] < 0.0) Tp[1] = 0.0; else if (Tp[1] > h - 1) Tp[1] = h - 1; c = pixel_lerp(img, Tp[0], Tp[1]); img_set_pixel(Timg, x, y, (int) rint(c.r), (int) rint(c.g), (int) rint(c.b)); #endif } } return Timg; }
/* Create a new image by applying transformation T to img and * resampling. Resize the image so that the whole thing fits when * transformed. */ img_t *img_resample_bbox(img_t *img, trans2D_t *T) { int w = img->w, h = img->h; int x, y; trans2D_t *Tinv = transform_invert(T); int w_new, h_new, i; // double x_min = DBL_MAX, x_max = -DBL_MAX, y_min = DBL_MAX, y_max = -DBL_MAX; v2_t min = v2_new(DBL_MAX, DBL_MAX); v2_t max = v2_new(-DBL_MAX, -DBL_MAX); v2_t origin; img_t *Timg; /* Find the new dimensions of the window */ v2_t crs[4]; /* Four corners of the original image */ crs[0] = v2_new(0, 0); crs[1] = v2_new(0, h - 1); crs[2] = v2_new(w - 1, 0); crs[3] = v2_new(w - 1, h - 1); for (i = 0; i < 4; i++) { crs[i] = v2_add(crs[i], img->origin); crs[i] = transform_vector(T, crs[i]); min = v2_minimum(min, crs[i]); max = v2_maximum(max, crs[i]); } Vx(min) = floor(Vx(min)); Vy(min) = floor(Vy(min)); w_new = iround(floor(Vx(max) - Vx(min) + 1)); h_new = iround(floor(Vy(max) - Vy(min) + 1)); origin = min; Timg = img_new(w_new, h_new); Timg->origin = origin; for (y = 0; y < h_new; y++) { for (x = 0; x < w_new; x++) { double Tp[2]; fcolor_t c; /* Invert the point (x, y) - trans */ transform_point(Tinv, x + Vx(origin), y + Vy(origin), &Tp[0], &Tp[1]); #if 1 /* Check if the result is in range */ if (Tp[0] < Vx(img->origin) || Tp[1] < Vy(img->origin) || Tp[0] > Vx(img->origin) + w - 1 || Tp[1] > Vy(img->origin) + h - 1) { /* pass */ } else { /* Check if the result is valid */ int x_f = (int) (Tp[0] - Vx(img->origin)); int x_c = x_f + 1; int y_f = (int) (Tp[1] - Vy(img->origin)); int y_c = y_f + 1; if (img_pixel_is_valid(img, x_f, y_f) || img_pixel_is_valid(img, x_c, y_f) || img_pixel_is_valid(img, x_f, y_c) || img_pixel_is_valid(img, x_c, y_c)) { /* Apply bilinear interpolation */ c = pixel_lerp(img, Tp[0] - Vx(img->origin), Tp[1] - Vy(img->origin)); img_set_pixel(Timg, x, y, iround(c.r), iround(c.g), iround(c.b)); } else { // img_nullify_pixel(Timg, x, y); } } #else if (Tp[0] < 0.0) Tp[0] = 0.0; else if (Tp[0] > w - 1) Tp[0] = w - 1; if (Tp[1] < 0.0) Tp[1] = 0.0; else if (Tp[1] > h - 1) Tp[1] = h - 1; c = pixel_lerp(img, Tp[0], Tp[1]); img_set_pixel(Timg, x, y, c.r, c.g, c.b); #endif } } /* Add the old origin to the image */ // Timg->origin = v2_add(origin, img->origin); transform_free(Tinv); return Timg; }
void source_set_transform(source_t *source, transform_t transform) { source->transform = transform; transform_invert(&source->transform); }
/** * Initialize an object. * Fills transformation and its inverse. * \param t Transformation from object space * to the camera space. */ void object_init(struct object *o, const struct transform *t){ o->transform = *t; transform_invert(t, &(o->invTransform)); }