/ examples / primer / cm3.ipynb
cm3.ipynb
  1  {
  2   "cells": [
  3    {
  4     "cell_type": "markdown",
  5     "metadata": {},
  6     "source": [
  7      "<h2>*Introduction*</h2>\n",
  8      "\n",
  9      "This file enables a user to construct and manipulate geometric objects in $\\mathbb{R}^3$. The constructions and manipulations are performed using a conformal model of $\\mathbb{R}^3$. A user need not know much about the conformal model, as all constructions and manipulations are via the functions provided here.   \n",
 10      "\n",
 11      "My intent is that the functions are self documenting through their code and comments. \n",
 12      "\n",
 13      "Vectors passed to the functions must be in conformal representation. \n",
 14      "Exceptions: pt, which converts a 3D point to a conformal point; a 3D normal vector $\\mathbf{n}$; and a 3D parallel bivector $\\mathbf{B}$.\n",
 15      "\n",
 16      "Objects returned by the functions are in conformal representation. Exception: tp, which returns a 3D point.\n",
 17      "\n",
 18      "To start, pull down the \"Run\" menu item and choose \"Run All Cells\".\n",
 19      "\n",
 20      "Comments and proposed changes or additions are welcome."
 21     ]
 22    },
 23    {
 24     "cell_type": "code",
 25     "execution_count": 1,
 26     "metadata": {},
 27     "outputs": [
 28      {
 29       "data": {
 30        "text/latex": [
 31         "$\\displaystyle \\DeclareMathOperator{\\Tr}{Tr}$$\n",
 32         "$$\\DeclareMathOperator{\\Adj}{Adj}$$\n",
 33         "$$\\newcommand{\\bfrac}[2]{\\displaystyle\\frac{#1}{#2}}$$\n",
 34         "$$\\newcommand{\\lp}{\\left (}$$\n",
 35         "$$\\newcommand{\\rp}{\\right )}$$\n",
 36         "$$\\newcommand{\\paren}[1]{\\lp {#1} \\rp}$$\n",
 37         "$$\\newcommand{\\half}{\\frac{1}{2}}$$\n",
 38         "$$\\newcommand{\\llt}{\\left <}$$\n",
 39         "$$\\newcommand{\\rgt}{\\right >}$$\n",
 40         "$$\\newcommand{\\abs}[1]{\\left |{#1}\\right | }$$\n",
 41         "$$\\newcommand{\\pdiff}[2]{\\bfrac{\\partial {#1}}{\\partial {#2}}}$$\n",
 42         "$$\\newcommand{\\npdiff}[3]{\\bfrac{\\partial^{#3} {#1}}{\\partial {#2}^{#3}}}$$\n",
 43         "$$\\newcommand{\\lbrc}{\\left \\{}$$\n",
 44         "$$\\newcommand{\\rbrc}{\\right \\}}$$\n",
 45         "$$\\newcommand{\\W}{\\wedge}$$\n",
 46         "$$\\newcommand{\\prm}[1]{{#1}^{\\prime}}$$\n",
 47         "$$\\newcommand{\\ddt}[1]{\\bfrac{d{#1}}{dt}}$$\n",
 48         "$$\\newcommand{\\R}{\\dagger}$$\n",
 49         "$$\\newcommand{\\deriv}[3]{\\bfrac{d^{#3}#1}{d{#2}^{#3}}}$$\n",
 50         "$$\\newcommand{\\grade}[2]{\\left < {#1} \\right >_{#2}}$$\n",
 51         "$$\\newcommand{\\f}[2]{{#1}\\lp {#2} \\rp}$$\n",
 52         "$$\\newcommand{\\eval}[2]{\\left . {#1} \\right |_{#2}}$$\n",
 53         "$$\\newcommand{\\bs}[1]{\\boldsymbol{#1}}$$\n",
 54         "$$\\newcommand{\\grad}{\\bs{\\nabla}}$"
 55        ],
 56        "text/plain": [
 57         "<IPython.core.display.Math object>"
 58        ]
 59       },
 60       "metadata": {},
 61       "output_type": "display_data"
 62      }
 63     ],
 64     "source": [
 65      "# Conformal Model, Amsterdam convention.  Dorst et al. p. 361\n",
 66      "\n",
 67      "# Make SymPy available to this program:\n",
 68      "import sympy \n",
 69      "from sympy import *\n",
 70      "\n",
 71      "# Make GAlgebra available to this program:\n",
 72      "from galgebra.ga import *  \n",
 73      "from galgebra.mv import *\n",
 74      "from galgebra.printer import Fmt, GaPrinter, Format\n",
 75      "    # Fmt:       sets the way that a multivector's basis expansion is output.\n",
 76      "    # GaPrinter: makes GA output a little more readable.\n",
 77      "    # Format:    turns on latex printer.\n",
 78      "from galgebra.gprinter import gFormat, gprint\n",
 79      "gFormat()"
 80     ]
 81    },
 82    {
 83     "cell_type": "code",
 84     "execution_count": 2,
 85     "metadata": {},
 86     "outputs": [],
 87     "source": [
 88      "# 3D confiormakl model\n",
 89      "\n",
 90      "cm3coords = (o,x,y,z,infty) = symbols('o 1 2 3 infty', real=True)\n",
 91      "cm3g = '0 0 0 0 -1, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0, -1 0 0 0 0'\n",
 92      "cm3 = Ga(r'o \\mathbf{e}_1 \\mathbf{e}_2 \\mathbf{e}_3 \\infty', g = cm3g,  coords = cm3coords)\n",
 93      "(eo, e1, e2, e3, eoo) = cm3.mv()\n",
 94      "ep = eo - eoo/2  # ep^2 = +1  Geometric Algebra for Computer Science 408\n",
 95      "em = eo + eoo/2  # em^2 = -1\n",
 96      "E = eo^eoo\n",
 97      "Ga.dual_mode('Iinv+')"
 98     ]
 99    },
100    {
101     "cell_type": "code",
102     "execution_count": 3,
103     "metadata": {},
104     "outputs": [],
105     "source": [
106      "def pt(arg): # R^3 vector --> conformal point. \n",
107      "    if isinstance(arg,str):           # Return general 3D point\n",
108      "        v = cm3.mv(arg, 'vector')     # General conformal vector \n",
109      "        v = v + (v < eoo)*eo + (v < eo)*eoo  # 3D part \n",
110      "        v = eo + v + (v<v)*eoo/2\n",
111      "    elif arg == 0:\n",
112      "        v = eo\n",
113      "    elif (arg < eoo) == 0:    # Return point for 3D vector in arg\n",
114      "        v = eo + arg + (arg<arg)*eoo/2\n",
115      "    else: v = arg             # arg already in conformal representation   \n",
116      "    return(v)"
117     ]
118    },
119    {
120     "cell_type": "code",
121     "execution_count": 4,
122     "metadata": {},
123     "outputs": [],
124     "source": [
125      "def tp(arg): # conformal point --> R^3 vector\n",
126      "    if isinstance(arg,str):   # Return general 3D vector\n",
127      "        v = cm3.mv(arg, 'vector')\n",
128      "    else:                     # Return 3D vector part of arg\n",
129      "        v = arg\n",
130      "    v = v + (v < eoo)*eo + (v < eo)*eoo\n",
131      "    return(v)       "
132     ]
133    },
134    {
135     "cell_type": "code",
136     "execution_count": 5,
137     "metadata": {},
138     "outputs": [],
139     "source": [
140      "def normalize(v): \n",
141      "    if (v < eoo) == 0: # Normalize 3D vector\n",
142      "        return(v/sqrt((v<v).scalar()))\n",
143      "    else:              # Normalize conformal vector: set eo coeff to 1.\n",
144      "        return(-v/(v<eoo))"
145     ]
146    },
147    {
148     "cell_type": "code",
149     "execution_count": 6,
150     "metadata": {},
151     "outputs": [],
152     "source": [
153      "def scalar(arg):\n",
154      "    return(cm3.mv(arg, 'scalar')) # Save user from typing all this"
155     ]
156    },
157    {
158     "cell_type": "markdown",
159     "metadata": {},
160     "source": [
161      "<h4>* Create direct representations of geometric objects *</h4>"
162     ]
163    },
164    {
165     "cell_type": "code",
166     "execution_count": 7,
167     "metadata": {},
168     "outputs": [],
169     "source": [
170      "def round(*args):  # args are conformal points\n",
171      "    ans = args[0]\n",
172      "    for i in range(1,len(args)):\n",
173      "        ans = ans ^ args[i]\n",
174      "    return(ans)"
175     ]
176    },
177    {
178     "cell_type": "code",
179     "execution_count": 8,
180     "metadata": {},
181     "outputs": [],
182     "source": [
183      "def flat(*args):   # args are conformal points\n",
184      "    return(round(*args) ^ eoo)"
185     ]
186    },
187    {
188     "cell_type": "code",
189     "execution_count": 9,
190     "metadata": {},
191     "outputs": [],
192     "source": [
193      "def line(p,q):     # If q is 3D vector, line thru p parallel to q returned\n",
194      "    return(flat(p,q))"
195     ]
196    },
197    {
198     "cell_type": "code",
199     "execution_count": 10,
200     "metadata": {},
201     "outputs": [],
202     "source": [
203      "def plane(p,q,r):\n",
204      "    return(flat(p,q,r))"
205     ]
206    },
207    {
208     "cell_type": "code",
209     "execution_count": 11,
210     "metadata": {},
211     "outputs": [],
212     "source": [
213      "def circle(p,q,r):\n",
214      "    return(round(p,q,r))"
215     ]
216    },
217    {
218     "cell_type": "code",
219     "execution_count": 12,
220     "metadata": {},
221     "outputs": [],
222     "source": [
223      "def sphere(p,q,r,s):\n",
224      "    return(round(p,q,r,s))"
225     ]
226    },
227    {
228     "cell_type": "markdown",
229     "metadata": {},
230     "source": [
231      "<h4>* Create dual representations of geometric objects *</h4>"
232     ]
233    },
234    {
235     "cell_type": "code",
236     "execution_count": 13,
237     "metadata": {},
238     "outputs": [],
239     "source": [
240      "def dualLine(p, B):      # Thru point p, orthogonal to 3D bivector B\n",
241      "    return(p < (B*eoo))  # A vector"
242     ]
243    },
244    {
245     "cell_type": "code",
246     "execution_count": 14,
247     "metadata": {},
248     "outputs": [],
249     "source": [
250      "def dualPlane(p,n):           # n: GA^3 normal vector    \n",
251      "    m = normalize(n)\n",
252      "    if isinstance(p,(int, long, float)):\n",
253      "        p = scalar(p)         # Python scalar -> GAlgebra scalar\n",
254      "    if (p!=0) and ((p<p)==0): # p: point on plane. \n",
255      "        return(p < (m^eoo))   # a vector\n",
256      "    else:                     # p: distance to origin.\n",
257      "        return(m + (p*eoo))   # a vector"
258     ]
259    },
260    {
261     "cell_type": "code",
262     "execution_count": 15,
263     "metadata": {},
264     "outputs": [],
265     "source": [
266      "def dualSphere(c,rho):               # c:center. \n",
267      "    if isinstance(rho,(int, long, float)):\n",
268      "        rho = scalar(rho)            # Python scalar -> GAlgebra scalar\n",
269      "    if (rho!=0) and ((rho<rho)==0):  # rho: point on sphere \n",
270      "        return(rho < (c ^ eoo))  \n",
271      "    else:                            # rho: radius. \n",
272      "        return(c - (rho*rho*eoo)/2)  # A vector     "
273     ]
274    },
275    {
276     "cell_type": "code",
277     "execution_count": 16,
278     "metadata": {},
279     "outputs": [],
280     "source": [
281      "def dualCircle(c,rho,n): # c:center. rho:radius. n:normal vector\n",
282      "    ds = dualSphere(c,rho)\n",
283      "    dp = dualPlane(c,n)    \n",
284      "    return(ds^dp)          # A Bivector "
285     ]
286    },
287    {
288     "cell_type": "markdown",
289     "metadata": {},
290     "source": [
291      "<h4>*  Geometric operations *</h4>"
292     ]
293    },
294    {
295     "cell_type": "code",
296     "execution_count": 17,
297     "metadata": {},
298     "outputs": [],
299     "source": [
300      "def translate(object,a3): # a3: 3D vector\n",
301      "    return(1 - a3*eoo/2)*object*(1 + a3*eoo/2)"
302     ]
303    },
304    {
305     "cell_type": "code",
306     "execution_count": 18,
307     "metadata": {},
308     "outputs": [],
309     "source": [
310      "def rotate(object,itheta):\n",
311      "    return(exp(-itheta/2)*object*exp(itheta/2))"
312     ]
313    },
314    {
315     "cell_type": "code",
316     "execution_count": 19,
317     "metadata": {},
318     "outputs": [],
319     "source": [
320      "def invert(p, norm=False):   # GACS 513\n",
321      "    ans = -(eo - eoo/2)*p*(eo - eoo/2) \n",
322      "    if norm:\n",
323      "        ans = normalize(ans)\n",
324      "    return(ans)"
325     ]
326    },
327    {
328     "cell_type": "code",
329     "execution_count": 20,
330     "metadata": {},
331     "outputs": [],
332     "source": [
333      "# Reflect point p in hyperplane with normal 3D vector n.\n",
334      "def reflect(p,n):\n",
335      "    return(-n*p*(n/norm2(n)))  "
336     ]
337    },
338    {
339     "cell_type": "code",
340     "execution_count": 21,
341     "metadata": {},
342     "outputs": [],
343     "source": [
344      "# Can be considerably simplified: A Covariant Approach ..., 16 \n",
345      "def dilate(p, alpha, norm = False):  # Dilate by alpha (> 0)\n",
346      "    ans = exp(E*ln(alpha)/2)*p*exp(-E*ln(alpha)/2)\n",
347      "    if norm:\n",
348      "        ans = normalize(ans)\n",
349      "    return(ans)"
350     ]
351    },
352    {
353     "cell_type": "markdown",
354     "metadata": {},
355     "source": [
356      "<h4>* Play *</h4>"
357     ]
358    },
359    {
360     "cell_type": "code",
361     "execution_count": null,
362     "metadata": {},
363     "outputs": [],
364     "source": []
365    }
366   ],
367   "metadata": {
368    "celltoolbar": "Raw Cell Format",
369    "kernelspec": {
370     "display_name": "Python 3 (ipykernel)",
371     "language": "python",
372     "name": "python3"
373    },
374    "language_info": {
375     "codemirror_mode": {
376      "name": "ipython",
377      "version": 3
378     },
379     "file_extension": ".py",
380     "mimetype": "text/x-python",
381     "name": "python",
382     "nbconvert_exporter": "python",
383     "pygments_lexer": "ipython3",
384     "version": "3.11.8"
385    }
386   },
387   "nbformat": 4,
388   "nbformat_minor": 4
389  }