Skip to content

Commit eaf431b

Browse files
authored
Merge pull request #2 from stevenewald/render
Render
2 parents 9926b8f + 45f207c commit eaf431b

6 files changed

+125
-39
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ prefix/
1010
CMakeLists.txt.user
1111
compile_commands.json
1212
conan_cache_*.tgz
13+
CMakeUserPresets.json
14+
.cache

CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ target_include_directories(
3030
target_compile_features(fractal-generator_lib PUBLIC cxx_std_20)
3131

3232
find_package(fmt REQUIRED)
33-
target_link_libraries(fractal-generator_lib PRIVATE fmt::fmt)
33+
find_package(argparse REQUIRED)
34+
target_link_libraries(fractal-generator_lib PUBLIC fmt::fmt)
35+
target_link_libraries(fractal-generator_lib PUBLIC argparse::argparse)
3436

3537
find_package(SFML REQUIRED graphics CONFIG)
3638
target_link_libraries(fractal-generator_lib PUBLIC sfml-graphics)

CMakePresets.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
{
8484
"name": "ci-darwin",
8585
"inherits": ["flags-appleclang", "ci-std"],
86-
"generator": "Xcode",
86+
"generator": "Unix Makefiles",
8787
"hidden": true,
8888
"cacheVariables": {
8989
"CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE": "PRE_TEST"

CMakeUserPresets.json

-36
This file was deleted.

conanfile.py

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def layout(self):
1111
def requirements(self):
1212
self.requires("fmt/11.0.2")
1313
self.requires("sfml/2.6.1")
14+
self.requires("argparse/3.1")
1415

1516
def build_requirements(self):
1617
self.test_requires("catch2/3.7.0")

source/main.cpp

+118-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,128 @@
11
#include "graphics/basic_display.hpp"
2+
#include "lib.hpp"
23

3-
int main()
4+
#include <argparse/argparse.hpp>
5+
6+
#include <complex>
7+
8+
#include <exception>
9+
#include <iostream>
10+
#include <string>
11+
12+
constexpr double DIVERGENCE_NORM = 4;
13+
constexpr double X_DIM = 2;
14+
constexpr double Y_DIM = 2;
15+
constexpr int MAX_ITERATIONS = 50;
16+
17+
// https://en.wikipedia.org/wiki/Mandelbrot_set#Formal_definition
18+
std::complex<double> step(std::complex<double> z_n, std::complex<double> constant)
19+
{
20+
return z_n * z_n + constant;
21+
}
22+
23+
int compute_iterations(
24+
std::complex<double> z_0, std::complex<double> constant, int max_iters
25+
)
26+
{
27+
int iterations = 0;
28+
std::complex<double> z_n = z_0;
29+
30+
while (iterations < max_iters && std::norm(z_n) < DIVERGENCE_NORM) {
31+
z_n = step(z_n, constant);
32+
++iterations;
33+
}
34+
35+
return iterations;
36+
}
37+
38+
void display_line()
439
{
540
fractal::BasicDisplay display;
641
for (std::size_t i = 0; i < 100; i++) {
742
display.set_pixel(100, 100 + i, 255);
843
}
944
display.display_window();
45+
}
46+
47+
void display_julia(std::size_t width, std::size_t height, std::complex<double> constant)
48+
{
49+
fractal::BasicDisplay display;
50+
51+
auto x_step = X_DIM * 2 / static_cast<double>(width);
52+
auto y_step = Y_DIM * 2 / static_cast<double>(height);
53+
54+
for (std::size_t j = 0; j < height; ++j) {
55+
for (std::size_t i = 0; i < width; ++i) {
56+
double x = -X_DIM + i * x_step;
57+
double y = -Y_DIM + j * y_step;
58+
59+
auto iterations = compute_iterations({x, y}, constant, MAX_ITERATIONS);
60+
61+
display.set_pixel(
62+
i, j,
63+
static_cast<int>(iterations / static_cast<double>(MAX_ITERATIONS) * 255)
64+
);
65+
}
66+
}
67+
68+
display.display_window();
69+
}
70+
71+
void display_mandelbrot(
72+
std::size_t width, std::size_t height, std::complex<double> constant
73+
)
74+
{
75+
fractal::BasicDisplay display;
76+
77+
auto x_step = X_DIM * 2 / static_cast<double>(width);
78+
auto y_step = Y_DIM * 2 / static_cast<double>(height);
79+
80+
for (std::size_t j = 0; j < height; ++j) {
81+
for (std::size_t i = 0; i < width; ++i) {
82+
// Compute complex coordinates from pixel index
83+
double x = -X_DIM + i * x_step;
84+
double y = -Y_DIM + j * y_step;
85+
86+
// Compute the number of iterations
87+
auto iterations = compute_iterations(constant, {x, y}, MAX_ITERATIONS);
88+
89+
display.set_pixel(
90+
i, j,
91+
static_cast<int>(iterations / static_cast<double>(MAX_ITERATIONS) * 255)
92+
);
93+
}
94+
}
95+
96+
display.display_window();
97+
}
98+
99+
int main(int argc, char** argv)
100+
{
101+
auto const lib = library{};
102+
argparse::ArgumentParser program(lib.name);
103+
104+
program.add_argument("width")
105+
.help("Horizontal resolution")
106+
.default_value(800)
107+
.scan<'i', int>();
108+
109+
program.add_argument("height")
110+
.help("Vertical resolution")
111+
.default_value(600)
112+
.scan<'i', int>();
113+
114+
try {
115+
program.parse_args(argc, argv);
116+
} catch (const std::exception& err) {
117+
std::cerr << err.what() << std::endl;
118+
std::cerr << program;
119+
return 1;
120+
}
121+
122+
auto width = program.get<int>("width");
123+
auto height = program.get<int>("height");
124+
125+
display_mandelbrot(width, height, {0, 0});
126+
10127
return 0;
11128
}

0 commit comments

Comments
 (0)