Well you have some work to do... You need to specify a function for each geometry form which would fill your image.
Here an example which is more C++ like where a class Image
handle the methods to compute the geometric forms such as makeFillCircle()
. Image
class also handles the PBM output. Remark how easy it is now to save it using std::ostream operator<<
!
#include <vector>
#include <iostream>
#include <algorithm>
struct Point {
Point(int xx, int yy) : x(xx), y(yy) {}
int x;
int y;
};
struct Image {
int width;
int height;
std::vector<int> data; // your 2D array of pixels in a linear/flatten storage
Image(size_t w, size_t h) : width(w), height(h), data(w * h, 0) {} // we fill data with 0s
void makeFillCircle(const Point& p, int radius) {
// we do not have to test every points (using bounding box)
for (int i = std::max(0, p.x - radius); i < std::min(width-1, p.x + radius) ; i ++) {
for (int j = std::max(0,p.y - radius); j < std::min(height-1, p.y + radius); j ++) {
// test if pixel (i,j) is inside the circle
if ( (p.x - i) * (p.x - i) + (p.y - j) * (p.y - j) < radius * radius ) {
data[i * width + j] = 1; //If yes set pixel on 1 !
}
}
}
}
};
std::ostream& operator<<(std::ostream& os, const Image& img) {
os << "P1\n" << img.width << " " << img.height << "\n";
for (auto el : img.data) { os << el << " "; }
return os;
}
int main() {
Image img(100,100);
img.makeFillCircle(Point(60,40), 30); // first big circle
img.makeFillCircle(Point(20,80), 10); // second big circle
std::cout << img << std::endl; // the output is the PBM file
}
Live Code
Result is :

And voilà... I let you the fun to create your own functions makeRectangle()
, makeTriangle()
for your needs ! That requires some little maths !
Edit BONUS
As asked in the comment, here a little member function which would save the image in a file. Add it in the Image class (you can also if you prefer have a free function outside the class). Since we have a ostream operator<< this is straightforward :
void save(const std::string& filename) {
std::ofstream ofs;
ofs.open(filename, std::ios::out);
ofs << (*this);
ofs.close();
}
An other way without modifying the code would be to catch the output of the program in a file with something like this on your terminal :
./main >> file.pgm