{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "In Lecture 27 of MCS 320, we make three dimensional plots." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Surfaces" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Surfaces can be defined explicitly, by a function $z = f(x,y)$, or implicitly by an equation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Consider the surface $z = \\cos(x y)$, for $x \\in [-\\pi, \\pi]$ and $y \\in [-\\pi, \\pi]$." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x, y = var('x,y')\n", "plot3d(cos(x*y), (x, -pi, pi), (y, -pi, pi), figsize=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can change the aspect ratio, so the plot does not look that flat." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot3d(cos(x*y), (x, -pi, pi), (y, -pi, pi), aspect_ratio=(1,1,2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``[-0.2194,-0.5297,-0.8193],142.51`` is the viewpoint copied to the clipboard" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot3d(cos(x*y), (x, -pi, pi), (y, -pi, pi), aspect_ratio=(1,1,2)).rotateX(-0.2).rotateZ(-0.8)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot3d(cos(x*y), (x, -pi, pi), (y, -pi, pi), adaptive=True, \\\n", " aspect_ratio=(1,1,2), color='automatic', num_colors=256)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the surface defined by $z^3 - x^2 - y^2 = 0$ for $x$ and $y$ in $[-1,1]$ and for $z \\in [0,1]$." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x, y, z = var('x, y, z')\n", "implicit_plot3d(z^3 - x^2 - y^2, (x, -1, 1), (y,-1, 1), (z, 0, 1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A surface can be defined in parameter form. As a surface is two dimensional, there are two free parameters." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "u, v = var('u, v')\n", "fx = cos(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u))\n", "fy = sin(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u))\n", "fz = v\n", "heart = parametric_plot3d([fx, fy, fz], (u, -pi, pi), (v, -1, 1), \\\n", " color='red').rotateX(-pi/9).rotateY(-pi/2).rotateZ(pi/4)\n", "show(heart, frame=False, figsize=4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Space Curves" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The twisted cubic is an example of a space curve. We can define it in parameter form, or as the intersection of two cylinders." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "t = var('t')\n", "twisted = (t, t^2, t^3)\n", "pt = parametric_plot3d(twisted, (t, -1, 1), thickness=10, color='red').rotateY(pi/15).rotateZ(pi/3)\n", "show(pt, figsize=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The twisted cubic lies on a parabolic cylinder." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x, y, z = var('x,y,z')\n", "c2 = implicit_plot3d(x^2 - y,(x,-1,1),(y,0,1), (z,-1,1)).rotateY(pi/15).rotateZ(pi/3)\n", "(pt+c2).show(figsize=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The twisted cubic lies in the intersection of $x^2 - y = 0$ and $x^3 - z = 0$, respectively a parabolic and a cubic cylinder." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c3 = implicit_plot3d(x^3 - z,(x,-1,1),(y,0,1), (z,-1,1), color='green').rotateY(pi/15).rotateZ(pi/3)\n", "(pt+c2+c3).show(figsize=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3. Four dimensional Plots" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The color coding of the surface can be used to make a complex plot, in four dimensions. As example we consider the complex cube root, defined by the equation $z = w^3$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The input is $w$ and we have two parameters in the input, the real part of $w$ and the imaginary part of $w$, which will be called ``u`` and ``v``." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "u, v = var('u, v', domain = RR)\n", "w = u + I*v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Observe that both ``u`` and ``v`` are declared as real variables." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The output is ``z`` and we take its real and imaginary part, expressed in the real variables ``u`` and ``v``." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the real part of the output : u^3 - 3*u*v^2\n", "the imaginary part of the output : 3*u^2*v - v^3\n" ] } ], "source": [ "z = w^3\n", "x = real_part(z)\n", "y = imag_part(z)\n", "print('the real part of the output :', x)\n", "print('the imaginary part of the output :', y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Instead of using the input ``u`` and ``v`` as rectangular coordinates, we transition to polar coordinates for the input." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the polar form of the real part of the output : r^3*cos(t)^3 - 3*r^3*cos(t)*sin(t)^2\n", "the polar form of the imaginary part of the output : 3*r^3*cos(t)^2*sin(t) - r^3*sin(t)^3\n" ] } ], "source": [ "r, t = var('r, t')\n", "rt = {u:r*cos(t), v:r*sin(t)}\n", "px = x.subs(rt)\n", "py = y.subs(rt)\n", "print('the polar form of the real part of the output :', px)\n", "print('the polar form of the imaginary part of the output :', py)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The height of the three dimensional part corresponds to the real part of the input." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parametric_plot3d((px, py, r*cos(t)), (r, 0, 1), (t, 0, 2*pi), adaptive=True, figsize=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The imaginary part of the input is represented via a colormap." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "cm = colormaps.autumn\n", "def c(r,t): return r*sin(t)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cr = parametric_plot3d((px, py, r*cos(t)), (r,0,1), (t, 0, 2*pi), \\\n", " adaptive=True,color=(c,cm))\n", "cr.show(figsize=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The colors show that, although the real parts are the same, the imaginary parts differ, so there is no intersection." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cr = parametric_plot3d((px, py, r*cos(t)), (r,0,1), (t, 0, 2*pi), \\\n", " adaptive=True,color=(c,cm)).rotateX(-pi/10).rotateY(-pi).rotateZ(-pi/2)\n", "cr.show(figsize=2)" ] } ], "metadata": { "kernelspec": { "display_name": "SageMath 10.3", "language": "sage", "name": "sagemath" }, "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.10" } }, "nbformat": 4, "nbformat_minor": 4 }