{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 3D Plots of charts, vector fields and curves on $\\mathbb{S}^2$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This worksheet is based on SageMath 7.5.beta4 and the **three.js** viewer developed at [trac #12402](https://trac.sagemath.org/ticket/12402). \n", "\n", "*NB:* a version of SageMath at least equal to 7.5.beta4 is required:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'SageMath version 7.5.beta4, Release Date: 2016-11-24'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "version()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we set up the notebook to display mathematical objects using LaTeX formatting:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%display latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also define a viewer for 3D plots (use 'threejs' or 'jmol' for interactive 3D graphics):" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "viewer3D = 'threejs' # must be 'jmol', 'tachyon', 'threejs' or None (default)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### $\\mathbb{S}^2$ as a 2-dimensional differentiable manifold\n", "\n", "We declare $\\mathbb{S}^2$ as a differentiable manifold of dimension 2 over $\\mathbb{R}$ and we endow it with the stereographic charts from the North pole (stereoN) and the South pole (stereoS):" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Coordinate frame (U, (d/dx,d/dy)),\n", " Coordinate frame (V, (d/dxp,d/dyp)),\n", " Coordinate frame (W, (d/dx,d/dy)),\n", " Coordinate frame (W, (d/dxp,d/dyp))]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S2 = Manifold(2, 'S^2', latex_name=r'\\mathbb{S}^2', start_index=1)\n", "U = S2.open_subset('U')\n", "V = S2.open_subset('V')\n", "S2.declare_union(U, V)\n", "stereoN. = U.chart()\n", "stereoS. = V.chart(r\"xp:x' yp:y'\")\n", "stereoN_to_S = stereoN.transition_map(stereoS, (x/(x^2+y^2), y/(x^2+y^2)), \n", " intersection_name='W',\n", " restrictions1= x^2+y^2!=0, \n", " restrictions2= xp^2+xp^2!=0)\n", "stereoS_to_N = stereoN_to_S.inverse()\n", "W = U.intersection(V)\n", "eU = stereoN.frame()\n", "eV = stereoS.frame()\n", "S2.frames()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

### Spherical coordinates

\n", "

The standard spherical (or polar) coordinates $(\\theta,\\phi)$ are defined on the open domain $A\\subset W \\subset \\mathbb{S}^2$ that is the complement of the \"origin meridian\"; since the latter is the half-circle defined by $y=0$ and $x\\geq 0$, we declare:

" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x = -cos(ph)*sin(th)/(cos(th) - 1)\n", "y = -sin(ph)*sin(th)/(cos(th) - 1)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = W.open_subset('A', coord_def={stereoN.restrict(W): (y!=0, x<0), \n", " stereoS.restrict(W): (yp!=0, xp<0)})\n", "spher. = A.chart(r'th:(0,pi):\\theta ph:(0,2*pi):\\phi')\n", "spher_to_stereoN = spher.transition_map(stereoN.restrict(A), \n", " (sin(th)*cos(ph)/(1-cos(th)),\n", " sin(th)*sin(ph)/(1-cos(th))) )\n", "spher_to_stereoN.set_inverse(2*atan(1/sqrt(x^2+y^2)), atan2(-y,-x)+pi)\n", "spher_to_stereoN.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Embedding of $\\mathbb{S}^2$ into $\\mathbb{R}^3$\n", "\n", "Let us first declare $\\mathbb{R}^3$ as a 3-dimensional manifold covered by a single chart (Cartesian coordinates):" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (R^3, (X, Y, Z))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R3 = Manifold(3, 'R^3', r'\\mathbb{R}^3', start_index=1)\n", "cart. = R3.chart() ; cart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The embedding of the sphere is defined as a differential mapping $\\Phi: \\mathbb{S}^2 \\rightarrow \\mathbb{R}^3$:

" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Phi = S2.diff_map(R3, {(stereoN, cart): [2*x/(1+x^2+y^2), 2*y/(1+x^2+y^2),\n", " (x^2+y^2-1)/(1+x^2+y^2)],\n", " (stereoS, cart): [2*xp/(1+xp^2+yp^2), 2*yp/(1+xp^2+yp^2),\n", " (1-xp^2-yp^2)/(1+xp^2+yp^2)]},\n", " name='Phi', latex_name=r'\\Phi')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: S^2 --> R^3\n", "on U: (x, y) |--> (X, Y, Z) = (2*x/(x^2 + y^2 + 1), 2*y/(x^2 + y^2 + 1), (x^2 + y^2 - 1)/(x^2 + y^2 + 1))\n", "on V: (xp, yp) |--> (X, Y, Z) = (2*xp/(xp^2 + yp^2 + 1), 2*yp/(xp^2 + yp^2 + 1), -(xp^2 + yp^2 - 1)/(xp^2 + yp^2 + 1))\n", "on A: (th, ph) |--> (X, Y, Z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.expr(stereoN.restrict(A), cart)\n", "Phi.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3D plots of coordinate charts on $\\mathbb{S}^2$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Let us use $\\Phi$ to draw the grid of spherical coordinates $(\\theta,\\phi)$ in terms of the Cartesian coordinates $(X,Y,Z)$ of $\\mathbb{R}^3$:

" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [], "source": [ "graph_spher = spher.plot(chart=cart, mapping=Phi, number_values=11, color='blue',\n", " label_axes=False)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show(graph_spher, viewer=viewer3D)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We may also use the embedding $\\Phi$ to display the stereographic coordinate grid in terms of the Cartesian coordinates in $\\mathbb{R}^3$. First for the stereographic coordinates from the North pole:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "graph_stereoN = stereoN.plot(chart=cart, mapping=Phi, number_values=25,\n", " label_axes=False)\n", "show(graph_stereoN, viewer=viewer3D)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and then have a view with the stereographic coordinates from the South pole superposed (in green):" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "graph_stereoS = stereoS.plot(chart=cart, mapping=Phi, number_values=25, \n", " color='green', label_axes=False)\n", "show(graph_stereoN + graph_stereoS, viewer=viewer3D)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us add the North and South poles to the graphic:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "