{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Parametric Surfaces - All About\n", "\n", "This document describes how parametric surfaces are implemented in OSCARS.\n", "\n", "A parametric surface in OSCARS is represented by a python class. This class must contain the variables *u* and *v*, start and stop points *ustart*, *ustop*, *vstart*, *vstop*, and the number of points in each dimension *nu*, *nv*. Later in this notebook we develop a custom surface. First we start with surfaces in OSCARS." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# matplotlib plots inline\n", "%matplotlib inline\n", "\n", "# Import the OSCARS SR module\n", "import oscars.sr\n", "\n", "# Import OSCARS 3D tools (matplotlib)\n", "from oscars.plots3d_mpl import *\n", "\n", "# Import OSCARS parametric surfaces\n", "from oscars.parametric_surfaces import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Plot the rectangle\n", "rectangle = PSRectangle(L=0.01, W=0.01, nu=51, nv=51)\n", "plot_surface(rectangle)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Plot the sphere\n", "sphere = PSSphere(R=0.010, nu=51, nv=51)\n", "plot_surface(sphere)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Plot the cylinder\n", "cylinder = PSCylinder(R=0.010, L=0.1, nu=51, nv=51)\n", "plot_surface(cylinder)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Plot the torus\n", "torus = PSTorus(R=0.010, r=0.005, nu=51, nv=51)\n", "plot_surface(torus)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Eample - Custom Parametric Surface in OSCARS \n", "\n", "The example that follows shows how to create a custom parametric surface. The parametric surface is created in a simple python class. OSCARS requires the class to have the following defined:\n", "\n", "Functions: position(u, v), normal(u, v) which each return a 3-element list [x, y, z]\n", "\n", "Integers: nu, nv\n", "\n", "Floats: ustart, ustop, vstart, vstop\n", "\n", "At the moment you must provide the normal. You can use the following recipe for the components of the normal:\n", "\n", "In the following, let x = x(u, v) = position(u, v)[0], and so on\n", "\n", "$$\n", "N_x = \\frac{\\partial y}{\\partial u}\\frac{\\partial z}{\\partial v} - \\frac{\\partial z}{\\partial u}\\frac{\\partial y}{\\partial v}\\\\\n", "N_y = \\frac{\\partial z}{\\partial u}\\frac{\\partial x}{\\partial v} - \\frac{\\partial x}{\\partial u}\\frac{\\partial z}{\\partial v}\\\\\n", "N_y = \\frac{\\partial x}{\\partial u}\\frac{\\partial y}{\\partial v} - \\frac{\\partial y}{\\partial u}\\frac{\\partial x}{\\partial v}\n", "$$\n", "\n", "*You* need to decide if you want to invert this or not since it's not clear which is the front and back side. It is also a good idea to normalize this.\n", "\n", "The position in this example is given by the following:\n", "$$\n", "x = u \\sin(v)\\\\\n", "y = u \\cos(v)\\\\\n", "z = A \\sin( 2 \\pi u / \\lambda )\n", "$$\n", "\n", "which gives a normal of:\n", "$$\n", "N_x = 2 A \\pi u \\cos(2 \\pi u / \\lambda) \\sin(v) / \\lambda\\\\\n", "N_y = 2 A \\pi u \\cos(2 \\pi u / \\lambda) \\cos(v) / \\lambda\\\\\n", "N_z = -u\n", "$$\n", "and in this example I did have to invert the normal vector\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from math import sin, cos, pi, sqrt, exp\n", "class PSWavyDisk:\n", " \"\"\"A Parametric surface - wavy disk with a hole in the center\"\"\"\n", "\n", " # This shape specific parameters\n", " R1 = 0.001\n", " R2 = 0.005\n", " A = 0.001\n", " Lambda = 0.01\n", "\n", " # Required for all PS shapes\n", " # Start, stop, and number of points for the u and v parameters\n", " # All PSShapes must have these defined\n", " ustart = R1\n", " ustop = R2\n", " vstart = 0\n", " vstop = 2 * pi\n", " nu = 21\n", " nv = 21\n", "\n", " def __init__ (self, R1=0.001, R2=0.005, nu=21, nv=21):\n", " self.R1 = R1\n", " self.R2 = R2\n", " self.ustart = R1\n", " self.ustop = R2\n", " self.nu = nu\n", " self.vstart = 0\n", " self.vstop = 2.*pi\n", " self.nv = nv\n", "\n", "\n", " def position (self, u, v):\n", " \"\"\"Return the position in 3D at this u and v\"\"\"\n", "\n", " x = u * sin(v)\n", " y = u * cos(v)\n", " z = self.A * sin( 2. * pi * u / self.Lambda )\n", "\n", " return [x, y, z]\n", "\n", "\n", " def normal (self, u, v):\n", " \"\"\"Return a unit normal in 3D at this u and v position\"\"\"\n", "\n", " xn = -2. * self.A * pi * u * cos(2. * pi * u / self.Lambda) * sin(v) / self.Lambda\n", " yn = -2. * self.A * pi * u * cos(2. * pi * u / self.Lambda) * cos(v) / self.Lambda\n", " zn = u\n", "\n", " mag = sqrt(xn*xn + yn*yn + zn*zn)\n", "\n", " return [xn / mag, yn / mag, zn / mag]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a parametric shape and plot it\n", "wavydisk = PSWavyDisk(R1=0.01, R2=0.04, nu=51, nv=101)\n", "plot_surface(wavydisk, zlim=[-0.01, 0.01])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "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.6.1" } }, "nbformat": 4, "nbformat_minor": 1 }