From 0cf04c37df99d326f363203ecc49712bd558c9e4 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 25 Apr 2026 21:48:51 +0200 Subject: [PATCH] feat(primitives_gallery): demos para surface_plot_3d + scatter_3d - demos_3d.cpp con dos demos: * demo_surface_plot_3d: malla 64x64 de A*sin(fx*x)*cos(fy*y) con sliders fx/fy/amp en tiempo real. * demo_scatter_3d: 3 clusters gaussianos (N=500) coloreados por cluster, semilla fija para reproducibilidad. - demos.h: declara las dos demos en la seccion Viz. - main.cpp: dos entradas nuevas en k_demos[] (Viz, tras heatmap / table_view). - CMakeLists.txt: anade demos_3d.cpp + surface_plot_3d.cpp + scatter_3d.cpp al target. Issue 0028. --- cpp/apps/primitives_gallery/CMakeLists.txt | 4 + cpp/apps/primitives_gallery/demos.h | 2 + cpp/apps/primitives_gallery/demos_3d.cpp | 100 +++++++++++++++++++++ cpp/apps/primitives_gallery/main.cpp | 2 + 4 files changed, 108 insertions(+) create mode 100644 cpp/apps/primitives_gallery/demos_3d.cpp diff --git a/cpp/apps/primitives_gallery/CMakeLists.txt b/cpp/apps/primitives_gallery/CMakeLists.txt index 6812bf9f..fefa8a23 100644 --- a/cpp/apps/primitives_gallery/CMakeLists.txt +++ b/cpp/apps/primitives_gallery/CMakeLists.txt @@ -5,6 +5,7 @@ add_imgui_app(primitives_gallery demos_viz.cpp demos_graph.cpp demos_gfx.cpp + demos_3d.cpp demos_text_editor.cpp demos_gl_texture.cpp demos_extras.cpp @@ -39,6 +40,9 @@ add_imgui_app(primitives_gallery ${CMAKE_SOURCE_DIR}/functions/viz/gauge.cpp ${CMAKE_SOURCE_DIR}/functions/viz/heatmap.cpp ${CMAKE_SOURCE_DIR}/functions/viz/table_view.cpp + # 3D viz primitives (issue 0028, ImPlot3D) + ${CMAKE_SOURCE_DIR}/functions/viz/surface_plot_3d.cpp + ${CMAKE_SOURCE_DIR}/functions/viz/scatter_3d.cpp # Graph stack (instanced GPU + Barnes-Hut + spatial hash) ${CMAKE_SOURCE_DIR}/functions/viz/graph_types.cpp ${CMAKE_SOURCE_DIR}/functions/viz/graph_renderer.cpp diff --git a/cpp/apps/primitives_gallery/demos.h b/cpp/apps/primitives_gallery/demos.h index b7f22c32..84b3c80a 100644 --- a/cpp/apps/primitives_gallery/demos.h +++ b/cpp/apps/primitives_gallery/demos.h @@ -34,6 +34,8 @@ void demo_candlestick(); void demo_gauge(); void demo_heatmap(); void demo_table_view(); +void demo_surface_plot_3d(); // issue 0028, ImPlot3D +void demo_scatter_3d(); // issue 0028, ImPlot3D // --- Gfx --- void demo_shader_canvas(); diff --git a/cpp/apps/primitives_gallery/demos_3d.cpp b/cpp/apps/primitives_gallery/demos_3d.cpp new file mode 100644 index 00000000..30f8c505 --- /dev/null +++ b/cpp/apps/primitives_gallery/demos_3d.cpp @@ -0,0 +1,100 @@ +// demos_3d — demos para los primitivos viz/* basados en ImPlot3D. +// Issue 0028: surface_plot_3d real + scatter_3d. + +#include "demos.h" +#include "demo.h" + +#include "viz/surface_plot_3d.h" +#include "viz/scatter_3d.h" + +#include +#include +#include +#include + +namespace gallery { + +// --------------------------------------------------------------------------- +// surface_plot_3d +// --------------------------------------------------------------------------- + +void demo_surface_plot_3d() { + demo_header("surface_plot_3d", "v2.0.0", + "Superficie 3D ImPlot3D (z = A * sin(fx*x) * cos(fy*y)) con sliders para " + "ajustar las frecuencias en tiempo real. Drag para orbitar, wheel para zoom."); + + section("Malla 64x64 — sin(fx*x) * cos(fy*y)"); + + static float fx = 0.20f; + static float fy = 0.20f; + static float amp = 1.0f; + + ImGui::SliderFloat("fx", &fx, 0.05f, 1.0f, "%.2f"); + ImGui::SliderFloat("fy", &fy, 0.05f, 1.0f, "%.2f"); + ImGui::SliderFloat("amplitud", &, 0.1f, 3.0f, "%.2f"); + + constexpr int N = 64; + static std::vector z(N * N); + for (int j = 0; j < N; ++j) { + for (int i = 0; i < N; ++i) { + z[j * N + i] = amp * std::sin(fx * float(i)) * std::cos(fy * float(j)); + } + } + + fn::SurfacePlot3DConfig cfg{}; + cfg.z = z.data(); + cfg.nx = N; cfg.ny = N; + cfg.x_min = 0.f; cfg.x_max = float(N); + cfg.y_min = 0.f; cfg.y_max = float(N); + cfg.size = ImVec2(-1.f, 420.f); + fn::surface_plot_3d("##gallery_surface", cfg); +} + +// --------------------------------------------------------------------------- +// scatter_3d +// --------------------------------------------------------------------------- + +void demo_scatter_3d() { + demo_header("scatter_3d", "v1.0.0", + "Scatter 3D ImPlot3D con color por punto. 3 clusters gaussianos sinteticos " + "(N=500) para simular una visualizacion tipica de PCA / clustering."); + + section("3 clusters gaussianos (500 puntos)"); + + constexpr int N = 500; + static std::vector xs(N), ys(N), zs(N); + static std::vector colors(N); + static bool initialized = false; + + if (!initialized) { + std::mt19937 rng(42); + std::normal_distribution g(0.f, 0.4f); + const ImU32 palette[3] = { + IM_COL32(255, 99, 71, 255), // tomate + IM_COL32( 65, 170, 255, 255), // azul + IM_COL32(120, 220, 120, 255), // verde + }; + const float cx[3] = {-1.5f, 1.5f, 0.f}; + const float cy[3] = { 0.f, 0.f, 2.0f}; + const float cz[3] = { 0.f, 1.0f,-1.0f}; + for (int i = 0; i < N; ++i) { + int c = i % 3; + xs[i] = cx[c] + g(rng); + ys[i] = cy[c] + g(rng); + zs[i] = cz[c] + g(rng); + colors[i] = palette[c]; + } + initialized = true; + } + + fn::Scatter3DConfig cfg{}; + cfg.xs = xs.data(); + cfg.ys = ys.data(); + cfg.zs = zs.data(); + cfg.colors = colors.data(); + cfg.n = N; + cfg.size = ImVec2(-1.f, 420.f); + fn::scatter_3d("##gallery_clusters", cfg); +} + +} // namespace gallery diff --git a/cpp/apps/primitives_gallery/main.cpp b/cpp/apps/primitives_gallery/main.cpp index 269bfe6b..9e34e670 100644 --- a/cpp/apps/primitives_gallery/main.cpp +++ b/cpp/apps/primitives_gallery/main.cpp @@ -61,6 +61,8 @@ static const DemoEntry k_demos[] = { {"gauge", "gauge", "Viz", &gallery::demo_gauge}, {"heatmap", "heatmap", "Viz", &gallery::demo_heatmap}, {"table_view", "table_view", "Viz", &gallery::demo_table_view}, + {"surface_plot_3d", "surface_plot_3d", "Viz", &gallery::demo_surface_plot_3d}, + {"scatter_3d", "scatter_3d", "Viz", &gallery::demo_scatter_3d}, // Gfx (shaders_lab core) {"shader_canvas", "shader_canvas", "Gfx", &gallery::demo_shader_canvas}, {"gl_texture", "gl_texture_load", "Gfx", &gallery::demo_gl_texture}, // wave 1