Reposting with full code, as suggested from others. Just updated the main function with hard coded arguments that causes segmentation fault.
Changing the width and height to something else lets the program run fine, for example 500 and 433 respectively.
Main file:
#include <cstdint>
#include <iostream>
#include <sstream>
#include <vector>
#include <cmath>
#include "sierpinski.h"
Triangle::Triangle() {
this->pixels = nullptr;
this->top = Coordinate();
this->left = Coordinate();
this->right = Coordinate();
this->fg_color = 0;
this->area = 0.0;
}
Triangle::Triangle(uint32_t* pixels, Coordinate top, Coordinate left, Coordinate right, uint32_t fg_color) {
this->pixels = pixels;
this->top = top;
this->left = left;
this->right = right;
this->fg_color = fg_color;
this->area = calculateArea(top, left, right);
}
void Triangle::DrawLines(Coordinate top, Coordinate left, Coordinate right) {
int width = getWidth(this->left, this->right);
//left to top
std::vector<Coordinate> line = left.Bresenham(top);
for (unsigned int i = 0; i < line.size(); i++) {
this->pixels[width * line[i].getY() + line[i].getX()] = this->fg_color;
}
line.clear();
// left to right
line = left.Bresenham(right);
for (unsigned int i = 0; i < line.size(); i++) {
this->pixels[width * line[i].getY() + line[i].getX()] = this->fg_color;
}
line.clear();
// top to right
line = top.Bresenham(right);
for (unsigned int i = 0; i < line.size(); i++) {
this->pixels[width * line[i].getY() + line[i].getX()] = this->fg_color;
}
}
void Triangle::Sierpinski(Coordinate top, Coordinate left, Coordinate right, const double min_area) {
if (calculateArea(top, left, right) < min_area) {
return;
}
DrawLines(top, left, right);
Triangle triangle(this->pixels, top, left, right, this->fg_color);
Sierpinski(top, top.Midpoint(left), top.Midpoint(right), min_area);
Sierpinski(top.Midpoint(left), left, left.Midpoint(right), min_area);
Sierpinski(top.Midpoint(right), left.Midpoint(right), right, min_area);
}
uint32_t* Triangle::getPixels() {
return this->pixels;
}
uint32_t Triangle::getFg_color() {
return this->fg_color;
}
double Triangle::getArea() {
return this->area;
}
double Triangle::getWidth(Coordinate left, Coordinate right) {
return left.distance(right);
}
double Triangle::calculateArea(Coordinate top, Coordinate left, Coordinate right) {
return std::abs(top.getX() * (left.getY() - right.getY()) + left.getX() * (right.getY() - top.getY()) + right.getX() * (top.getY() - left.getY())) / 2.0;
}
Coordinate::Coordinate() {
this->x = 0;
this->y = 0;
}
Coordinate::Coordinate(int x, int y) {
this->x = x;
this->y = y;
}
Coordinate::Coordinate(const Coordinate &other) {
this->x = other.x;
this->y = other.y;
}
int Coordinate::getX() {
return this->x;
}
int Coordinate::getY() {
return this->y;
}
double Coordinate::distance(Coordinate other) {
return std::sqrt(std::pow((this->x - other.x), 2) + std::pow((this->y - other.y), 2));
}
Coordinate Coordinate::Midpoint(Coordinate other) {
double midX = (this->x + other.getX()) / 2;
double midY = (this->y + other.getY()) / 2;
return Coordinate(midX, midY);
}
int Coordinate::gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a%b);
}
std::vector<Coordinate> Coordinate::Bresenham(Coordinate other) {
int x1 = this->x, y1 = this->y;
int const x2 = other.x, y2 = other.y;
std::vector<Coordinate> points;
int delta_x(x2 - x1);
signed char const ix((delta_x > 0) - (delta_x < 0));
delta_x = std::abs(delta_x) << 1;
int delta_y(y2 - y1);
signed char const iy((delta_y > 0) - (delta_y < 0));
delta_y = std::abs(delta_y) << 1;
Coordinate newPoint1(x1, y1);
points.push_back(newPoint1);
if (delta_x >= delta_y) {
int error(delta_y - (delta_x >> 1));
while (x1 != x2) {
if ((error > 0) || (!error && (ix > 0))) {
error -= delta_x;
y1 += iy;
}
error += delta_y;
x1 += ix;
Coordinate newPoint2(x1, y1);
points.push_back(newPoint2);
}
} else {
int error(delta_x - (delta_y >> 1));
while (y1 != y2) {
if ((error > 0) || (!error && (iy > 0))) {
error -= delta_y;
x1 += ix;
}
error += delta_x;
y1 += iy;
Coordinate newPoint3(x1, y1);
points.push_back(newPoint3);
}
}
return points;
}
int main() {
int width = 55;
int height = 40;
uint32_t bg_color = 4095617261;
uint32_t fg_color = 2988200782;
double min_area = 1.08;
std::vector<uint32_t> pixels(width * height, bg_color);
Coordinate top, left, right;
top = Coordinate(width / 2, 0);
left = Coordinate(0, height);
right = Coordinate(width, height);
Triangle triangle = Triangle(pixels.data(), top, left, right, fg_color);
triangle.Sierpinski(top, left, right, min_area);
std::cout.write(reinterpret_cast<char *>(pixels.data()), width * height * 4);
}
Header file:
#ifndef SIERPINSKI_H
#define SIERPINSKI_H
#include <vector>
class Coordinate {
public:
Coordinate();
Coordinate(int x, int y);
Coordinate(const Coordinate &other);
int getX();
int getY();
double distance(Coordinate);
Coordinate Midpoint(Coordinate other);
int gcd(int a, int b);
std::vector<Coordinate> Bresenham(Coordinate other);
int countPoints(Coordinate other);
std::vector<Coordinate> getPoints(Coordinate other);
private:
int x;
int y;
};
class Triangle {
public:
Triangle();
Triangle(uint32_t* pixels, Coordinate top, Coordinate left, Coordinate right, uint32_t fg_color);
void DrawLines(Coordinate top, Coordinate left, Coordinate right);
void Draw(double min_area);
void Sierpinski(Coordinate top, Coordinate left, Coordinate right, double min_area);
double calculateArea(Coordinate top, Coordinate left, Coordinate right);
uint32_t* getPixels();
uint32_t getFg_color();
double getArea();
Coordinate top, left, right;
double getWidth(Coordinate left, Coordinate right);
private:
uint32_t* pixels;
uint32_t fg_color;
double area;
};
#endif
After using gdb, it seemed the error was occuring in my Bresenham function at the line:
points.push_back(newPoint3);
But other users stated that seg fault may not be occurring exactly where gdb says it is. If anyone can provide further insight it would be greatly appreciated.