{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Reconstructing Surfaces\n\nThis example demonstrates :meth:`~pyvisual.core.mixins.StackMeshMixin.add_surface`\n\u2014 the method for building a triangulated surface through scattered spherical\ncoordinate points using one of three reconstruction strategies:\n``'delaunay_2d'``, ``'delaunay_3d'``, or ``'reconstruct_surface'``.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nfrom pyvisual import Plot3d"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Surface of Revolution\n\nThe surface below is defined by the relation $r = 5\\sin\\theta$, sampled\nat 10 equally-spaced longitudes and 100 latitudinal points per meridian.\nThe resulting point cloud forms a closed, non-planar surface that wraps\naround itself \u2014 the default ``'delaunay_2d'`` projects points onto a plane\nbefore triangulating, which produces incorrect connectivity for such a surface.\n:meth:`~pyvista.DataSetFilters.delaunay_3d` instead builds a full volumetric\ntetrahedralization and extracts the outer boundary, correctly handling the\nclosed topology.  The surface is colored by colatitude $\\theta$.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "n_lines, n_pts = 10, 100\nt = np.tile(np.linspace(0, np.pi, n_pts), (n_lines, 1))\nr = 5 * np.sin(t)\np = np.tile(np.linspace(0, 2 * np.pi, n_lines)[:, None], (1, n_pts))\n\nplotter = Plot3d()\nplotter.show_axes()\nplotter.add_sun()\nplotter.add_surface(r, t, p, t, method='delaunay_3d')\nplotter.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Open Shell Patch (``delaunay_2d``)\n\nFor nearly-planar or open surfaces, ``'delaunay_2d'`` gives better results.\nThe example below samples a spherical cap at $r = 3\\,R_\\odot$ over a\nlimited colatitude/longitude range and reconstructs it as a surface patch\ncolored by longitude $\\phi$.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "n_t, n_p = 20, 40\nt_vals = np.tile(np.linspace(np.pi / 6, np.pi / 3, n_t), (n_p, 1)).T\np_vals = np.tile(np.linspace(0, np.pi / 2, n_p), (n_t, 1))\nr_vals = np.full_like(t_vals, 3.0)\n\nplotter = Plot3d()\nplotter.show_axes()\nplotter.add_sun()\nplotter.add_surface(r_vals, t_vals, p_vals, p_vals, method='delaunay_2d',\n                    show_scalar_bar=False)\nplotter.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.13.12"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}