{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## This notebook both plots a given parametic curve in 3D and computes its Frenet frame, curvature, and torsion.\n",
    "Start by importing the required libraries:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import *  #python symbolic math package.\n",
    "import numpy as np   #numerical mathmatics library.\n",
    "import matplotlib.pyplot as plt    #plotting library.\n",
    "from mpl_toolkits.mplot3d import Axes3D\n",
    "init_printing()            #to get good looking output."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Declare $t$ to be a symbol, give the domain $[a,b]$ of \n",
    "the curve, and define $x$, $y$, and $z$ as functions of $t$.\n",
    "These should all be editted as needed (the default is a helix)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = symbols('t')\n",
    "a = 0\n",
    "b = 10*pi\n",
    "x = cos(t)\n",
    "y = sin(t)\n",
    "z = t\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Divide the domain into pieces of length $h$ to be used in plotting\n",
    "and compute the $x$, $y$, and $z$ values at these the subdivsions of the domain\n",
    "and store in them in lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "h = .1   #edit if need be.\n",
    "t_dom = np.arange(a,b,h)\n",
    "x_vals = [x.subs(t,s) for s in t_dom]\n",
    "y_vals = [y.subs(t,s) for s in t_dom]\n",
    "z_vals = [z.subs(t,s) for s in t_dom]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot the curve."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure()\n",
    "ax = fig.gca(projection='3d')\n",
    "ax.plot(x_vals,y_vals,z_vals)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compute the deriviatives of $x$, $y$, and $z$ with respect to $t$ and use\n",
    "them to compute the speed, $v$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dx = diff(x,t).simplify()\n",
    "dy = diff(y,t).simplify()\n",
    "dz = diff(z,t).simplify()\n",
    "v2 = (dx*dx + dy*dy+ dz*dz).simplify()\n",
    "simplify(v2)\n",
    "v = sqrt(v2).simplify()  # simplfy v if possible.\n",
    "simplify(v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compute the unit tangent $\\mathbf t$ and unit normal $\\mathbf n$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t1 = simplify(dx/v)\n",
    "t2 = simplify(dy/v)\n",
    "t3 = simplify(dz/v)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The unit tangent is"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "(t1,t2,t3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compute the derivative of the unit tangent with respect to arclength and use to compute curvature."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dt1_ds = simplify(diff(t1,t)/v)\n",
    "dt2_ds = simplify(diff(t2,t)/v)\n",
    "dt3_ds = simplify(diff(t3,t)/v)\n",
    "kappa = sqrt(dt1_ds**2 + dt2_ds**2 + dt3_ds**2).simplify()\n",
    "kappa.simplify()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compute unit normal.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n1 = simplify(dt1_ds/kappa)\n",
    "n2 = simplify(dt2_ds/kappa)\n",
    "n3 = simplify(dt3_ds/kappa)\n",
    "(n1,n2,n3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compute the binormal\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b1 = simplify(t2*n3 - t3*n2)\n",
    "b2 = simplify(t3*n1 - t1*n3)\n",
    "b3 = simplify(t1*n2 - t2*n1)\n",
    "(b1,b2,b3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compute the derivative of the binormal with respect to arclength and use to compute torson."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "db1_ds = simplify(diff(b1,t) / v)\n",
    "db2_ds = simplify(diff(b2,t) / v)\n",
    "db3_ds = simplify(diff(b3,t) / v)\n",
    "tau = - simplify(db1_ds*n1 + db2_ds*n2 + db3_ds*n3)\n",
    "tau"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
