From 86687cd7dbf10e05fe2fde46bcd3d7f2002064de Mon Sep 17 00:00:00 2001 From: Tarun Date: Thu, 23 Oct 2025 00:30:00 +0530 Subject: [PATCH 1/2] feat(graph): enhance plotting support for polar coordinates --- src/core/Core/Application.cpp | 80 ++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 21 deletions(-) diff --git a/src/core/Core/Application.cpp b/src/core/Core/Application.cpp index 75c44b2..3a0e6eb 100644 --- a/src/core/Core/Application.cpp +++ b/src/core/Core/Application.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -212,33 +213,70 @@ ExitStatus App::Application::run() { } if (!plotted) { - // Fallback to y = f(x) plotting using variable x - double x; + std::string func_str(function); + bool is_polar = func_str.find("theta") != std::string::npos; - exprtk::symbol_table symbolTable; - symbolTable.add_constants(); - addConstants(symbolTable); - symbolTable.add_variable("x", x); + if (is_polar) { + double theta; - exprtk::expression expression; - expression.register_symbol_table(symbolTable); + exprtk::symbol_table symbolTable; + symbolTable.add_constants(); + addConstants(symbolTable); + symbolTable.add_variable("theta", theta); - exprtk::parser parser; - parser.compile(function, expression); + exprtk::expression expression; + expression.register_symbol_table(symbolTable); - for (x = -canvas_sz.x / (2 * zoom); x < canvas_sz.x / (2 * zoom); x += 0.05) { - const double y = expression.value(); + exprtk::parser parser; + if (parser.compile(function, expression)) { + const double theta_min = 0.0; + const double theta_max = 4.0 * M_PI; + const double theta_step = 0.02; - - ImVec2 screen_pos(origin.x + x * zoom, origin.y - y * zoom); - points.push_back(screen_pos); - } + for (theta = theta_min; theta <= theta_max; theta += theta_step) { + const double r = expression.value(); + + const double x = r * cos(theta); + const double y = r * sin(theta); + + ImVec2 screen_pos(origin.x + static_cast(x * zoom), + origin.y - static_cast(y * zoom)); + points.push_back(screen_pos); + } + + draw_list->AddPolyline(points.data(), + points.size(), + IM_COL32(128, 64, 199, 255), + ImDrawFlags_None, + lineThickness); + } + } else { + double x; + + exprtk::symbol_table symbolTable; + symbolTable.add_constants(); + addConstants(symbolTable); + symbolTable.add_variable("x", x); + + exprtk::expression expression; + expression.register_symbol_table(symbolTable); + + exprtk::parser parser; + parser.compile(function, expression); + + for (x = -canvas_sz.x / (2 * zoom); x < canvas_sz.x / (2 * zoom); x += 0.05) { + const double y = expression.value(); - draw_list->AddPolyline(points.data(), - points.size(), - IM_COL32(199, 68, 64, 255), - ImDrawFlags_None, - lineThickness); + ImVec2 screen_pos(origin.x + x * zoom, origin.y - y * zoom); + points.push_back(screen_pos); + } + + draw_list->AddPolyline(points.data(), + points.size(), + IM_COL32(199, 68, 64, 255), + ImDrawFlags_None, + lineThickness); + } } ImGui::End(); From c8a6dcd6c6efd10074564d685d24b82b7dd57de8 Mon Sep 17 00:00:00 2001 From: Tarun Date: Thu, 23 Oct 2025 10:58:45 +0530 Subject: [PATCH 2/2] feat(graph): update default polar function and improve parsing logic --- src/core/Core/Application.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/core/Core/Application.cpp b/src/core/Core/Application.cpp index 3a0e6eb..6a5495d 100644 --- a/src/core/Core/Application.cpp +++ b/src/core/Core/Application.cpp @@ -113,7 +113,7 @@ ExitStatus App::Application::run() { const ImVec2 base_pos = viewport->Pos; const ImVec2 base_size = viewport->Size; - static char function[1024] = "tanh(x)"; + static char function[1024] = "r = 1 + 0.5*cos(theta)"; static float zoom = 100.0f; // Left Pane (expression) @@ -214,7 +214,7 @@ ExitStatus App::Application::run() { if (!plotted) { std::string func_str(function); - bool is_polar = func_str.find("theta") != std::string::npos; + bool is_polar = func_str.find("r=") != std::string::npos || func_str.find("r =") != std::string::npos; if (is_polar) { double theta; @@ -227,8 +227,19 @@ ExitStatus App::Application::run() { exprtk::expression expression; expression.register_symbol_table(symbolTable); + std::string polar_function = func_str; + size_t eq_pos = func_str.find("r="); + if (eq_pos == std::string::npos) { + eq_pos = func_str.find("r ="); + } + if (eq_pos != std::string::npos) { + size_t start_pos = func_str.find("=", eq_pos) + 1; + polar_function = func_str.substr(start_pos); + polar_function.erase(0, polar_function.find_first_not_of(" \t")); + } + exprtk::parser parser; - if (parser.compile(function, expression)) { + if (parser.compile(polar_function, expression)) { const double theta_min = 0.0; const double theta_max = 4.0 * M_PI; const double theta_step = 0.02;