{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "28e2967f",
   "metadata": {},
   "source": [
    "# Summary\n",
    "\n",
    "## Objective\n",
    "\n",
    "Understand the performance of `Calculator.zero_angle()` and get it working as well as possible.  The \"cost\" of a method is the number of iterations, because each iteration requires computing a trajectory, and that is by far the most computationally expensive operation involved.\n",
    "\n",
    "We will:\n",
    "\n",
    "0. Define a standard long-range rifle round to use throughout the study.\n",
    "1. Compute the \"reachable range\" of the shot for launch angles from 0 to 90 degrees using `calc.find_max_range()`.  (This region is a convex hull.)\n",
    "2. Sample target points within the reachable range and, for each point, determine how long it takes `.zero_angle()` to return the firing solution (i.e., the launch angle for a trajectory that will hit the point), and where it is unable to find a solution.\n",
    "\n",
    "During the study we will use SciPy, but our goal is to have a `.zero_angle()` method that does not depend on SciPy and that can:\n",
    "*  Calculate the zero angle for as large a region as possible, and \n",
    "*  Know where it won't work well – or at all.\n",
    "\n",
    "(Note that in the `SciPyIntegrationEngine` the `._zero_angle()` method falls back on `._find_zero_angle()`, which uses SciPy's `root_scalar`.)\n",
    "\n",
    "## Conclusions\n",
    "\n",
    "* The current implementation can solve for targets out to about 85% of the maximum range in less than a dozen iterations: see [`ZeroBaseline` chart here](#baseline-huge-sample).  Beyond that it soon struggles and takes more than 20 iterations to converge, and right at the range limit it doesn't converge in less than 50 iterations.\n",
    "  * However there are anomalies: within the region of good performance there are a scattered points (a few dozen out of 20,000 sampled) where it took an extraordinary number of iterations to converge, and _those exceptions need to be investigated_.\n",
    "* Confirming that a target is in range using SciPy `.minimize_scalar()` (called through `scipy_engine.find_max_range()`) takes on average a dozen iterations, but as many as 26.  [There is a strange slice about the look angle 21° where it consistently takes more than 20 iterations](#find_max_range), and it would be interesting to know why.\n",
    "  * Having paid the price to find the max-range for a look angle as well as the launch angle to reach that, SciPy `.root_scalar(method='brentq')` [can find the zero in less than 10 iterations on average](#zero-knowing-max_range_angle).\n",
    "* If we know (or are willing to assert) that a target is in range, Newton's method (SciPy `.root_scalar(method='newton')` started at the look-angle) [finds the solution in 12 iterations over almost the entire reachable range](#newtons-method-huge).  However, it also has a few scattered sample points that fail to converge, and those need to be investigated."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "126708fe",
   "metadata": {},
   "source": [
    "# Load\n",
    "\n",
    "**Note extra Python package dependencies:**\n",
    "* plotly\n",
    "* shapely\n",
    "* tqdm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9c64faa7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "import math\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import plotly.express as px\n",
    "import plotly.graph_objects as go\n",
    "from tqdm.auto import tqdm\n",
    "from shapely.geometry import Point, Polygon\n",
    "from py_ballisticcalc import Ammo, Atmo, Calculator, HitResult, Shot\n",
    "from py_ballisticcalc import RangeError, TrajFlag, BaseEngineConfigDict, SciPyEngineConfigDict\n",
    "from py_ballisticcalc import TableG7, logger, loadMetricUnits, ZeroFindingError\n",
    "from py_ballisticcalc.drag_model import DragModel\n",
    "from py_ballisticcalc.helpers import must_fire\n",
    "from py_ballisticcalc.unit import *\n",
    "logger.setLevel(logging.WARNING)\n",
    "loadMetricUnits()\n",
    "PreferredUnits.drop = Distance.Meter\n",
    "PreferredUnits.distance = Distance.Meter\n",
    "\n",
    "def create_shot():\n",
    "    \"\"\"This is a standard 7.62mm NATO shot.\"\"\"\n",
    "    dm = DragModel(0.22, TableG7, Weight.Gram(10), Distance.Centimeter(7.62), Distance.Centimeter(3.0))\n",
    "    ammo = Ammo(dm, Velocity.MPS(800))\n",
    "    return Shot(ammo=ammo, atmo=Atmo.icao())\n",
    "shot = create_shot()\n",
    "calc = Calculator(engine=\"scipy_engine\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "122c2f75",
   "metadata": {},
   "source": [
    "## Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1b68ae7b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max range for target at look-angle 15.00° is 3901.71m. Launch angle to hit is 43.44°.\n"
     ]
    }
   ],
   "source": [
    "# Here's how to get the max range at a particular slant angle\n",
    "shot.slant_angle = Angular.Degree(15)\n",
    "max_range, angle_to_reach = calc.find_max_range(shot)\n",
    "print(f\"Max range for target at look-angle {shot.slant_angle >> Angular.Degree:.2f}° \"\n",
    "      f\"is {max_range >> Distance.Meter:.2f}m. Launch angle to hit is {angle_to_reach >> Angular.Degree:.2f}°.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "20272fb6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 60548 characters]",
      "text/plain": [
       "<Figure size 640x480 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confirm the finding:\n",
    "shot.barrel_elevation = angle_to_reach\n",
    "trajectory, e = must_fire(calc, shot, trajectory_range=Distance.Meter((max_range >> Distance.Meter)+100), trajectory_step=Distance.Meter(100), extra_data=True)\n",
    "trajectory.plot()\n",
    "# Slant height at the target distance should be approximately zero (within a small tolerance)\n",
    "slant_zero = trajectory.flag(TrajFlag.ZERO_DOWN)\n",
    "assert abs(slant_zero.slant_distance.raw_value - max_range.raw_value) < 1e-6\n",
    "assert abs(slant_zero.slant_height.raw_value) < 1e-6 "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8903dde6",
   "metadata": {},
   "source": [
    "# Find Reachable Range Envelope\n",
    "For slant angles from 0-90°."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad757892",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "841ed5ab69a74c67b8dc8890225a2cd2",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Slant angles:   0%|          | 0/91 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>slant_angle_deg</th>\n",
       "      <th>launch_angle_deg</th>\n",
       "      <th>max_dist_m</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.0</td>\n",
       "      <td>35.917251</td>\n",
       "      <td>4342.467980</td>\n",
       "      <td>4342.467980</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.0</td>\n",
       "      <td>36.384966</td>\n",
       "      <td>4307.781751</td>\n",
       "      <td>4307.125655</td>\n",
       "      <td>75.181158</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2.0</td>\n",
       "      <td>36.857060</td>\n",
       "      <td>4273.950320</td>\n",
       "      <td>4271.346745</td>\n",
       "      <td>149.158715</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3.0</td>\n",
       "      <td>37.335156</td>\n",
       "      <td>4240.949794</td>\n",
       "      <td>4235.137719</td>\n",
       "      <td>221.954163</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4.0</td>\n",
       "      <td>37.816928</td>\n",
       "      <td>4208.744156</td>\n",
       "      <td>4198.491866</td>\n",
       "      <td>293.587151</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   slant_angle_deg  launch_angle_deg   max_dist_m            x           y\n",
       "0              0.0         35.917251  4342.467980  4342.467980    0.000000\n",
       "1              1.0         36.384966  4307.781751  4307.125655   75.181158\n",
       "2              2.0         36.857060  4273.950320  4271.346745  149.158715\n",
       "3              3.0         37.335156  4240.949794  4235.137719  221.954163\n",
       "4              4.0         37.816928  4208.744156  4198.491866  293.587151"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>slant_angle_deg</th>\n",
       "      <th>launch_angle_deg</th>\n",
       "      <th>max_dist_m</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>86</th>\n",
       "      <td>86.0</td>\n",
       "      <td>87.367315</td>\n",
       "      <td>3143.251126</td>\n",
       "      <td>2.192621e+02</td>\n",
       "      <td>3135.594324</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>87</th>\n",
       "      <td>87.0</td>\n",
       "      <td>88.025528</td>\n",
       "      <td>3142.488487</td>\n",
       "      <td>1.644651e+02</td>\n",
       "      <td>3138.181816</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>88</th>\n",
       "      <td>88.0</td>\n",
       "      <td>88.683571</td>\n",
       "      <td>3141.935598</td>\n",
       "      <td>1.096520e+02</td>\n",
       "      <td>3140.021616</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>89</th>\n",
       "      <td>89.0</td>\n",
       "      <td>89.341752</td>\n",
       "      <td>3141.590724</td>\n",
       "      <td>5.482832e+01</td>\n",
       "      <td>3141.112245</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>90</th>\n",
       "      <td>90.0</td>\n",
       "      <td>90.000000</td>\n",
       "      <td>3141.485247</td>\n",
       "      <td>1.923605e-13</td>\n",
       "      <td>3141.485247</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    slant_angle_deg  launch_angle_deg   max_dist_m             x            y\n",
       "86             86.0         87.367315  3143.251126  2.192621e+02  3135.594324\n",
       "87             87.0         88.025528  3142.488487  1.644651e+02  3138.181816\n",
       "88             88.0         88.683571  3141.935598  1.096520e+02  3140.021616\n",
       "89             89.0         89.341752  3141.590724  5.482832e+01  3141.112245\n",
       "90             90.0         90.000000  3141.485247  1.923605e-13  3141.485247"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "customdata": {
          "bdata": "AAAAAAAAAABo0v99aPVBQEoUkM139rBAAAAAAAAA8D+3nuiSRjFCQAO+ziDI07BAAAAAAAAAAECw33YitG1CQFfrMUjzsbBAAAAAAAAACEBdCV9l5qpCQPz+qyXzkLBAAAAAAAAAEEAxZsUWkehCQEao+4C+cLBAAAAAAAAAFED/K9TSJidDQHiaWzZVUbBAAAAAAAAAGEAH5/0h7mRDQEQdlKKuMrBAAAAAAAAAHEA3briD36VDQFOV6F3AFLBAAAAAAAAAIECVxlRhIOZDQDWnF3oZ769AAAAAAAAAIkBw3JF41iZEQFaBi4ATtq9AAAAAAAAAJEDWK1vaPGhEQGm0u1xqfq9AAAAAAAAAJkD8LPcHK6pEQFuwESgZSK9AAAAAAAAAKED9C3dyqOxEQDHEAeEPE69AAAAAAAAAKkC4EiQOsS9FQLi4JtBI365AAAAAAAAALECic9nEPnNFQNBo5TfBrK5AAAAAAAAALkCZPKPG6bhFQKZ390dqe65AAAAAAAAAMED1gCCD7PtFQHX624ozS65AAAAAAAAAMUBYm6YLxEFGQF2F6s8tHK5AAAAAAAAAMkDRwgkOgoZGQAoigo087q1AAAAAAAAAM0D3FUFQl8xGQJPjtP9jwa1AAAAAAAAANEB0ss7VFhRHQNxQHo6ela1AAAAAAAAANUCTeMGY01lHQLltWDneaq1AAAAAAAAANkA9EaEii6FHQBlJCtQkQa1AAAAAAAAAN0Aj40Y4aOlHQGrGCEZfGK1AAAAAAAAAOEAHAO7trjFIQCrh0MCi8KxAAAAAAAAAOUBMVaLSFXtIQBeaVEjMyaxAAAAAAAAAOkBCzs2Ke8NIQCn6GnLio6xAAAAAAAAAO0A8pGExKw5JQKYfW5fnfqxAAAAAAAAAPEA2VsJM8FZJQDP+h9rOWqxAAAAAAAAAPUApqrydNaFJQBoYfjySN6xAAAAAAAAAPkAiuSER4etJQCiFuBQyFaxAAAAAAAAAP0Cd27WD3jZKQALX+3ms86tAAAAAAAAAQEB8sSokUIJKQJuB6P740qtAAAAAAACAQEAYXEWug81KQFrabsYVs6tAAAAAAAAAQUD7h5/0fRlLQPkDOdj5k6tAAAAAAACAQUBRFOrdhmZLQPZNKjuidatAAAAAAAAAQkDrFUAAQrNLQKKZX6MYWKtAAAAAAACAQkBv8pI4TABMQNckA85EO6tAAAAAAAAAQ0B8gYlcqE1MQDD7GIktH6tAAAAAAACAQ0AIrKCyz5xMQMd5/wjYA6tAAAAAAAAARECGIWUcOulMQNmaVPgp6apAAAAAAACAREAoIYs+czdNQAtBkvE6z6pAAAAAAAAARUBy/vjp+YVNQN8FtMfytapAAAAAAACARUATs9Teg9RNQIwP4vxhnapAAAAAAAAARkBy7tWp5SROQJkUhER3hapAAAAAAACARkA+BDwMFHNOQJGq7FosbqpAAAAAAAAAR0D25CVFosJOQDm12SOPV6pAAAAAAACAR0DyP+2lahJPQM2OW3OQQapAAAAAAAAASEBnqGJfamJPQJGHHZYvLKpAAAAAAACASEC+e2qQorJPQPesnbd2F6pAAAAAAAAASUDpPGLAhgFQQKWSXHtPA6pAAAAAAACASUA6Ym1z2ilQQDqH7ufK76lAAAAAAAAASkCO22t3SlJQQCCUMHXP3KlAAAAAAACASkCb1g8TzHpQQD+daOh3yqlAAAAAAAAAS0DM8pZQbaNQQE2ZHx2yuKlAAAAAAACAS0Bb3RVCJcxQQGnMirxzp6lAAAAAAAAATEDni5qr8fRQQEMM74nNlqlAAAAAAACATEAHXquo1h1RQGDVmt2thqlAAAAAAAAATUBDwSqUzUZRQLK5rNQgd6lAAAAAAACATUCL27Qn3G9RQMmpkS4baKlAAAAAAAAATkCyy/Kf/ZhRQIQ9IiKiWalAAAAAAACATkBwe9jMmsFRQAAyPPSxS6lAAAAAAAAAT0Bw6pIpl+tRQLK/yNVCPqlAAAAAAACAT0BVD4zQzBRSQC2LfG9ZMalAAAAAAAAAUEAsu8RtND5SQHeVpg3yJKlAAAAAAABAUEB3bn5aqGdSQKZ8SjwVGalAAAAAAACAUEAL9zefLZFSQLO+SdiwDalAAAAAAADAUECMb0ZyjrpSQF9+vYrOAqlAAAAAAAAAUUAKkZV0Y+RSQCQAE31t+KhAAAAAAABAUUAUGdJN7A1TQD0t4fqG7qhAAAAAAACAUUBuL6K7yDdTQHj+Fyki5ahAAAAAAADAUUDoI5m9jmFTQO2Ww5gz3KhAAAAAAAAAUkB7p11vXYtTQIWuMOnJ06hAAAAAAABAUkC15v2rMLVTQDbVZ5jWy6hAAAAAAACAUkDOqxGKGN9TQK27LoJbxKhAAAAAAADAUkCMK9BRDwlUQIMv/rVVvahAAAAAAAAAU0BKv16u9DJUQFOXrljHtqhAAAAAAABAU0BYgCo71lxUQMVyX4m2sKhAAAAAAACAU0CkmbyH64ZUQNKo4Ewaq6hAAAAAAADAU0AUhDWo8LBUQL8ylQftpahAAAAAAAAAVEBDyUlh+9pUQOolf6k4oahAAAAAAABAVEAmLnXFCAVVQO/lTO34nKhAAAAAAACAVECtMxvfGy9VQGol5qUvmahAAAAAAADAVEA5UoyyMllVQGhL2nXglahAAAAAAAAAVUBuM+2pS4NVQAqZbfP0kqhAAAAAAABAVUBLCGaaZa1VQFw/o8GBkKhAAAAAAACAVUDnkA8VgtdVQE0ZmZOAjqhAAAAAAADAVUA9/+JAogFWQIxZABv6jKhAAAAAAAAAVkBuIxugvytWQBNqwwbfi6hAAAAAAABAVkBIvzJF31VWQN7OY3Mui6hAAAAAAACAVkAAAAAAAIBWQPIhQHL4iqhA",
          "dtype": "f8",
          "shape": "91, 3"
         },
         "hovertemplate": "Horizontal Distance (m)=%{x}<br>Vertical Distance (m)=%{y}<br>slant_angle_deg=%{customdata[0]}<br>launch_angle_deg=%{customdata[1]}<br>max_dist_m=%{customdata[2]}<extra></extra>",
         "legendgroup": "",
         "line": {
          "color": "#636efa",
          "dash": "solid"
         },
         "marker": {
          "symbol": "circle"
         },
         "mode": "lines",
         "name": "",
         "orientation": "v",
         "showlegend": false,
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "xaxis": "x",
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         },
         "yaxis": "y"
        }
       ],
       "layout": {
        "legend": {
         "tracegroupgap": 0
        },
        "margin": {
         "t": 50
        },
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Reachable Range Envelope",
         "x": 0.5
        },
        "xaxis": {
         "anchor": "y",
         "constrain": "domain",
         "domain": [
          0,
          1
         ],
         "title": {
          "text": "Horizontal Distance (m)"
         }
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0,
          1
         ],
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Calculate the max range for a variety of slant angles to map the envelope.\n",
    "slant_angles_deg = np.linspace(0, 90, 91)\n",
    "envelope_points = []\n",
    "shot = create_shot()\n",
    "for slant_angle_deg in tqdm(slant_angles_deg, desc=\"Slant angles\"):\n",
    "    shot.slant_angle = Angular.Degree(slant_angle_deg)\n",
    "    try:\n",
    "        max_dist, launch_angle = calc.find_max_range(shot)\n",
    "        \n",
    "        slant_angle_rad = shot.slant_angle >> Angular.Radian\n",
    "        x = (max_dist >> Distance.Meter) * math.cos(slant_angle_rad)\n",
    "        y = (max_dist >> Distance.Meter) * math.sin(slant_angle_rad)\n",
    "        \n",
    "        envelope_points.append({\n",
    "            'slant_angle_deg': slant_angle_deg,\n",
    "            'launch_angle_deg': launch_angle >> Angular.Degree,\n",
    "            'max_dist_m': max_dist >> Distance.Meter,\n",
    "            'x': x, 'y': y\n",
    "        })\n",
    "    except Exception as e:\n",
    "        print(f\"Could not determine range for slant angle {slant_angle_deg:.1f}: {e}\")\n",
    "\n",
    "envelope_df = pd.DataFrame(envelope_points)\n",
    "display(envelope_df.head())\n",
    "display(envelope_df.tail())\n",
    "# --- Visualize the envelope ---\n",
    "fig = px.line(\n",
    "    envelope_df.sort_values('slant_angle_deg'), \n",
    "    x='x', y='y', \n",
    "    title='Reachable Range Envelope',\n",
    "    labels={'x': 'Horizontal Distance (m)', 'y': 'Vertical Distance (m)'},\n",
    "    hover_data=['slant_angle_deg', 'launch_angle_deg', 'max_dist_m']\n",
    ")\n",
    "fig.update_layout(\n",
    "    yaxis=dict(scaleanchor=\"x\", scaleratio=1, dtick=1000),\n",
    "    xaxis=dict(constrain='domain'),\n",
    "    title_x=0.5,\n",
    "    margin=dict(t=50)\n",
    ")\n",
    "fig.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cb99aa91",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "hovertemplate": "Slant Angle (deg)=%{x}<br>Launch Angle (deg)=%{y}<extra></extra>",
         "legendgroup": "",
         "line": {
          "color": "#636efa",
          "dash": "solid"
         },
         "marker": {
          "symbol": "circle"
         },
         "mode": "lines",
         "name": "",
         "orientation": "v",
         "showlegend": false,
         "type": "scatter",
         "x": {
          "bdata": "AAAAAAAAAAAAAAAAAADwPwAAAAAAAABAAAAAAAAACEAAAAAAAAAQQAAAAAAAABRAAAAAAAAAGEAAAAAAAAAcQAAAAAAAACBAAAAAAAAAIkAAAAAAAAAkQAAAAAAAACZAAAAAAAAAKEAAAAAAAAAqQAAAAAAAACxAAAAAAAAALkAAAAAAAAAwQAAAAAAAADFAAAAAAAAAMkAAAAAAAAAzQAAAAAAAADRAAAAAAAAANUAAAAAAAAA2QAAAAAAAADdAAAAAAAAAOEAAAAAAAAA5QAAAAAAAADpAAAAAAAAAO0AAAAAAAAA8QAAAAAAAAD1AAAAAAAAAPkAAAAAAAAA/QAAAAAAAAEBAAAAAAACAQEAAAAAAAABBQAAAAAAAgEFAAAAAAAAAQkAAAAAAAIBCQAAAAAAAAENAAAAAAACAQ0AAAAAAAABEQAAAAAAAgERAAAAAAAAARUAAAAAAAIBFQAAAAAAAAEZAAAAAAACARkAAAAAAAABHQAAAAAAAgEdAAAAAAAAASEAAAAAAAIBIQAAAAAAAAElAAAAAAACASUAAAAAAAABKQAAAAAAAgEpAAAAAAAAAS0AAAAAAAIBLQAAAAAAAAExAAAAAAACATEAAAAAAAABNQAAAAAAAgE1AAAAAAAAATkAAAAAAAIBOQAAAAAAAAE9AAAAAAACAT0AAAAAAAABQQAAAAAAAQFBAAAAAAACAUEAAAAAAAMBQQAAAAAAAAFFAAAAAAABAUUAAAAAAAIBRQAAAAAAAwFFAAAAAAAAAUkAAAAAAAEBSQAAAAAAAgFJAAAAAAADAUkAAAAAAAABTQAAAAAAAQFNAAAAAAACAU0AAAAAAAMBTQAAAAAAAAFRAAAAAAABAVEAAAAAAAIBUQAAAAAAAwFRAAAAAAAAAVUAAAAAAAEBVQAAAAAAAgFVAAAAAAADAVUAAAAAAAABWQAAAAAAAQFZAAAAAAACAVkA=",
          "dtype": "f8"
         },
         "xaxis": "x",
         "y": {
          "bdata": "aNL/fWj1QUC3nuiSRjFCQLDfdiK0bUJAXQlfZeaqQkAxZsUWkehCQP8r1NImJ0NAB+f9Ie5kQ0A3briD36VDQJXGVGEg5kNAcNyReNYmREDWK1vaPGhEQPws9wcrqkRA/Qt3cqjsREC4EiQOsS9FQKJz2cQ+c0VAmTyjxum4RUD1gCCD7PtFQFibpgvEQUZA0cIJDoKGRkD3FUFQl8xGQHSyztUWFEdAk3jBmNNZR0A9EaEii6FHQCPjRjho6UdABwDu7a4xSEBMVaLSFXtIQELOzYp7w0hAPKRhMSsOSUA2VsJM8FZJQCmqvJ01oUlAIrkhEeHrSUCd27WD3jZKQHyxKiRQgkpAGFxFroPNSkD7h5/0fRlLQFEU6t2GZktA6xVAAEKzS0Bv8pI4TABMQHyBiVyoTUxACKygss+cTECGIWUcOulMQCghiz5zN01Acv746fmFTUATs9Teg9RNQHLu1anlJE5APgQ8DBRzTkD25CVFosJOQPI/7aVqEk9AZ6hiX2piT0C+e2qQorJPQOk8YsCGAVBAOmJtc9opUECO22t3SlJQQJvWDxPMelBAzPKWUG2jUEBb3RVCJcxQQOeLmqvx9FBAB16rqNYdUUBDwSqUzUZRQIvbtCfcb1FAssvyn/2YUUBwe9jMmsFRQHDqkimX61FAVQ+M0MwUUkAsu8RtND5SQHduflqoZ1JAC/c3ny2RUkCMb0ZyjrpSQAqRlXRj5FJAFBnSTewNU0BuL6K7yDdTQOgjmb2OYVNAe6ddb12LU0C15v2rMLVTQM6rEYoY31NAjCvQUQ8JVEBKv16u9DJUQFiAKjvWXFRApJm8h+uGVEAUhDWo8LBUQEPJSWH72lRAJi51xQgFVUCtMxvfGy9VQDlSjLIyWVVAbjPtqUuDVUBLCGaaZa1VQOeQDxWC11VAPf/iQKIBVkBuIxugvytWQEi/MkXfVVZAAAAAAACAVkA=",
          "dtype": "f8"
         },
         "yaxis": "y"
        },
        {
         "line": {
          "color": "red",
          "dash": "dash"
         },
         "mode": "lines",
         "showlegend": false,
         "type": "scatter",
         "x": [
          0,
          90
         ],
         "y": [
          35.91725134841255,
          90
         ]
        }
       ],
       "layout": {
        "legend": {
         "tracegroupgap": 0
        },
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Launch Angle vs Slant Angle"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          1
         ],
         "title": {
          "text": "Slant Angle (deg)"
         }
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0,
          1
         ],
         "title": {
          "text": "Launch Angle (deg)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import plotly.express as px\n",
    "import plotly.graph_objects as go\n",
    "\n",
    "fig = px.line(\n",
    "    envelope_df,\n",
    "    x='slant_angle_deg',\n",
    "    y='launch_angle_deg',\n",
    "    title='Launch Angle vs Slant Angle',\n",
    "    labels={'slant_angle_deg': 'Slant Angle (deg)', 'launch_angle_deg': 'Launch Angle (deg)'}\n",
    ")\n",
    "\n",
    "# Add a chord (straight line) connecting the first and last points\n",
    "fig.add_trace(go.Scatter(\n",
    "    x=[envelope_df['slant_angle_deg'].iloc[0], envelope_df['slant_angle_deg'].iloc[-1]],\n",
    "    y=[envelope_df['launch_angle_deg'].iloc[0], envelope_df['launch_angle_deg'].iloc[-1]],\n",
    "    mode='lines',\n",
    "    line=dict(color='red', dash='dash'),\n",
    "    showlegend=False,\n",
    "))\n",
    "fig.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a16acd7",
   "metadata": {},
   "source": [
    "# Define sample region\n",
    "We'll define several sample sizes.  Use the smallest to make sure things are working; the largest can take hours to complete."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4da9d120",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_sample_points(envelope_df, min_distance: float=500, lin_density: int=50, extreme_only: bool=False):\n",
    "    \"\"\"Generate sample points within the reachable range envelope.\"\"\"\n",
    "    # Create a polygon from the envelope\n",
    "    x_min, x_max = 0., envelope_df['x'].max()\n",
    "    y_min, y_max = 0., envelope_df['y'].max()\n",
    "    if extreme_only:  # Only cover points outside the chord\n",
    "        envelope = envelope_df[['x', 'y']].values\n",
    "    else:\n",
    "        envelope = np.vstack([[0, -1], envelope_df[['x', 'y']].values])\n",
    "    envelope_polygon = Polygon(envelope)\n",
    "\n",
    "    x_points = np.linspace(x_min, x_max, lin_density)\n",
    "    y_points = np.linspace(y_min, y_max, lin_density)\n",
    "    test_points = np.array(np.meshgrid(x_points, y_points)).T.reshape(-1, 2)\n",
    "\n",
    "    # Filter points that are inside the envelope\n",
    "    use_points = []\n",
    "    for p in test_points:\n",
    "        point = Point(p)\n",
    "        if point.within(envelope_polygon) and point.distance(Point(0,0)) > min_distance:\n",
    "            use_points.append({'x': p[0], 'y': p[1]})\n",
    "\n",
    "    return use_points\n",
    "\n",
    "def plot_sample_points(envelope_df, point_list):\n",
    "    fig = go.Figure()\n",
    "    fig.add_trace(go.Scatter(x=envelope_df['x'], y=envelope_df['y'], mode='lines', name='Envelope', line=dict(color='black')))\n",
    "    fig.add_trace(go.Scatter(x=point_list['x'], y=point_list['y'], mode='markers', name='Test Points', marker=dict(size=2)))\n",
    "    fig.update_layout(\n",
    "        title=str(len(point_list))+' Selected Test Points within Envelope',\n",
    "        yaxis=dict(scaleanchor=\"x\", scaleratio=1, dtick=1000),\n",
    "        xaxis=dict(constrain='domain', range=[0, envelope_df['x'].max()]),\n",
    "        title_x=0.5,\n",
    "        margin=dict(t=50)\n",
    "    )\n",
    "    fig.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4fcc1aef",
   "metadata": {},
   "source": [
    "## Small Sample (400 pts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "241cace3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "line": {
          "color": "black"
         },
         "mode": "lines",
         "name": "Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        },
        {
         "marker": {
          "size": 2
         },
         "mode": "markers",
         "name": "Test Points",
         "type": "scatter",
         "x": {
          "bdata": "[encoded data, 4312 characters]",
          "dtype": "f8"
         },
         "y": {
          "bdata": "[encoded data, 4312 characters]",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "margin": {
         "t": 50
        },
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "404 Selected Test Points within Envelope",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "range": [
          0,
          4342.467980389551
         ]
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "small_sample = get_sample_points(envelope_df, min_distance=2000, lin_density=30)\n",
    "plot_sample_points(envelope_df, pd.DataFrame(small_sample))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41a6ec6a",
   "metadata": {},
   "source": [
    "## Big Sample (5,000 pts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f9932650",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "line": {
          "color": "black"
         },
         "mode": "lines",
         "name": "Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        },
        {
         "marker": {
          "size": 2
         },
         "mode": "markers",
         "name": "Test Points",
         "type": "scatter",
         "x": {
          "bdata": "[encoded data, 53388 characters]",
          "dtype": "f8"
         },
         "y": {
          "bdata": "[encoded data, 53388 characters]",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "margin": {
         "t": 50
        },
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "5005 Selected Test Points within Envelope",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "range": [
          0,
          4342.467980389551
         ]
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "big_sample = get_sample_points(envelope_df, min_distance=565, lin_density=86)\n",
    "plot_sample_points(envelope_df, pd.DataFrame(big_sample))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4052c179",
   "metadata": {},
   "source": [
    "## Huge Sample (20,000 pts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "200447e9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "line": {
          "color": "black"
         },
         "mode": "lines",
         "name": "Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        },
        {
         "marker": {
          "size": 2
         },
         "mode": "markers",
         "name": "Test Points",
         "type": "scatter",
         "x": {
          "bdata": "[encoded data, 214112 characters]",
          "dtype": "f8"
         },
         "y": {
          "bdata": "[encoded data, 214112 characters]",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "margin": {
         "t": 50
        },
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "20073 Selected Test Points within Envelope",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "range": [
          0,
          4342.467980389551
         ]
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "huge_sample = get_sample_points(envelope_df, min_distance=0, lin_density=169)\n",
    "plot_sample_points(envelope_df, pd.DataFrame(huge_sample))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21766b7c",
   "metadata": {},
   "source": [
    "# Define Visualizations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "027517f1",
   "metadata": {},
   "source": [
    "### plotly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "026eea68",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_test_results(df, envelope_df, title_str, show=True, legend=True):\n",
    "    fig = go.Figure()\n",
    "    converged_df = df[df['solution'].notna()].copy()\n",
    "    failed_df = df[df['solution'].isna()].copy()\n",
    "    if not converged_df.empty:\n",
    "        heatmap_data = converged_df.pivot_table(index='y', columns='x', values='iterations', aggfunc='mean')\n",
    "        # Normalize color stops\n",
    "        green_stop = 3 / 50\n",
    "        blue_stop = 20 / 50\n",
    "        red_stop = 48 / 50\n",
    "        colorscale = [\n",
    "            [0.0, \"#00FF00\"],         # Green at min\n",
    "            [green_stop, \"#00FF00\"],  # Green up to z=3\n",
    "            [blue_stop, \"#1212FF\"],   # Blue at z=20\n",
    "            [red_stop, \"#FF0000\"],    # Red at z=48\n",
    "            [1.0, \"#FF0000\"]          # Red at max\n",
    "        ]\n",
    "        fig.add_trace(\n",
    "            go.Heatmap(\n",
    "                z=heatmap_data.values,\n",
    "                x=heatmap_data.columns,\n",
    "                y=heatmap_data.index,\n",
    "                colorscale=colorscale,#[[0.0, \"#00FF00\"], [0.5, \"#1212FF\"], [1.0, \"#FF0000\"]],\n",
    "                zmin=0, zmax=50,\n",
    "                colorbar=dict(title='Iterations', x=.85),\n",
    "                name='Converged',\n",
    "                hoverongaps=False,\n",
    "                hovertemplate='x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>'\n",
    "            )\n",
    "        )\n",
    "    if not failed_df.empty:\n",
    "        fig.add_trace(  # Add failed points, colored white\n",
    "            go.Scatter(\n",
    "                x=failed_df['x'], y=failed_df['y'], mode='markers',\n",
    "                marker=dict(color='white', symbol='square', size=7, line=dict(color='black', width=1)),\n",
    "                name='Failed to converge',\n",
    "                hoverinfo='text',\n",
    "                text=[f\"x: {r['x']:.2f}<br>y: {r['y']:.2f}<br>{r['error']}\" for i, r in failed_df.iterrows()]\n",
    "            )\n",
    "        )\n",
    "    fig.add_trace(  # Add the reachable envelope\n",
    "        go.Scatter(\n",
    "            x=envelope_df['x'], y=envelope_df['y'], mode='lines', \n",
    "            name='Reachable Envelope',\n",
    "            line=dict(color='black', width=2)\n",
    "        )\n",
    "    )\n",
    "    fig.update_layout(\n",
    "        title=title_str,\n",
    "        xaxis_title='Horizontal Distance to Target (m)',\n",
    "        yaxis_title='Vertical Distance to Target (m)',\n",
    "        yaxis=dict(scaleanchor=\"x\", scaleratio=1, dtick=1000),\n",
    "        xaxis=dict(constrain='domain'),\n",
    "        title_x=0.5,\n",
    "        legend=dict(x=1, y=1, traceorder='normal'),\n",
    "        showlegend=True if legend else False,\n",
    "        margin=dict(t=50)\n",
    "    )\n",
    "    if show:\n",
    "        fig.show()\n",
    "    return fig"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7072f1f",
   "metadata": {},
   "source": [
    "## matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f14a5d28",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from matplotlib.colors import LinearSegmentedColormap\n",
    "\n",
    "def pyplot_test_results(df, envelope_df, title_str, show=True, legend=True):\n",
    "    converged_df = df[df['solution'].notna()].copy()\n",
    "    failed_df = df[df['solution'].isna()].copy()\n",
    "    # Pivot for heatmap\n",
    "    heatmap_data = converged_df.pivot_table(index='y', columns='x', values='iterations', aggfunc='mean')\n",
    "    x = heatmap_data.columns.values\n",
    "    y = heatmap_data.index.values\n",
    "    z = heatmap_data.values\n",
    "    # Normalize color stops    \n",
    "    green_stop = 3 / 50\n",
    "    blue_stop = 20 / 50\n",
    "    red_stop = 48 / 50\n",
    "    colors = [\n",
    "        (0.0, \"#00FF00\"),\n",
    "        (green_stop, \"#00FF00\"),\n",
    "        (blue_stop, \"#1212FF\"),\n",
    "        (red_stop, \"#FF0000\"),\n",
    "        (1.0, \"#FF0000\")\n",
    "    ]\n",
    "    cmap = LinearSegmentedColormap.from_list(\"custom\", colors)\n",
    "\n",
    "    fig, ax = plt.subplots(figsize=(8, 6))\n",
    "    mesh = ax.pcolormesh(x, y, z, cmap=cmap, shading='auto', vmin=0, vmax=50)\n",
    "    cbar = fig.colorbar(mesh, ax=ax, label='Iterations', fraction=0.044, pad=0.04, aspect=15)\n",
    "    cbar.ax.set_ylabel('Iterations')\n",
    "    cbar.set_ticks(np.arange(0, 51, 10))\n",
    "    \n",
    "    if not failed_df.empty:  # Overlay failed points (white squares with black edge)\n",
    "        ax.scatter(failed_df['x'], failed_df['y'], color='white', edgecolor='black', marker='s', s=49, label='Failed to converge', zorder=3)\n",
    "    ax.plot(envelope_df['x'], envelope_df['y'], color='black', linewidth=2, label='Reachable Envelope', zorder=4)\n",
    "    ax.set_title(title_str, fontsize=16)\n",
    "    ax.set_xlabel('Horizontal Distance to Target (m)')\n",
    "    ax.set_ylabel('Vertical Distance to Target (m)')\n",
    "    ax.set_aspect('equal', adjustable='box')\n",
    "    ax.set_yticks(np.arange(y.min(), y.max()+1, 1000))\n",
    "    ax.grid(True)\n",
    "    ax.set_axisbelow(True)\n",
    "    ax.set_xlim(left=0)\n",
    "    if legend:\n",
    "        ax.legend(loc='upper right')\n",
    "    plt.tight_layout()\n",
    "    if show:\n",
    "        plt.show()\n",
    "    return fig"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35f8cc87",
   "metadata": {},
   "source": [
    "## Define plot_samples()\n",
    "Pick the package(s) and file output(s) you want:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "id": "5f342936",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_samples(df, filename=None, title_str=\"Iterations to find zero for target point\", show_legend=True):\n",
    "    \"\"\"Plot the test results.  Output to filename if provided.\"\"\"\n",
    "    # plotly\n",
    "    p = plot_test_results(df, envelope_df, title_str, legend=show_legend)\n",
    "    if filename:\n",
    "        p.write_html(filename+'.html')\n",
    "    # matplotlib\n",
    "    fig = pyplot_test_results(df, envelope_df, title_str, legend=show_legend)\n",
    "    if filename:\n",
    "        fig.savefig(filename+'.svg', bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65cfb81e",
   "metadata": {},
   "source": [
    "# Baseline\n",
    "\n",
    "## Engine Constraints\n",
    "\n",
    "The iterative zeroing algorithm takes a test shot (starting with launch angle equal to the slant angle to the target), observes how far the projectile was from the target when it reached the slant distance, and then calculates an adjustment based on that.  If the calculator isn't allowed to compute the trajectory all the way to the slant distance then it starts in a degraded state.  (And if we set `cMaximumDrop=0` then the `zero()` method can't even get started and will fail.)  To avoid this, let's check how much drop we need to allow the calculator to see in the most extreme case.\n",
    "\n",
    "_When we launch at a look angle of zero: How far do we drop before reaching max horizontal distance of this projectile?_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "af81bf64",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max horizontal range is 4342.47m.  Launching at 0°, when trajectory x=4342.47m, y=-2078.12m\n"
     ]
    }
   ],
   "source": [
    "max_x_m = envelope_df.x.max()\n",
    "max_x = Distance.Meter(max_x_m)\n",
    "max_x_ft = max_x >> Distance.Foot\n",
    "conf = BaseEngineConfigDict(\n",
    "    cMinimumVelocity=0,\n",
    "    cMinimumAltitude=-max_x_ft/2.0,\n",
    "    cMaximumDrop=max_x_ft/2.0,\n",
    ")\n",
    "calc = Calculator(config=conf, engine=\"scipy_engine\")\n",
    "t, e = must_fire(calc, create_shot(), trajectory_range=max_x, trajectory_step=max_x)\n",
    "if e is not None:\n",
    "    print(f\"Error: {e}\")\n",
    "print(f'Max horizontal range is {max_x_m:.2f}m.  Launching at 0°, when trajectory x={t[-1].distance >> Distance.Meter:.2f}m, y={t[-1].height >> Distance.Meter:.2f}m')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b433ad9",
   "metadata": {},
   "source": [
    "Conclusion: **On the longest possible shot, when launch from the look-angle to the target, we can get a trajectory that reaches the target horizontal distance if calculator is allowed to drop half of the horizontal distance.**  This is the heuristic we'll use for setting the `cMaximumDrop` here.\n",
    "\n",
    "## Define Zero Test Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0972755c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def zero_test(x_m: float, y_m: float, max_iterations: int=50,\n",
    "              cZeroFindingAccuracy: float=0.000005, sensitivity_limit: float=-0.5, calc_config=None):\n",
    "    target_dist = Distance.Meter(math.sqrt(x_m**2 + y_m**2))\n",
    "    slant_range_ft = target_dist >> Distance.Foot\n",
    "    slant_angle_rad = math.atan2(y_m, x_m)\n",
    "    slant_angle = Angular.Radian(slant_angle_rad)\n",
    "    shot = create_shot()\n",
    "    shot.slant_angle = slant_angle\n",
    "\n",
    "    target_x_ft = Distance.Meter(x_m) >> Distance.Foot\n",
    "    iterations_count = 0\n",
    "    range_error_ft = 9e9  # Absolute value of error from target distance along sight line\n",
    "    prev_range_error_ft = 9e9\n",
    "    prev_height_error_ft = 9e9\n",
    "    damping_factor = 1.0  # Start with no damping\n",
    "    damping_rate = 0.7  # Damping rate for correction\n",
    "    last_correction = 0.0\n",
    "    height_error_ft = cZeroFindingAccuracy * 2  # Absolute value of error from sight line in feet at zero distance\n",
    "    warned = False\n",
    "    sensitive = []  # Record sensitive values encountered\n",
    "    damping = []  # Record damping values applied\n",
    "\n",
    "    if calc_config is None:\n",
    "        calc_config = BaseEngineConfigDict(\n",
    "            cMinimumVelocity=0,\n",
    "            cMinimumAltitude=-target_x_ft/2.0,\n",
    "            cMaximumDrop=target_x_ft/2.0,\n",
    "        )\n",
    "    calc = Calculator(config=calc_config, engine=\"scipy_engine\")\n",
    "    props = calc._init_trajectory(shot)\n",
    "\n",
    "    while iterations_count < max_iterations:\n",
    "        iterations_count += 1\n",
    "        try:\n",
    "            t = calc._integrate(props, target_x_ft, target_x_ft, filter_flags=TrajFlag.NONE)[-1]\n",
    "            height_diff_ft = t.slant_height >> Distance.Foot\n",
    "            look_dist_ft = t.slant_distance >> Distance.Foot\n",
    "            range_diff_ft = look_dist_ft - slant_range_ft\n",
    "            range_error_ft = math.fabs(range_diff_ft)\n",
    "            height_error_ft = math.fabs(height_diff_ft)\n",
    "            trajectory_angle = t.angle >> Angular.Radian  # Trajectory angle at target distance\n",
    "            sensitivity = math.tan(props.barrel_elevation_rad - slant_angle_rad) * math.tan(trajectory_angle - slant_angle_rad)\n",
    "            if sensitivity < sensitivity_limit:\n",
    "                sensitive.append(sensitivity)\n",
    "                if not warned:\n",
    "                    logger.info(f\"Sensitivity {sensitivity} critical for point ({x_m}, {y_m}) after {iterations_count} iterations\")\n",
    "                    warned = True\n",
    "                denominator = look_dist_ft\n",
    "            else:\n",
    "                denominator = look_dist_ft * (1 + sensitivity)\n",
    "            if abs(denominator) > 1e-9:\n",
    "                correction = -height_diff_ft / denominator\n",
    "            else:\n",
    "                raise ZeroFindingError(height_error_ft, iterations_count, Angular.Radian(props.barrel_elevation_rad),\n",
    "                      'Correction denominator is zero')\n",
    "\n",
    "            if range_error_ft > calc.ALLOWED_ZERO_ERROR_FEET:\n",
    "                # We're still trying to reach zero_distance\n",
    "                if range_error_ft > prev_range_error_ft - 1e-6:  # We're not getting closer to zero_distance\n",
    "                    raise ZeroFindingError(range_error_ft, iterations_count, Angular.Radian(props.barrel_elevation_rad),\n",
    "                          'Distance non-convergent')\n",
    "            elif height_error_ft > math.fabs(prev_height_error_ft):  # Error is increasing, we are diverging\n",
    "                damping_factor *= damping_rate  # Apply damping to prevent overcorrection\n",
    "                if damping_factor < 0.3:\n",
    "                    raise ZeroFindingError(height_error_ft, iterations_count, Angular.Radian(props.barrel_elevation_rad),\n",
    "                          'Error non-convergent')\n",
    "                logger.info(f'Tightened damping factor to {damping_factor:.2f} for point ({x_m}, {y_m}) after {iterations_count} iterations')\n",
    "                damping.append(damping_factor)\n",
    "                props.barrel_elevation_rad -= last_correction  # Revert previous adjustment\n",
    "                correction = last_correction\n",
    "            elif damping_factor < 1.0:\n",
    "                logger.info(f'Reseting damping factor to 1.0 at iteration {iterations_count}')\n",
    "                damping_factor = 1.0\n",
    "\n",
    "            prev_range_error_ft = range_error_ft\n",
    "            prev_height_error_ft = height_error_ft\n",
    "\n",
    "            if height_error_ft > cZeroFindingAccuracy or range_error_ft > calc.ALLOWED_ZERO_ERROR_FEET:\n",
    "                # Adjust barrel elevation to reduce error at zero distance\n",
    "                applied_correction = correction * damping_factor\n",
    "                props.barrel_elevation_rad += applied_correction\n",
    "                last_correction = applied_correction\n",
    "            else:  # We are close enough to zero, stop iterating\n",
    "                result = {\n",
    "                    'x': x_m, 'y': y_m,\n",
    "                    'iterations': iterations_count,\n",
    "                    'solution': props.barrel_elevation_rad,\n",
    "                    'sensitivity': sensitive,\n",
    "                    'damping': damping,\n",
    "                    'error': None\n",
    "                }\n",
    "                break\n",
    "        except Exception as e:\n",
    "            result = {\n",
    "                'x': x_m, 'y': y_m,\n",
    "                'iterations': iterations_count,\n",
    "                'solution': None,\n",
    "                'sensitivity': sensitive,\n",
    "                'damping': damping,\n",
    "                'error': e\n",
    "            }\n",
    "            break\n",
    "    if iterations_count >= max_iterations:\n",
    "        result = {\n",
    "            'x': x_m, 'y': y_m,\n",
    "            'iterations': iterations_count,\n",
    "            'solution': None,\n",
    "            'sensitivity': sensitive,\n",
    "            'damping': damping,\n",
    "            'error': 'Max iterations reached'\n",
    "        }\n",
    "    return result"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc0bf2c7",
   "metadata": {},
   "source": [
    "## Baseline (small sample)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "79a3885c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c9e9a45b12e4415980f46cdf88fd2ee0",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/404 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(small_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(zero_test(point['x'], point['y']))\n",
    "baseline_small_df = pd.DataFrame(results)\n",
    "baseline_small_df.to_csv('ZeroSmallBaseline.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "id": "47801ce0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0,
           "#00FF00"
          ],
          [
           0.38095238095238093,
           "#1212FF"
          ],
          [
           1,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "CyiWVbC3YkALKJZVsLdyQBA8YYCIE3xACyiWVbC3gkAOsvtqnGWHQBA8YYCIE4xACmPjSrpgkEALKJZVsLeSQAztSGCmDpVADrL7apxll0APd651kryZQBA8YYCIE5xAEgEUi35qnkAKY+NKumCgQIrFPFA1jKFACyiWVbC3okCMiu9aK+OjQAztSGCmDqVAjU+iZSE6pkAOsvtqnGWnQI4UVXAXkahAD3eudZK8qUCQ2Qd7DeiqQBA8YYCIE6xAkZ66hQM/rUASARSLfmquQJNjbZD5la9ACmPjSrpgsEA=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAAAUbFjW7hRbQBRsWNbuFGtAD1HCILNPdEAUbFjW7hR7QIxD90UV7YBAD1HCILNPhECSXo37ULKHQBRsWNbuFItAlnkjsYx3jkCMQ/dFFe2QQE7KXDNknpJAD1HCILNPlEDQ1ycOAgGWQJJejftQspdAU+Xy6J9jmUAUbFjW7hSbQNXyvcM9xpxAlnkjsYx3nkAsgETPbRSgQIxD90UV7aBA7QaqvLzFoUBOylwzZJ6iQK6ND6oLd6NAD1HCILNPpEBwFHWXWiilQNDXJw4CAaZAMZvahKnZpkCSXo37ULKnQA==",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 8664 characters]",
          "dtype": "f8",
          "shape": "29, 28"
         }
        },
        {
         "hoverinfo": "text",
         "marker": {
          "color": "white",
          "line": {
           "color": "black",
           "width": 1
          },
          "size": 7,
          "symbol": "square"
         },
         "mode": "markers",
         "name": "Failed to converge",
         "text": [
          "x: 149.74<br>y: 2816.50<br>Distance non-convergent. Vertical error 0.013747036819040659 feet with 1.527181rad elevation, after 14 iterations.",
          "x: 898.44<br>y: 3033.16<br>Max iterations reached",
          "x: 2395.84<br>y: 2383.20<br>Max iterations reached",
          "x: 2545.58<br>y: 2274.87<br>Max iterations reached",
          "x: 2695.32<br>y: 2166.54<br>Max iterations reached",
          "x: 3144.55<br>y: 1733.23<br>Max iterations reached",
          "x: 3444.03<br>y: 1408.25<br>Max iterations reached",
          "x: 4042.99<br>y: 541.64<br>Max iterations reached"
         ],
         "type": "scatter",
         "x": {
          "bdata": "CyiWVbC3YkAQPGGAiBOMQAsollWwt6JAjIrvWivjo0AM7Uhgpg6lQI4UVXAXkahAkNkHew3oqkCTY22Q+ZWvQA==",
          "dtype": "f8"
         },
         "y": {
          "bdata": "0NcnDgIBpkCSXo37ULKnQE7KXDNknqJA7QaqvLzFoUCMQ/dFFe2gQBRsWNbuFJtA0NcnDgIBlkCMQ/dFFe2AQA==",
          "dtype": "f8"
         }
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": true,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Iterations to find zero for target point",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 65376 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_samples(baseline_small_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "0f5a9ba9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>iterations</th>\n",
       "      <th>solution</th>\n",
       "      <th>sensitivity</th>\n",
       "      <th>damping</th>\n",
       "      <th>error</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>149.740275</td>\n",
       "      <td>2816.504014</td>\n",
       "      <td>14</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[]</td>\n",
       "      <td>[]</td>\n",
       "      <td>Distance non-convergent. Vertical error 0.0137...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>64</th>\n",
       "      <td>898.441651</td>\n",
       "      <td>3033.158169</td>\n",
       "      <td>50</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[]</td>\n",
       "      <td>[]</td>\n",
       "      <td>Max iterations reached</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>238</th>\n",
       "      <td>2395.844403</td>\n",
       "      <td>2383.195704</td>\n",
       "      <td>50</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[-0.5720505598575796, -0.6145936418602207, -0....</td>\n",
       "      <td>[]</td>\n",
       "      <td>Max iterations reached</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>260</th>\n",
       "      <td>2545.584678</td>\n",
       "      <td>2274.868627</td>\n",
       "      <td>50</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[-0.5011172197033307, -0.5610969634956718, -0....</td>\n",
       "      <td>[]</td>\n",
       "      <td>Max iterations reached</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>281</th>\n",
       "      <td>2695.324953</td>\n",
       "      <td>2166.541549</td>\n",
       "      <td>50</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[-0.5998856477406131, -0.665295641427659, -0.7...</td>\n",
       "      <td>[]</td>\n",
       "      <td>Max iterations reached</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>335</th>\n",
       "      <td>3144.545779</td>\n",
       "      <td>1733.233240</td>\n",
       "      <td>50</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[-0.5364972537017535, -0.6100281333829783, -0....</td>\n",
       "      <td>[]</td>\n",
       "      <td>Max iterations reached</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>364</th>\n",
       "      <td>3444.026329</td>\n",
       "      <td>1408.252007</td>\n",
       "      <td>50</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[-0.7020134077820933, -0.7651133582381656, -0....</td>\n",
       "      <td>[]</td>\n",
       "      <td>Max iterations reached</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>400</th>\n",
       "      <td>4042.987430</td>\n",
       "      <td>541.635387</td>\n",
       "      <td>50</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[-0.6245175406735637, -0.7915887052339943, -0....</td>\n",
       "      <td>[]</td>\n",
       "      <td>Max iterations reached</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               x            y  iterations  solution  \\\n",
       "7     149.740275  2816.504014          14       NaN   \n",
       "64    898.441651  3033.158169          50       NaN   \n",
       "238  2395.844403  2383.195704          50       NaN   \n",
       "260  2545.584678  2274.868627          50       NaN   \n",
       "281  2695.324953  2166.541549          50       NaN   \n",
       "335  3144.545779  1733.233240          50       NaN   \n",
       "364  3444.026329  1408.252007          50       NaN   \n",
       "400  4042.987430   541.635387          50       NaN   \n",
       "\n",
       "                                           sensitivity damping  \\\n",
       "7                                                   []      []   \n",
       "64                                                  []      []   \n",
       "238  [-0.5720505598575796, -0.6145936418602207, -0....      []   \n",
       "260  [-0.5011172197033307, -0.5610969634956718, -0....      []   \n",
       "281  [-0.5998856477406131, -0.665295641427659, -0.7...      []   \n",
       "335  [-0.5364972537017535, -0.6100281333829783, -0....      []   \n",
       "364  [-0.7020134077820933, -0.7651133582381656, -0....      []   \n",
       "400  [-0.6245175406735637, -0.7915887052339943, -0....      []   \n",
       "\n",
       "                                                 error  \n",
       "7    Distance non-convergent. Vertical error 0.0137...  \n",
       "64                              Max iterations reached  \n",
       "238                             Max iterations reached  \n",
       "260                             Max iterations reached  \n",
       "281                             Max iterations reached  \n",
       "335                             Max iterations reached  \n",
       "364                             Max iterations reached  \n",
       "400                             Max iterations reached  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Check points with no solution\n",
    "baseline_small_df[baseline_small_df['solution'].isna()]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ce7c0b2",
   "metadata": {},
   "source": [
    "## Baseline (big sample)\n",
    "\n",
    "See how the current algorithm performes when the calculator is allowed sufficient drop to reach the target horizontal distance when launched at the slant angle."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0ff0fd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(big_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(zero_test(point['x'], point['y']))\n",
    "baseline_big_df = pd.DataFrame(results)\n",
    "baseline_big_df.to_csv('ZeroBigBaseline.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "id": "c342009a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0,
           "#00FF00"
          ],
          [
           0.3695652173913043,
           "#1212FF"
          ],
          [
           0.9782608695652174,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "2WlL8z6LSUDZaUvzPotZQGOPeDZvKGNA2WlL8z6LaUBPRB6wDu5vQGOPeDZvKHNAnvzhFNdZdkDZaUvzPot5QBTXtNGmvHxAT0QesA7uf0DF2ENHu4+BQGOPeDZvKINAAEatJSPBhECe/OEU11mGQDuzFgSL8odA2WlL8z6LiUB3IIDi8iOLQBTXtNGmvIxAso3pwFpVjkBPRB6wDu6PQHZ9qU9hw5BAxdhDR7uPkUAUNN4+FVySQGOPeDZvKJNAsuoSLsn0k0AARq0lI8GUQE+hRx19jZVAnvzhFNdZlkDtV3wMMSaXQDuzFgSL8pdAig6x++S+mEDZaUvzPouZQCjF5eqYV5pAdyCA4vIjm0DFexraTPCbQBTXtNGmvJxAYzJPyQCJnUCyjenAWlWeQADpg7i0IZ9AT0QesA7un0DPT9xTNF2gQHZ9qU9hw6BAHqt2S44poUDF2ENHu4+hQG0GEUPo9aFAFDTePhVcokC7Yas6QsKiQGOPeDZvKKNACr1FMpyOo0Cy6hIuyfSjQFkY4Cn2WqRAAEatJSPBpECoc3ohUCelQE+hRx19jaVA9s4UGarzpUCe/OEU11mmQEUqrxAEwKZA7Vd8DDEmp0CUhUkIXoynQDuzFgSL8qdA4+Dj/7dYqECKDrH75L6oQDI8fvcRJalA2WlL8z6LqUCAlxjva/GpQCjF5eqYV6pAz/Ky5sW9qkB3IIDi8iOrQB5OTd4fiqtAxXsa2kzwq0BtqefVeVasQBTXtNGmvKxAvASCzdMirUBjMk/JAImtQApgHMUt761Aso3pwFpVrkBZu7a8h7uuQADpg7i0Ia9AqBZRtOGHr0BPRB6wDu6vQPu49dUdKrBAz0/cUzRdsECj5sLRSpCwQHZ9qU9hw7BA",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAABK1LoKtXpCQErUugq1elJAbz4YkA+4W0BK1LoKtXpiQFyJaU1iGWdAbz4YkA+4a0DBeWNpXitwQErUugq1enJA0y4SrAvKdEBciWlNYhl3QObjwO64aHlAbz4YkA+4e0D4mG8xZgd+QMF5Y2leK4BABScPuglTgUBK1LoKtXqCQI+BZltgooNA0y4SrAvKhEAY3L38tvGFQFyJaU1iGYdAoTYVng1BiEDm48DuuGiJQCqRbD9kkIpAbz4YkA+4i0C068Pgut+MQPiYbzFmB45APUYbghEvj0DBeWNpXiuQQGNQuRE0v5BABScPuglTkUCo/WRi3+aRQErUugq1epJA7KoQs4oOk0CPgWZbYKKTQDFYvAM2NpRA0y4SrAvKlEB2BWhU4V2VQBjcvfy28ZVAurITpYyFlkBciWlNYhmXQP9fv/U3rZdAoTYVng1BmEBDDWtG49SYQObjwO64aJlAiLoWl478mUAqkWw/ZJCaQM1nwuc5JJtAbz4YkA+4m0ARFW445UucQLTrw+C635xAVsIZiZBznUD4mG8xZgeeQJtvxdk7m55APUYbghEvn0DfHHEq58KfQMF5Y2leK6BAEmWOPUl1oEBjULkRNL+gQLQ75OUeCaFABScPuglToUBXEjqO9JyhQKj9ZGLf5qFA+eiPNsowokBK1LoKtXqiQJu/5d6fxKJA7KoQs4oOo0A9ljuHdVijQI+BZltgoqNA4GyRL0vso0AxWLwDNjakQIJD59cggKRA0y4SrAvKpEAkGj2A9hOlQHYFaFThXaVAx/CSKMynpUAY3L38tvGlQGnH6NChO6ZAurITpYyFpkALnj55d8+mQFyJaU1iGadArnSUIU1jp0D/X7/1N62nQFBL6ski96dAoTYVng1BqEA=",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 76160 characters]",
          "dtype": "f8",
          "shape": "85, 84"
         }
        },
        {
         "hoverinfo": "text",
         "marker": {
          "color": "white",
          "line": {
           "color": "black",
           "width": 1
          },
          "size": 7,
          "symbol": "square"
         },
         "mode": "markers",
         "name": "Failed to converge",
         "text": [
          "x: 357.62<br>y: 3104.53<br>Max iterations reached",
          "x: 408.70<br>y: 3104.53<br>Max iterations reached",
          "x: 459.79<br>y: 3104.53<br>Max iterations reached",
          "x: 510.88<br>y: 3104.53<br>Max iterations reached",
          "x: 664.14<br>y: 3067.57<br>Max iterations reached",
          "x: 715.23<br>y: 3067.57<br>Max iterations reached",
          "x: 766.32<br>y: 3067.57<br>Distance non-convergent. Vertical error 0.14725593661387393 feet with 1.406684rad elevation, after 49 iterations.",
          "x: 868.49<br>y: 3030.61<br>Max iterations reached",
          "x: 919.58<br>y: 3030.61<br>Max iterations reached",
          "x: 1021.76<br>y: 2993.65<br>Max iterations reached",
          "x: 1072.85<br>y: 2993.65<br>Max iterations reached",
          "x: 1175.02<br>y: 2956.69<br>Max iterations reached",
          "x: 1328.28<br>y: 2919.73<br>Max iterations reached",
          "x: 1430.46<br>y: 2882.77<br>Max iterations reached",
          "x: 1532.64<br>y: 2845.82<br>Max iterations reached",
          "x: 1788.08<br>y: 2661.02<br>Distance non-convergent. Vertical error 0.010948462711894535 feet with 1.13829rad elevation, after 21 iterations.",
          "x: 1788.08<br>y: 2734.94<br>Max iterations reached",
          "x: 1992.43<br>y: 2624.06<br>Max iterations reached",
          "x: 2196.78<br>y: 2513.19<br>Max iterations reached",
          "x: 2247.87<br>y: 2476.23<br>Max iterations reached",
          "x: 2298.95<br>y: 2439.27<br>Max iterations reached",
          "x: 2350.04<br>y: 2402.31<br>Max iterations reached",
          "x: 2401.13<br>y: 2365.35<br>Max iterations reached",
          "x: 2452.22<br>y: 2328.39<br>Max iterations reached",
          "x: 2503.31<br>y: 2291.44<br>Max iterations reached",
          "x: 2554.39<br>y: 2254.48<br>Max iterations reached",
          "x: 2605.48<br>y: 2217.52<br>Max iterations reached",
          "x: 2656.57<br>y: 2180.56<br>Max iterations reached",
          "x: 2707.66<br>y: 2143.60<br>Max iterations reached",
          "x: 2758.74<br>y: 2106.64<br>Max iterations reached",
          "x: 2809.83<br>y: 2069.68<br>Max iterations reached",
          "x: 2860.92<br>y: 1995.77<br>Max iterations reached",
          "x: 2912.01<br>y: 1958.81<br>Max iterations reached",
          "x: 2963.10<br>y: 1921.85<br>Max iterations reached",
          "x: 3014.18<br>y: 1884.89<br>Max iterations reached",
          "x: 3065.27<br>y: 258.71<br>Max iterations reached",
          "x: 3065.27<br>y: 1810.97<br>Max iterations reached",
          "x: 3116.36<br>y: 1774.02<br>Max iterations reached",
          "x: 3167.45<br>y: 1700.10<br>Max iterations reached",
          "x: 3167.45<br>y: 1737.06<br>Max iterations reached",
          "x: 3218.54<br>y: 1404.43<br>Distance non-convergent. Vertical error 0.010795315114592086 feet with 0.692018rad elevation, after 11 iterations.",
          "x: 3218.54<br>y: 1663.14<br>Max iterations reached",
          "x: 3269.62<br>y: 1626.18<br>Max iterations reached",
          "x: 3320.71<br>y: 1552.26<br>Max iterations reached",
          "x: 3371.80<br>y: 1478.35<br>Max iterations reached",
          "x: 3371.80<br>y: 1515.30<br>Max iterations reached",
          "x: 3422.89<br>y: 1219.64<br>Distance non-convergent. Vertical error 0.01025869820114167 feet with 0.660634rad elevation, after 7 iterations.",
          "x: 3422.89<br>y: 1441.39<br>Max iterations reached",
          "x: 3473.97<br>y: 1367.47<br>Max iterations reached",
          "x: 3525.06<br>y: 1330.51<br>Max iterations reached",
          "x: 3576.15<br>y: 1256.59<br>Max iterations reached",
          "x: 3627.24<br>y: 1071.80<br>Distance non-convergent. Vertical error 0.010730563904871815 feet with 0.664367rad elevation, after 18 iterations.",
          "x: 3627.24<br>y: 1182.68<br>Max iterations reached",
          "x: 3678.33<br>y: 1108.76<br>Max iterations reached",
          "x: 3729.41<br>y: 1034.84<br>Max iterations reached",
          "x: 3780.50<br>y: 960.92<br>Max iterations reached",
          "x: 3831.59<br>y: 887.01<br>Max iterations reached",
          "x: 3882.68<br>y: 813.09<br>Max iterations reached",
          "x: 3933.77<br>y: 739.17<br>Max iterations reached",
          "x: 3984.85<br>y: 628.30<br>Max iterations reached",
          "x: 3984.85<br>y: 665.26<br>Distance non-convergent. Vertical error 0.04593749125342583 feet with 0.677024rad elevation, after 38 iterations.",
          "x: 4035.94<br>y: 554.38<br>Max iterations reached",
          "x: 4087.03<br>y: 480.46<br>Max iterations reached",
          "x: 4138.12<br>y: 369.59<br>Max iterations reached",
          "x: 4138.12<br>y: 406.55<br>Distance non-convergent. Vertical error 0.1382969472433615 feet with 0.662729rad elevation, after 49 iterations.",
          "x: 4189.20<br>y: 258.71<br>Max iterations reached",
          "x: 4189.20<br>y: 295.67<br>Max iterations reached",
          "x: 4240.29<br>y: 184.79<br>Max iterations reached",
          "x: 4291.38<br>y: 73.92<br>Max iterations reached"
         ],
         "type": "scatter",
         "x": {
          "bdata": "nvzhFNdZdkDZaUvzPot5QBTXtNGmvHxAT0QesA7uf0AARq0lI8GEQJ784RTXWYZAO7MWBIvyh0B3IIDi8iOLQBTXtNGmvIxAT0QesA7uj0B2falPYcOQQBQ03j4VXJJAAEatJSPBlECe/OEU11mWQDuzFgSL8pdAxXsa2kzwm0DFexraTPCbQADpg7i0IZ9AHqt2S44poUDF2ENHu4+hQG0GEUPo9aFAFDTePhVcokC7Yas6QsKiQGOPeDZvKKNACr1FMpyOo0Cy6hIuyfSjQFkY4Cn2WqRAAEatJSPBpECoc3ohUCelQE+hRx19jaVA9s4UGarzpUCe/OEU11mmQEUqrxAEwKZA7Vd8DDEmp0CUhUkIXoynQDuzFgSL8qdAO7MWBIvyp0Dj4OP/t1ioQIoOsfvkvqhAig6x++S+qEAyPH73ESWpQDI8fvcRJalA2WlL8z6LqUCAlxjva/GpQCjF5eqYV6pAKMXl6phXqkDP8rLmxb2qQM/ysubFvapAdyCA4vIjq0AeTk3eH4qrQMV7GtpM8KtAbann1XlWrEBtqefVeVasQBTXtNGmvKxAvASCzdMirUBjMk/JAImtQApgHMUt761Aso3pwFpVrkBZu7a8h7uuQADpg7i0Ia9AAOmDuLQhr0CoFlG04YevQE9EHrAO7q9A+7j11R0qsED7uPXVHSqwQM9P3FM0XbBAz0/cUzRdsECj5sLRSpCwQHZ9qU9hw7BA",
          "dtype": "f8"
         },
         "y": {
          "bdata": "oTYVng1BqEChNhWeDUGoQKE2FZ4NQahAoTYVng1BqEBQS+rJIvenQFBL6ski96dAUEvqySL3p0D/X7/1N62nQP9fv/U3radArnSUIU1jp0CudJQhTWOnQFyJaU1iGadAC54+eXfPpkC6shOljIWmQGnH6NChO6ZA0y4SrAvKpEB2BWhU4V2lQIJD59cggKRAj4FmW2Cio0A9ljuHdVijQOyqELOKDqNAm7/l3p/EokBK1LoKtXqiQPnojzbKMKJAqP1kYt/moUBXEjqO9JyhQAUnD7oJU6FAtDvk5R4JoUBjULkRNL+gQBJljj1JdaBAwXljaV4roEA9RhuCES+fQJtvxdk7m55A+JhvMWYHnkBWwhmJkHOdQMF5Y2leK3BAERVuOOVLnEBvPhiQD7ibQCqRbD9kkJpAzWfC5zkkm0AY3L38tvGVQIi6FpeO/JlA5uPA7rhomUChNhWeDUGYQFyJaU1iGZdA/1+/9Tetl0DsqhCzig6TQLqyE6WMhZZAdgVoVOFdlUDTLhKsC8qUQI+BZltgopNAY1C5ETS/kEBK1LoKtXqSQAUnD7oJU5FAwXljaV4rkED4mG8xZgeOQG8+GJAPuItA5uPA7rhoiUBciWlNYhmHQI+BZltgooNA0y4SrAvKhEAFJw+6CVOBQPiYbzFmB35AXIlpTWIZd0Dm48DuuGh5QMF5Y2leK3BAStS6CrV6ckBciWlNYhlnQErUugq1elJA",
          "dtype": "f8"
         }
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": true,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Iterations to find zero for target point",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 73332 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_samples(baseline_big_df, 'ZeroBaselineBig')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "261d7ead",
   "metadata": {},
   "source": [
    "## Baseline (huge sample)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e2094ec2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7089c036ff5f4ecb8204cdb993c6af49",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/20073 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(huge_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(zero_test(point['x'], point['y']))\n",
    "baseline_huge_df = pd.DataFrame(results)\n",
    "baseline_huge_df.to_csv('ZeroHugeBaseline.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "id": "2b9db473",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.02127659574468085,
           "#00FF00"
          ],
          [
           0.3829787234042553,
           "#1212FF"
          ],
          [
           0.9787234042553191,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "lcmqFBjZOUCVyaoUGNlJQDAXgA/SYlNAlcmqFBjZWUD9veoMrydgQDAXgA/SYmNAYnAVEvWdZkCVyaoUGNlpQMgiQBc7FG1A/b3qDK8ncECWajWOQMVxQDAXgA/SYnNAycPKkGMAdUBicBUS9Z12QPwcYJOGO3hAlcmqFBjZeUAudvWVqXZ7QMgiQBc7FH1AYc+KmMyxfkD9veoMryeAQEoUkM139oBAlmo1jkDFgUDjwNpOCZSCQDAXgA/SYoNAfG0l0JoxhEDJw8qQYwCFQBYacFEsz4VAYnAVEvWdhkCvxrrSvWyHQPwcYJOGO4hASHMFVE8KiUCVyaoUGNmJQOIfUNXgp4pALnb1lal2i0B7zJpWckWMQMgiQBc7FI1AFHnl1wPjjUBhz4qYzLGOQK4lMFmVgI9A/b3qDK8nkEAjaT1tE4+QQEoUkM139pBAcL/iLdxdkUCWajWOQMWRQL0ViO6kLJJA48DaTgmUkkAJbC2vbfuSQDAXgA/SYpNAVsLSbzbKk0B8bSXQmjGUQKMYeDD/mJRAycPKkGMAlUDvbh3xx2eVQBYacFEsz5VAPMXCsZA2lkBicBUS9Z2WQIkbaHJZBZdAr8a60r1sl0DVcQ0zItSXQPwcYJOGO5hAIsiy8+qimEBIcwVUTwqZQG8eWLSzcZlAlcmqFBjZmUC7dP10fECaQOIfUNXgp5pACMuiNUUPm0AudvWVqXabQFUhSPYN3ptAe8yaVnJFnEChd+221qycQMgiQBc7FJ1A7s2Sd597nUAUeeXXA+OdQDskODhoSp5AYc+KmMyxnkCHet34MBmfQK4lMFmVgJ9A1NCCufnnn0D9veoMryegQJATFD1hW6BAI2k9bROPoEC3vmadxcKgQEoUkM139qBA3Wm5/SkqoUBwv+It3F2hQAMVDF6OkaFAlmo1jkDFoUAqwF6+8vihQL0ViO6kLKJAUGuxHldgokDjwNpOCZSiQHYWBH+7x6JACWwtr237okCdwVbfHy+jQDAXgA/SYqNAw2ypP4SWo0BWwtJvNsqjQOkX/J/o/aNAfG0l0JoxpEAQw04ATWWkQKMYeDD/mKRANm6hYLHMpEDJw8qQYwClQFwZ9MAVNKVA724d8cdnpUCDxEYhepulQBYacFEsz6VAqW+Zgd4CpkA8xcKxkDamQM8a7OFCaqZAYnAVEvWdpkD2xT5Cp9GmQIkbaHJZBadAHHGRogs5p0CvxrrSvWynQEIc5AJwoKdA1XENMyLUp0BpxzZj1AeoQPwcYJOGO6hAj3KJwzhvqEAiyLLz6qKoQLUd3COd1qhASHMFVE8KqUDcyC6EAT6pQG8eWLSzcalAAnSB5GWlqUCVyaoUGNmpQCgf1ETKDKpAu3T9dHxAqkBOyialLnSqQOIfUNXgp6pAdXV5BZPbqkAIy6I1RQ+rQJsgzGX3QqtALnb1lal2q0DByx7GW6qrQFUhSPYN3qtA6HZxJsARrEB7zJpWckWsQA4ixIYkeaxAoXftttasrEA0zRbniOCsQMgiQBc7FK1AW3hpR+1HrUDuzZJ3n3utQIEjvKdRr61AFHnl1wPjrUCnzg4IthauQDskODhoSq5AznlhaBp+rkBhz4qYzLGuQPQktMh+5a5Ah3rd+DAZr0Aa0AYp40yvQK4lMFmVgK9AQXtZiUe0r0DU0IK5+eevQDQT1vTVDbBA/b3qDK8nsEDHaP8kiEGwQJATFD1hW7BAWr4oVTp1sEAjaT1tE4+wQO0TUoXsqLBAt75mncXCsEA=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAAC40G1vBrMyQLjQbW8Gs0JAFLkkp4kMTEC40G1vBrNSQOZESQvIX1dAFLkkp4kMXEChFoChpVxgQLjQbW8Gs2JAz4pbPWcJZUDmREkLyF9nQP3+NtkotmlAFLkkp4kMbEArcxJ16mJuQKEWgKGlXHBArPN2CNaHcUC40G1vBrNyQMStZNY23nNAz4pbPWcJdUDaZ1KklzR2QOZESQvIX3dA8iFAcviKeED9/jbZKLZ5QAjcLUBZ4XpAFLkkp4kMfEAglhsOujd9QCtzEnXqYn5ANlAJ3BqOf0ChFoChpVyAQCeF+9Q98oBArPN2CNaHgUAyYvI7bh2CQLjQbW8Gs4JAPj/pop5Ig0DErWTWNt6DQEkc4AnPc4RAz4pbPWcJhUBV+dZw/56FQNpnUqSXNIZAYNbN1y/KhkDmREkLyF+HQGyzxD5g9YdA8iFAcviKiEB3kLulkCCJQP3+NtkotolAg22yDMFLikAI3C1AWeGKQI5KqXPxdotAFLkkp4kMjECaJ6DaIaKMQCCWGw66N41ApQSXQVLNjUArcxJ16mKOQLHhjaiC+I5ANlAJ3BqOj0BeX8KH2RGQQKEWgKGlXJBA5M09u3GnkEAnhfvUPfKQQGo8ue4JPZFArPN2CNaHkUDvqjQiotKRQDJi8jtuHZJAdRmwVTpokkC40G1vBrOSQPuHK4nS/ZJAPj/pop5Ik0CB9qa8apOTQMStZNY23pNABmUi8AIplEBJHOAJz3OUQIzTnSObvpRAz4pbPWcJlUASQhlXM1SVQFX51nD/npVAmLCUisvplUDaZ1KklzSWQB0fEL5jf5ZAYNbN1y/KlkCjjYvx+xSXQOZESQvIX5dAKfwGJZSql0Bss8Q+YPWXQK9qglgsQJhA8iFAcviKmEA02f2LxNWYQHeQu6WQIJlAukd5v1xrmUD9/jbZKLaZQEC29PL0AJpAg22yDMFLmkDGJHAmjZaaQAjcLUBZ4ZpAS5PrWSUsm0COSqlz8XabQNEBZ429wZtAFLkkp4kMnEBXcOLAVVecQJonoNohopxA3d5d9O3snEAglhsOujedQGJN2SeGgp1ApQSXQVLNnUDou1RbHhieQCtzEnXqYp5AbirQjratnkCx4Y2ogvieQPSYS8JOQ59ANlAJ3BqOn0B5B8f15tifQF5fwofZEaBAADuhlD83oEChFoChpVygQELyXq4LgqBA5M09u3GnoECFqRzI18ygQCeF+9Q98qBAyGDa4aMXoUBqPLnuCT2hQAsYmPtvYqFArPN2CNaHoUBOz1UVPK2hQO+qNCKi0qFAkYYTLwj4oUAyYvI7bh2iQNQ90UjUQqJAdRmwVTpookAX9Y5ioI2iQLjQbW8Gs6JAWaxMfGzYokD7hyuJ0v2iQJxjCpY4I6NAPj/pop5Io0DfGsivBG6jQIH2prxqk6NAItKFydC4o0DErWTWNt6jQGWJQ+OcA6RABmUi8AIppECoQAH9aE6kQEkc4AnPc6RA6/e+FjWZpECM050jm76kQC6vfDAB5KRAz4pbPWcJpUBwZjpKzS6lQBJCGVczVKVAsx34Y5l5pUBV+dZw/56lQPbUtX1lxKVAmLCUisvppUA5jHOXMQ+mQNpnUqSXNKZAfEMxsf1ZpkAdHxC+Y3+mQL/67srJpKZAYNbN1y/KpkACsqzkle+mQKONi/H7FKdARWlq/mE6p0DmREkLyF+nQIcgKBguhadAKfwGJZSqp0DK1+Ux+s+nQGyzxD5g9adADY+jS8YaqECvaoJYLECoQFBGYWWSZahA",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 297472 characters]",
          "dtype": "f8",
          "shape": "168, 166"
         }
        },
        {
         "hoverinfo": "text",
         "marker": {
          "color": "white",
          "line": {
           "color": "black",
           "width": 1
          },
          "size": 7,
          "symbol": "square"
         },
         "mode": "markers",
         "name": "Failed to converge",
         "text": [
          "x: 25.85<br>y: 2075.62<br>Error non-convergent. Vertical error 3.798123562148703e-05 feet with 1.559316rad elevation, after 10 iterations.",
          "x: 51.70<br>y: 3122.79<br>Max iterations reached",
          "x: 77.54<br>y: 3122.79<br>Max iterations reached",
          "x: 103.39<br>y: 3122.79<br>Max iterations reached",
          "x: 129.24<br>y: 3122.79<br>Max iterations reached",
          "x: 155.09<br>y: 3122.79<br>Max iterations reached",
          "x: 180.94<br>y: 3122.79<br>Max iterations reached",
          "x: 206.78<br>y: 3122.79<br>Max iterations reached",
          "x: 232.63<br>y: 3122.79<br>Max iterations reached",
          "x: 258.48<br>y: 3122.79<br>Max iterations reached",
          "x: 284.33<br>y: 3122.79<br>Max iterations reached",
          "x: 310.18<br>y: 3122.79<br>Max iterations reached",
          "x: 336.02<br>y: 3104.09<br>Max iterations reached",
          "x: 336.02<br>y: 3122.79<br>Distance non-convergent. Vertical error 0.3954634075962531 feet with 1.497861rad elevation, after 36 iterations.",
          "x: 361.87<br>y: 3104.09<br>Max iterations reached",
          "x: 361.87<br>y: 3122.79<br>Max iterations reached",
          "x: 387.72<br>y: 3104.09<br>Max iterations reached",
          "x: 387.72<br>y: 3122.79<br>Max iterations reached",
          "x: 413.57<br>y: 3104.09<br>Max iterations reached",
          "x: 439.42<br>y: 3104.09<br>Distance non-convergent. Vertical error 0.18998360158548167 feet with 1.4731rad elevation, after 29 iterations.",
          "x: 465.26<br>y: 3104.09<br>Max iterations reached",
          "x: 491.11<br>y: 3047.99<br>Max iterations reached",
          "x: 491.11<br>y: 3104.09<br>Max iterations reached",
          "x: 516.96<br>y: 3085.39<br>Max iterations reached",
          "x: 516.96<br>y: 3104.09<br>Max iterations reached",
          "x: 542.81<br>y: 3085.39<br>Max iterations reached",
          "x: 542.81<br>y: 3104.09<br>Max iterations reached",
          "x: 568.66<br>y: 3085.39<br>Max iterations reached",
          "x: 594.50<br>y: 3085.39<br>Max iterations reached",
          "x: 620.35<br>y: 3085.39<br>Max iterations reached",
          "x: 646.20<br>y: 3066.69<br>Max iterations reached",
          "x: 646.20<br>y: 3085.39<br>Max iterations reached",
          "x: 672.05<br>y: 3066.69<br>Max iterations reached",
          "x: 672.05<br>y: 3085.39<br>Max iterations reached",
          "x: 697.90<br>y: 3066.69<br>Max iterations reached",
          "x: 723.74<br>y: 3066.69<br>Max iterations reached",
          "x: 749.59<br>y: 2898.39<br>Distance non-convergent. Vertical error 0.024499431186995935 feet with 1.373451rad elevation, after 14 iterations.",
          "x: 749.59<br>y: 3047.99<br>Max iterations reached",
          "x: 749.59<br>y: 3066.69<br>Max iterations reached",
          "x: 775.44<br>y: 3047.99<br>Max iterations reached",
          "x: 775.44<br>y: 3066.69<br>Max iterations reached",
          "x: 801.29<br>y: 3047.99<br>Max iterations reached",
          "x: 827.14<br>y: 3047.99<br>Max iterations reached",
          "x: 852.98<br>y: 3029.29<br>Max iterations reached",
          "x: 852.98<br>y: 3047.99<br>Max iterations reached",
          "x: 878.83<br>y: 3029.29<br>Max iterations reached",
          "x: 904.68<br>y: 3029.29<br>Max iterations reached",
          "x: 930.53<br>y: 3029.29<br>Max iterations reached",
          "x: 956.38<br>y: 3010.59<br>Error non-convergent. Vertical error 0.001107521829453617 feet with 1.356091rad elevation, after 49 iterations.",
          "x: 982.22<br>y: 3010.59<br>Max iterations reached",
          "x: 1008.07<br>y: 3010.59<br>Distance non-convergent. Vertical error 0.08151772163182613 feet with 1.35132rad elevation, after 38 iterations.",
          "x: 1033.92<br>y: 2991.89<br>Max iterations reached",
          "x: 1059.77<br>y: 2991.89<br>Max iterations reached",
          "x: 1085.62<br>y: 2991.89<br>Max iterations reached",
          "x: 1111.47<br>y: 2617.90<br>Max iterations reached",
          "x: 1111.47<br>y: 2973.19<br>Max iterations reached",
          "x: 1137.31<br>y: 2973.19<br>Max iterations reached",
          "x: 1163.16<br>y: 2954.49<br>Max iterations reached",
          "x: 1163.16<br>y: 2973.19<br>Max iterations reached",
          "x: 1189.01<br>y: 2954.49<br>Max iterations reached",
          "x: 1214.86<br>y: 2954.49<br>Max iterations reached",
          "x: 1240.71<br>y: 2935.79<br>Max iterations reached",
          "x: 1266.55<br>y: 2804.90<br>Distance non-convergent. Vertical error 0.03769170449959347 feet with 1.247155rad elevation, after 15 iterations.",
          "x: 1266.55<br>y: 2935.79<br>Max iterations reached",
          "x: 1292.40<br>y: 2917.09<br>Max iterations reached",
          "x: 1318.25<br>y: 2917.09<br>Max iterations reached",
          "x: 1369.95<br>y: 2898.39<br>Max iterations reached",
          "x: 1473.34<br>y: 2861.00<br>Max iterations reached",
          "x: 1525.03<br>y: 1458.55<br>Error non-convergent. Vertical error 0.000772090905229561 feet with 0.820568rad elevation, after 11 iterations.",
          "x: 1525.03<br>y: 2842.30<br>Max iterations reached",
          "x: 1576.73<br>y: 2767.50<br>Distance non-convergent. Vertical error 0.021483667547727237 feet with 1.19466rad elevation, after 20 iterations.",
          "x: 1576.73<br>y: 2823.60<br>Max iterations reached",
          "x: 1628.43<br>y: 2804.90<br>Max iterations reached",
          "x: 1654.27<br>y: 2786.20<br>Distance non-convergent. Vertical error 0.02540472079454048 feet with 1.204485rad elevation, after 27 iterations.",
          "x: 1705.97<br>y: 2767.50<br>Max iterations reached",
          "x: 1731.82<br>y: 878.87<br>Error non-convergent. Vertical error 0.0002225489938609826 feet with 0.527933rad elevation, after 10 iterations.",
          "x: 1757.67<br>y: 2748.80<br>Max iterations reached",
          "x: 1783.51<br>y: 2730.10<br>Max iterations reached",
          "x: 1835.21<br>y: 2711.40<br>Max iterations reached",
          "x: 1861.06<br>y: 2692.70<br>Max iterations reached",
          "x: 1912.75<br>y: 2674.00<br>Max iterations reached",
          "x: 1938.60<br>y: 2655.30<br>Max iterations reached",
          "x: 1964.45<br>y: 2636.60<br>Max iterations reached",
          "x: 2016.15<br>y: 2617.90<br>Max iterations reached",
          "x: 2041.99<br>y: 2599.21<br>Max iterations reached",
          "x: 2067.84<br>y: 18.70<br>Max iterations reached",
          "x: 2067.84<br>y: 2580.51<br>Max iterations reached",
          "x: 2093.69<br>y: 2561.81<br>Max iterations reached",
          "x: 2119.54<br>y: 1402.45<br>Error non-convergent. Vertical error 0.0011642111303444835 feet with 0.685903rad elevation, after 12 iterations.",
          "x: 2119.54<br>y: 2505.71<br>Max iterations reached",
          "x: 2119.54<br>y: 2543.11<br>Max iterations reached",
          "x: 2119.54<br>y: 2561.81<br>Max iterations reached",
          "x: 2145.39<br>y: 2543.11<br>Max iterations reached",
          "x: 2171.23<br>y: 2524.41<br>Max iterations reached",
          "x: 2197.08<br>y: 2505.71<br>Max iterations reached",
          "x: 2222.93<br>y: 2487.01<br>Max iterations reached",
          "x: 2248.78<br>y: 2468.31<br>Max iterations reached",
          "x: 2274.63<br>y: 2449.61<br>Distance non-convergent. Vertical error 0.09243435859389137 feet with 1.05648rad elevation, after 27 iterations.",
          "x: 2274.63<br>y: 2468.31<br>Max iterations reached",
          "x: 2300.47<br>y: 2430.91<br>Distance non-convergent. Vertical error 0.02136710743798176 feet with 1.048663rad elevation, after 31 iterations.",
          "x: 2300.47<br>y: 2449.61<br>Max iterations reached",
          "x: 2326.32<br>y: 2412.21<br>Max iterations reached",
          "x: 2326.32<br>y: 2430.91<br>Max iterations reached",
          "x: 2352.17<br>y: 2393.51<br>Max iterations reached",
          "x: 2352.17<br>y: 2412.21<br>Max iterations reached",
          "x: 2378.02<br>y: 2374.81<br>Max iterations reached",
          "x: 2378.02<br>y: 2393.51<br>Max iterations reached",
          "x: 2403.87<br>y: 56.10<br>Max iterations reached",
          "x: 2403.87<br>y: 2356.11<br>Max iterations reached",
          "x: 2403.87<br>y: 2374.81<br>Max iterations reached",
          "x: 2429.71<br>y: 2337.41<br>Max iterations reached",
          "x: 2429.71<br>y: 2356.11<br>Max iterations reached",
          "x: 2455.56<br>y: 2318.72<br>Max iterations reached",
          "x: 2455.56<br>y: 2337.41<br>Max iterations reached",
          "x: 2481.41<br>y: 2300.02<br>Max iterations reached",
          "x: 2481.41<br>y: 2318.72<br>Max iterations reached",
          "x: 2507.26<br>y: 2281.32<br>Max iterations reached",
          "x: 2507.26<br>y: 2300.02<br>Max iterations reached",
          "x: 2533.11<br>y: 2262.62<br>Max iterations reached",
          "x: 2533.11<br>y: 2281.32<br>Max iterations reached",
          "x: 2558.95<br>y: 2243.92<br>Max iterations reached",
          "x: 2558.95<br>y: 2262.62<br>Max iterations reached",
          "x: 2584.80<br>y: 2225.22<br>Max iterations reached",
          "x: 2584.80<br>y: 2243.92<br>Max iterations reached",
          "x: 2610.65<br>y: 2206.52<br>Max iterations reached",
          "x: 2610.65<br>y: 2225.22<br>Max iterations reached",
          "x: 2636.50<br>y: 2187.82<br>Max iterations reached",
          "x: 2636.50<br>y: 2206.52<br>Max iterations reached",
          "x: 2662.35<br>y: 2169.12<br>Max iterations reached",
          "x: 2662.35<br>y: 2187.82<br>Max iterations reached",
          "x: 2688.19<br>y: 2150.42<br>Max iterations reached",
          "x: 2688.19<br>y: 2169.12<br>Max iterations reached",
          "x: 2714.04<br>y: 2131.72<br>Max iterations reached",
          "x: 2714.04<br>y: 2150.42<br>Max iterations reached",
          "x: 2739.89<br>y: 1458.55<br>Max iterations reached",
          "x: 2739.89<br>y: 2113.02<br>Max iterations reached",
          "x: 2739.89<br>y: 2131.72<br>Max iterations reached",
          "x: 2765.74<br>y: 2075.62<br>Max iterations reached",
          "x: 2765.74<br>y: 2094.32<br>Max iterations reached",
          "x: 2791.59<br>y: 2056.92<br>Max iterations reached",
          "x: 2791.59<br>y: 2075.62<br>Max iterations reached",
          "x: 2817.43<br>y: 2038.23<br>Max iterations reached",
          "x: 2817.43<br>y: 2056.92<br>Max iterations reached",
          "x: 2843.28<br>y: 1832.53<br>Distance non-convergent. Vertical error 0.012434862335794605 feet with 0.81598rad elevation, after 10 iterations.",
          "x: 2843.28<br>y: 2019.53<br>Max iterations reached",
          "x: 2843.28<br>y: 2038.23<br>Max iterations reached",
          "x: 2869.13<br>y: 2000.83<br>Max iterations reached",
          "x: 2869.13<br>y: 2019.53<br>Max iterations reached",
          "x: 2894.98<br>y: 224.39<br>Error non-convergent. Vertical error 0.0074289417792670065 feet with 0.233872rad elevation, after 8 iterations.",
          "x: 2894.98<br>y: 373.99<br>Max iterations reached",
          "x: 2894.98<br>y: 1982.13<br>Max iterations reached",
          "x: 2894.98<br>y: 2000.83<br>Max iterations reached",
          "x: 2920.83<br>y: 1720.34<br>Error non-convergent. Vertical error 0.011993921387329465 feet with 0.777731rad elevation, after 13 iterations.",
          "x: 2920.83<br>y: 1944.73<br>Max iterations reached",
          "x: 2920.83<br>y: 1963.43<br>Max iterations reached",
          "x: 2946.67<br>y: 1926.03<br>Max iterations reached",
          "x: 2946.67<br>y: 1944.73<br>Max iterations reached",
          "x: 2972.52<br>y: 1907.33<br>Max iterations reached",
          "x: 2972.52<br>y: 1926.03<br>Max iterations reached",
          "x: 2998.37<br>y: 1869.93<br>Max iterations reached",
          "x: 2998.37<br>y: 1888.63<br>Max iterations reached",
          "x: 2998.37<br>y: 1907.33<br>Max iterations reached",
          "x: 3024.22<br>y: 1851.23<br>Max iterations reached",
          "x: 3024.22<br>y: 1869.93<br>Max iterations reached",
          "x: 3050.07<br>y: 1757.74<br>Distance non-convergent. Vertical error 0.012567207901156507 feet with 0.820026rad elevation, after 10 iterations.",
          "x: 3050.07<br>y: 1832.53<br>Max iterations reached",
          "x: 3050.07<br>y: 1851.23<br>Max iterations reached",
          "x: 3075.91<br>y: 1813.83<br>Max iterations reached",
          "x: 3075.91<br>y: 1832.53<br>Max iterations reached",
          "x: 3101.76<br>y: 1776.44<br>Max iterations reached",
          "x: 3101.76<br>y: 1795.13<br>Max iterations reached",
          "x: 3127.61<br>y: 1757.74<br>Max iterations reached",
          "x: 3127.61<br>y: 1776.44<br>Max iterations reached",
          "x: 3153.46<br>y: 261.79<br>Error non-convergent. Vertical error 0.011399616616245112 feet with 0.276728rad elevation, after 23 iterations.",
          "x: 3153.46<br>y: 1720.34<br>Max iterations reached",
          "x: 3153.46<br>y: 1739.04<br>Max iterations reached",
          "x: 3179.31<br>y: 1701.64<br>Max iterations reached",
          "x: 3179.31<br>y: 1720.34<br>Max iterations reached",
          "x: 3205.15<br>y: 224.39<br>Max iterations reached",
          "x: 3205.15<br>y: 1664.24<br>Max iterations reached",
          "x: 3205.15<br>y: 1682.94<br>Max iterations reached",
          "x: 3205.15<br>y: 1701.64<br>Max iterations reached",
          "x: 3231.00<br>y: 1327.65<br>Distance non-convergent. Vertical error 0.011955051813856699 feet with 0.662837rad elevation, after 9 iterations.",
          "x: 3231.00<br>y: 1645.54<br>Max iterations reached",
          "x: 3231.00<br>y: 1664.24<br>Max iterations reached",
          "x: 3256.85<br>y: 1608.14<br>Distance non-convergent. Vertical error 0.014793107602599775 feet with 0.811643rad elevation, after 29 iterations.",
          "x: 3256.85<br>y: 1626.84<br>Max iterations reached",
          "x: 3256.85<br>y: 1645.54<br>Max iterations reached",
          "x: 3282.70<br>y: 1589.44<br>Max iterations reached",
          "x: 3282.70<br>y: 1608.14<br>Max iterations reached",
          "x: 3308.55<br>y: 1552.04<br>Max iterations reached",
          "x: 3308.55<br>y: 1570.74<br>Distance non-convergent. Vertical error 0.09403489134456322 feet with 0.817517rad elevation, after 28 iterations.",
          "x: 3308.55<br>y: 1589.44<br>Max iterations reached",
          "x: 3334.40<br>y: 1533.34<br>Max iterations reached",
          "x: 3334.40<br>y: 1552.04<br>Max iterations reached",
          "x: 3360.24<br>y: 1495.95<br>Max iterations reached",
          "x: 3360.24<br>y: 1514.64<br>Max iterations reached",
          "x: 3360.24<br>y: 1533.34<br>Max iterations reached",
          "x: 3386.09<br>y: 953.67<br>Max iterations reached",
          "x: 3386.09<br>y: 1477.25<br>Max iterations reached",
          "x: 3386.09<br>y: 1495.95<br>Distance non-convergent. Vertical error 0.06252589579526102 feet with 0.816848rad elevation, after 44 iterations.",
          "x: 3411.94<br>y: 1308.95<br>Distance non-convergent. Vertical error 0.014344801633342286 feet with 0.69912rad elevation, after 9 iterations.",
          "x: 3411.94<br>y: 1439.85<br>Max iterations reached",
          "x: 3411.94<br>y: 1458.55<br>Max iterations reached",
          "x: 3437.79<br>y: 93.50<br>Max iterations reached",
          "x: 3437.79<br>y: 1402.45<br>Max iterations reached",
          "x: 3437.79<br>y: 1421.15<br>Max iterations reached",
          "x: 3437.79<br>y: 1439.85<br>Max iterations reached",
          "x: 3463.64<br>y: 1383.75<br>Max iterations reached",
          "x: 3463.64<br>y: 1402.45<br>Max iterations reached",
          "x: 3489.48<br>y: 1346.35<br>Max iterations reached",
          "x: 3489.48<br>y: 1365.05<br>Max iterations reached",
          "x: 3515.33<br>y: 1308.95<br>Max iterations reached",
          "x: 3515.33<br>y: 1327.65<br>Max iterations reached",
          "x: 3515.33<br>y: 1346.35<br>Max iterations reached",
          "x: 3541.18<br>y: 1140.66<br>Distance non-convergent. Vertical error 0.02200459137930011 feet with 0.66279rad elevation, after 13 iterations.",
          "x: 3541.18<br>y: 1290.25<br>Max iterations reached",
          "x: 3541.18<br>y: 1308.95<br>Max iterations reached",
          "x: 3567.03<br>y: 785.37<br>Max iterations reached",
          "x: 3567.03<br>y: 1252.85<br>Max iterations reached",
          "x: 3567.03<br>y: 1271.55<br>Max iterations reached",
          "x: 3592.88<br>y: 1215.46<br>Max iterations reached",
          "x: 3592.88<br>y: 1234.15<br>Max iterations reached",
          "x: 3618.72<br>y: 1178.06<br>Max iterations reached",
          "x: 3618.72<br>y: 1196.76<br>Max iterations reached",
          "x: 3618.72<br>y: 1215.46<br>Max iterations reached",
          "x: 3644.57<br>y: 392.69<br>Max iterations reached",
          "x: 3644.57<br>y: 1140.66<br>Max iterations reached",
          "x: 3644.57<br>y: 1159.36<br>Max iterations reached",
          "x: 3644.57<br>y: 1178.06<br>Max iterations reached",
          "x: 3670.42<br>y: 1121.96<br>Max iterations reached",
          "x: 3670.42<br>y: 1140.66<br>Max iterations reached",
          "x: 3696.27<br>y: 1084.56<br>Max iterations reached",
          "x: 3696.27<br>y: 1103.26<br>Max iterations reached",
          "x: 3722.12<br>y: 1047.16<br>Max iterations reached",
          "x: 3722.12<br>y: 1065.86<br>Max iterations reached",
          "x: 3747.96<br>y: 972.36<br>Distance non-convergent. Vertical error 0.016669876044034027 feet with 0.676802rad elevation, after 30 iterations.",
          "x: 3747.96<br>y: 991.06<br>Max iterations reached",
          "x: 3747.96<br>y: 1009.76<br>Max iterations reached",
          "x: 3747.96<br>y: 1028.46<br>Max iterations reached",
          "x: 3773.81<br>y: 953.67<br>Max iterations reached",
          "x: 3773.81<br>y: 972.36<br>Max iterations reached",
          "x: 3773.81<br>y: 991.06<br>Max iterations reached",
          "x: 3799.66<br>y: 860.17<br>Error non-convergent. Vertical error 6.916546681168256e-06 feet with 0.64081rad elevation, after 31 iterations.",
          "x: 3799.66<br>y: 934.97<br>Max iterations reached",
          "x: 3799.66<br>y: 953.67<br>Max iterations reached",
          "x: 3825.51<br>y: 860.17<br>Distance non-convergent. Vertical error 0.04247387774375966 feet with 0.659601rad elevation, after 13 iterations.",
          "x: 3825.51<br>y: 878.87<br>Max iterations reached",
          "x: 3825.51<br>y: 897.57<br>Max iterations reached",
          "x: 3825.51<br>y: 916.27<br>Max iterations reached",
          "x: 3851.36<br>y: 841.47<br>Max iterations reached",
          "x: 3851.36<br>y: 860.17<br>Distance non-convergent. Vertical error 0.026096129418874625 feet with 0.686298rad elevation, after 30 iterations.",
          "x: 3851.36<br>y: 878.87<br>Max iterations reached",
          "x: 3877.20<br>y: 804.07<br>Max iterations reached",
          "x: 3877.20<br>y: 822.77<br>Max iterations reached",
          "x: 3877.20<br>y: 841.47<br>Max iterations reached",
          "x: 3903.05<br>y: 766.67<br>Max iterations reached",
          "x: 3903.05<br>y: 785.37<br>Max iterations reached",
          "x: 3903.05<br>y: 804.07<br>Max iterations reached",
          "x: 3928.90<br>y: 729.27<br>Max iterations reached",
          "x: 3928.90<br>y: 747.97<br>Max iterations reached",
          "x: 3954.75<br>y: 691.87<br>Max iterations reached",
          "x: 3954.75<br>y: 710.57<br>Max iterations reached",
          "x: 3980.60<br>y: 542.28<br>Error non-convergent. Vertical error 0.04456922497547566 feet with 0.579291rad elevation, after 40 iterations.",
          "x: 3980.60<br>y: 635.78<br>Max iterations reached",
          "x: 3980.60<br>y: 654.48<br>Max iterations reached",
          "x: 3980.60<br>y: 673.18<br>Max iterations reached",
          "x: 4006.44<br>y: 598.38<br>Max iterations reached",
          "x: 4006.44<br>y: 617.08<br>Max iterations reached",
          "x: 4006.44<br>y: 635.78<br>Max iterations reached",
          "x: 4032.29<br>y: 542.28<br>Max iterations reached",
          "x: 4032.29<br>y: 560.98<br>Max iterations reached",
          "x: 4032.29<br>y: 579.68<br>Max iterations reached",
          "x: 4058.14<br>y: 504.88<br>Max iterations reached",
          "x: 4058.14<br>y: 523.58<br>Max iterations reached",
          "x: 4058.14<br>y: 542.28<br>Distance non-convergent. Vertical error 0.10899982326554891 feet with 0.662722rad elevation, after 33 iterations.",
          "x: 4083.99<br>y: 467.48<br>Max iterations reached",
          "x: 4083.99<br>y: 486.18<br>Max iterations reached",
          "x: 4083.99<br>y: 504.88<br>Distance non-convergent. Vertical error 0.2608633926975017 feet with 0.675906rad elevation, after 44 iterations.",
          "x: 4109.84<br>y: 411.38<br>Max iterations reached",
          "x: 4109.84<br>y: 430.08<br>Max iterations reached",
          "x: 4109.84<br>y: 448.78<br>Max iterations reached",
          "x: 4135.68<br>y: 373.99<br>Max iterations reached",
          "x: 4135.68<br>y: 392.69<br>Max iterations reached",
          "x: 4135.68<br>y: 411.38<br>Max iterations reached",
          "x: 4161.53<br>y: 317.89<br>Max iterations reached",
          "x: 4161.53<br>y: 336.59<br>Max iterations reached",
          "x: 4161.53<br>y: 355.29<br>Max iterations reached",
          "x: 4187.38<br>y: 261.79<br>Max iterations reached",
          "x: 4187.38<br>y: 280.49<br>Max iterations reached",
          "x: 4187.38<br>y: 299.19<br>Max iterations reached",
          "x: 4213.23<br>y: 224.39<br>Max iterations reached",
          "x: 4213.23<br>y: 243.09<br>Max iterations reached",
          "x: 4213.23<br>y: 261.79<br>Max iterations reached",
          "x: 4239.08<br>y: 168.29<br>Max iterations reached",
          "x: 4239.08<br>y: 186.99<br>Max iterations reached",
          "x: 4239.08<br>y: 205.69<br>Max iterations reached",
          "x: 4264.92<br>y: 112.20<br>Max iterations reached",
          "x: 4264.92<br>y: 130.90<br>Error non-convergent. Vertical error 0.15694698494138493 feet with 0.587748rad elevation, after 36 iterations.",
          "x: 4264.92<br>y: 149.59<br>Max iterations reached",
          "x: 4290.77<br>y: 56.10<br>Max iterations reached",
          "x: 4290.77<br>y: 74.80<br>Max iterations reached",
          "x: 4290.77<br>y: 93.50<br>Max iterations reached",
          "x: 4316.62<br>y: 0.00<br>Max iterations reached",
          "x: 4316.62<br>y: 18.70<br>Max iterations reached",
          "x: 4316.62<br>y: 37.40<br>Max iterations reached"
         ],
         "type": "scatter",
         "x": {
          "bdata": "lcmqFBjZOUCVyaoUGNlJQDAXgA/SYlNAlcmqFBjZWUD9veoMrydgQDAXgA/SYmNAYnAVEvWdZkCVyaoUGNlpQMgiQBc7FG1A/b3qDK8ncECWajWOQMVxQDAXgA/SYnNAycPKkGMAdUDJw8qQYwB1QGJwFRL1nXZAYnAVEvWddkD8HGCThjt4QPwcYJOGO3hAlcmqFBjZeUAudvWVqXZ7QMgiQBc7FH1AYc+KmMyxfkBhz4qYzLF+QP296gyvJ4BA/b3qDK8ngEBKFJDNd/aAQEoUkM139oBAlmo1jkDFgUDjwNpOCZSCQDAXgA/SYoNAfG0l0JoxhEB8bSXQmjGEQMnDypBjAIVAycPKkGMAhUAWGnBRLM+FQGJwFRL1nYZAr8a60r1sh0CvxrrSvWyHQK/GutK9bIdA/Bxgk4Y7iED8HGCThjuIQEhzBVRPColAlcmqFBjZiUDiH1DV4KeKQOIfUNXgp4pALnb1lal2i0B7zJpWckWMQMgiQBc7FI1AFHnl1wPjjUBhz4qYzLGOQK4lMFmVgI9A/b3qDK8nkEAjaT1tE4+QQEoUkM139pBAcL/iLdxdkUBwv+It3F2RQJZqNY5AxZFAvRWI7qQskkC9FYjupCySQOPA2k4JlJJACWwtr237kkAwF4AP0mKTQFbC0m82ypNAVsLSbzbKk0B8bSXQmjGUQKMYeDD/mJRA724d8cdnlUCJG2hyWQWXQNVxDTMi1JdA1XENMyLUl0AiyLLz6qKYQCLIsvPqophAbx5YtLNxmUCVyaoUGNmZQOIfUNXgp5pACMuiNUUPm0AudvWVqXabQFUhSPYN3ptAoXftttasnEDIIkAXOxSdQBR55dcD451AOyQ4OGhKnkBhz4qYzLGeQK4lMFmVgJ9A1NCCufnnn0D9veoMryegQP296gyvJ6BAkBMUPWFboEAjaT1tE4+gQCNpPW0Tj6BAI2k9bROPoEAjaT1tE4+gQLe+Zp3FwqBAShSQzXf2oEDdabn9KSqhQHC/4i3cXaFAAxUMXo6RoUCWajWOQMWhQJZqNY5AxaFAKsBevvL4oUAqwF6+8vihQL0ViO6kLKJAvRWI7qQsokBQa7EeV2CiQFBrsR5XYKJA48DaTgmUokDjwNpOCZSiQHYWBH+7x6JAdhYEf7vHokB2FgR/u8eiQAlsLa9t+6JACWwtr237okCdwVbfHy+jQJ3BVt8fL6NAMBeAD9Jio0AwF4AP0mKjQMNsqT+ElqNAw2ypP4SWo0BWwtJvNsqjQFbC0m82yqNA6Rf8n+j9o0DpF/yf6P2jQHxtJdCaMaRAfG0l0JoxpEAQw04ATWWkQBDDTgBNZaRAoxh4MP+YpECjGHgw/5ikQDZuoWCxzKRANm6hYLHMpEDJw8qQYwClQMnDypBjAKVAXBn0wBU0pUBcGfTAFTSlQO9uHfHHZ6VA724d8cdnpUDvbh3xx2elQIPERiF6m6VAg8RGIXqbpUAWGnBRLM+lQBYacFEsz6VAqW+Zgd4CpkCpb5mB3gKmQDzFwrGQNqZAPMXCsZA2pkA8xcKxkDamQM8a7OFCaqZAzxrs4UJqpkBicBUS9Z2mQGJwFRL1naZAYnAVEvWdpkBicBUS9Z2mQPbFPkKn0aZA9sU+QqfRpkD2xT5Cp9GmQIkbaHJZBadAiRtoclkFp0AccZGiCzmnQBxxkaILOadAr8a60r1sp0CvxrrSvWynQK/GutK9bKdAQhzkAnCgp0BCHOQCcKCnQNVxDTMi1KdA1XENMyLUp0DVcQ0zItSnQGnHNmPUB6hAacc2Y9QHqED8HGCThjuoQPwcYJOGO6hAj3KJwzhvqECPconDOG+oQCLIsvPqoqhAIsiy8+qiqEAiyLLz6qKoQLUd3COd1qhAtR3cI53WqEBIcwVUTwqpQEhzBVRPCqlASHMFVE8KqUBIcwVUTwqpQNzILoQBPqlA3MguhAE+qUDcyC6EAT6pQG8eWLSzcalAbx5YtLNxqUBvHli0s3GpQAJ0geRlpalAAnSB5GWlqUCVyaoUGNmpQJXJqhQY2alAlcmqFBjZqUAoH9REygyqQCgf1ETKDKpAu3T9dHxAqkC7dP10fECqQLt0/XR8QKpATsompS50qkBOyialLnSqQE7KJqUudKpA4h9Q1eCnqkDiH1DV4KeqQOIfUNXgp6pAdXV5BZPbqkB1dXkFk9uqQHV1eQWT26pAdXV5BZPbqkAIy6I1RQ+rQAjLojVFD6tAmyDMZfdCq0CbIMxl90KrQC529ZWpdqtALnb1lal2q0AudvWVqXarQMHLHsZbqqtAwcsexluqq0DByx7GW6qrQFUhSPYN3qtAVSFI9g3eq0BVIUj2Dd6rQOh2cSbAEaxA6HZxJsARrEB7zJpWckWsQHvMmlZyRaxAe8yaVnJFrEAOIsSGJHmsQA4ixIYkeaxADiLEhiR5rEAOIsSGJHmsQKF37bbWrKxAoXftttasrEA0zRbniOCsQDTNFueI4KxAyCJAFzsUrUDIIkAXOxStQFt4aUftR61AW3hpR+1HrUBbeGlH7UetQFt4aUftR61A7s2Sd597rUDuzZJ3n3utQO7Nknefe61AgSO8p1GvrUCBI7ynUa+tQIEjvKdRr61AFHnl1wPjrUAUeeXXA+OtQBR55dcD461AFHnl1wPjrUCnzg4IthauQKfODgi2Fq5Ap84OCLYWrkA7JDg4aEquQDskODhoSq5AOyQ4OGhKrkDOeWFoGn6uQM55YWgafq5AznlhaBp+rkBhz4qYzLGuQGHPipjMsa5A9CS0yH7lrkD0JLTIfuWuQId63fgwGa9Ah3rd+DAZr0CHet34MBmvQId63fgwGa9AGtAGKeNMr0Aa0AYp40yvQBrQBinjTK9AriUwWZWAr0CuJTBZlYCvQK4lMFmVgK9AQXtZiUe0r0BBe1mJR7SvQEF7WYlHtK9A1NCCufnnr0DU0IK5+eevQNTQgrn5569ANBPW9NUNsEA0E9b01Q2wQDQT1vTVDbBA/b3qDK8nsED9veoMryewQP296gyvJ7BAx2j/JIhBsEDHaP8kiEGwQMdo/ySIQbBAkBMUPWFbsECQExQ9YVuwQJATFD1hW7BAWr4oVTp1sEBavihVOnWwQFq+KFU6dbBAI2k9bROPsEAjaT1tE4+wQCNpPW0Tj7BA7RNSheyosEDtE1KF7KiwQO0TUoXsqLBAt75mncXCsEC3vmadxcKwQLe+Zp3FwrBAgGl7tZ7csECAaXu1ntywQIBpe7We3LBA",
          "dtype": "f8"
         },
         "y": {
          "bdata": "ADuhlD83oEBQRmFlkmWoQFBGYWWSZahAUEZhZZJlqEBQRmFlkmWoQFBGYWWSZahAUEZhZZJlqEBQRmFlkmWoQFBGYWWSZahAUEZhZZJlqEBQRmFlkmWoQFBGYWWSZahAr2qCWCxAqEBQRmFlkmWoQK9qglgsQKhAUEZhZZJlqECvaoJYLECoQFBGYWWSZahAr2qCWCxAqECvaoJYLECoQK9qglgsQKhAytflMfrPp0CvaoJYLECoQA2Po0vGGqhAr2qCWCxAqEANj6NLxhqoQK9qglgsQKhADY+jS8YaqEANj6NLxhqoQA2Po0vGGqhAbLPEPmD1p0ANj6NLxhqoQGyzxD5g9adADY+jS8YaqEBss8Q+YPWnQGyzxD5g9adAv/ruysmkpkDK1+Ux+s+nQGyzxD5g9adAytflMfrPp0Bss8Q+YPWnQMrX5TH6z6dAytflMfrPp0Ap/AYllKqnQMrX5TH6z6dAKfwGJZSqp0Ap/AYllKqnQCn8BiWUqqdAhyAoGC6Fp0CHICgYLoWnQIcgKBguhadA5kRJC8hfp0DmREkLyF+nQOZESQvIX6dASRzgCc9zpEBFaWr+YTqnQEVpav5hOqdAo42L8fsUp0BFaWr+YTqnQKONi/H7FKdAo42L8fsUp0ACsqzkle+mQJiwlIrL6aVAArKs5JXvpkBg1s3XL8qmQGDWzdcvyqZAv/ruysmkpkB8QzGx/VmmQGDWzdcvypZA2mdSpJc0pkBV+dZw/56lQDmMc5cxD6ZAmLCUisvppUD21LV9ZcSlQFX51nD/nqVAjkqpc/F2i0CzHfhjmXmlQBJCGVczVKVAcGY6Ss0upUDPils9ZwmlQC6vfDAB5KRAjNOdI5u+pEDr974WNZmkQEkc4AnPc6RAqEAB/WhOpEC40G1vBrMyQAZlIvACKaRAZYlD45wDpECYsJSKy+mVQIH2prxqk6NAxK1k1jbeo0BliUPjnAOkQMStZNY23qNAItKFydC4o0CB9qa8apOjQN8ayK8EbqNAPj/pop5Io0CcYwqWOCOjQD4/6aKeSKNA+4cridL9okCcYwqWOCOjQFmsTHxs2KJA+4cridL9okC40G1vBrOiQFmsTHxs2KJAF/WOYqCNokC40G1vBrOiQBS5JKeJDExAdRmwVTpookAX9Y5ioI2iQNQ90UjUQqJAdRmwVTpookAyYvI7bh2iQNQ90UjUQqJAkYYTLwj4oUAyYvI7bh2iQO+qNCKi0qFAkYYTLwj4oUBOz1UVPK2hQO+qNCKi0qFArPN2CNaHoUBOz1UVPK2hQAsYmPtvYqFArPN2CNaHoUBqPLnuCT2hQAsYmPtvYqFAyGDa4aMXoUBqPLnuCT2hQCeF+9Q98qBAyGDa4aMXoUCFqRzI18ygQCeF+9Q98qBA5M09u3GnoECFqRzI18ygQGDWzdcvypZAQvJerguCoEDkzT27caegQAA7oZQ/N6BAoRaAoaVcoEBeX8KH2RGgQAA7oZQ/N6BAeQfH9ebYn0BeX8KH2RGgQJonoNohopxANlAJ3BqOn0B5B8f15tifQPSYS8JOQ59ANlAJ3BqOn0AUuSSniQxsQOZESQvIX3dAseGNqIL4nkD0mEvCTkOfQAjcLUBZ4ZpAK3MSdepinkBuKtCOtq2eQOi7VFseGJ5AK3MSdepinkClBJdBUs2dQOi7VFseGJ5AIJYbDro3nUBiTdknhoKdQKUEl0FSzZ1A3d5d9O3snEAglhsOujedQI5KqXPxdptAmieg2iGinEDd3l307eycQFdw4sBVV5xAmieg2iGinEDRAWeNvcGbQBS5JKeJDJxAjkqpc/F2m0DRAWeNvcGbQKEWgKGlXHBACNwtQFnhmkBLk+tZJSybQMYkcCaNlppACNwtQFnhmkAUuSSniQxsQEC29PL0AJpAg22yDMFLmkDGJHAmjZaaQIzTnSObvpRA/f422Si2mUBAtvTy9ACaQHeQu6WQIJlAukd5v1xrmUD9/jbZKLaZQDTZ/YvE1ZhAd5C7pZAgmUCvaoJYLECYQPIhQHL4iphANNn9i8TVmEBss8Q+YPWXQK9qglgsQJhA5kRJC8hfl0Ap/AYllKqXQGyzxD5g9ZdApQSXQVLNjUCjjYvx+xSXQOZESQvIX5dASRzgCc9zlEAdHxC+Y3+WQGDWzdcvypZA5kRJC8hfV0CYsJSKy+mVQNpnUqSXNJZAHR8QvmN/lkBV+dZw/56VQJiwlIrL6ZVAz4pbPWcJlUASQhlXM1SVQEkc4AnPc5RAjNOdI5u+lEDPils9ZwmVQO+qNCKi0pFABmUi8AIplEBJHOAJz3OUQPIhQHL4iohAgfamvGqTk0DErWTWNt6TQPuHK4nS/ZJAPj/pop5Ik0B1GbBVOmiSQLjQbW8Gs5JA+4cridL9kkDyIUBy+Ip4QO+qNCKi0pFAMmLyO24dkkB1GbBVOmiSQKzzdgjWh5FA76o0IqLSkUAnhfvUPfKQQGo8ue4JPZFAoRaAoaVckEDkzT27caeQQCtzEnXqYo5AseGNqIL4jkA2UAncGo6PQF5fwofZEZBApQSXQVLNjUArcxJ16mKOQLHhjaiC+I5ACNwtQFnhikAglhsOujeNQKUEl0FSzY1ACNwtQFnhikCOSqlz8XaLQBS5JKeJDIxAmieg2iGijECDbbIMwUuKQAjcLUBZ4YpAjkqpc/F2i0B3kLulkCCJQP3+NtkotolAg22yDMFLikBss8Q+YPWHQPIhQHL4iohAd5C7pZAgiUBg1s3XL8qGQOZESQvIX4dAVfnWcP+ehUDaZ1KklzSGQCeF+9Q98oBAxK1k1jbeg0BJHOAJz3OEQM+KWz1nCYVAuNBtbwazgkA+P+minkiDQMStZNY23oNAJ4X71D3ygECs83YI1oeBQDJi8jtuHYJANlAJ3BqOf0ChFoChpVyAQCeF+9Q98oBAIJYbDro3fUArcxJ16mJ+QDZQCdwajn9A/f422Si2eUAI3C1AWeF6QBS5JKeJDHxA5kRJC8hfd0DyIUBy+Ip4QP3+NtkotnlAxK1k1jbec0DPils9Zwl1QNpnUqSXNHZAoRaAoaVccECs83YI1odxQLjQbW8Gs3JAFLkkp4kMbEArcxJ16mJuQKEWgKGlXHBAz4pbPWcJZUDmREkLyF9nQP3+NtkotmlAFLkkp4kMXEChFoChpVxgQLjQbW8Gs2JAFLkkp4kMTEC40G1vBrNSQOZESQvIX1dAAAAAAAAAAAC40G1vBrMyQLjQbW8Gs0JA",
          "dtype": "f8"
         }
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": true,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Iterations to find zero for target point",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 86556 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_samples(baseline_huge_df, filename='ZeroBaseline')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "05cbb75a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "count    20073.000000\n",
       "mean        10.294226\n",
       "std          7.930109\n",
       "min          2.000000\n",
       "25%          6.000000\n",
       "50%          8.000000\n",
       "75%         11.000000\n",
       "max         50.000000\n",
       "Name: iterations, dtype: float64"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "baseline_huge_df['iterations'].describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d935a03",
   "metadata": {},
   "source": [
    "## Sensitivity Limit\n",
    "\n",
    "What if we bound the sensitivity term at 0, instead of letting it go as low as -0.5?  It looks like this costs some extra iterations in a small slice approaching the maximum range at elevated look angles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "b965129d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c302d7b8a83b483cb961061eb46cfac8",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/404 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.36,
           "#00FF00"
          ],
          [
           1,
           "#1212FF"
          ],
          [
           1,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "CyiWVbC3YkALKJZVsLdyQBA8YYCIE3xACyiWVbC3gkAOsvtqnGWHQBA8YYCIE4xACmPjSrpgkEALKJZVsLeSQAztSGCmDpVADrL7apxll0APd651kryZQBA8YYCIE5xAEgEUi35qnkAKY+NKumCgQIrFPFA1jKFACyiWVbC3okCMiu9aK+OjQAztSGCmDqVAjU+iZSE6pkAOsvtqnGWnQI4UVXAXkahAD3eudZK8qUCQ2Qd7DeiqQBA8YYCIE6xAkZ66hQM/rUASARSLfmquQJNjbZD5la9ACmPjSrpgsEA=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAAAUbFjW7hRbQBRsWNbuFGtAD1HCILNPdEAUbFjW7hR7QIxD90UV7YBAD1HCILNPhECSXo37ULKHQBRsWNbuFItAlnkjsYx3jkCMQ/dFFe2QQE7KXDNknpJAD1HCILNPlEDQ1ycOAgGWQJJejftQspdAU+Xy6J9jmUAUbFjW7hSbQNXyvcM9xpxAlnkjsYx3nkAsgETPbRSgQIxD90UV7aBA7QaqvLzFoUBOylwzZJ6iQK6ND6oLd6NAD1HCILNPpEBwFHWXWiilQNDXJw4CAaZAMZvahKnZpkCSXo37ULKnQA==",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 8664 characters]",
          "dtype": "f8",
          "shape": "29, 28"
         }
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "title": {
          "text": "Result"
         },
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": true,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Extra iterations to find zero with sensitivity limit raised from -0.5 to 0.0",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(small_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(zero_test(point['x'], point['y'], sensitivity_limit=0.0))\n",
    "sensitivity_positive_df = pd.DataFrame(results)\n",
    "sensitivity_positive_df.to_csv('ZeroSensitivityPositive.csv')\n",
    "diff_df = sensitivity_positive_df[~sensitivity_positive_df.solution.isna()].copy()\n",
    "diff_df['iterations'] -= baseline_small_df['iterations']\n",
    "p = plot_test_results(diff_df, envelope_df, title_str='Extra iterations to find zero with sensitivity limit raised from -0.5 to 0.0')\n",
    "p.write_html('ZeroSensitivityPositiveChart.html')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a85e5b57",
   "metadata": {},
   "source": [
    "# scipy_engine.find_zero_angle()\n",
    "\n",
    "For comparison, how many trajectory calculations does `scipy_engine.find_zero_angle()` take?  We want to decompose the current version because it does two operations:\n",
    "\n",
    "1. Calls `._find_max_range()` on the look-angle to the target.  This returns the maximum range along that look-angle as well as the max-launch-angle to hit it.  We use the maximum range to ensure that a solution exists to hit the target.  We use the max-launch-angle in the next step:\n",
    "2. Runs SciPy's `root_scalar` with the `brentq` method to find the solution, using the angle to the max range found in step #1 to define the search bracket [slant-angle, max-launch-angle].\n",
    "\n",
    "As we will see, the first step is relatively expensive.  If we want to skip the first step then we have two general problems:\n",
    "1. We can't guarantee that the target is within range.\n",
    "2. For every target inside the reachable envelope, there are two trajectories that can hit it.\n",
    "\n",
    "Here we already know that we are only studying points that are within range of the shot.  However, to guarantee that we find the flatter of the two possible trajectories we can no longer use a method that requires a bracket.  (The most tricky points are near the vertical where the launch difference between the \"lofted\" and \"flat\" trajectories approaches zero.)  But we'll add an option to run Newton's method starting with the slant-angle, since the flat trajectory is always closer to that, and see how that does."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d1d67560",
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.optimize import root_scalar\n",
    "def scipy_zero_test(x_m: float, y_m: float, check_in_range: bool=True, calc_config=None, root_method='brentq'):\n",
    "    target_dist = Distance.Meter(math.sqrt(x_m**2 + y_m**2))\n",
    "    slant_angle_rad = math.atan2(y_m, x_m)\n",
    "    slant_angle = Angular.Radian(slant_angle_rad)\n",
    "    shot = create_shot()\n",
    "    shot.slant_angle = slant_angle\n",
    "\n",
    "    target_x_ft = Distance.Meter(x_m) >> Distance.Foot\n",
    "    target_y_ft = Distance.Meter(y_m) >> Distance.Foot\n",
    "    if calc_config is None:\n",
    "        calc_config = BaseEngineConfigDict(\n",
    "            cMinimumVelocity=0,\n",
    "            cMinimumAltitude=-target_x_ft/2.0,\n",
    "            cMaximumDrop=target_x_ft/2.0,\n",
    "        )\n",
    "    calc = Calculator(config=calc_config, engine=\"scipy_engine\")\n",
    "    props = calc._init_trajectory(shot)\n",
    "    start_count = calc.trajectory_count\n",
    "\n",
    "    def error_at_distance(angle_rad: float) -> float:\n",
    "        \"\"\"Target miss (in feet) for launch at <angle_rad>.\"\"\"\n",
    "        props.barrel_elevation_rad = angle_rad\n",
    "        # Integrate to find the projectile's state at the target's horizontal distance.\n",
    "        t = calc._integrate(props, target_x_ft, target_x_ft, filter_flags=TrajFlag.NONE)[-1]\n",
    "        if t.time == 0.0:\n",
    "            logger.warning(\"Integrator returned initial point. Consider removing constraints.\")\n",
    "            return -1e6  # Large negative error to discourage this angle.\n",
    "        # return -abs(t.slant_height >> Distance.Foot) - abs((t.slant_distance >> Distance.Foot) - slant_range_ft)\n",
    "        return (t.height >> Distance.Foot) - target_y_ft - abs((t.distance >> Distance.Foot) - target_x_ft)\n",
    "\n",
    "    if check_in_range:  # Current implementation, first calls find_max_range\n",
    "        max_range, angle_at_max = calc._find_max_range(props)\n",
    "        max_range_count = calc.trajectory_count\n",
    "        angle_bracket = (props.look_angle_rad, angle_at_max >> Angular.Radian)\n",
    "        try:\n",
    "            sol = root_scalar(error_at_distance, bracket=angle_bracket, method=root_method)\n",
    "            if not sol.converged:\n",
    "                raise ValueError()\n",
    "            result = {\n",
    "                'x': point['x'], 'y': point['y'],\n",
    "                'iterations': calc.trajectory_count - start_count,\n",
    "                'range_iterations': max_range_count - start_count,\n",
    "                'zero_iterations': calc.trajectory_count - max_range_count,\n",
    "                'solution': sol.root,\n",
    "                'max_range': max_range >> Distance.Meter,\n",
    "                'angle_at_max': angle_at_max >> Angular.Degree,\n",
    "                'error': None\n",
    "            }\n",
    "            return result\n",
    "        except ValueError as e:\n",
    "            result = {\n",
    "                'x': point['x'], 'y': point['y'],\n",
    "                'iterations': calc.trajectory_count - start_count,\n",
    "                'range_iterations': max_range_count - start_count,\n",
    "                'zero_iterations': calc.trajectory_count - max_range_count,\n",
    "                'solution': None,\n",
    "                'max_range': max_range >> Distance.Meter,\n",
    "                'angle_at_max': angle_at_max >> Angular.Degree,\n",
    "                'error': \"No solution found\"\n",
    "            }\n",
    "            return result\n",
    "    else:  # Use Newton's method\n",
    "        try:\n",
    "            sol = root_scalar(error_at_distance, x0=slant_angle_rad, method='newton')\n",
    "            if not sol.converged:\n",
    "                raise ValueError()\n",
    "            result = {\n",
    "                'x': point['x'], 'y': point['y'],\n",
    "                'iterations': calc.trajectory_count - start_count,\n",
    "                'solution': sol.root,\n",
    "                'error': None\n",
    "            }\n",
    "            return result\n",
    "        except ValueError as e:\n",
    "            result = {\n",
    "                'x': point['x'], 'y': point['y'],\n",
    "                'iterations': calc.trajectory_count - start_count,\n",
    "                'solution': None,\n",
    "                'error': \"No solution found\"\n",
    "            }\n",
    "            return result"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "533e9e59",
   "metadata": {},
   "source": [
    "## Newton's method (small sample)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d66c5d0c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "27f60e6ee04d4315b5f916b08d0cd3c9",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/404 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(small_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(scipy_zero_test(point['x'], point['y'], check_in_range=False))\n",
    "newton_small_df = pd.DataFrame(results)    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "3830d6c6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(1.2138255368887574e-07)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Confirm that it is finding the same points as the baseline\n",
    "newton_small_df['chk'] = abs(newton_small_df['solution'] - baseline_small_df['solution'])\n",
    "newton_small_df['chk'].sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a49abcfb",
   "metadata": {},
   "source": [
    "## Newton's method (big sample)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "6bc056b5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "702ea81a1ed94c14a57ff5c7b2751ae4",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/5005 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(big_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(scipy_zero_test(point['x'], point['y'], check_in_range=False))\n",
    "newton_big_df = pd.DataFrame(results)\n",
    "newton_big_df.to_csv('ZeroNewtonBig.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "id": "df51bca2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.06,
           "#00FF00"
          ],
          [
           0.4,
           "#1212FF"
          ],
          [
           0.96,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "2WlL8z6LSUDZaUvzPotZQGOPeDZvKGNA2WlL8z6LaUBPRB6wDu5vQGOPeDZvKHNAnvzhFNdZdkDZaUvzPot5QBTXtNGmvHxAT0QesA7uf0DF2ENHu4+BQGOPeDZvKINAAEatJSPBhECe/OEU11mGQDuzFgSL8odA2WlL8z6LiUB3IIDi8iOLQBTXtNGmvIxAso3pwFpVjkBPRB6wDu6PQHZ9qU9hw5BAxdhDR7uPkUAUNN4+FVySQGOPeDZvKJNAsuoSLsn0k0AARq0lI8GUQE+hRx19jZVAnvzhFNdZlkDtV3wMMSaXQDuzFgSL8pdAig6x++S+mEDZaUvzPouZQCjF5eqYV5pAdyCA4vIjm0DFexraTPCbQBTXtNGmvJxAYzJPyQCJnUCyjenAWlWeQADpg7i0IZ9AT0QesA7un0DPT9xTNF2gQHZ9qU9hw6BAHqt2S44poUDF2ENHu4+hQG0GEUPo9aFAFDTePhVcokC7Yas6QsKiQGOPeDZvKKNACr1FMpyOo0Cy6hIuyfSjQFkY4Cn2WqRAAEatJSPBpECoc3ohUCelQE+hRx19jaVA9s4UGarzpUCe/OEU11mmQEUqrxAEwKZA7Vd8DDEmp0CUhUkIXoynQDuzFgSL8qdA4+Dj/7dYqECKDrH75L6oQDI8fvcRJalA2WlL8z6LqUCAlxjva/GpQCjF5eqYV6pAz/Ky5sW9qkB3IIDi8iOrQB5OTd4fiqtAxXsa2kzwq0BtqefVeVasQBTXtNGmvKxAvASCzdMirUBjMk/JAImtQApgHMUt761Aso3pwFpVrkBZu7a8h7uuQADpg7i0Ia9AqBZRtOGHr0BPRB6wDu6vQPu49dUdKrBAz0/cUzRdsECj5sLRSpCwQHZ9qU9hw7BA",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAABK1LoKtXpCQErUugq1elJAbz4YkA+4W0BK1LoKtXpiQFyJaU1iGWdAbz4YkA+4a0DBeWNpXitwQErUugq1enJA0y4SrAvKdEBciWlNYhl3QObjwO64aHlAbz4YkA+4e0D4mG8xZgd+QMF5Y2leK4BABScPuglTgUBK1LoKtXqCQI+BZltgooNA0y4SrAvKhEAY3L38tvGFQFyJaU1iGYdAoTYVng1BiEDm48DuuGiJQCqRbD9kkIpAbz4YkA+4i0C068Pgut+MQPiYbzFmB45APUYbghEvj0DBeWNpXiuQQGNQuRE0v5BABScPuglTkUCo/WRi3+aRQErUugq1epJA7KoQs4oOk0CPgWZbYKKTQDFYvAM2NpRA0y4SrAvKlEB2BWhU4V2VQBjcvfy28ZVAurITpYyFlkBciWlNYhmXQP9fv/U3rZdAoTYVng1BmEBDDWtG49SYQObjwO64aJlAiLoWl478mUAqkWw/ZJCaQM1nwuc5JJtAbz4YkA+4m0ARFW445UucQLTrw+C635xAVsIZiZBznUD4mG8xZgeeQJtvxdk7m55APUYbghEvn0DfHHEq58KfQMF5Y2leK6BAEmWOPUl1oEBjULkRNL+gQLQ75OUeCaFABScPuglToUBXEjqO9JyhQKj9ZGLf5qFA+eiPNsowokBK1LoKtXqiQJu/5d6fxKJA7KoQs4oOo0A9ljuHdVijQI+BZltgoqNA4GyRL0vso0AxWLwDNjakQIJD59cggKRA0y4SrAvKpEAkGj2A9hOlQHYFaFThXaVAx/CSKMynpUAY3L38tvGlQGnH6NChO6ZAurITpYyFpkALnj55d8+mQFyJaU1iGadArnSUIU1jp0D/X7/1N62nQFBL6ski96dAoTYVng1BqEA=",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 76160 characters]",
          "dtype": "f8",
          "shape": "85, 84"
         },
         "zmax": 50,
         "zmin": 0
        },
        {
         "hoverinfo": "text",
         "marker": {
          "color": "white",
          "line": {
           "color": "black",
           "width": 1
          },
          "size": 7,
          "symbol": "square"
         },
         "mode": "markers",
         "name": "Failed to converge",
         "text": [
          "x: 3065.27<br>y: 258.71<br>No solution found"
         ],
         "type": "scatter",
         "x": {
          "bdata": "O7MWBIvyp0A=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "wXljaV4rcEA=",
          "dtype": "f8"
         }
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Newton's method iterations to find zero",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 60088 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_samples(newton_big_df, \"ZeroNewton\", \"Newton's method iterations to find zero\", show_legend=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "17894497",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "count    5005.000000\n",
       "mean       12.638362\n",
       "std         3.060652\n",
       "min         9.000000\n",
       "25%        12.000000\n",
       "50%        12.000000\n",
       "75%        12.000000\n",
       "max       150.000000\n",
       "Name: iterations, dtype: float64"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "newton_big_df['iterations'].describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "300222d7",
   "metadata": {},
   "source": [
    "## Newton's method (huge)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "id": "a143d322",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "850ba78e319d43879fbd2e6118544e16",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/20073 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(huge_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(scipy_zero_test(point['x'], point['y'], check_in_range=False))\n",
    "newton_huge_df = pd.DataFrame(results)\n",
    "newton_huge_df.to_csv('ZeroNewtonHuge.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "id": "33665352",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.06,
           "#00FF00"
          ],
          [
           0.4,
           "#1212FF"
          ],
          [
           0.96,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "lcmqFBjZOUCVyaoUGNlJQDAXgA/SYlNAlcmqFBjZWUD9veoMrydgQDAXgA/SYmNAYnAVEvWdZkCVyaoUGNlpQMgiQBc7FG1A/b3qDK8ncECWajWOQMVxQDAXgA/SYnNAycPKkGMAdUBicBUS9Z12QPwcYJOGO3hAlcmqFBjZeUAudvWVqXZ7QMgiQBc7FH1AYc+KmMyxfkD9veoMryeAQEoUkM139oBAlmo1jkDFgUDjwNpOCZSCQDAXgA/SYoNAfG0l0JoxhEDJw8qQYwCFQBYacFEsz4VAYnAVEvWdhkCvxrrSvWyHQPwcYJOGO4hASHMFVE8KiUCVyaoUGNmJQOIfUNXgp4pALnb1lal2i0B7zJpWckWMQMgiQBc7FI1AFHnl1wPjjUBhz4qYzLGOQK4lMFmVgI9A/b3qDK8nkEAjaT1tE4+QQEoUkM139pBAcL/iLdxdkUCWajWOQMWRQL0ViO6kLJJA48DaTgmUkkAJbC2vbfuSQDAXgA/SYpNAVsLSbzbKk0B8bSXQmjGUQKMYeDD/mJRAycPKkGMAlUDvbh3xx2eVQBYacFEsz5VAPMXCsZA2lkBicBUS9Z2WQIkbaHJZBZdAr8a60r1sl0DVcQ0zItSXQPwcYJOGO5hAIsiy8+qimEBIcwVUTwqZQG8eWLSzcZlAlcmqFBjZmUC7dP10fECaQOIfUNXgp5pACMuiNUUPm0AudvWVqXabQFUhSPYN3ptAe8yaVnJFnEChd+221qycQMgiQBc7FJ1A7s2Sd597nUAUeeXXA+OdQDskODhoSp5AYc+KmMyxnkCHet34MBmfQK4lMFmVgJ9A1NCCufnnn0D9veoMryegQJATFD1hW6BAI2k9bROPoEC3vmadxcKgQEoUkM139qBA3Wm5/SkqoUBwv+It3F2hQAMVDF6OkaFAlmo1jkDFoUAqwF6+8vihQL0ViO6kLKJAUGuxHldgokDjwNpOCZSiQHYWBH+7x6JACWwtr237okCdwVbfHy+jQDAXgA/SYqNAw2ypP4SWo0BWwtJvNsqjQOkX/J/o/aNAfG0l0JoxpEAQw04ATWWkQKMYeDD/mKRANm6hYLHMpEDJw8qQYwClQFwZ9MAVNKVA724d8cdnpUCDxEYhepulQBYacFEsz6VAqW+Zgd4CpkA8xcKxkDamQM8a7OFCaqZAYnAVEvWdpkD2xT5Cp9GmQIkbaHJZBadAHHGRogs5p0CvxrrSvWynQEIc5AJwoKdA1XENMyLUp0BpxzZj1AeoQPwcYJOGO6hAj3KJwzhvqEAiyLLz6qKoQLUd3COd1qhASHMFVE8KqUDcyC6EAT6pQG8eWLSzcalAAnSB5GWlqUCVyaoUGNmpQCgf1ETKDKpAu3T9dHxAqkBOyialLnSqQOIfUNXgp6pAdXV5BZPbqkAIy6I1RQ+rQJsgzGX3QqtALnb1lal2q0DByx7GW6qrQFUhSPYN3qtA6HZxJsARrEB7zJpWckWsQA4ixIYkeaxAoXftttasrEA0zRbniOCsQMgiQBc7FK1AW3hpR+1HrUDuzZJ3n3utQIEjvKdRr61AFHnl1wPjrUCnzg4IthauQDskODhoSq5AznlhaBp+rkBhz4qYzLGuQPQktMh+5a5Ah3rd+DAZr0Aa0AYp40yvQK4lMFmVgK9AQXtZiUe0r0DU0IK5+eevQDQT1vTVDbBA/b3qDK8nsEDHaP8kiEGwQJATFD1hW7BAWr4oVTp1sEAjaT1tE4+wQO0TUoXsqLBAt75mncXCsECAaXu1ntywQA==",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAAC40G1vBrMyQLjQbW8Gs0JAFLkkp4kMTEC40G1vBrNSQOZESQvIX1dAFLkkp4kMXEChFoChpVxgQLjQbW8Gs2JAz4pbPWcJZUDmREkLyF9nQP3+NtkotmlAFLkkp4kMbEArcxJ16mJuQKEWgKGlXHBArPN2CNaHcUC40G1vBrNyQMStZNY23nNAz4pbPWcJdUDaZ1KklzR2QOZESQvIX3dA8iFAcviKeED9/jbZKLZ5QAjcLUBZ4XpAFLkkp4kMfEAglhsOujd9QCtzEnXqYn5ANlAJ3BqOf0ChFoChpVyAQCeF+9Q98oBArPN2CNaHgUAyYvI7bh2CQLjQbW8Gs4JAPj/pop5Ig0DErWTWNt6DQEkc4AnPc4RAz4pbPWcJhUBV+dZw/56FQNpnUqSXNIZAYNbN1y/KhkDmREkLyF+HQGyzxD5g9YdA8iFAcviKiEB3kLulkCCJQP3+NtkotolAg22yDMFLikAI3C1AWeGKQI5KqXPxdotAFLkkp4kMjECaJ6DaIaKMQCCWGw66N41ApQSXQVLNjUArcxJ16mKOQLHhjaiC+I5ANlAJ3BqOj0BeX8KH2RGQQKEWgKGlXJBA5M09u3GnkEAnhfvUPfKQQGo8ue4JPZFArPN2CNaHkUDvqjQiotKRQDJi8jtuHZJAdRmwVTpokkC40G1vBrOSQPuHK4nS/ZJAPj/pop5Ik0CB9qa8apOTQMStZNY23pNABmUi8AIplEBJHOAJz3OUQIzTnSObvpRAz4pbPWcJlUASQhlXM1SVQFX51nD/npVAmLCUisvplUDaZ1KklzSWQB0fEL5jf5ZAYNbN1y/KlkCjjYvx+xSXQOZESQvIX5dAKfwGJZSql0Bss8Q+YPWXQK9qglgsQJhA8iFAcviKmEA02f2LxNWYQHeQu6WQIJlAukd5v1xrmUD9/jbZKLaZQEC29PL0AJpAg22yDMFLmkDGJHAmjZaaQAjcLUBZ4ZpAS5PrWSUsm0COSqlz8XabQNEBZ429wZtAFLkkp4kMnEBXcOLAVVecQJonoNohopxA3d5d9O3snEAglhsOujedQGJN2SeGgp1ApQSXQVLNnUDou1RbHhieQCtzEnXqYp5AbirQjratnkCx4Y2ogvieQPSYS8JOQ59ANlAJ3BqOn0B5B8f15tifQF5fwofZEaBAADuhlD83oEChFoChpVygQELyXq4LgqBA5M09u3GnoECFqRzI18ygQCeF+9Q98qBAyGDa4aMXoUBqPLnuCT2hQAsYmPtvYqFArPN2CNaHoUBOz1UVPK2hQO+qNCKi0qFAkYYTLwj4oUAyYvI7bh2iQNQ90UjUQqJAdRmwVTpookAX9Y5ioI2iQLjQbW8Gs6JAWaxMfGzYokD7hyuJ0v2iQJxjCpY4I6NAPj/pop5Io0DfGsivBG6jQIH2prxqk6NAItKFydC4o0DErWTWNt6jQGWJQ+OcA6RABmUi8AIppECoQAH9aE6kQEkc4AnPc6RA6/e+FjWZpECM050jm76kQC6vfDAB5KRAz4pbPWcJpUBwZjpKzS6lQBJCGVczVKVAsx34Y5l5pUBV+dZw/56lQPbUtX1lxKVAmLCUisvppUA5jHOXMQ+mQNpnUqSXNKZAfEMxsf1ZpkAdHxC+Y3+mQL/67srJpKZAYNbN1y/KpkACsqzkle+mQKONi/H7FKdARWlq/mE6p0DmREkLyF+nQIcgKBguhadAKfwGJZSqp0DK1+Ux+s+nQGyzxD5g9adADY+jS8YaqECvaoJYLECoQFBGYWWSZahA",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 299264 characters]",
          "dtype": "f8",
          "shape": "168, 167"
         },
         "zmax": 50,
         "zmin": 0
        },
        {
         "hoverinfo": "text",
         "marker": {
          "color": "white",
          "line": {
           "color": "black",
           "width": 1
          },
          "size": 7,
          "symbol": "square"
         },
         "mode": "markers",
         "name": "Failed to converge",
         "text": [
          "x: 1266.55<br>y: 2804.90<br>No solution found",
          "x: 1576.73<br>y: 2767.50<br>No solution found",
          "x: 1654.27<br>y: 2786.20<br>No solution found",
          "x: 2067.84<br>y: 18.70<br>No solution found",
          "x: 2300.47<br>y: 2430.91<br>No solution found",
          "x: 3256.85<br>y: 1608.14<br>No solution found",
          "x: 3567.03<br>y: 785.37<br>No solution found",
          "x: 3644.57<br>y: 392.69<br>No solution found"
         ],
         "type": "scatter",
         "x": {
          "bdata": "VsLSbzbKk0AiyLLz6qKYQJXJqhQY2ZlA/b3qDK8noEAqwF6+8vihQG8eWLSzcalAVSFI9g3eq0AOIsSGJHmsQA==",
          "dtype": "f8"
         },
         "y": {
          "bdata": "mLCUisvppUBV+dZw/56lQPbUtX1lxKVAuNBtbwazMkD7hyuJ0v2iQHeQu6WQIJlA8iFAcviKiEDyIUBy+Ip4QA==",
          "dtype": "f8"
         }
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Newton's method iterations to find zero",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 68128 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_samples(newton_huge_df, \"ZeroNewtonHuge\", \"Newton's method iterations to find zero\", show_legend=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47d0c795",
   "metadata": {},
   "source": [
    "## scipy_engine (big sample)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "49e8a698",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f42204d56342439d8efe9e1869562cba",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/5005 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(big_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(scipy_zero_test(point['x'], point['y']))\n",
    "scipy_big_df = pd.DataFrame(results)\n",
    "scipy_big_df.to_csv('ZeroSciPy.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "id": "72ca9dc5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.06,
           "#00FF00"
          ],
          [
           0.4,
           "#1212FF"
          ],
          [
           0.96,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "2WlL8z6LSUDZaUvzPotZQGOPeDZvKGNA2WlL8z6LaUBPRB6wDu5vQGOPeDZvKHNAnvzhFNdZdkDZaUvzPot5QBTXtNGmvHxAT0QesA7uf0DF2ENHu4+BQGOPeDZvKINAAEatJSPBhECe/OEU11mGQDuzFgSL8odA2WlL8z6LiUB3IIDi8iOLQBTXtNGmvIxAso3pwFpVjkBPRB6wDu6PQHZ9qU9hw5BAxdhDR7uPkUAUNN4+FVySQGOPeDZvKJNAsuoSLsn0k0AARq0lI8GUQE+hRx19jZVAnvzhFNdZlkDtV3wMMSaXQDuzFgSL8pdAig6x++S+mEDZaUvzPouZQCjF5eqYV5pAdyCA4vIjm0DFexraTPCbQBTXtNGmvJxAYzJPyQCJnUCyjenAWlWeQADpg7i0IZ9AT0QesA7un0DPT9xTNF2gQHZ9qU9hw6BAHqt2S44poUDF2ENHu4+hQG0GEUPo9aFAFDTePhVcokC7Yas6QsKiQGOPeDZvKKNACr1FMpyOo0Cy6hIuyfSjQFkY4Cn2WqRAAEatJSPBpECoc3ohUCelQE+hRx19jaVA9s4UGarzpUCe/OEU11mmQEUqrxAEwKZA7Vd8DDEmp0CUhUkIXoynQDuzFgSL8qdA4+Dj/7dYqECKDrH75L6oQDI8fvcRJalA2WlL8z6LqUCAlxjva/GpQCjF5eqYV6pAz/Ky5sW9qkB3IIDi8iOrQB5OTd4fiqtAxXsa2kzwq0BtqefVeVasQBTXtNGmvKxAvASCzdMirUBjMk/JAImtQApgHMUt761Aso3pwFpVrkBZu7a8h7uuQADpg7i0Ia9AqBZRtOGHr0BPRB6wDu6vQPu49dUdKrBAz0/cUzRdsECj5sLRSpCwQHZ9qU9hw7BA",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAABK1LoKtXpCQErUugq1elJAbz4YkA+4W0BK1LoKtXpiQFyJaU1iGWdAbz4YkA+4a0DBeWNpXitwQErUugq1enJA0y4SrAvKdEBciWlNYhl3QObjwO64aHlAbz4YkA+4e0D4mG8xZgd+QMF5Y2leK4BABScPuglTgUBK1LoKtXqCQI+BZltgooNA0y4SrAvKhEAY3L38tvGFQFyJaU1iGYdAoTYVng1BiEDm48DuuGiJQCqRbD9kkIpAbz4YkA+4i0C068Pgut+MQPiYbzFmB45APUYbghEvj0DBeWNpXiuQQGNQuRE0v5BABScPuglTkUCo/WRi3+aRQErUugq1epJA7KoQs4oOk0CPgWZbYKKTQDFYvAM2NpRA0y4SrAvKlEB2BWhU4V2VQBjcvfy28ZVAurITpYyFlkBciWlNYhmXQP9fv/U3rZdAoTYVng1BmEBDDWtG49SYQObjwO64aJlAiLoWl478mUAqkWw/ZJCaQM1nwuc5JJtAbz4YkA+4m0ARFW445UucQLTrw+C635xAVsIZiZBznUD4mG8xZgeeQJtvxdk7m55APUYbghEvn0DfHHEq58KfQMF5Y2leK6BAEmWOPUl1oEBjULkRNL+gQLQ75OUeCaFABScPuglToUBXEjqO9JyhQKj9ZGLf5qFA+eiPNsowokBK1LoKtXqiQJu/5d6fxKJA7KoQs4oOo0A9ljuHdVijQI+BZltgoqNA4GyRL0vso0AxWLwDNjakQIJD59cggKRA0y4SrAvKpEAkGj2A9hOlQHYFaFThXaVAx/CSKMynpUAY3L38tvGlQGnH6NChO6ZAurITpYyFpkALnj55d8+mQFyJaU1iGadArnSUIU1jp0D/X7/1N62nQFBL6ski96dAoTYVng1BqEA=",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 76160 characters]",
          "dtype": "f8",
          "shape": "85, 84"
         },
         "zmax": 50,
         "zmin": 0
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Iterations to find zero for target point",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 80552 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_samples(scipy_big_df, show_legend=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2830c75a",
   "metadata": {},
   "source": [
    "## scipy_engine (huge sample)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "id": "61ef5919",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "03d54d9432754fcaa3722c6808e176fa",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/20073 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(huge_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(scipy_zero_test(point['x'], point['y']))\n",
    "scipy_huge_df = pd.DataFrame(results)\n",
    "scipy_huge_df.to_csv('ZeroSciPyHuge.csv')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e12f244",
   "metadata": {},
   "source": [
    "### Plots\n",
    "\n",
    "1. The first chart shows the iterations to for `.find_zero_angle()` with the current implementation, which begins by running `.find_max_range()` on the look-angle to the target point, to ensure that it is within range.\n",
    "2. The second chart shows the iterations involved in just that `.find_max_range()` step.\n",
    "3. The third chart shows the iterations to find the zero, given that we have verified it is in range, and exploiting the max-range-launch-angle to narrow the search bracket.\n",
    "\n",
    "We see a curious artifact in the first two charts: for targets near the 21° look angle, `.find_max_range()` takes more iterations than for similar points at any other look angle."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "id": "1c93ef1c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.06,
           "#00FF00"
          ],
          [
           0.4,
           "#1212FF"
          ],
          [
           0.96,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "lcmqFBjZOUCVyaoUGNlJQDAXgA/SYlNAlcmqFBjZWUD9veoMrydgQDAXgA/SYmNAYnAVEvWdZkCVyaoUGNlpQMgiQBc7FG1A/b3qDK8ncECWajWOQMVxQDAXgA/SYnNAycPKkGMAdUBicBUS9Z12QPwcYJOGO3hAlcmqFBjZeUAudvWVqXZ7QMgiQBc7FH1AYc+KmMyxfkD9veoMryeAQEoUkM139oBAlmo1jkDFgUDjwNpOCZSCQDAXgA/SYoNAfG0l0JoxhEDJw8qQYwCFQBYacFEsz4VAYnAVEvWdhkCvxrrSvWyHQPwcYJOGO4hASHMFVE8KiUCVyaoUGNmJQOIfUNXgp4pALnb1lal2i0B7zJpWckWMQMgiQBc7FI1AFHnl1wPjjUBhz4qYzLGOQK4lMFmVgI9A/b3qDK8nkEAjaT1tE4+QQEoUkM139pBAcL/iLdxdkUCWajWOQMWRQL0ViO6kLJJA48DaTgmUkkAJbC2vbfuSQDAXgA/SYpNAVsLSbzbKk0B8bSXQmjGUQKMYeDD/mJRAycPKkGMAlUDvbh3xx2eVQBYacFEsz5VAPMXCsZA2lkBicBUS9Z2WQIkbaHJZBZdAr8a60r1sl0DVcQ0zItSXQPwcYJOGO5hAIsiy8+qimEBIcwVUTwqZQG8eWLSzcZlAlcmqFBjZmUC7dP10fECaQOIfUNXgp5pACMuiNUUPm0AudvWVqXabQFUhSPYN3ptAe8yaVnJFnEChd+221qycQMgiQBc7FJ1A7s2Sd597nUAUeeXXA+OdQDskODhoSp5AYc+KmMyxnkCHet34MBmfQK4lMFmVgJ9A1NCCufnnn0D9veoMryegQJATFD1hW6BAI2k9bROPoEC3vmadxcKgQEoUkM139qBA3Wm5/SkqoUBwv+It3F2hQAMVDF6OkaFAlmo1jkDFoUAqwF6+8vihQL0ViO6kLKJAUGuxHldgokDjwNpOCZSiQHYWBH+7x6JACWwtr237okCdwVbfHy+jQDAXgA/SYqNAw2ypP4SWo0BWwtJvNsqjQOkX/J/o/aNAfG0l0JoxpEAQw04ATWWkQKMYeDD/mKRANm6hYLHMpEDJw8qQYwClQFwZ9MAVNKVA724d8cdnpUCDxEYhepulQBYacFEsz6VAqW+Zgd4CpkA8xcKxkDamQM8a7OFCaqZAYnAVEvWdpkD2xT5Cp9GmQIkbaHJZBadAHHGRogs5p0CvxrrSvWynQEIc5AJwoKdA1XENMyLUp0BpxzZj1AeoQPwcYJOGO6hAj3KJwzhvqEAiyLLz6qKoQLUd3COd1qhASHMFVE8KqUDcyC6EAT6pQG8eWLSzcalAAnSB5GWlqUCVyaoUGNmpQCgf1ETKDKpAu3T9dHxAqkBOyialLnSqQOIfUNXgp6pAdXV5BZPbqkAIy6I1RQ+rQJsgzGX3QqtALnb1lal2q0DByx7GW6qrQFUhSPYN3qtA6HZxJsARrEB7zJpWckWsQA4ixIYkeaxAoXftttasrEA0zRbniOCsQMgiQBc7FK1AW3hpR+1HrUDuzZJ3n3utQIEjvKdRr61AFHnl1wPjrUCnzg4IthauQDskODhoSq5AznlhaBp+rkBhz4qYzLGuQPQktMh+5a5Ah3rd+DAZr0Aa0AYp40yvQK4lMFmVgK9AQXtZiUe0r0DU0IK5+eevQDQT1vTVDbBA/b3qDK8nsEDHaP8kiEGwQJATFD1hW7BAWr4oVTp1sEAjaT1tE4+wQO0TUoXsqLBAt75mncXCsECAaXu1ntywQA==",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAAC40G1vBrMyQLjQbW8Gs0JAFLkkp4kMTEC40G1vBrNSQOZESQvIX1dAFLkkp4kMXEChFoChpVxgQLjQbW8Gs2JAz4pbPWcJZUDmREkLyF9nQP3+NtkotmlAFLkkp4kMbEArcxJ16mJuQKEWgKGlXHBArPN2CNaHcUC40G1vBrNyQMStZNY23nNAz4pbPWcJdUDaZ1KklzR2QOZESQvIX3dA8iFAcviKeED9/jbZKLZ5QAjcLUBZ4XpAFLkkp4kMfEAglhsOujd9QCtzEnXqYn5ANlAJ3BqOf0ChFoChpVyAQCeF+9Q98oBArPN2CNaHgUAyYvI7bh2CQLjQbW8Gs4JAPj/pop5Ig0DErWTWNt6DQEkc4AnPc4RAz4pbPWcJhUBV+dZw/56FQNpnUqSXNIZAYNbN1y/KhkDmREkLyF+HQGyzxD5g9YdA8iFAcviKiEB3kLulkCCJQP3+NtkotolAg22yDMFLikAI3C1AWeGKQI5KqXPxdotAFLkkp4kMjECaJ6DaIaKMQCCWGw66N41ApQSXQVLNjUArcxJ16mKOQLHhjaiC+I5ANlAJ3BqOj0BeX8KH2RGQQKEWgKGlXJBA5M09u3GnkEAnhfvUPfKQQGo8ue4JPZFArPN2CNaHkUDvqjQiotKRQDJi8jtuHZJAdRmwVTpokkC40G1vBrOSQPuHK4nS/ZJAPj/pop5Ik0CB9qa8apOTQMStZNY23pNABmUi8AIplEBJHOAJz3OUQIzTnSObvpRAz4pbPWcJlUASQhlXM1SVQFX51nD/npVAmLCUisvplUDaZ1KklzSWQB0fEL5jf5ZAYNbN1y/KlkCjjYvx+xSXQOZESQvIX5dAKfwGJZSql0Bss8Q+YPWXQK9qglgsQJhA8iFAcviKmEA02f2LxNWYQHeQu6WQIJlAukd5v1xrmUD9/jbZKLaZQEC29PL0AJpAg22yDMFLmkDGJHAmjZaaQAjcLUBZ4ZpAS5PrWSUsm0COSqlz8XabQNEBZ429wZtAFLkkp4kMnEBXcOLAVVecQJonoNohopxA3d5d9O3snEAglhsOujedQGJN2SeGgp1ApQSXQVLNnUDou1RbHhieQCtzEnXqYp5AbirQjratnkCx4Y2ogvieQPSYS8JOQ59ANlAJ3BqOn0B5B8f15tifQF5fwofZEaBAADuhlD83oEChFoChpVygQELyXq4LgqBA5M09u3GnoECFqRzI18ygQCeF+9Q98qBAyGDa4aMXoUBqPLnuCT2hQAsYmPtvYqFArPN2CNaHoUBOz1UVPK2hQO+qNCKi0qFAkYYTLwj4oUAyYvI7bh2iQNQ90UjUQqJAdRmwVTpookAX9Y5ioI2iQLjQbW8Gs6JAWaxMfGzYokD7hyuJ0v2iQJxjCpY4I6NAPj/pop5Io0DfGsivBG6jQIH2prxqk6NAItKFydC4o0DErWTWNt6jQGWJQ+OcA6RABmUi8AIppECoQAH9aE6kQEkc4AnPc6RA6/e+FjWZpECM050jm76kQC6vfDAB5KRAz4pbPWcJpUBwZjpKzS6lQBJCGVczVKVAsx34Y5l5pUBV+dZw/56lQPbUtX1lxKVAmLCUisvppUA5jHOXMQ+mQNpnUqSXNKZAfEMxsf1ZpkAdHxC+Y3+mQL/67srJpKZAYNbN1y/KpkACsqzkle+mQKONi/H7FKdARWlq/mE6p0DmREkLyF+nQIcgKBguhadAKfwGJZSqp0DK1+Ux+s+nQGyzxD5g9adADY+jS8YaqECvaoJYLECoQFBGYWWSZahA",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 299264 characters]",
          "dtype": "f8",
          "shape": "168, 167"
         },
         "zmax": 50,
         "zmin": 0
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "SciPy.find_zero_angle() iterations to find zero",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 130912 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_samples(scipy_huge_df, \"ZeroSciPyTotal\", \"SciPy.find_zero_angle() iterations to find zero\", show_legend=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e1585b64",
   "metadata": {},
   "source": [
    "#### find_max_range()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "id": "310774ab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.06,
           "#00FF00"
          ],
          [
           0.4,
           "#1212FF"
          ],
          [
           0.96,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "lcmqFBjZOUCVyaoUGNlJQDAXgA/SYlNAlcmqFBjZWUD9veoMrydgQDAXgA/SYmNAYnAVEvWdZkCVyaoUGNlpQMgiQBc7FG1A/b3qDK8ncECWajWOQMVxQDAXgA/SYnNAycPKkGMAdUBicBUS9Z12QPwcYJOGO3hAlcmqFBjZeUAudvWVqXZ7QMgiQBc7FH1AYc+KmMyxfkD9veoMryeAQEoUkM139oBAlmo1jkDFgUDjwNpOCZSCQDAXgA/SYoNAfG0l0JoxhEDJw8qQYwCFQBYacFEsz4VAYnAVEvWdhkCvxrrSvWyHQPwcYJOGO4hASHMFVE8KiUCVyaoUGNmJQOIfUNXgp4pALnb1lal2i0B7zJpWckWMQMgiQBc7FI1AFHnl1wPjjUBhz4qYzLGOQK4lMFmVgI9A/b3qDK8nkEAjaT1tE4+QQEoUkM139pBAcL/iLdxdkUCWajWOQMWRQL0ViO6kLJJA48DaTgmUkkAJbC2vbfuSQDAXgA/SYpNAVsLSbzbKk0B8bSXQmjGUQKMYeDD/mJRAycPKkGMAlUDvbh3xx2eVQBYacFEsz5VAPMXCsZA2lkBicBUS9Z2WQIkbaHJZBZdAr8a60r1sl0DVcQ0zItSXQPwcYJOGO5hAIsiy8+qimEBIcwVUTwqZQG8eWLSzcZlAlcmqFBjZmUC7dP10fECaQOIfUNXgp5pACMuiNUUPm0AudvWVqXabQFUhSPYN3ptAe8yaVnJFnEChd+221qycQMgiQBc7FJ1A7s2Sd597nUAUeeXXA+OdQDskODhoSp5AYc+KmMyxnkCHet34MBmfQK4lMFmVgJ9A1NCCufnnn0D9veoMryegQJATFD1hW6BAI2k9bROPoEC3vmadxcKgQEoUkM139qBA3Wm5/SkqoUBwv+It3F2hQAMVDF6OkaFAlmo1jkDFoUAqwF6+8vihQL0ViO6kLKJAUGuxHldgokDjwNpOCZSiQHYWBH+7x6JACWwtr237okCdwVbfHy+jQDAXgA/SYqNAw2ypP4SWo0BWwtJvNsqjQOkX/J/o/aNAfG0l0JoxpEAQw04ATWWkQKMYeDD/mKRANm6hYLHMpEDJw8qQYwClQFwZ9MAVNKVA724d8cdnpUCDxEYhepulQBYacFEsz6VAqW+Zgd4CpkA8xcKxkDamQM8a7OFCaqZAYnAVEvWdpkD2xT5Cp9GmQIkbaHJZBadAHHGRogs5p0CvxrrSvWynQEIc5AJwoKdA1XENMyLUp0BpxzZj1AeoQPwcYJOGO6hAj3KJwzhvqEAiyLLz6qKoQLUd3COd1qhASHMFVE8KqUDcyC6EAT6pQG8eWLSzcalAAnSB5GWlqUCVyaoUGNmpQCgf1ETKDKpAu3T9dHxAqkBOyialLnSqQOIfUNXgp6pAdXV5BZPbqkAIy6I1RQ+rQJsgzGX3QqtALnb1lal2q0DByx7GW6qrQFUhSPYN3qtA6HZxJsARrEB7zJpWckWsQA4ixIYkeaxAoXftttasrEA0zRbniOCsQMgiQBc7FK1AW3hpR+1HrUDuzZJ3n3utQIEjvKdRr61AFHnl1wPjrUCnzg4IthauQDskODhoSq5AznlhaBp+rkBhz4qYzLGuQPQktMh+5a5Ah3rd+DAZr0Aa0AYp40yvQK4lMFmVgK9AQXtZiUe0r0DU0IK5+eevQDQT1vTVDbBA/b3qDK8nsEDHaP8kiEGwQJATFD1hW7BAWr4oVTp1sEAjaT1tE4+wQO0TUoXsqLBAt75mncXCsECAaXu1ntywQA==",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAAC40G1vBrMyQLjQbW8Gs0JAFLkkp4kMTEC40G1vBrNSQOZESQvIX1dAFLkkp4kMXEChFoChpVxgQLjQbW8Gs2JAz4pbPWcJZUDmREkLyF9nQP3+NtkotmlAFLkkp4kMbEArcxJ16mJuQKEWgKGlXHBArPN2CNaHcUC40G1vBrNyQMStZNY23nNAz4pbPWcJdUDaZ1KklzR2QOZESQvIX3dA8iFAcviKeED9/jbZKLZ5QAjcLUBZ4XpAFLkkp4kMfEAglhsOujd9QCtzEnXqYn5ANlAJ3BqOf0ChFoChpVyAQCeF+9Q98oBArPN2CNaHgUAyYvI7bh2CQLjQbW8Gs4JAPj/pop5Ig0DErWTWNt6DQEkc4AnPc4RAz4pbPWcJhUBV+dZw/56FQNpnUqSXNIZAYNbN1y/KhkDmREkLyF+HQGyzxD5g9YdA8iFAcviKiEB3kLulkCCJQP3+NtkotolAg22yDMFLikAI3C1AWeGKQI5KqXPxdotAFLkkp4kMjECaJ6DaIaKMQCCWGw66N41ApQSXQVLNjUArcxJ16mKOQLHhjaiC+I5ANlAJ3BqOj0BeX8KH2RGQQKEWgKGlXJBA5M09u3GnkEAnhfvUPfKQQGo8ue4JPZFArPN2CNaHkUDvqjQiotKRQDJi8jtuHZJAdRmwVTpokkC40G1vBrOSQPuHK4nS/ZJAPj/pop5Ik0CB9qa8apOTQMStZNY23pNABmUi8AIplEBJHOAJz3OUQIzTnSObvpRAz4pbPWcJlUASQhlXM1SVQFX51nD/npVAmLCUisvplUDaZ1KklzSWQB0fEL5jf5ZAYNbN1y/KlkCjjYvx+xSXQOZESQvIX5dAKfwGJZSql0Bss8Q+YPWXQK9qglgsQJhA8iFAcviKmEA02f2LxNWYQHeQu6WQIJlAukd5v1xrmUD9/jbZKLaZQEC29PL0AJpAg22yDMFLmkDGJHAmjZaaQAjcLUBZ4ZpAS5PrWSUsm0COSqlz8XabQNEBZ429wZtAFLkkp4kMnEBXcOLAVVecQJonoNohopxA3d5d9O3snEAglhsOujedQGJN2SeGgp1ApQSXQVLNnUDou1RbHhieQCtzEnXqYp5AbirQjratnkCx4Y2ogvieQPSYS8JOQ59ANlAJ3BqOn0B5B8f15tifQF5fwofZEaBAADuhlD83oEChFoChpVygQELyXq4LgqBA5M09u3GnoECFqRzI18ygQCeF+9Q98qBAyGDa4aMXoUBqPLnuCT2hQAsYmPtvYqFArPN2CNaHoUBOz1UVPK2hQO+qNCKi0qFAkYYTLwj4oUAyYvI7bh2iQNQ90UjUQqJAdRmwVTpookAX9Y5ioI2iQLjQbW8Gs6JAWaxMfGzYokD7hyuJ0v2iQJxjCpY4I6NAPj/pop5Io0DfGsivBG6jQIH2prxqk6NAItKFydC4o0DErWTWNt6jQGWJQ+OcA6RABmUi8AIppECoQAH9aE6kQEkc4AnPc6RA6/e+FjWZpECM050jm76kQC6vfDAB5KRAz4pbPWcJpUBwZjpKzS6lQBJCGVczVKVAsx34Y5l5pUBV+dZw/56lQPbUtX1lxKVAmLCUisvppUA5jHOXMQ+mQNpnUqSXNKZAfEMxsf1ZpkAdHxC+Y3+mQL/67srJpKZAYNbN1y/KpkACsqzkle+mQKONi/H7FKdARWlq/mE6p0DmREkLyF+nQIcgKBguhadAKfwGJZSqp0DK1+Ux+s+nQGyzxD5g9adADY+jS8YaqECvaoJYLECoQFBGYWWSZahA",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 299264 characters]",
          "dtype": "f8",
          "shape": "168, 167"
         },
         "zmax": 50,
         "zmin": 0
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Ray at 0.36 rad (21°)",
         "type": "scatter",
         "x": [
          0,
          4064.101989769717
         ],
         "y": [
          0,
          1529.7395783133572
         ]
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": true,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Iterations to find max range for look angle",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "range_iterations_df = scipy_huge_df.copy()\n",
    "range_iterations_df['iterations'] = range_iterations_df['range_iterations']\n",
    "p_max_range = plot_test_results(range_iterations_df, envelope_df, show=False, title_str='Iterations to find max range for look angle')\n",
    "ray_length = envelope_df['max_dist_m'].max()\n",
    "# Add a line along the strange angle that takes more iterations to find the max range\n",
    "angle_rad = 0.36\n",
    "x_ray = ray_length * np.cos(angle_rad)\n",
    "y_ray = ray_length * np.sin(angle_rad)\n",
    "p_max_range.add_trace(go.Scatter(x=[0, x_ray], y=[0, y_ray],\n",
    "    mode='lines', line=dict(color='black', width=2), name='Ray at 0.36 rad (21°)'\n",
    "))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7effd65c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "count    20073.000000\n",
       "mean        11.871071\n",
       "std          3.227648\n",
       "min          7.000000\n",
       "25%         10.000000\n",
       "50%         11.000000\n",
       "75%         13.000000\n",
       "max         26.000000\n",
       "Name: range_iterations, dtype: float64"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "scipy_huge_df['range_iterations'].describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "234d607d",
   "metadata": {},
   "source": [
    "#### Zero, knowing max_range_angle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "id": "8eb168cb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "colorbar": {
          "title": {
           "text": "Iterations"
          },
          "x": 0.85
         },
         "colorscale": [
          [
           0,
           "#00FF00"
          ],
          [
           0.06,
           "#00FF00"
          ],
          [
           0.4,
           "#1212FF"
          ],
          [
           0.96,
           "#FF0000"
          ],
          [
           1,
           "#FF0000"
          ]
         ],
         "hoverongaps": false,
         "hovertemplate": "x: %{x}<br>y: %{y}<br>iterations: %{z}<extra></extra>",
         "name": "Converged",
         "type": "heatmap",
         "x": {
          "bdata": "lcmqFBjZOUCVyaoUGNlJQDAXgA/SYlNAlcmqFBjZWUD9veoMrydgQDAXgA/SYmNAYnAVEvWdZkCVyaoUGNlpQMgiQBc7FG1A/b3qDK8ncECWajWOQMVxQDAXgA/SYnNAycPKkGMAdUBicBUS9Z12QPwcYJOGO3hAlcmqFBjZeUAudvWVqXZ7QMgiQBc7FH1AYc+KmMyxfkD9veoMryeAQEoUkM139oBAlmo1jkDFgUDjwNpOCZSCQDAXgA/SYoNAfG0l0JoxhEDJw8qQYwCFQBYacFEsz4VAYnAVEvWdhkCvxrrSvWyHQPwcYJOGO4hASHMFVE8KiUCVyaoUGNmJQOIfUNXgp4pALnb1lal2i0B7zJpWckWMQMgiQBc7FI1AFHnl1wPjjUBhz4qYzLGOQK4lMFmVgI9A/b3qDK8nkEAjaT1tE4+QQEoUkM139pBAcL/iLdxdkUCWajWOQMWRQL0ViO6kLJJA48DaTgmUkkAJbC2vbfuSQDAXgA/SYpNAVsLSbzbKk0B8bSXQmjGUQKMYeDD/mJRAycPKkGMAlUDvbh3xx2eVQBYacFEsz5VAPMXCsZA2lkBicBUS9Z2WQIkbaHJZBZdAr8a60r1sl0DVcQ0zItSXQPwcYJOGO5hAIsiy8+qimEBIcwVUTwqZQG8eWLSzcZlAlcmqFBjZmUC7dP10fECaQOIfUNXgp5pACMuiNUUPm0AudvWVqXabQFUhSPYN3ptAe8yaVnJFnEChd+221qycQMgiQBc7FJ1A7s2Sd597nUAUeeXXA+OdQDskODhoSp5AYc+KmMyxnkCHet34MBmfQK4lMFmVgJ9A1NCCufnnn0D9veoMryegQJATFD1hW6BAI2k9bROPoEC3vmadxcKgQEoUkM139qBA3Wm5/SkqoUBwv+It3F2hQAMVDF6OkaFAlmo1jkDFoUAqwF6+8vihQL0ViO6kLKJAUGuxHldgokDjwNpOCZSiQHYWBH+7x6JACWwtr237okCdwVbfHy+jQDAXgA/SYqNAw2ypP4SWo0BWwtJvNsqjQOkX/J/o/aNAfG0l0JoxpEAQw04ATWWkQKMYeDD/mKRANm6hYLHMpEDJw8qQYwClQFwZ9MAVNKVA724d8cdnpUCDxEYhepulQBYacFEsz6VAqW+Zgd4CpkA8xcKxkDamQM8a7OFCaqZAYnAVEvWdpkD2xT5Cp9GmQIkbaHJZBadAHHGRogs5p0CvxrrSvWynQEIc5AJwoKdA1XENMyLUp0BpxzZj1AeoQPwcYJOGO6hAj3KJwzhvqEAiyLLz6qKoQLUd3COd1qhASHMFVE8KqUDcyC6EAT6pQG8eWLSzcalAAnSB5GWlqUCVyaoUGNmpQCgf1ETKDKpAu3T9dHxAqkBOyialLnSqQOIfUNXgp6pAdXV5BZPbqkAIy6I1RQ+rQJsgzGX3QqtALnb1lal2q0DByx7GW6qrQFUhSPYN3qtA6HZxJsARrEB7zJpWckWsQA4ixIYkeaxAoXftttasrEA0zRbniOCsQMgiQBc7FK1AW3hpR+1HrUDuzZJ3n3utQIEjvKdRr61AFHnl1wPjrUCnzg4IthauQDskODhoSq5AznlhaBp+rkBhz4qYzLGuQPQktMh+5a5Ah3rd+DAZr0Aa0AYp40yvQK4lMFmVgK9AQXtZiUe0r0DU0IK5+eevQDQT1vTVDbBA/b3qDK8nsEDHaP8kiEGwQJATFD1hW7BAWr4oVTp1sEAjaT1tE4+wQO0TUoXsqLBAt75mncXCsECAaXu1ntywQA==",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAAC40G1vBrMyQLjQbW8Gs0JAFLkkp4kMTEC40G1vBrNSQOZESQvIX1dAFLkkp4kMXEChFoChpVxgQLjQbW8Gs2JAz4pbPWcJZUDmREkLyF9nQP3+NtkotmlAFLkkp4kMbEArcxJ16mJuQKEWgKGlXHBArPN2CNaHcUC40G1vBrNyQMStZNY23nNAz4pbPWcJdUDaZ1KklzR2QOZESQvIX3dA8iFAcviKeED9/jbZKLZ5QAjcLUBZ4XpAFLkkp4kMfEAglhsOujd9QCtzEnXqYn5ANlAJ3BqOf0ChFoChpVyAQCeF+9Q98oBArPN2CNaHgUAyYvI7bh2CQLjQbW8Gs4JAPj/pop5Ig0DErWTWNt6DQEkc4AnPc4RAz4pbPWcJhUBV+dZw/56FQNpnUqSXNIZAYNbN1y/KhkDmREkLyF+HQGyzxD5g9YdA8iFAcviKiEB3kLulkCCJQP3+NtkotolAg22yDMFLikAI3C1AWeGKQI5KqXPxdotAFLkkp4kMjECaJ6DaIaKMQCCWGw66N41ApQSXQVLNjUArcxJ16mKOQLHhjaiC+I5ANlAJ3BqOj0BeX8KH2RGQQKEWgKGlXJBA5M09u3GnkEAnhfvUPfKQQGo8ue4JPZFArPN2CNaHkUDvqjQiotKRQDJi8jtuHZJAdRmwVTpokkC40G1vBrOSQPuHK4nS/ZJAPj/pop5Ik0CB9qa8apOTQMStZNY23pNABmUi8AIplEBJHOAJz3OUQIzTnSObvpRAz4pbPWcJlUASQhlXM1SVQFX51nD/npVAmLCUisvplUDaZ1KklzSWQB0fEL5jf5ZAYNbN1y/KlkCjjYvx+xSXQOZESQvIX5dAKfwGJZSql0Bss8Q+YPWXQK9qglgsQJhA8iFAcviKmEA02f2LxNWYQHeQu6WQIJlAukd5v1xrmUD9/jbZKLaZQEC29PL0AJpAg22yDMFLmkDGJHAmjZaaQAjcLUBZ4ZpAS5PrWSUsm0COSqlz8XabQNEBZ429wZtAFLkkp4kMnEBXcOLAVVecQJonoNohopxA3d5d9O3snEAglhsOujedQGJN2SeGgp1ApQSXQVLNnUDou1RbHhieQCtzEnXqYp5AbirQjratnkCx4Y2ogvieQPSYS8JOQ59ANlAJ3BqOn0B5B8f15tifQF5fwofZEaBAADuhlD83oEChFoChpVygQELyXq4LgqBA5M09u3GnoECFqRzI18ygQCeF+9Q98qBAyGDa4aMXoUBqPLnuCT2hQAsYmPtvYqFArPN2CNaHoUBOz1UVPK2hQO+qNCKi0qFAkYYTLwj4oUAyYvI7bh2iQNQ90UjUQqJAdRmwVTpookAX9Y5ioI2iQLjQbW8Gs6JAWaxMfGzYokD7hyuJ0v2iQJxjCpY4I6NAPj/pop5Io0DfGsivBG6jQIH2prxqk6NAItKFydC4o0DErWTWNt6jQGWJQ+OcA6RABmUi8AIppECoQAH9aE6kQEkc4AnPc6RA6/e+FjWZpECM050jm76kQC6vfDAB5KRAz4pbPWcJpUBwZjpKzS6lQBJCGVczVKVAsx34Y5l5pUBV+dZw/56lQPbUtX1lxKVAmLCUisvppUA5jHOXMQ+mQNpnUqSXNKZAfEMxsf1ZpkAdHxC+Y3+mQL/67srJpKZAYNbN1y/KpkACsqzkle+mQKONi/H7FKdARWlq/mE6p0DmREkLyF+nQIcgKBguhadAKfwGJZSqp0DK1+Ux+s+nQGyzxD5g9adADY+jS8YaqECvaoJYLECoQFBGYWWSZahA",
          "dtype": "f8"
         },
         "z": {
          "bdata": "[encoded data, 299264 characters]",
          "dtype": "f8",
          "shape": "168, 167"
         },
         "zmax": 50,
         "zmin": 0
        },
        {
         "line": {
          "color": "black",
          "width": 2
         },
         "mode": "lines",
         "name": "Reachable Envelope",
         "type": "scatter",
         "x": {
          "bdata": "ShSQzXf2sEANAOYqINOwQFLRTMRYr7BA4A+SQSOLsEAmtvTqfWawQKPkRNVvQbBAe8+AWfcbsEDV032vIeyvQIVgRT6Kn69AjkmtEiFSr0CXnKfk7QOvQMfk2on3tK5AKGjRjjllrkBMgTlIuRSuQHyy1o9+w61A2OI+LoVxrUCL9Fsqxx6tQJsL60Fey6xA7bb0UDh3rECxsGdjYiKsQJJg+8zfzKtAQfLQx6t2q0ALXpcy0B+rQCh4/0FDyKpAERp0IyBwqkAhDfEnTheqQPYy3avavalAcGt0wc5jqUCeUWKmJQmpQL15yLTgrahAd6EHqwZSqECmjOUKnPWnQBw6OZafmKdAKm7nlhU7p0B2zHw+/NymQC6kdr1WfqZA1835YjIfpkAPDMG2gL+lQHqbAoBMX6VACoX1wZ7+pEAaYMTfZ52kQI3R8eC+O6RATOUwAJbZo0D7ufUh/najQKfuhdvuE6NAj5nsMGiwokBEWRBFeEyiQNGgg4YY6KFA5T1UqEyDoUBOTdRbHx6hQHS0CLOFuKBAM7p0j45SoEAm7hQUW9ifQGFd1ejtCp9AX8lMLMY8nkCLYxsd322dQCrAWDFTnpxAlChCLBXOm0C1WkkpOf2aQPY+voK5K5pAhj0iIqJZmUAcnZRm9YaYQHyjmhOys5dAtLwq/eLflkD/qWLZiguWQHEznPu2NpVAAjTOul1hlECx1HZGjYuTQKQo6IZKtZJAQrOAH5bekUA5mujiegeRQIpS63P2L5BAMPPJ2C+wjkBrkcWStv+MQGupZ7WOTotAjezgK8CciUAoUtJdWOqHQM4pkXxnN4ZAinzCS++DhEAB/G1l9s+CQLNJPI+PG4FAebJZkYPNfkAwryj9MGN7QPGdc7w++HdAOdjhIqyMdEDGPq7JoiBxQB0KQj5jaGtA3BQ0beKOZEAmgNHkuWlbQB7Ce1QGaktAlr9tY4QSSz0=",
          "dtype": "f8"
         },
         "y": {
          "bdata": "AAAAAAAAAACwqYgXmMtSQM7stjEUpWJAnCR6gIi+a0BDyKT4ZFlyQGXBu7tBwXZAQNXjGiQXe0D0T7/uSlt/QF1BqgsEx4FAjtxOocnXg0CPk0xTGOCFQCfYB5kR4IdA5ejENM3XiUBBbcudaMeLQJAViWUDr41AfUl2mbCOj0Dj19MSP7OQQBGDM41Om5FAgWKjyYV/kkAYQSWp9V+TQEp1QiepPJRAsqbfu6QVlUCQAGog9+qVQGHCGCmfvJZAMv6TLrqKl0ABO6rwOFWYQKJVEFwsHJlAr5Bxg6LfmUB7ctGem5+aQKhbfxgdXJtAJ4W4FDIVnEBbqMiL48qcQJL5SmozfZ1AjJGz1yksnkCQTlDjxteeQDE9w4MQgJ9A7NVwp40SoEDAZ/INamOgQIy/f6qlsqBAEquZFUgAoUCcJ/LrREyhQKXq7yWvlqFAQnMoBHvfoUCF92VDtyaiQDp1zPtbbKJAj5nsMGiwokDWqpoV6fKiQPPjYEXXM6NA7sVEXjVzo0AHt3wmDrGjQN5tu+lT7aNA66yBhxYopECO9DQQRWGkQE1DyTj3mKRAJmcmeiHPpEDsokHnvQOlQEp/3pncNqVAsbH/bXFopUDAmq7HiJilQM5PWG0bx6VAefO49C/0pUCwZ8dExR+mQL8bAn7WSaZANrELkGlypkBbv+kBfZmmQAJhRUsav6ZAX72BtjLjpkDjrMCS0AWnQC0Xu6v0JqdA6LQxP5pGp0Dsc7tVyWSnQJ84T4V4gadAYZ6Z2racp0Cz76vJd7anQC6kiCW+zqdALgS6Gojlp0DRYSGp2PqnQIHOZay2DqhAVbxIQxohqEA7cUuq/jGoQO/km0xuQahArMsynmVPqECC/O3/5luoQLFa85P2ZqhAPgK7i35wqEDHh/jCk3ioQJH5Rkswf6hA1Yv8Fl2EqEBQV0cRC4ioQGeAIHg5iqhA8iFAcviKqEA=",
          "dtype": "f8"
         }
        }
       ],
       "layout": {
        "legend": {
         "traceorder": "normal",
         "x": 1,
         "y": 1
        },
        "margin": {
         "t": 50
        },
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Root_scalar iterations to find zero, given max-range-angle",
         "x": 0.5
        },
        "xaxis": {
         "constrain": "domain",
         "title": {
          "text": "Horizontal Distance to Target (m)"
         }
        },
        "yaxis": {
         "dtick": 1000,
         "scaleanchor": "x",
         "scaleratio": 1,
         "title": {
          "text": "Vertical Distance to Target (m)"
         }
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 106540 characters]",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "zero_iterations_df = scipy_huge_df.copy()\n",
    "zero_iterations_df['iterations'] = zero_iterations_df['zero_iterations']\n",
    "plot_samples(zero_iterations_df, filename=\"ZeroSciPyRoot\", title_str=\"Root_scalar iterations to find zero, given max-range-angle\", show_legend=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0ab58bb9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "count    20073.000000\n",
       "mean         9.980621\n",
       "std          2.814490\n",
       "min          6.000000\n",
       "25%          8.000000\n",
       "50%          9.000000\n",
       "75%         12.000000\n",
       "max         32.000000\n",
       "Name: zero_iterations, dtype: float64"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "scipy_huge_df['zero_iterations'].describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2e360e5",
   "metadata": {},
   "source": [
    "## scipy_engine brenth\n",
    "Testing the `brenth` root method shows similar performance to `brentq`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a043a797",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "ba22e71b02cc4e9793fcd015a2b61d7c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/20073 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = []\n",
    "df = pd.DataFrame(huge_sample)\n",
    "for i, point in tqdm(df.iterrows(), total=len(df)):\n",
    "    results.append(scipy_zero_test(point['x'], point['y'], root_method='brenth'))\n",
    "scipy_huge_brenth_df = pd.DataFrame(results)\n",
    "scipy_huge_brenth_df.to_csv('ZeroSciPyHugeBrenth.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "id": "688bbaa5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "count    20073.000000\n",
       "mean         9.820455\n",
       "std          2.870016\n",
       "min          6.000000\n",
       "25%          8.000000\n",
       "50%          9.000000\n",
       "75%         11.000000\n",
       "max         35.000000\n",
       "Name: zero_iterations, dtype: float64"
      ]
     },
     "execution_count": 137,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scipy_huge_brenth_df['zero_iterations'].describe()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py-ballisticcalc",
   "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.12.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
