-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgallery_fractal.cpp
More file actions
197 lines (180 loc) 路 6.35 KB
/
Copy pathgallery_fractal.cpp
File metadata and controls
197 lines (180 loc) 路 6.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/**
* @file gallery_fractal.cpp
* @brief Fractal Visualization - Mandelbrot and Julia Sets
* @author plotly.cpp contributors
* @date 2025
*
* @example gallery_fractal.cpp
*
* # Fractal Visualization Example
*
* This example demonstrates advanced mathematical visualization by computing
* and displaying the famous Mandelbrot and Julia fractals. It showcases complex
* number calculations, iterative algorithms, and interactive switching between
* different fractal types using Plotly's update menu functionality.
*
* ## What You'll Learn
* - Mathematical fractal generation using complex number arithmetic
* - Implementing the Mandelbrot set iterative escape algorithm
* - Computing Julia sets with different parameter values
* - Creating interactive heatmap visualizations of mathematical data
* - Using Plotly's update menu buttons for switching between datasets
* - Color mapping iterations to create visually appealing mathematical art
* - Complex plane coordinate system visualization
*
* ## Sample Output
* The example creates an interactive fractal explorer featuring:
* - Mandelbrot set visualization with "Hot" colorscale showing iteration counts
* - Julia set with parameter \f$c = -0.8 + 0.156i\f$ using "Viridis" colorscale
* - Interactive buttons to switch between the two fractal types
* - 400x400 pixel resolution showing intricate fractal boundary details
* - Hover information displaying complex coordinates and iteration values
*
* @image html fractal_julia.png "Julia Set Fractal Visualization"
* @image html fractal_mandelbrot.png "Mandelbrot and Julia Set Fractal
* Visualization"
*
* @see std::complex For complex number arithmetic
* @see plotly::Object For heatmap trace configuration with update menus
*/
#include "plotly/plotly.hpp"
#include <complex>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
// Mandelbrot set calculation
auto mandelbrot(const std::complex<double> &c, int maxIter) -> int {
std::complex<double> z = 0;
for (int i = 0; i < maxIter; i++) {
if (std::abs(z) > 2.0) {
return i;
}
z = z * z + c;
}
return maxIter;
}
// Julia set calculation
auto julia(const std::complex<double> &z, const std::complex<double> &c,
int maxIter) -> int {
std::complex<double> current = z;
for (int i = 0; i < maxIter; i++) {
if (std::abs(current) > 2.0) {
return i;
}
current = current * current + c;
}
return maxIter;
}
auto main() -> int {
plotly::Figure fig;
fig.openBrowser();
// Initial parameters
const int width = 400;
const int height = 400;
const int maxIterations = 100;
double xMin = -2.5, xMax = 1.5, yMin = -2.0, yMax = 2.0;
// Julia set parameter
std::complex<double> juliaC(-0.8, 0.156);
// Generate initial Mandelbrot set
std::vector<std::vector<int>> mandelbrotData(height, std::vector<int>(width));
std::vector<double> xCoords, yCoords;
// Create coordinate arrays
for (int i = 0; i < width; i++) {
xCoords.push_back(xMin + (xMax - xMin) * i / (width - 1));
}
for (int j = 0; j < height; j++) {
yCoords.push_back(yMin + (yMax - yMin) * j / (height - 1));
}
// Calculate Mandelbrot set
std::cout << "Calculating Mandelbrot set..." << '\n';
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
std::complex<double> c(xCoords[i], yCoords[j]);
mandelbrotData[j][i] = mandelbrot(c, maxIterations);
}
if (j % 50 == 0) {
std::cout << "Progress: " << (j * 100 / height) << "%" << '\n';
}
}
// Create Mandelbrot trace
plotly::Object mandelbrotTrace = {
{"type", "heatmap"},
{"z", mandelbrotData},
{"x", xCoords},
{"y", yCoords},
{"colorscale", "Hot"},
{"showscale", true},
{"colorbar", {{"title", "Iterations"}, {"titleside", "right"}}},
{"name", "Mandelbrot Set"},
{"hovertemplate", "Real: %{x:.4f}<br>Imaginary: %{y:.4f}<br>" +
std::string("Iterations: %{z}<extra></extra>")}};
// Generate Julia set for comparison
std::vector<std::vector<int>> juliaData(height, std::vector<int>(width));
std::cout << "Calculating Julia set..." << '\n';
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
std::complex<double> z(xCoords[i], yCoords[j]);
juliaData[j][i] = julia(z, juliaC, maxIterations);
}
}
// Create Julia trace (initially invisible)
plotly::Object juliaTrace = {
{"type", "heatmap"},
{"z", juliaData},
{"x", xCoords},
{"y", yCoords},
{"colorscale", "Viridis"},
{"showscale", true},
{"visible", false},
{"colorbar", {{"title", "Iterations"}, {"titleside", "right"}}},
{"name", "Julia Set"},
{"hovertemplate", "Real: %{x:.4f}<br>Imaginary: %{y:.4f}<br>" +
std::string("Iterations: %{z}<extra></extra>")}};
// Create layout with buttons to switch between fractals
plotly::Object layout = {
{"title",
{{"text",
"Fractal<br>" + std::string("<sub>Click buttons to switch between "
"Mandelbrot and Julia sets</sub>")},
{"font", {{"size", 16}}}}},
{"xaxis", {{"title", "Real Axis"}, {"showgrid", false}}},
{"yaxis",
{{"title", "Imaginary Axis"},
{"showgrid", false},
{"scaleanchor", "x"}}},
{"width", 800},
{"height", 700},
{"updatemenus",
{{{"type", "buttons"},
{"direction", "left"},
{"showactive", true},
{"x", 0.1},
{"y", 1.02},
{"xanchor", "left"},
{"yanchor", "top"},
{"buttons",
{{{"label", "Mandelbrot Set"},
{"method", "update"},
{"args",
{{{"visible", {true, false}}},
{{"title", "Mandelbrot Set - The Classic Fractal"}}}}},
{{"label", "Julia Set"},
{"method", "update"},
{"args",
{{{"visible", {false, true}}},
{{"title", "Julia Set - c = -0.8 + 0.156i"}}}}}}}}}},
{"annotations",
{{{"text", "Use buttons to switch between fractals."},
{"x", 0.5},
{"y", -0.1},
{"xref", "paper"},
{"yref", "paper"},
{"showarrow", false},
{"font", {{"size", 12}}}}}}};
// Create the plot
std::vector<plotly::Object> data = {mandelbrotTrace, juliaTrace};
fig.newPlot(data, layout);
fig.waitClose();
return 0;
}