diff --git a/graphics/image.cc b/graphics/image.cc index cd37217..ed470e7 100644 --- a/graphics/image.cc +++ b/graphics/image.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include "cimg/CImg.h" @@ -238,6 +239,31 @@ bool Image::DrawRectangle(int x, int y, int width, int height, int red, return true; } +bool Image::DrawPolygon(const 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(points[i], points[i + 1])) { + return false; + } + } + CImg c_points(points.size() / 2, 2); + int c_point_loc = 0; + for (int i = 0; i < points.size(); i += 2) { + 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; +} + 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..31bcdeb 100644 --- a/graphics/image.h +++ b/graphics/image.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "image_event.h" @@ -277,6 +278,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 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(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 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(const 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..88fb27b 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, red); + 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);