0b6b984dd3
contour_compute implementa marching squares clasico (16 casos, casos
ambiguos 5 y 10 partidos en 2 segmentos). Para cada level devuelve un
ContourLine{pts, level} con segmentos en coords [0..nx-1]x[0..ny-1].
Verificado con gaussiana 32x32 + 4 niveles: todos los endpoints aparecen
>=2 veces (curvas cerradas, ningun endpoint huerfano).
65 lines
2.2 KiB
Markdown
65 lines
2.2 KiB
Markdown
---
|
|
name: contour
|
|
kind: component
|
|
lang: cpp
|
|
domain: viz
|
|
version: "1.0.0"
|
|
purity: pure
|
|
signature: "void contour(const char* id, const float* grid, int nx, int ny, const float* levels, int n_levels, ImVec2 size)"
|
|
description: "Contour plot 2D usando marching squares clasico (16 casos) con interpolacion lineal entre celdas. Layout puro separado del render."
|
|
tags: [imgui, drawlist, chart, visualization, contour, marching-squares, scalar-field]
|
|
uses_functions: []
|
|
uses_types: []
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: ""
|
|
imports: [imgui]
|
|
tested: false
|
|
tests: []
|
|
test_file_path: ""
|
|
file_path: "cpp/functions/viz/contour.cpp"
|
|
framework: imgui
|
|
params:
|
|
- name: id
|
|
desc: "Identificador unico para PushID"
|
|
- name: grid
|
|
desc: "Grid 2D row-major (grid[y*nx + x])"
|
|
- name: nx
|
|
desc: "Numero de columnas del grid"
|
|
- name: ny
|
|
desc: "Numero de filas del grid"
|
|
- name: levels
|
|
desc: "Array de niveles a contornear"
|
|
- name: n_levels
|
|
desc: "Cantidad de niveles"
|
|
- name: size
|
|
desc: "Tamano del rect de render. x <= 0 usa el ancho disponible"
|
|
output: "Renderiza los contornos como segmentos de linea (AddLine) con color por nivel (gradiente azul->amarillo)"
|
|
---
|
|
|
|
# contour
|
|
|
|
Marching squares clasico para contornos isovaluados de un grid 2D escalar.
|
|
|
|
`contour_compute` es pura: para cada nivel devuelve un `ContourLine{pts, level}` donde `pts` es una secuencia de pares (cada par es un segmento). Los puntos estan en coords [0..nx-1] x [0..ny-1] del grid — el render escala a la region.
|
|
|
|
Casos ambiguos 5 y 10 se resuelven con dos segmentos (sin desambiguar por el centro). Para campos suaves (gaussianas, etc.) este caso es raro.
|
|
|
|
## Validacion
|
|
|
|
Para una gaussiana 2D (cumbre en el centro) con varios niveles, los contornos resultantes son anillos cerrados aproximadamente concentricos. Si las isolineas de una gaussiana no se cierran, es un bug del algoritmo.
|
|
|
|
## Ejemplo
|
|
|
|
```cpp
|
|
constexpr int N = 32;
|
|
float grid[N*N];
|
|
for (int y = 0; y < N; y++)
|
|
for (int x = 0; x < N; x++) {
|
|
float dx = x - N/2.0f, dy = y - N/2.0f;
|
|
grid[y*N + x] = std::exp(-(dx*dx + dy*dy) / 80.0f);
|
|
}
|
|
float levels[] = {0.1f, 0.3f, 0.5f, 0.7f, 0.9f};
|
|
contour("##gauss", grid, N, N, levels, 5, ImVec2(-1, 300));
|
|
```
|