Para la realización de gráficos en tres dimensiones, SageMath dispone de una gama bastante amplia de funciones, detallada en la documentación. Vamos a ver en esta guía tan sólo algunas de ellas.
Los principios generales de los gráficos en 3D son similares a los de los gráficos bidimensionales. Los objetos gráficos se combinan mediante la suma o la función sum
. Todos ellos admiten el método show
, que también actúa como función. Sus opciones más relevantes son:
aspect_ratio
: terna que indica la proporción entre las escalas usadas en cada una de las tres direcciones del espacio;frame
: controla si se traza o no una caja englobando la escena tridimensional.Varias funciones, como point3d, line3d, arrow3d, polygon3d o text3d, son extensiones de sus homólogas en el caso bidimensional y tienen una sintaxis similar.
La siguiente celda ejemplifica estos principios y algunas de las funciones citadas; presenta además la función sphere
para la representación de esferas:
# Ejes y planos coordenados
e0 = vector((0,0,0)); e1 = vector((3,0,0)); e2 = vector((0,3,0)); e3 = vector((0,0,3))
planos = polygon3d([e0,e1,e1+e3,e3], opacity=0.4, color="red")
planos += polygon3d([e0,e2,e2+e3,e3], opacity=0.4, color="green")
planos += polygon3d([e0,e1,e1+e2,e2], opacity=0.4, color="blue")
ejes = sum([arrow3d(e0, pt, color="dimgray", width=2) for pt in [e1,e2,e3]])
texto = text3d("x", 1.05*e1) + text3d("y", 1.05*e2) + text3d("z", 1.05*e3)
# Línea poligonal salpicada de esferas
vertices = [(1.5+cos(t),1.5+sin(t),1.5+sin(3*t)) for t in [0,pi/18..2*pi]]
esferas = sum(sphere(pt, 0.1, color="goldenrod") for pt in vertices)
linea = line3d(vertices, radius=0.05, color="silver")
# Representación de la escena
show(ejes + planos + texto + esferas + linea, frame=False)
La misión principal de esta orden es trazar el grafo de una función bivariada $f:D\subset\mathbb{R}^2\to\mathbb{R}$ sobre un rectángulo $[a_1,b_1]\times[a_2,b_2]$. Se usa con la siguiente sintaxis:
plot3d(fun, rango_x, rango_y, opciones),
donde:
Indicamos las principales opciones:
También es posible añadir las opciones de show
.
Demos algunos ejemplos. La celda siguiente traza y superpone los grafos de las funciones $\cos(xy)$ y $\operatorname{sen}(x^2-y^2)$ en el rectángulo $[-\pi,\pi]\times[-\pi,\pi]$:
var("x,y")
s1 = plot3d(cos(x*y), (x,-pi,pi), (y,-pi,pi), color="green", opacity=0.5, plot_points=60, mesh=True)
s2 = plot3d(sin(x^2-y^2), (x,-pi,pi), (y,-pi,pi), color="brown", plot_points=80)
show(s1+s2)
En el ejemplo previo, cada superficie tiene un único color. Para policromar la superficie, se usa la opción color
en la forma color=(col, gama)
, donde col
es una función bivariada con recorrido en el intervalo $[0,1]$ y gama
es una gama de colores. Dentro de la gama, cada color está indexado mediante un número entre $0$ y $1$. Por ello, el punto $(x,y,z)$ de la superficie recibe el color que corresponde al número $\mathtt{col}(x,y)$.
La orden sorted(colormaps)
proporciona una lista ordenada alfabéticamente de las gamas predefinidas de colores. Si 'gama' es uno de los elementos de esta lista, entonces colormaps.gama
es el nombre correcto de la gama que hay que usar en la opción color
.
Repetimos el ejemplo anterior. Una de las superficies se colorea con tonos verdes elegidos aleatoriamente; la otra superficie se pinta en tonos rojos siguiendo un patrón determinado (al punto $(x,y,z)$ se le asigna el tono de rojo que corresponde a (x^2+y^2)%1
, esto es, la parte fraccionaria del número real $x^2+y^2$):
s1 = plot3d(cos(x*y), (x,-pi,pi), (y,-pi,pi),
color=(lambda x,y: random(), colormaps.Greens),
opacity=0.5, plot_points=60, mesh=True)
s2 = plot3d(sin(x^2-y^2), (x,-pi,pi), (y,-pi,pi),
color=(lambda x,y: (x^2+y^2)%1, colormaps.Reds),
plot_points=80)
show(s1+s2)
Dibujamos ahora la superficie $z=f(x,y)$, con $$ f(x,y) = \frac{2x+3y^2}{(x^2+y^2+1)^2} $$ en el rectángulo $[-2,2]\times[-2,2]$. Para hacernos una idea más cabal de la superficie, pintamos cada punto $(x,y,f(x,y))$ de acuerdo con el valor de $f$. Para definir la función que asigna el color, se necesita determinar previamente el rango de valores que toma $f$ en el rectángulo considerado, para lo cual basta con representar la superficie una vez, sin opciones añadidas, y observar el gráfico:
# Definición de f
def f(x,y):
return (2*x+3*y^2) / (x^2+y^2+1)^2
# Definición de col.
# Se necesita conocer previamente zmin y zmax tales que
# zmin <= f(x,y) <= zmax en el rectángulo considerado
zmin, zmax = -0.64, 0.84
def col(x,y):
return (f(x,y)-zmin)/(zmax-zmin)
gama = colormaps.jet
# Representación de la superficie
plot3d(f, (-2,2), (-2,2), color=(col,gama), mesh=True, aspect_ratio=[1,1,2])
La función plot
admite también la opción transformation
, gracias a la cual se pueden representar fácilmente en el sistema de referencia cartesiano superficies dadas de forma explícita en otro sistema de coordenadas. Consideremos, por ejemplo, la superficie dada en coordenadas cilíndricas mediante la ecuación
$$
r = 1 + e^{-z} \left(1+\cos 6\theta\right),
$$
con $(\theta,z)\in[0,2\pi]\times[0,3]$. La siguiente celda muestra esta superficie:
# Cambio a coordenadas cilíndricas
var("r,θ,z")
Cilíndricas = (r*cos(θ), r*sin(θ), z)
# Representación de la superficie
plot3d(1+e^(-z)*(1+cos(6*θ)), (θ,0,2*pi), (z,0,3), transformation=Cilíndricas,
plot_points=[80,40], color="lightgreen", mesh=True)
Pongamos otro ejemplo. Trazamos ahora la superficie $z=\operatorname{sen}(\pi r)\,\operatorname{sen}\theta$, con $(r,\theta)\in[0,5]\times[0,2\pi]$:
plot3d(sin(pi*r)*sin(θ), (r,0,5), (θ,0,2*pi), transformation=Cilíndricas,
plot_points=61, color="lightgreen", mesh=True, aspect_ratio=[1,1,1.75])
Añadimos un último ejemplo en coordenadas esféricas. Representamos la superficie $\rho=(2-\varphi)(3+\cos6\theta)$, con $(\theta,\varphi)\in[0,2\pi]\times[-\pi/2,\pi/2]$:
var("ρ,θ,φ")
Esféricas = (ρ*cos(θ)*cos(φ), ρ*sin(θ)*cos(φ), ρ*sin(φ))
plot3d((2-φ)*(3+cos(6*θ)), (θ,0,2*pi), (φ,-pi/2,pi/2), transformation=Esféricas,
plot_points=[85,40], color="lightgreen", mesh=True)
La representación gráfica de curvas y superficies paramétricas se efectúa mediante la función parametric_plot3d
.
Consideremos primero una curva dada en forma paramétrica mediante la ecuación $(x,y,z)=\boldsymbol{\varphi}(t)$, con $\boldsymbol{\varphi}=(\varphi_1,\varphi_2,\varphi_3):I\subset\mathbb{R}\to\mathbb{R}^3$ y $t\in[a,b]$. Para trazar esta curva, se usa parametric_plot3d
con la siguiente sintaxis:
parametric_plot3d(fun, rango_t, opciones),
donde:
Asimismo, para dibujar una superficie de ecuación paramétrica $(x,y,z)=\boldsymbol{\varphi}(u,v)$, con
$(u,v)\in D=[a_1,b_1]\times[a_2,b_2]$ y $\boldsymbol{\varphi}=(\varphi_1,\varphi_2,\varphi_3):D\to\mathbb{R}^3$, la sintaxis que ahora adopta parametric_plot3d
es
parametric_plot3d(fun, rango_u, rango_v, opciones).
Las opciones que admite parametric_plot3d
son similares a las de plot3d
. Demos algunos ejemplos. Representamos primero una hélice de ecuación $\boldsymbol{x}=(10\cos t, 10\operatorname{sen} t, t)$, con $t\in[0,6\pi]$:
var("t")
g(t) = (10*cos(t), 10*sin(t), t)
helice = parametric_plot3d(g(t), (t,0,6*pi), radius=0.5, plot_points=150, color="brown")
helice
La hélice anterior, en realidad, está contenida en el helicoide de ecuación paramétrica $$ \left\{ \begin{aligned} &x=v\cos u, \\ &y=v\operatorname{sen} u, \\ &z=u, \end{aligned} \right. \qquad (u,v)\in[0,6\pi]\times[5,15] $$ Lo mostramos en la siguiente celda:
var("u,v")
def φ(u,v):
return (v*cos(u), v*sin(u), u)
helicoide = parametric_plot3d(φ(u,v), (u,0,6*pi), (v,5,15),
plot_points=[120,15], mesh=True, color="lightgreen")
show(helice + helicoide)
Pongamos otro ejemplo. Con el auxilio de la función plot3d
, hemos representado antes la superficie de ecuación $z=\operatorname{sen}(\pi r)\,\operatorname{sen}\theta$ en coordenadas cilíndricas, con $(r,\theta)\in[0,5]\times[0,2\pi]$. En este caso, es obvio que tal superficie se expresa en forma paramétrica mediante la ecuación
$$
(x,y,z) = \left(r\cos\theta, r\operatorname{sen}\theta, \operatorname{sen}(\pi r)\,\operatorname{sen}\theta\right).
$$
Por ello, para trazar esta superficie se puede usar también la función parametric_plot3d
:
var("r,θ")
g = (r*cos(θ), r*sin(θ), sin(pi*r)*sin(θ))
parametric_plot3d(g, (r,0,5), (θ,0,2*pi), plot_points=61, color="lightgreen", mesh=True, aspect_ratio=[1,1,1.75])
Concluimos dibujando el toro de ecuación $$ (x,y,z) = \bigl((2+\cos v)\cos u, (2+\cos v)\operatorname{sen}u, \operatorname{sen}v\bigr), $$ con $(u,v)\in[0,2\pi]\times[0,2\pi]$:
var("u,v")
toro = ((2+cos(v))*cos(u), (2+cos(v))*sin(u), sin(v))
parametric_plot3d(toro, (u,0,2*pi), (v,0,2*pi), mesh=True, plot_points=[80,40],
color=(lambda u,v: sin(u/2)*(1+sin(v))/2,colormaps.Oranges_r))
%%html
<style>
h1{text-align: center; color: rgb(185,74,72);}
h2{text-align: center; color: rgb(0,102,0); padding: 0.25em 0;
border: 2px solid rgb(0,191,0); border-width: 2px 0;}
h3{border-bottom: 2px solid rgb(153,153,153);}
h4{color: rgb(58,135,173); font-size: 115%!important;
font-weight: bold!important;}
.text_cell_render{font-family: "Trebuchet MS",Geneva,sans-serif;
font-size: 110%; line-height: 1.5;}
.MathJax_Display{margin: 0.5em 0;}
</style>