void Image::Shift(double sx, double sy) { for(int y = 0; y < height; y++) { int y_ = (0 < sy) ? height - 1 - y : y; for(int x = 0; x < width; x++) { int x_ = (0 < sx) ? width - 1 - x : x; if(sx == floor(sx) && sy == floor(sy)) GetPixel(x_, y_) = (ValidCoord(x_ - (int) sx, y_ - (int) sy)) ? GetPixel(x_ - (int) sx, y_ - (int) sy) : Pixel(0, 0, 0); else { if(sampling_method == IMAGE_SAMPLING_HAT) { if(ValidCoord(x_ - (int) sx, y_ - (int) sy)) { float h_r, h_g, h_b, h_all, h_tmp; h_r = h_g = h_b = h_all = 0.0f; for(int c = -1; c < 2; c++) { for(int r = -1; r < 2; r++) { if(ValidCoord(x_ - (int) sx + r, y_ - (int) sy + c)) { h_tmp = hat(-((int) sx) + r + (float) sx) * hat(-((int) sy) + c + (float) sy); h_all += h_tmp; h_r += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).r * h_tmp; h_g += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).g * h_tmp; h_b += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).b * h_tmp; } } } GetPixel(x_, y_).SetClamp(h_r / h_all, h_g / h_all, h_b / h_all); } else GetPixel(x_, y_) = Pixel(0, 0, 0); } else if (sampling_method == IMAGE_SAMPLING_MITCHELL) { if (ValidCoord(x_ - (int) sx, y_ - (int) sy)) { float h_r, h_g, h_b, h_all, h_tmp; h_r = h_g = h_b = h_all = 0.0f; for(int c = -4; c < 5; c++) { for(int r = -4; r < 5; r++) { if(ValidCoord(x_ - (int) sx + r, y_ - (int) sy + c)) { h_tmp = mitchell(-((int) sx) + r + (float) sx) * mitchell(-((int) sy) + c + (float) sy); h_all += h_tmp; h_r += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).r * h_tmp; h_g += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).g * h_tmp; h_b += (float) GetPixel(x_ - (int) sx + r, y_ - (int) sy + c).b * h_tmp; } } } GetPixel(x_, y_).SetClamp(h_r / h_all, h_g / h_all, h_b / h_all); } else GetPixel(x_, y_) = Pixel(0, 0, 0); } } } } }
static float catmull_rom_filter(float t) { return mitchell(t, 0.0f, .5f); }
static float mitchell_filter(float t) { return mitchell(t, 1.0f / 3.0f, 1.0f / 3.0f); }
static Resample_Real catmull_rom_filter(Resample_Real t) { return mitchell(t, 0.0f, .5f); }
static Resample_Real mitchell_filter(Resample_Real t) { return mitchell(t, 1.0f / 3.0f, 1.0f / 3.0f); }
Pixel Image::Sample (double u, double v, double sx, double sy) { // To sample the image in scale and shift // This is an auxiliary function that it is not essential you fill in or // you may define it differently. // u and v are the floating point coords of the points to be sampled. // sx and sy correspond to the scale values. // In the assignment, it says implement MinifyX MinifyY MagnifyX MagnifyY // separately. That may be a better way to do it. // This hook is primarily to get you thinking about that you have to have // some equivalent of this function. if (sampling_method == IMAGE_SAMPLING_POINT) { // Your work here return GetPixel((int) round(u / sx), (int) round(v / sy)); } else if (sampling_method == IMAGE_SAMPLING_HAT) { int sumr, sumg, sumb; sumr = sumg = sumb = 0; float xdif = 0; float ydif = 0; if (sx < 1) xdif = 1 / sx; else xdif = 1; if (sy < 1) ydif = 1 / sy; else ydif = 1; float n = 0; for (int x = round(u / sx - xdif); x <= round(u / sx + xdif); x++) { float hu = hat((x - u / sx) / xdif); for (int y = round(v / sy - ydif); y <= round(v / sy + ydif); y++) { float hv = hat((y - v / sy) / ydif); float h = hu * hv; n += h; if (!ValidCoord(x, y)) continue; Pixel curr = GetPixel(x, y); sumr += h * curr.r; sumg += h * curr.g; sumb += h * curr.b; } } sumr /= n; sumg /= n; sumb /= n; if (sumr > 255) sumr = 255; else if (sumr < 0) sumr = 0; if (sumg > 255) sumg = 255; else if (sumg < 0) sumg = 0; if (sumb > 255) sumb = 255; else if (sumb < 0) sumb = 0; return Pixel(sumr, sumg, sumb); } else if (sampling_method == IMAGE_SAMPLING_MITCHELL) { int sumr, sumg, sumb; sumr = sumg = sumb = 0; float xdif = 0; float ydif = 0; if (sx < 1) xdif = 1 / sx; else xdif = 1; if (sy < 1) ydif = 1 / sy; else ydif = 1; float n = 0; for (int x = round(u / sx - xdif); x <= round(u / sx + xdif); x++) { float hu = mitchell((x - u / sx) / xdif); for (int y = round(v / sy - ydif); y <= round(v / sy + ydif); y++) { float hv = mitchell((y - v / sy) / ydif); float h = hu * hv; n += h; if (!ValidCoord(x, y)) continue; Pixel curr = GetPixel(x, y); sumr += h * curr.r; sumg += h * curr.g; sumb += h * curr.b; } } sumr /= n; sumg /= n; sumb /= n; if (sumr > 255) sumr = 255; else if (sumr < 0) sumr = 0; if (sumg > 255) sumg = 255; else if (sumg < 0) sumg = 0; if (sumb > 255) sumb = 255; else if (sumb < 0) sumb = 0; return Pixel(sumr, sumg, sumb); } else { fprintf(stderr,"I don't understand what sampling method is used\n") ; exit(1) ; } return Pixel() ; }