From 7ca29186acf606e4dd99af3613a505ea58903827 Mon Sep 17 00:00:00 2001 From: pinventado Date: Wed, 10 Feb 2021 08:53:33 -0800 Subject: [PATCH 1/4] Initial DrawPolygon implementation --- graphics/image.cc | 22 ++++++++++++++++++++++ graphics/image.h | 22 ++++++++++++++++++++++ graphics/test/image_unittest.cc | 9 +++++++++ 3 files changed, 53 insertions(+) diff --git a/graphics/image.cc b/graphics/image.cc index cd37217..14e2af6 100644 --- a/graphics/image.cc +++ b/graphics/image.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include "cimg/CImg.h" @@ -238,6 +239,27 @@ bool Image::DrawRectangle(int x, int y, int width, int height, int red, return true; } +bool DrawPolygon(std::vector& points, int red, int green, int blue) { + const int color[] = {red, green, blue}; + if (!CheckColorInBounds(color)) { + return false; + } + for (int i = 0; i < points.size(); i += 2) { + if (!CheckPixelInBounds(i, i + 1) { + return false; + } + } + CImg c_points(points.size(), 2); + for (int i = 0; i < points.size(); i += 2) { + c_points(i, 0) = points[i]; + c_points(i, 1) = points[i+1]; + } + + cimage_->draw_polygon(c_points, color); + + return true; +} + bool Image::DrawText(int x, int y, const string& text, int font_size, int red, int green, int blue) { const int color[] = {red, green, blue}; diff --git a/graphics/image.h b/graphics/image.h index 6171c5c..b062c84 100644 --- a/graphics/image.h +++ b/graphics/image.h @@ -277,6 +277,28 @@ class Image { bool DrawRectangle(int x, int y, int width, int height, int red, int green, int blue); + /** + * Draws a polygon whose vertices are listed in |points| and colored with + * |color|. Each vertex is represented by it's x and y coordinate, and are + * listed sequentially in the vector. For example, a polygon with three + * vertices (0, 0), (0, 2), (2,1) is represented as a vector of integers + * {0, 0, 0, 2, 2, 1}. The last vertex will connect with the first vertex in + * the list. Returns false if params are out of bounds. + */ + bool DrawPolygon(std::vector& points, const Color& color) { + return DrawPolgyon(points, color.Red(), color.Green(), color.Blue()); + } + + /** + * Draws a polygon whose vertices are listed in |points| and colored with + * |red|, |green|, |blue|. Each vertex is represented by it's x and y + * coordinate, and are listed sequentially in the vector. For example, a + * polygon with three vertices (0, 0), (0, 2), (2,1) is represented as a + * vector of integers {0, 0, 0, 2, 2, 1}. The last vertex will connect with + * the first vertex in* the list. Returns false if params are out of bounds. + */ + bool DrawPolygon(std::vector& points, int red, int green, int blue); + /** * Draws the string |text| with position (x,y) at the top left corner, * with |font_size| in pixels, colored by |color|. Returns false if the diff --git a/graphics/test/image_unittest.cc b/graphics/test/image_unittest.cc index d52285f..42fa8d1 100644 --- a/graphics/test/image_unittest.cc +++ b/graphics/test/image_unittest.cc @@ -109,6 +109,7 @@ TEST(ImageTest, Drawing) { graphics::Image image(50, 50); graphics::Color white(255, 255, 255); graphics::Color blue(0, 0, 255); + graphics::Color red(255, 0, 0); image.DrawCircle(20, 20, 5, blue); // Spot check some pixels. EXPECT_EQ(image.GetColor(20, 20), blue); @@ -123,6 +124,10 @@ TEST(ImageTest, Drawing) { EXPECT_EQ(image.GetBlue(i, j), 0); } } + std::vector points = {20, 20, 20, 22, 22, 21}; + image.DrawPolygon(points, blue); + EXPECT_EQ(image.GetColor(20, 21), red); + EXPECT_EQ(image.GetColor(21, 21), red); // Drawing something out of bounds doesn't work. image.DrawRectangle(-1, -1, 50, 50, 0, 255, 0); @@ -131,6 +136,10 @@ TEST(ImageTest, Drawing) { image.DrawCircle(40, 50, 100, 0, 255, 0); EXPECT_EQ(image.GetColor(0, 0), white); + std::vector out_points = {-1, 0, 0, 0, -2, 0}; + image.DrawPolygon(out_points, red); + EXPECT_EQ(image.GetColor(0, 0, white); + // Hard to test the line because of anti-aliasing. image.DrawLine(0, 0, 40, 40, 255, 0, 0); EXPECT_EQ(image.GetGreen(0, 0), 0); From fa984c6268d29e578606dc650601002fa68217d1 Mon Sep 17 00:00:00 2001 From: pinventado Date: Wed, 10 Feb 2021 09:21:31 -0800 Subject: [PATCH 2/4] Fixed point drawing bugs and created unittest --- graphics/image.cc | 16 ++++++++++------ graphics/image.h | 3 ++- graphics/test/image_unittest.cc | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/graphics/image.cc b/graphics/image.cc index 14e2af6..c4ca6da 100644 --- a/graphics/image.cc +++ b/graphics/image.cc @@ -239,22 +239,26 @@ bool Image::DrawRectangle(int x, int y, int width, int height, int red, return true; } -bool DrawPolygon(std::vector& points, int red, int green, int blue) { +bool Image::DrawPolygon(std::vector& points, int red, int green, int blue) { const int color[] = {red, green, blue}; if (!CheckColorInBounds(color)) { return false; } + if (points.size() % 2 != 0) { + cout << "Invalid vector of vertices. Each vertex should be represented by 2 integers." << endl; + return false; + } for (int i = 0; i < points.size(); i += 2) { - if (!CheckPixelInBounds(i, i + 1) { + if (!CheckPixelInBounds(points[i], points[i + 1])) { return false; } } - CImg c_points(points.size(), 2); + CImg c_points(points.size() / 2, 2); + int c_point_loc = 0; for (int i = 0; i < points.size(); i += 2) { - c_points(i, 0) = points[i]; - c_points(i, 1) = points[i+1]; + c_points(c_point_loc, 0) = points[i]; + c_points(c_point_loc++, 1) = points[i+1]; } - cimage_->draw_polygon(c_points, color); return true; diff --git a/graphics/image.h b/graphics/image.h index b062c84..c8716ba 100644 --- a/graphics/image.h +++ b/graphics/image.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "image_event.h" @@ -286,7 +287,7 @@ class Image { * the list. Returns false if params are out of bounds. */ bool DrawPolygon(std::vector& points, const Color& color) { - return DrawPolgyon(points, color.Red(), color.Green(), color.Blue()); + return DrawPolygon(points, color.Red(), color.Green(), color.Blue()); } /** diff --git a/graphics/test/image_unittest.cc b/graphics/test/image_unittest.cc index 42fa8d1..88fb27b 100644 --- a/graphics/test/image_unittest.cc +++ b/graphics/test/image_unittest.cc @@ -125,7 +125,7 @@ TEST(ImageTest, Drawing) { } } std::vector points = {20, 20, 20, 22, 22, 21}; - image.DrawPolygon(points, blue); + image.DrawPolygon(points, red); EXPECT_EQ(image.GetColor(20, 21), red); EXPECT_EQ(image.GetColor(21, 21), red); @@ -138,7 +138,7 @@ TEST(ImageTest, Drawing) { std::vector out_points = {-1, 0, 0, 0, -2, 0}; image.DrawPolygon(out_points, red); - EXPECT_EQ(image.GetColor(0, 0, white); + EXPECT_EQ(image.GetColor(0, 0), white); // Hard to test the line because of anti-aliasing. image.DrawLine(0, 0, 40, 40, 255, 0, 0); From d382e64096e2784e20901aa3d0e4c0796785e0ef Mon Sep 17 00:00:00 2001 From: pinventado Date: Wed, 10 Feb 2021 16:57:36 -0800 Subject: [PATCH 3/4] Use const references --- graphics/image.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/image.cc b/graphics/image.cc index c4ca6da..ed470e7 100644 --- a/graphics/image.cc +++ b/graphics/image.cc @@ -239,7 +239,7 @@ bool Image::DrawRectangle(int x, int y, int width, int height, int red, return true; } -bool Image::DrawPolygon(std::vector& points, int red, int green, int blue) { +bool Image::DrawPolygon(const std::vector& points, int red, int green, int blue) { const int color[] = {red, green, blue}; if (!CheckColorInBounds(color)) { return false; From 4021860db4ab22c757aa5721b32a3011ee38b580 Mon Sep 17 00:00:00 2001 From: pinventado Date: Wed, 10 Feb 2021 16:57:59 -0800 Subject: [PATCH 4/4] Use const references and fix typos --- graphics/image.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/graphics/image.h b/graphics/image.h index c8716ba..31bcdeb 100644 --- a/graphics/image.h +++ b/graphics/image.h @@ -280,25 +280,25 @@ class Image { /** * Draws a polygon whose vertices are listed in |points| and colored with - * |color|. Each vertex is represented by it's x and y coordinate, and are + * |color|. Each vertex is represented by its x and y coordinate, and are * listed sequentially in the vector. For example, a polygon with three * vertices (0, 0), (0, 2), (2,1) is represented as a vector of integers * {0, 0, 0, 2, 2, 1}. The last vertex will connect with the first vertex in * the list. Returns false if params are out of bounds. */ - bool DrawPolygon(std::vector& points, const Color& color) { + bool DrawPolygon(const std::vector& points, const Color& color) { return DrawPolygon(points, color.Red(), color.Green(), color.Blue()); } /** * Draws a polygon whose vertices are listed in |points| and colored with - * |red|, |green|, |blue|. Each vertex is represented by it's x and y + * |red|, |green|, |blue|. Each vertex is represented by its x and y * coordinate, and are listed sequentially in the vector. For example, a * polygon with three vertices (0, 0), (0, 2), (2,1) is represented as a * vector of integers {0, 0, 0, 2, 2, 1}. The last vertex will connect with * the first vertex in* the list. Returns false if params are out of bounds. */ - bool DrawPolygon(std::vector& points, int red, int green, int blue); + bool DrawPolygon(const std::vector& points, int red, int green, int blue); /** * Draws the string |text| with position (x,y) at the top left corner,