FIll new interpolated pixels.
- Take input image in argument. - Allow set_pixel() out of bounds, noop.
This commit is contained in:
parent
00543d258d
commit
6a94c79ac2
2
TODO.md
2
TODO.md
|
@ -3,4 +3,6 @@
|
||||||
[X] Use atan2 at beginning and end of line.
|
[X] Use atan2 at beginning and end of line.
|
||||||
Interpolation in-between values
|
Interpolation in-between values
|
||||||
[X] Test pixel perfect 90
|
[X] Test pixel perfect 90
|
||||||
|
[ ] Fix out-of-bounds pixel set
|
||||||
|
|
||||||
[ ] Optimization for square images?
|
[ ] Optimization for square images?
|
||||||
|
|
38
rotation.cpp
38
rotation.cpp
|
@ -104,9 +104,10 @@ struct Image {
|
||||||
{
|
{
|
||||||
if (x >= width || y >= height)
|
if (x >= width || y >= height)
|
||||||
{
|
{
|
||||||
cerr << "Point (" << x << ", " << y << ") out of bounds" << endl;
|
cerr << __LINE__ << " | Point (" << x << ", " << y << ") out of bounds" << endl;
|
||||||
cerr << " Image dimensions: " << width << " x " << height << endl;
|
cerr << " Image dimensions: " << width << " x " << height << endl;
|
||||||
assert(false);
|
// assert(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
int const index = y * width + x;
|
int const index = y * width + x;
|
||||||
r_chan[index] = r;
|
r_chan[index] = r;
|
||||||
|
@ -501,13 +502,11 @@ Image rotate(Image const& src, double angle)
|
||||||
int origin_nb_steps = max(abs(bl.x - tl.x), abs(bl.y - tl.y));
|
int origin_nb_steps = max(abs(bl.x - tl.x), abs(bl.y - tl.y));
|
||||||
double origin_y_inc = (src_bl.y - src_tl.y) / origin_nb_steps;
|
double origin_y_inc = (src_bl.y - src_tl.y) / origin_nb_steps;
|
||||||
double origin_x_inc = (src_bl.x - src_tl.x) / origin_nb_steps;
|
double origin_x_inc = (src_bl.x - src_tl.x) / origin_nb_steps;
|
||||||
//cout << " origin steps: " << origin_nb_steps << " (" << origin_x_inc << ", " << origin_y_inc << ")" << endl;
|
|
||||||
|
|
||||||
// steps for line in source image
|
// steps for line in source image
|
||||||
int line_nb_steps = max(abs(tr.x - tl.x), abs(tr.y - tl.y));
|
int line_nb_steps = max(abs(tr.x - tl.x), abs(tr.y - tl.y));
|
||||||
double line_y_inc = (src_tr.y - src_tl.y) / line_nb_steps;
|
double line_y_inc = (src_tr.y - src_tl.y) / line_nb_steps;
|
||||||
double line_x_inc = (src_tr.x - src_tl.x) / line_nb_steps;
|
double line_x_inc = (src_tr.x - src_tl.x) / line_nb_steps;
|
||||||
//cout << " line steps: " << line_nb_steps << " (" << line_x_inc << ", " << line_y_inc << ")" << endl;
|
|
||||||
|
|
||||||
// steps for first column in rotated image
|
// steps for first column in rotated image
|
||||||
double rotated_y_inc = (bl.y - tl.y) / (float) origin_nb_steps;
|
double rotated_y_inc = (bl.y - tl.y) / (float) origin_nb_steps;
|
||||||
|
@ -515,7 +514,6 @@ Image rotate(Image const& src, double angle)
|
||||||
|
|
||||||
// steps for line in rotated image
|
// steps for line in rotated image
|
||||||
DPoint bresenham((tr.x - tl.x) / (float) line_nb_steps, (tr.y - tl.y) / (float) line_nb_steps);
|
DPoint bresenham((tr.x - tl.x) / (float) line_nb_steps, (tr.y - tl.y) / (float) line_nb_steps);
|
||||||
cout << "bresenham: " << bresenham << endl;
|
|
||||||
|
|
||||||
for (int y_i = 0; y_i <= (int) origin_nb_steps; ++y_i)
|
for (int y_i = 0; y_i <= (int) origin_nb_steps; ++y_i)
|
||||||
{
|
{
|
||||||
|
@ -523,6 +521,8 @@ Image rotate(Image const& src, double angle)
|
||||||
DPoint const src_origin(src_tl.x + y_i * origin_x_inc, src_tl.y + y_i * origin_y_inc);
|
DPoint const src_origin(src_tl.x + y_i * origin_x_inc, src_tl.y + y_i * origin_y_inc);
|
||||||
APoint const rot_origin(tl.x + y_i * rotated_x_inc, tl.y + y_i * rotated_y_inc);
|
APoint const rot_origin(tl.x + y_i * rotated_x_inc, tl.y + y_i * rotated_y_inc);
|
||||||
|
|
||||||
|
APoint previous = rot_origin;
|
||||||
|
|
||||||
for (int x_i = 0; x_i <= (int) line_nb_steps; ++x_i)
|
for (int x_i = 0; x_i <= (int) line_nb_steps; ++x_i)
|
||||||
{
|
{
|
||||||
DPoint const src_rotated_point(src_origin.x + x_i * line_x_inc, src_origin.y + x_i * line_y_inc);
|
DPoint const src_rotated_point(src_origin.x + x_i * line_x_inc, src_origin.y + x_i * line_y_inc);
|
||||||
|
@ -546,6 +546,13 @@ Image rotate(Image const& src, double angle)
|
||||||
// TODO: bypass variables, access src pixels
|
// TODO: bypass variables, access src pixels
|
||||||
src.get_pixel(src_p, r, g, b);
|
src.get_pixel(src_p, r, g, b);
|
||||||
rotated.set_pixel(rot_point, r, g, b);
|
rotated.set_pixel(rot_point, r, g, b);
|
||||||
|
|
||||||
|
// Fill missing points, created by interpolation
|
||||||
|
if (previous.x != rot_point.x && previous.y != rot_point.y)
|
||||||
|
{
|
||||||
|
rotated.set_pixel(APoint(rot_point.x, previous.y), r, g, b);
|
||||||
|
}
|
||||||
|
previous = rot_point;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,9 +684,9 @@ void check_lines()
|
||||||
draw_outline(rect1, 90, "rect1");
|
draw_outline(rect1, 90, "rect1");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_90()
|
bool check_90(string const& path)
|
||||||
{
|
{
|
||||||
Image const src("img/lena.ppm");
|
Image const src(path);
|
||||||
Image const rotated = rotate(src, 90);
|
Image const rotated = rotate(src, 90);
|
||||||
|
|
||||||
for (unsigned int y = 0; y < rotated.height; ++y)
|
for (unsigned int y = 0; y < rotated.height; ++y)
|
||||||
|
@ -708,8 +715,14 @@ bool check_90()
|
||||||
// Main
|
// Main
|
||||||
//
|
//
|
||||||
|
|
||||||
int main()
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
cout << "Usage: " << argv[0] << " image.ppm" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool perform_check = true;
|
bool perform_check = true;
|
||||||
|
|
||||||
if (perform_check)
|
if (perform_check)
|
||||||
|
@ -722,19 +735,16 @@ int main()
|
||||||
|
|
||||||
//check_lines();
|
//check_lines();
|
||||||
|
|
||||||
if (!check_90())
|
if (false && !check_90(argv[1]))
|
||||||
{
|
{
|
||||||
cerr << __LINE__ << " | 90 degrees check failed" << endl;
|
cerr << __LINE__ << " | 90 degrees check failed" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Image img("img/luigi.ppm");
|
Image img(argv[1]);
|
||||||
//Image img("img/wallpaper.ppm");
|
|
||||||
Image img("img/mini_lena.ppm");
|
|
||||||
|
|
||||||
//for (double rotation : {0, 1, 5, 15, 30, 45, 60, 75, 90, 110, 140, 160, 180, 200, 210, 235, 260, 270, 300, 315, 355, 359})
|
for (double rotation = 0; rotation <= 360; rotation += 5)
|
||||||
for (double rotation : {0, 45, 90})
|
|
||||||
{
|
{
|
||||||
auto const before = chrono::high_resolution_clock::now();
|
auto const before = chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue