// Requires the matching spatial-plot-enabled native development runtime.
import aner.plot
import aner.math

// A parametric path connects samples in their original order.
let pathX = List()
let pathY = List()
let pathZ = List()
for sample in Range(81) {
    let t = Float64(sample) * 0.15707963267948966
    pathX.append(math.cos(t))
    pathY.append(math.sin(t))
    pathZ.append(t / 6.283185307179586)
}
let trajectory = plot.line3d(pathX, pathY, pathZ)
    .labels("x (m)", "y (m)", "z (m)").aspect("equal")
    .view(-35.0, 25.0).title("A supplied helix connects 81 ordered samples")
    .caption("Synthetic parametric path: x=cos(t), y=sin(t), z=t/(2π), 0≤t≤4π. No smoothing, fitted trajectory or physical simulation.")
    .theme(plot.theme("light")).size(940, 640)
trajectory.show()

// Surface axes are strictly increasing; z is row-major, one row per y.
let gridX = List()
let gridY = List()
let gridZ = List()
for column in Range(21) { gridX.append(-2.0 + Float64(column) * 0.2) }
for row in Range(17) { gridY.append(-2.0 + Float64(row) * 0.25) }
for row in Range(17) {
    let y = -2.0 + Float64(row) * 0.25
    for column in Range(21) {
        let x = -2.0 + Float64(column) * 0.2
        gridZ.append((x * x - y * y) / 4.0)
    }
}
let saddle = plot.surface3d(x: gridX, y: gridY, z: gridZ)
    .labels("x (m)", "y (m)", "Response (arbitrary units)")
    .color_label("Response (arbitrary units)").color_limits(-1.0, 1.0)
    .aspect("auto").view(-45.0, 30.0)
    .title("An explicitly sampled saddle surface")
    .caption("Synthetic z=(x²−y²)/4 on a 17×21 rectangular grid. Flat triangles join supplied neighboring vertices; no fitted surface. Auto aspect normalizes each axis independently.")
    .theme(plot.theme("light")).size(1000, 680)
saddle.show()

// Export initial native views, using fresh filenames.
trajectory.save("spatial-trajectory.html")
trajectory.save("spatial-trajectory.svg")
saddle.save("spatial-surface.html")
saddle.save("spatial-surface.svg")
