|
5 | 5 | #include <backends/imgui_impl_sdlrenderer2.h> |
6 | 6 | #include <imgui.h> |
7 | 7 |
|
| 8 | +#include <cmath> |
8 | 9 | #include <memory> |
9 | 10 | #include <string> |
10 | 11 | #include <vector> |
@@ -112,7 +113,7 @@ ExitStatus App::Application::run() { |
112 | 113 | const ImVec2 base_pos = viewport->Pos; |
113 | 114 | const ImVec2 base_size = viewport->Size; |
114 | 115 |
|
115 | | - static char function[1024] = "tanh(x)"; |
| 116 | + static char function[1024] = "r = 1 + 0.5*cos(theta)"; |
116 | 117 | static float zoom = 100.0f; |
117 | 118 |
|
118 | 119 | // Left Pane (expression) |
@@ -212,33 +213,81 @@ ExitStatus App::Application::run() { |
212 | 213 | } |
213 | 214 |
|
214 | 215 | if (!plotted) { |
215 | | - // Fallback to y = f(x) plotting using variable x |
216 | | - double x; |
| 216 | + std::string func_str(function); |
| 217 | + bool is_polar = func_str.find("r=") != std::string::npos || func_str.find("r =") != std::string::npos; |
217 | 218 |
|
218 | | - exprtk::symbol_table<double> symbolTable; |
219 | | - symbolTable.add_constants(); |
220 | | - addConstants(symbolTable); |
221 | | - symbolTable.add_variable("x", x); |
| 219 | + if (is_polar) { |
| 220 | + double theta; |
222 | 221 |
|
223 | | - exprtk::expression<double> expression; |
224 | | - expression.register_symbol_table(symbolTable); |
| 222 | + exprtk::symbol_table<double> symbolTable; |
| 223 | + symbolTable.add_constants(); |
| 224 | + addConstants(symbolTable); |
| 225 | + symbolTable.add_variable("theta", theta); |
225 | 226 |
|
226 | | - exprtk::parser<double> parser; |
227 | | - parser.compile(function, expression); |
| 227 | + exprtk::expression<double> expression; |
| 228 | + expression.register_symbol_table(symbolTable); |
228 | 229 |
|
229 | | - for (x = -canvas_sz.x / (2 * zoom); x < canvas_sz.x / (2 * zoom); x += 0.05) { |
230 | | - const double y = expression.value(); |
| 230 | + std::string polar_function = func_str; |
| 231 | + size_t eq_pos = func_str.find("r="); |
| 232 | + if (eq_pos == std::string::npos) { |
| 233 | + eq_pos = func_str.find("r ="); |
| 234 | + } |
| 235 | + if (eq_pos != std::string::npos) { |
| 236 | + size_t start_pos = func_str.find("=", eq_pos) + 1; |
| 237 | + polar_function = func_str.substr(start_pos); |
| 238 | + polar_function.erase(0, polar_function.find_first_not_of(" \t")); |
| 239 | + } |
231 | 240 |
|
232 | | - |
233 | | - ImVec2 screen_pos(origin.x + x * zoom, origin.y - y * zoom); |
234 | | - points.push_back(screen_pos); |
235 | | - } |
| 241 | + exprtk::parser<double> parser; |
| 242 | + if (parser.compile(polar_function, expression)) { |
| 243 | + const double theta_min = 0.0; |
| 244 | + const double theta_max = 4.0 * M_PI; |
| 245 | + const double theta_step = 0.02; |
| 246 | + |
| 247 | + for (theta = theta_min; theta <= theta_max; theta += theta_step) { |
| 248 | + const double r = expression.value(); |
| 249 | + |
| 250 | + const double x = r * cos(theta); |
| 251 | + const double y = r * sin(theta); |
236 | 252 |
|
237 | | - draw_list->AddPolyline(points.data(), |
238 | | - points.size(), |
239 | | - IM_COL32(199, 68, 64, 255), |
240 | | - ImDrawFlags_None, |
241 | | - lineThickness); |
| 253 | + ImVec2 screen_pos(origin.x + static_cast<float>(x * zoom), |
| 254 | + origin.y - static_cast<float>(y * zoom)); |
| 255 | + points.push_back(screen_pos); |
| 256 | + } |
| 257 | + |
| 258 | + draw_list->AddPolyline(points.data(), |
| 259 | + points.size(), |
| 260 | + IM_COL32(128, 64, 199, 255), |
| 261 | + ImDrawFlags_None, |
| 262 | + lineThickness); |
| 263 | + } |
| 264 | + } else { |
| 265 | + double x; |
| 266 | + |
| 267 | + exprtk::symbol_table<double> symbolTable; |
| 268 | + symbolTable.add_constants(); |
| 269 | + addConstants(symbolTable); |
| 270 | + symbolTable.add_variable("x", x); |
| 271 | + |
| 272 | + exprtk::expression<double> expression; |
| 273 | + expression.register_symbol_table(symbolTable); |
| 274 | + |
| 275 | + exprtk::parser<double> parser; |
| 276 | + parser.compile(function, expression); |
| 277 | + |
| 278 | + for (x = -canvas_sz.x / (2 * zoom); x < canvas_sz.x / (2 * zoom); x += 0.05) { |
| 279 | + const double y = expression.value(); |
| 280 | + |
| 281 | + ImVec2 screen_pos(origin.x + x * zoom, origin.y - y * zoom); |
| 282 | + points.push_back(screen_pos); |
| 283 | + } |
| 284 | + |
| 285 | + draw_list->AddPolyline(points.data(), |
| 286 | + points.size(), |
| 287 | + IM_COL32(199, 68, 64, 255), |
| 288 | + ImDrawFlags_None, |
| 289 | + lineThickness); |
| 290 | + } |
242 | 291 | } |
243 | 292 |
|
244 | 293 | ImGui::End(); |
|
0 commit comments