Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions graphics/image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include "cimg/CImg.h"

Expand Down Expand Up @@ -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<int>& 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<int> 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};
Expand Down
23 changes: 23 additions & 0 deletions graphics/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "image_event.h"

Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little hard to read this polygon vector, especially for large numbers of vertices. What do you think of making a simple graphics::Point class and having a std::vectorgraphics::Point instead?

You could also add a DrawTriangle that takes int x1, int y1, int x2, int y2, int x3, int y3 as that's probably the most common polygon that would be used.

* the list. Returns false if params are out of bounds.
*/
bool DrawPolygon(const std::vector<int>& 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<int>& 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
Expand Down
9 changes: 9 additions & 0 deletions graphics/test/image_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -123,6 +124,10 @@ TEST(ImageTest, Drawing) {
EXPECT_EQ(image.GetBlue(i, j), 0);
}
}
std::vector<int> points = {20, 20, 20, 22, 22, 21};
image.DrawPolygon(points, red);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add some polygon-speicifc tests: first, that drawing a polygon clockwise is the same as drawing the same thing counterclockwise? second, if drawing a rect is the same as drawing a polygon with four points?

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);
Expand All @@ -131,6 +136,10 @@ TEST(ImageTest, Drawing) {
image.DrawCircle(40, 50, 100, 0, 255, 0);
EXPECT_EQ(image.GetColor(0, 0), white);

std::vector<int> 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);
Expand Down