saturniid/test.cpp

138 lines
3.8 KiB
C++

#include <iostream>
#include <fstream>
#include <vector>
// Define a structure for a pixel
struct Pixel {
unsigned char r, g, b;
};
// Define a structure for an image
struct Image {
int width, height;
std::vector<Pixel> pixels;
Image(int w, int h) : width(w), height(h) {
pixels.resize(width * height);
}
// Set the color of a specific pixel
void setPixel(int x, int y, const Pixel& color) {
if (x >= 0 && x < width && y >= 0 && y < height) {
pixels[y * width + x] = color;
}
}
// Save the image in PPM format
void savePPM(const std::string& filename) {
std::ofstream file(filename);
if (!file.is_open()) {
std::cerr << "Failed to open file for writing." << std::endl;
return;
}
// Write the header for P3 format
file << "P3\n" << width << " " << height << "\n255\n";
// Write pixel data in ASCII format
for (const auto& pixel : pixels) {
file << static_cast<int>(pixel.r) << " "
<< static_cast<int>(pixel.g) << " "
<< static_cast<int>(pixel.b) << "\n";
}
file.close();
}
// void savePPM(const std::string& filename) {
// std::ofstream file(filename, std::ios::binary);
// file << "P6\n" << width << " " << height << "\n255\n";
// for (const auto& pixel : pixels) {
// file << pixel.r << pixel.g << pixel.b;
// }
// file.close();
// }
};
struct Point {
int x, y;
};
// Function to check if a point is inside a triangle using barycentric coordinates
bool isInsideTriangle(int x, int y, const Point& v1, const Point& v2, const Point& v3) {
int a = (v1.x - x) * (v2.y - v1.y) - (v2.x - v1.x) * (v1.y - y);
int b = (v2.x - x) * (v3.y - v2.y) - (v3.x - v2.x) * (v2.y - y);
int c = (v3.x - x) * (v1.y - v3.y) - (v1.x - v3.x) * (v3.y - y);
// A point is inside the triangle if all barycentric coordinates are positive or all are negative
return (a <= 0 && b <= 0 && c <= 0) || (a > 0 && b > 0 && c > 0);
}
// Function to draw a triangle
void drawTriangle(Image& img, const Point& v1, const Point& v2, const Point& v3, const Pixel& color) {
// Find the bounding box of the triangle
int minX = std::min(std::min(v1.x, v2.x), v3.x);
int maxX = std::max(std::max(v1.x, v2.x), v3.x);
int minY = std::min(std::min(v1.y, v2.y), v3.y);
int maxY = std::max(std::max(v1.y, v2.y), v3.y);
// Iterate over the bounding box and color the pixels inside the triangle
for (int y = minY; y <= maxY; ++y) {
for (int x = minX; x <= maxX; ++x) {
if (isInsideTriangle(x, y, v1, v2, v3)) {
img.setPixel(x, y, color);
}
}
}
}
bool insideCircle(int x, int y, const Point& c, const int r){
return ((x - c.x)*(x - c.x) + (y - c.y)*(y - c.y)) < r*r;
}
void drawCircle(Image& img, const Point& c, const int r, const Pixel& color){
int minX = c.x - r;
int maxX = c.x + r;
int minY = c.y - r;
int maxY = c.y + r;
for(int y= minY; y <= maxY; y++){
for(int x = minX; x <= maxX; x++){
if(insideCircle(x,y,c,r)){
img.setPixel(x,y,color);
}
}
}
}
int main() {
// Create an image of 100x100
Image img(200, 200);
// Set some pixels to create a pattern
for (int y = 0; y < img.height; ++y) {
for (int x = 0; x < img.width; ++x) {
if ((x + y) % 20 < 10) {
img.setPixel(x, y, {255, 0, 0}); // Red color
} else {
img.setPixel(x, y, {0, 0, 255}); // Blue color
}
}
}
drawTriangle(img, {20,80}, {80,80}, {80, 120}, {100,100,100});
drawCircle(img, {100,100}, 30, {0,200,0});
// Save the image
img.savePPM("output.ppm");
std::cout << "Image saved as output.ppm" << std::endl;
return 0;
}