Bases: sage.structure.sage_object.SageObject
Class representing a parametrized two-dimensional surface in Euclidian three-space. Provides methods for calculating the main geometrical objects related to such a surface, such as the first and the second fundamental form, the total (Gaussian) and the mean curvature, the geodesic curves, parallel transport, etc.
INPUT:
- surface_equation – a 3-tuple of functions specifying a parametric representation of the surface.
- variables – a 2-tuple of intrinsic coordinates
on the surface, with
and
symbolic variables, or a 2-tuple of triples $(u, u_{min}, u_{max})$, $(v, v_{min}, v_{max})$ when the parameter range for the coordinates is known.
- name – name of the surface (optional).
Note
Throughout the documentation, we use the Einstein summation
convention: whenever an index appears twice, once as a
subscript, and once as a superscript, summation over that index
is implied. For instance, stands for
.
EXAMPLES:
We give several examples of standard surfaces in differential geometry. First, let’s construct an elliptic paraboloid by explicitly specifying its parametric equation:
sage: u, v = var('u,v', domain='real')
sage: eparaboloid = ParametrizedSurface3D((u, v, u^2 + v^2), (u, v),'elliptic paraboloid'); eparaboloid
Parametrized surface ('elliptic paraboloid') with equation (u, v, u^2 + v^2)
When the ranges for the intrinsic coordinates are known, they can be specified explicitly. This is mainly useful for plotting. Here we construct half of an ellipsoid:
sage: u1, u2 = var ('u1, u2', domain='real');
sage: coords = ((u1, -pi/2, pi/2), (u2, 0, pi))
sage: ellipsoid_eq = (cos(u1)*cos(u2), 2*sin(u1)*cos(u2), 3*sin(u2))
sage: ellipsoid = ParametrizedSurface3D(ellipsoid_eq, coords, 'ellipsoid'); ellipsoid
Parametrized surface ('ellipsoid') with equation (cos(u1)*cos(u2), 2*cos(u2)*sin(u1), 3*sin(u2))
sage: ellipsoid.plot()
Graphics3d Object
Standard surfaces can be constructed using the surfaces generator:
sage: klein = surfaces.Klein(); klein
Parametrized surface ('Klein bottle') with equation (-(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*cos(u), -(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*sin(u), cos(1/2*u)*sin(2*v) + sin(1/2*u)*sin(v))
Latex representation of the surfaces:
sage: u, v = var('u, v', domain='real')
sage: sphere = ParametrizedSurface3D((cos(u)*cos(v), sin(u)*cos(v), sin(v)), (u, v), 'sphere')
sage: print latex(sphere)
\left(\cos\left(u\right) \cos\left(v\right), \cos\left(v\right) \sin\left(u\right), \sin\left(v\right)\right)
sage: print sphere._latex_()
\left(\cos\left(u\right) \cos\left(v\right), \cos\left(v\right) \sin\left(u\right), \sin\left(v\right)\right)
sage: print sphere
Parametrized surface ('sphere') with equation (cos(u)*cos(v), cos(v)*sin(u), sin(v))
To plot a parametric surface, use the plot() member function:
sage: enneper = surfaces.Enneper(); enneper
Parametrized surface ('Enneper's surface') with equation (-1/9*(u^2 - 3*v^2 - 3)*u, -1/9*(3*u^2 - v^2 + 3)*v, 1/3*u^2 - 1/3*v^2)
sage: enneper.plot(aspect_ratio='automatic')
Graphics3d Object
We construct an ellipsoid whose axes are given by symbolic variables ,
and
, and find the natural frame of tangent vectors,
expressed in intrinsic coordinates. Note that the result is a
dictionary of vector fields:
sage: a, b, c = var('a, b, c', domain='real')
sage: u1, u2 = var('u1, u2', domain='real')
sage: ellipsoid_eq = (a*cos(u1)*cos(u2), b*sin(u1)*cos(u2), c*sin(u2))
sage: ellipsoid = ParametrizedSurface3D(ellipsoid_eq, (u1, u2), 'Symbolic ellipsoid'); ellipsoid
Parametrized surface ('Symbolic ellipsoid') with equation (a*cos(u1)*cos(u2), b*cos(u2)*sin(u1), c*sin(u2))
sage: ellipsoid.natural_frame()
{1: (-a*cos(u2)*sin(u1), b*cos(u1)*cos(u2), 0), 2: (-a*cos(u1)*sin(u2), -b*sin(u1)*sin(u2), c*cos(u2))}
We find the normal vector field to the surface. The normal vector field is the vector product of the vectors of the natural frame, and is given by:
sage: ellipsoid.normal_vector()
(b*c*cos(u1)*cos(u2)^2, a*c*cos(u2)^2*sin(u1), a*b*cos(u2)*sin(u2))
By default, the normal vector field is not normalized. To obtain the unit normal vector field of the elliptic paraboloid, we put:
sage: u, v = var('u,v', domain='real')
sage: eparaboloid = ParametrizedSurface3D([u,v,u^2+v^2],[u,v],'elliptic paraboloid')
sage: eparaboloid.normal_vector(normalized=True)
(-2*u/sqrt(4*u^2 + 4*v^2 + 1), -2*v/sqrt(4*u^2 + 4*v^2 + 1), 1/sqrt(4*u^2 + 4*v^2 + 1))
Now let us compute the coefficients of the first fundamental form of the torus:
sage: u, v = var('u, v', domain='real')
sage: a, b = var('a, b', domain='real')
sage: torus = ParametrizedSurface3D(((a + b*cos(u))*cos(v),(a + b*cos(u))*sin(v), b*sin(u)),[u,v],'torus')
sage: torus.first_fundamental_form_coefficients()
{(1, 1): b^2, (1, 2): 0, (2, 1): 0, (2, 2): b^2*cos(u)^2 + 2*a*b*cos(u) + a^2}
The first fundamental form can be used to compute the length of a
curve on the surface. For example, let us find the length of the
curve ,
,
, on the ellipsoid
with axes
,
and
. So we take the curve:
sage: t = var('t', domain='real')
sage: u1 = t
sage: u2 = t
Then find the tangent vector:
sage: du1 = diff(u1,t)
sage: du2 = diff(u2,t)
sage: du = vector([du1, du2]); du
(1, 1)
Once we specify numerical values for the axes of the ellipsoid, we can determine the numerical value of the length integral:
sage: L = sqrt(ellipsoid.first_fundamental_form(du, du).substitute(u1=u1,u2=u2))
sage: print numerical_integral(L.substitute(a=2, b=1.5, c=1),0,1)[0]
2.00127905972
We find the area of the sphere of radius :
sage: R = var('R', domain='real');
sage: u, v = var('u,v', domain='real');
sage: assume(R>0)
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere')
sage: integral(integral(sphere.area_form(),u,0,2*pi),v,-pi/2,pi/2)
4*pi*R^2
We can find an orthonormal frame field of a surface
and calculate its structure functions. Let us first determine the
orthonormal frame field for the elliptic paraboloid:
sage: u, v = var('u,v', domain='real')
sage: eparaboloid = ParametrizedSurface3D([u,v,u^2+v^2],[u,v],'elliptic paraboloid')
sage: eparaboloid.orthonormal_frame()
{1: (1/sqrt(4*u^2 + 1), 0, 2*u/sqrt(4*u^2 + 1)), 2: (-4*u*v/(sqrt(4*u^2 + 4*v^2 + 1)*sqrt(4*u^2 + 1)), sqrt(4*u^2 + 1)/sqrt(4*u^2 + 4*v^2 + 1), 2*v/(sqrt(4*u^2 + 4*v^2 + 1)*sqrt(4*u^2 + 1)))}
We can express the orthogonal frame field both in exterior
coordinates (i.e. expressed as vector field fields in the ambient
space , the default) or in intrinsic coordinates
(with respect to the natural frame). Here we use intrinsic
coordinates:
sage: eparaboloid.orthonormal_frame(coordinates='int')
{1: (1/sqrt(4*u^2 + 1), 0), 2: (-4*u*v/(sqrt(4*u^2 + 4*v^2 + 1)*sqrt(4*u^2 + 1)), sqrt(4*u^2 + 1)/sqrt(4*u^2 + 4*v^2 + 1))}
Using the orthonormal frame in interior coordinates, we can calculate
the structure functions of the surface, defined by
, where
represents the Lie
bracket of two frame vector fields
. For the
elliptic paraboloid, we get:
sage: EE = eparaboloid.orthonormal_frame(coordinates='int')
sage: E1 = EE[1]; E2 = EE[2]
sage: CC = eparaboloid.frame_structure_functions(E1,E2)
sage: CC[1,2,1].simplify_full()
4*sqrt(4*u^2 + 4*v^2 + 1)*v/((16*u^4 + 4*(4*u^2 + 1)*v^2 + 8*u^2 + 1)*sqrt(4*u^2 + 1))
We compute the Gaussian and mean curvatures of the sphere:
sage: sphere = surfaces.Sphere(); sphere
Parametrized surface ('Sphere') with equation (cos(u)*cos(v), cos(v)*sin(u), sin(v))
sage: K = sphere.gauss_curvature(); K # Not tested -- see trac 12737
1
sage: H = sphere.mean_curvature(); H # Not tested -- see trac 12737
-1
We can easily generate a color plot of the Gaussian curvature of a surface. Here we deal with the ellipsoid:
sage: u1, u2 = var('u1,u2', domain='real');
sage: u = [u1,u2]
sage: ellipsoid_equation(u1,u2) = [2*cos(u1)*cos(u2),1.5*cos(u1)*sin(u2),sin(u1)]
sage: ellipsoid = ParametrizedSurface3D(ellipsoid_equation(u1,u2), [u1, u2],'ellipsoid')
sage: # set intervals for variables and the number of division points
sage: u1min, u1max = -1.5, 1.5
sage: u2min, u2max = 0, 6.28
sage: u1num, u2num = 10, 20
sage: # make the arguments array
sage: from numpy import linspace
sage: u1_array = linspace(u1min, u1max, u1num)
sage: u2_array = linspace(u2min, u2max, u2num)
sage: u_array = [ (uu1,uu2) for uu1 in u1_array for uu2 in u2_array]
sage: # Find the gaussian curvature
sage: K(u1,u2) = ellipsoid.gauss_curvature()
sage: # Make array of K values
sage: K_array = [K(uu[0],uu[1]) for uu in u_array]
sage: # Find minimum and max of the gauss curvature
sage: K_max = max(K_array)
sage: K_min = min(K_array)
sage: # Make the array of color coefficients
sage: cc_array = [ (ccc - K_min)/(K_max - K_min) for ccc in K_array ]
sage: points_array = [ellipsoid_equation(u_array[counter][0],u_array[counter][1]) for counter in range(0,len(u_array)) ]
sage: curvature_ellipsoid_plot = sum( point([xx for xx in points_array[counter]],color=hue(cc_array[counter]/2)) for counter in range(0,len(u_array)) )
sage: curvature_ellipsoid_plot.show(aspect_ratio=1)
We can find the principal curvatures and principal directions of the elliptic paraboloid:
sage: u, v = var('u, v', domain='real')
sage: eparaboloid = ParametrizedSurface3D([u, v, u^2+v^2], [u, v], 'elliptic paraboloid')
sage: pd = eparaboloid.principal_directions(); pd
[(2*sqrt(4*u^2 + 4*v^2 + 1)/(16*u^4 + 16*v^4 + 8*(4*u^2 + 1)*v^2 + 8*u^2 + 1), [(1, v/u)], 1), (2/sqrt(4*u^2 + 4*v^2 + 1), [(1, -u/v)], 1)]
We extract the principal curvatures:
sage: k1 = pd[0][0].simplify_full()
sage: k1
2*sqrt(4*u^2 + 4*v^2 + 1)/(16*u^4 + 16*v^4 + 8*(4*u^2 + 1)*v^2 + 8*u^2 + 1)
sage: k2 = pd[1][0].simplify_full()
sage: k2
2/sqrt(4*u^2 + 4*v^2 + 1)
and check them by comparison with the Gaussian and mean curvature expressed in terms of the principal curvatures:
sage: K = eparaboloid.gauss_curvature().simplify_full()
sage: K
4/(16*u^4 + 16*v^4 + 8*(4*u^2 + 1)*v^2 + 8*u^2 + 1)
sage: H = eparaboloid.mean_curvature().simplify_full()
sage: H
2*(2*u^2 + 2*v^2 + 1)/(4*u^2 + 4*v^2 + 1)^(3/2)
sage: (K - k1*k2).simplify_full()
0
sage: (2*H - k1 - k2).simplify_full()
0
We can find the intrinsic (local coordinates) of the principal directions:
sage: pd[0][1]
[(1, v/u)]
sage: pd[1][1]
[(1, -u/v)]
The ParametrizedSurface3D class also contains functionality to compute the coefficients of the second fundamental form, the shape operator, the rotation on the surface at a given angle, the connection coefficients. One can also calculate numerically the geodesics and the parallel translation along a curve.
Here we compute a number of geodesics on the sphere emanating from the point (1, 0, 0), in various directions. The geodesics intersect again in the antipodal point (-1, 0, 0), indicating that these points are conjugate:
sage: S = surfaces.Sphere()
sage: g1 = [c[-1] for c in S.geodesics_numerical((0,0),(1,0),(0,2*pi,100))]
sage: g2 = [c[-1] for c in S.geodesics_numerical((0,0),(cos(pi/3),sin(pi/3)),(0,2*pi,100))]
sage: g3 = [c[-1] for c in S.geodesics_numerical((0,0),(cos(2*pi/3),sin(2*pi/3)),(0,2*pi,100))]
sage: (S.plot(opacity=0.3) + line3d(g1,color='red') + line3d(g2,color='red') + line3d(g3,color='red')).show()
Returns the coefficient of the area form on the surface. In terms of
the coefficients (where
) of the first
fundamental form, the coefficient of the area form is given by
.
See also area_form_squared().
OUTPUT:
- Coefficient of the area form
EXAMPLES:
sage: u, v = var('u,v', domain='real')
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.area_form()
cos(v)
Returns the square of the coefficient of the area form on the surface.
In terms of the coefficients (where
) of the
first fundamental form, this invariant is given by
.
See also area_form().
OUTPUT:
- Square of the area form
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.area_form_squared()
cos(v)^2
Computes the connection coefficients or Christoffel symbols
of the surface. If the coefficients of the first
fundamental form are given by
(where
), then
.
Here,
is the inverse of the matrix
, with
.
OUTPUT:
Dictionary of connection coefficients, where the keys are 3-tuples
and the values are the corresponding coefficients
.
EXAMPLES:
sage: r = var('r')
sage: assume(r > 0)
sage: u, v = var('u,v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([r*cos(u)*cos(v),r*sin(u)*cos(v),r*sin(v)],[u,v],'sphere')
sage: sphere.connection_coefficients()
{(1, 1, 1): 0,
(1, 1, 2): cos(v)*sin(v),
(1, 2, 1): -sin(v)/cos(v),
(1, 2, 2): 0,
(2, 1, 1): -sin(v)/cos(v),
(2, 1, 2): 0,
(2, 2, 1): 0,
(2, 2, 2): 0}
Evaluate the first fundamental form on two vectors expressed with
respect to the natural coordinate frame on the surface. In other words,
if the vectors are and
, calculate
, with
the coefficients of the first fundamental form.
INPUT:
- vector1, vector2 - vectors on the surface.
OUTPUT:
- First fundamental form evaluated on the input vectors.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: v1, v2, w1, w2 = var('v1, v2, w1, w2', domain='real')
sage: sphere = ParametrizedSurface3D((cos(u)*cos(v), sin(u)*cos(v), sin(v)), (u, v),'sphere')
sage: sphere.first_fundamental_form(vector([v1,v2]),vector([w1,w2]))
v1*w1*cos(v)^2 + v2*w2
sage: vv = vector([1,2])
sage: sphere.first_fundamental_form(vv,vv)
cos(v)^2 + 4
sage: sphere.first_fundamental_form([1,1],[2,1])
2*cos(v)^2 + 1
Compute a single component of the first fundamental form. If
the parametric representation of the surface is given by the vector
function
, where
,
are curvilinear
coordinates, then
.
INPUT:
- index - tuple (i, j) specifying the index of the component $g_{ij}$.
OUTPUT:
- Component $g_{ij}$ of the first fundamental form
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: eparaboloid = ParametrizedSurface3D((u, v, u^2+v^2), (u, v))
sage: eparaboloid.first_fundamental_form_coefficient((1,2))
4*u*v
When the index is invalid, an error is raised:
sage: u, v = var('u, v', domain='real')
sage: eparaboloid = ParametrizedSurface3D((u, v, u^2+v^2), (u, v))
sage: eparaboloid.first_fundamental_form_coefficient((1,5))
Traceback (most recent call last):
...
ValueError: Index (1, 5) out of bounds.
Returns the coefficients of the first fundamental form as a dictionary.
The keys are tuples , where
and
range over
,
while the values are the corresponding coefficients
.
OUTPUT:
- Dictionary of first fundamental form coefficients.
EXAMPLES:
sage: u, v = var('u,v', domain='real')
sage: sphere = ParametrizedSurface3D((cos(u)*cos(v), sin(u)*cos(v), sin(v)), (u, v), 'sphere')
sage: sphere.first_fundamental_form_coefficients()
{(1, 1): cos(v)^2, (1, 2): 0, (2, 1): 0, (2, 2): 1}
Returns a specific component of the inverse of the fundamental
form.
INPUT:
- index - tuple (i, j) specifying the index of the component $g^{ij}$.
OUTPUT:
- Component of the inverse of the fundamental form.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.first_fundamental_form_inverse_coefficient((1, 2))
0
sage: sphere.first_fundamental_form_inverse_coefficient((1, 1))
cos(v)^(-2)
Returns the coefficients of the inverse of the fundamental
form, as a dictionary. The inverse coefficients are defined by
with
the Kronecker
delta.
OUTPUT:
- Dictionary of the inverse coefficients.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.first_fundamental_form_inverse_coefficients()
{(1, 1): cos(v)^(-2), (1, 2): 0, (2, 1): 0, (2, 2): 1}
Returns the structure functions for a frame field
, i.e. a pair of vector fields on the surface which are
linearly independent at each point. The structure functions are
defined using the Lie bracket by
.
INPUT:
- e1, e2 - vector fields in intrinsic coordinates on the surface, expressed as pairs of functions, or as vectors of length 2.
OUTPUT:
- Dictionary of structure functions, where the key (i, j, k) refers to the structure function $c_{i,j}^k$.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: assume(cos(v) > 0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v), sin(u)*cos(v), sin(v)], [u, v], 'sphere')
sage: sphere.frame_structure_functions([u, v], [-v, u])
{(1, 1, 1): 0,
(1, 1, 2): 0,
(1, 2, 1): 0,
(1, 2, 2): 0,
(2, 1, 1): 0,
(2, 1, 2): 0,
(2, 2, 1): 0,
(2, 2, 2): 0}
We construct the structure functions of the orthonormal frame on the surface:
sage: EE_int = sphere.orthonormal_frame(coordinates='int')
sage: CC = sphere.frame_structure_functions(EE_int[1],EE_int[2]); CC
{(1, 1, 1): 0,
(1, 1, 2): 0,
(1, 2, 1): sin(v)/cos(v),
(1, 2, 2): 0,
(2, 1, 1): -sin(v)/cos(v),
(2, 1, 2): 0,
(2, 2, 1): 0,
(2, 2, 2): 0}
sage: sphere.lie_bracket(EE_int[1],EE_int[2]) - CC[(1,2,1)]*EE_int[1] - CC[(1,2,2)]*EE_int[2]
(0, 0)
Finds the gaussian curvature of the surface, given by
,
where
and
are the coefficients of the first
and second fundamental form, respectively.
OUTPUT:
- Gaussian curvature of the surface.
EXAMPLES:
sage: R = var('R')
sage: assume(R>0)
sage: u, v = var('u,v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere')
sage: sphere.gauss_curvature()
R^(-2)
Numerical integration of the geodesic equations. Explicitly, the
geodesic equations are given by
.
Solving these equations gives the coordinates of
the geodesic on the surface. The coordinates in space can
then be found by substituting
into the vector
representing the surface.
ALGORITHM:
The geodesic equations are integrated forward in time using the ode solvers from sage.gsl.ode. See the member function _create_geodesic_ode_system for more details.
INPUT:
- p0 - 2-tuple with coordinates of the initial point.
- v0 - 2-tuple with components of the initial tangent vector to the geodesic.
- tinterval - List [a, b, M], where (a,b) is the domain of the geodesic and M is the number of subdivision points used when returning the solution.
OUTPUT:
List of lists [t, [u1(t), u2(t)], [v1(t), v2(t)], [x1(t), x2(t), x3(t)]], where
- t is a subdivision point;
- [u1(t), u2(t)] are the intrinsic coordinates of the geodesic point;
- [v1(t), v2(t)] are the intrinsic coordinates of the tangent vector to the geodesic;
- [x1(t), x2(t), x3(t)] are the coordinates of the geodesic point in the three-dimensional space.
EXAMPLES:
sage: p, q = var('p,q', domain='real')
sage: assume(cos(q)>0)
sage: sphere = ParametrizedSurface3D([cos(q)*cos(p),sin(q)*cos(p),sin(p)],[p,q],'sphere')
sage: geodesic = sphere.geodesics_numerical([0.0,0.0],[1.0,1.0],[0,2*pi,5])
sage: times, points, tangent_vectors, ext_points = zip(*geodesic)
sage: round4 = lambda vec: [N(x, digits=4) for x in vec] # helper function to round to 4 digits
sage: round4(times)
[0.0000, 1.257, 2.513, 3.770, 5.027, 6.283]
sage: [round4(p) for p in points]
[[0.0000, 0.0000], [0.7644, 1.859], [-0.2876, 3.442], [-0.6137, 5.502], [0.5464, 6.937], [0.3714, 9.025]]
sage: [round4(p) for p in ext_points]
[[1.000, 0.0000, 0.0000], [-0.2049, 0.6921, 0.6921], [-0.9160, -0.2836, -0.2836], [0.5803, -0.5759, -0.5759], [0.6782, 0.5196, 0.5196], [-0.8582, 0.3629, 0.3629]]
Returns the Lie bracket of two vector fields that are tangent to the surface. The vector fields should be given in intrinsic coordinates, i.e. with respect to the natural frame.
INPUT:
- v and w - vector fields on the surface, expressed as pairs of functions or as vectors of length 2.
OUTPUT:
- The Lie bracket $[v, w]$.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.lie_bracket([u,v],[-v,u])
(0, 0)
sage: EE_int = sphere.orthonormal_frame(coordinates='int')
sage: sphere.lie_bracket(EE_int[1],EE_int[2])
(sin(v)/cos(v)^2, 0)
Finds the mean curvature of the surface, given by
,
where
and
are the components of the first and second
fundamental forms, respectively.
OUTPUT:
- Mean curvature of the surface
EXAMPLES:
sage: R = var('R')
sage: assume(R>0)
sage: u, v = var('u,v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere')
sage: sphere.mean_curvature()
-1/R
Returns the natural tangent frame on the parametrized surface. The vectors of this frame are tangent to the coordinate lines on the surface.
OUTPUT:
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: eparaboloid = ParametrizedSurface3D((u, v, u^2+v^2), (u, v), 'elliptic paraboloid')
sage: eparaboloid.natural_frame()
{1: (1, 0, 2*u), 2: (0, 1, 2*v)}
Returns the normal vector field of the parametrized surface.
INPUT:
- normalized - default False - specifies whether the normal vector should be normalized.
OUTPUT:
- Normal vector field.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: eparaboloid = ParametrizedSurface3D((u, v, u^2 + v^2), (u, v), 'elliptic paraboloid')
sage: eparaboloid.normal_vector(normalized=False)
(-2*u, -2*v, 1)
sage: eparaboloid.normal_vector(normalized=True)
(-2*u/sqrt(4*u^2 + 4*v^2 + 1), -2*v/sqrt(4*u^2 + 4*v^2 + 1), 1/sqrt(4*u^2 + 4*v^2 + 1))
Returns the orthonormal frame field on the surface, expressed either
in exterior coordinates (i.e. expressed as vector fields in the
ambient space , the default) or interior coordinates
(with respect to the natural frame)
INPUT:
- coordinates - either ext (default) or int.
OUTPUT:
- Orthogonal frame field as a dictionary.
ALGORITHM:
We normalize the first vector of the natural frame and then
get the second frame vector as
, where
is the unit normal to the surface.
EXAMPLES:
sage: u, v = var('u,v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v), sin(u)*cos(v), sin(v)], [u, v],'sphere')
sage: frame = sphere.orthonormal_frame(); frame
{1: (-sin(u), cos(u), 0), 2: (-cos(u)*sin(v), -sin(u)*sin(v), cos(v))}
sage: (frame[1]*frame[1]).simplify_full()
1
sage: (frame[1]*frame[2]).simplify_full()
0
sage: frame[1] == sphere.orthonormal_frame_vector(1)
True
We compute the orthonormal frame with respect to the natural frame on the surface:
sage: frame_int = sphere.orthonormal_frame(coordinates='int'); frame_int
{1: (1/cos(v), 0), 2: (0, 1)}
sage: sphere.first_fundamental_form(frame_int[1], frame_int[1])
1
sage: sphere.first_fundamental_form(frame_int[1], frame_int[2])
0
sage: sphere.first_fundamental_form(frame_int[2], frame_int[2])
1
Returns a specific basis vector field of the orthonormal frame field on the surface, expressed in exterior or interior coordinates. See orthogonal_frame() for more details.
INPUT:
- index - index of the basis vector;
- coordinates - either ext (default) or int.
OUTPUT:
- Orthonormal frame vector field.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: V1 = sphere.orthonormal_frame_vector(1); V1
(-sin(u), cos(u), 0)
sage: V2 = sphere.orthonormal_frame_vector(2); V2
(-cos(u)*sin(v), -sin(u)*sin(v), cos(v))
sage: (V1*V1).simplify_full()
1
sage: (V1*V2).simplify_full()
0
sage: n = sphere.normal_vector(normalized=True)
sage: (V1.cross_product(V2) - n).simplify_full()
(0, 0, 0)
Numerically solves the equations for parallel translation of a vector
along a curve on the surface. Explicitly, the equations for parallel
translation are given by
,
where
are the connection coefficients of the surface,
the vector to be transported has components
and the curve along
which to transport has components
.
ALGORITHM:
The parallel transport equations are integrated forward in time using the ode solvers from sage.gsl.ode. See _create_pt_ode_system() for more details.
INPUT:
- curve - 2-tuple of functions which determine the curve with respect to the local coordinate system;
- t - symbolic variable denoting the curve parameter;
- v0 - 2-tuple representing the initial vector;
- tinterval - list [a, b, N], where (a, b) is the domain of the curve and N is the number of subdivision points.
OUTPUT:
The list consisting of lists [t, [v1(t), v2(t)]], where
- t is a subdivision point;
- [v1(t), v2(t)] is the list of coordinates of the vector parallel translated along the curve.
EXAMPLES:
sage: p, q = var('p,q', domain='real')
sage: v = [p,q]
sage: assume(cos(q)>0)
sage: sphere = ParametrizedSurface3D([cos(q)*cos(p),sin(q)*cos(p),sin(p)],v,'sphere')
sage: s = var('s')
sage: vector_field = sphere.parallel_translation_numerical([s,s],s,[1.0,1.0],[0.0, pi/4, 5])
sage: times, components = zip(*vector_field)
sage: round4 = lambda vec: [N(x, digits=4) for x in vec] # helper function to round to 4 digits
sage: round4(times)
[0.0000, 0.1571, 0.3142, 0.4712, 0.6283, 0.7854]
sage: [round4(v) for v in components]
[[1.000, 1.000], [0.9876, 1.025], [0.9499, 1.102], [0.8853, 1.238], [0.7920, 1.448], [0.6687, 1.762]]
Enable easy plotting directly from the surface class.
The optional keywords urange and vrange specify the range for
the surface parameters and
. If either of these parameters
is None, the method checks whether a parameter range was
specified when the surface was created. If not, the default of
is used.
INPUT:
- urange - 2-tuple specifying the parameter range for
.
- vrange - 2-tuple specifying the parameter range for
.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: eq = (3*u + 3*u*v^2 - u^3, 3*v + 3*u^2*v - v^3, 3*(u^2-v^2))
sage: enneper = ParametrizedSurface3D(eq, (u, v), 'Enneper Surface')
sage: enneper.plot((-5, 5), (-5, 5))
Graphics3d Object
Returns a point on the surface given its intrinsic coordinates.
INPUT:
- coords - 2-tuple specifying the intrinsic coordinates (u, v) of the point.
OUTPUT:
- 3-vector specifying the coordinates in
of the point.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: torus = ParametrizedSurface3D(((2 + cos(u))*cos(v),(2 + cos(u))*sin(v), sin(u)),[u,v],'torus')
sage: torus.point((0, pi/2))
(0, 3, 0)
sage: torus.point((pi/2, pi))
(-2, 0, 1)
sage: torus.point((pi, pi/2))
(0, 1, 0)
Finds the principal curvatures and principal directions of the surface
OUTPUT:
For each principal curvature, returns a list of the form
, where
is the principal curvature,
is the corresponding principal direction, and
is
the multiplicity.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: R, r = var('R,r', domain='real')
sage: assume(R>r,r>0)
sage: torus = ParametrizedSurface3D([(R+r*cos(v))*cos(u),(R+r*cos(v))*sin(u),r*sin(v)],[u,v],'torus')
sage: torus.principal_directions()
[(-cos(v)/(r*cos(v) + R), [(1, 0)], 1), (-1/r, [(0, 1)], 1)]
Gives the matrix of the rotation operator over a given angle
with respect to the natural frame.
INPUT:
- theta - rotation angle
OUTPUT:
- Rotation matrix with respect to the natural frame.
ALGORITHM:
The operator of rotation over is
,
where
is the area form. The operator of rotation over an
angle
is
.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
We first compute the matrix of rotation over :
sage: rotation = sphere.rotation(pi/3); rotation
[ 1/2 -1/2*sqrt(3)/cos(v)]
[ 1/2*sqrt(3)*cos(v) 1/2]
We verify that three succesive rotations over yield minus the identity:
sage: rotation^3
[-1 0]
[ 0 -1]
Evaluates the second fundamental form on two vectors on the surface.
If the vectors are given by and
, the
result of this function is
.
INPUT:
- vector1, vector2 - 2-tuples representing the input vectors.
OUTPUT:
- Value of the second fundamental form evaluated on the given vectors.
EXAMPLES:
We evaluate the second fundamental form on two symbolic vectors:
sage: u, v = var('u, v', domain='real')
sage: v1, v2, w1, w2 = var('v1, v2, w1, w2', domain='real')
sage: assume(cos(v) > 0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.second_fundamental_form(vector([v1, v2]), vector([w1, w2]))
-v1*w1*cos(v)^2 - v2*w2
We evaluate the second fundamental form on vectors with numerical components:
sage: vect = vector([1,2])
sage: sphere.second_fundamental_form(vect, vect)
-cos(v)^2 - 4
sage: sphere.second_fundamental_form([1,1], [2,1])
-2*cos(v)^2 - 1
Returns the coefficient of the second fundamental form
corresponding to the index
. If the equation of the surface
is
, then
,
where
is the unit normal.
INPUT:
- index - a 2-tuple (i, j)
OUTPUT:
- Component $h_{ij}$ of the second fundamental form.
EXAMPLES:
sage: u, v = var('u,v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.second_fundamental_form_coefficient((1, 1))
-cos(v)^2
sage: sphere.second_fundamental_form_coefficient((2, 1))
0
Returns the coefficients of the second fundamental form as
a dictionary, where the keys are the indices
and the values
are the corresponding components
.
When only one component is needed, consider instead the function second_fundamental_form_coefficient().
OUTPUT:
Dictionary of second fundamental form coefficients.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.second_fundamental_form_coefficients()
{(1, 1): -cos(v)^2, (1, 2): 0, (2, 1): 0, (2, 2): -1}
Returns the second-order frame of the surface, i.e. computes the
second-order derivatives (with respect to the parameters on the
surface) of the parametric expression
of the surface.
OUTPUT:
- Dictionary where the keys are 2-tuples (i, j) and the values are the corresponding derivatives $r_{ij}$.
EXAMPLES:
We compute the second-order natural frame of the sphere:
sage: u, v = var('u, v', domain='real')
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.second_order_natural_frame()
{(1, 1): (-cos(u)*cos(v), -cos(v)*sin(u), 0),
(1, 2): (sin(u)*sin(v), -cos(u)*sin(v), 0),
(2, 1): (sin(u)*sin(v), -cos(u)*sin(v), 0),
(2, 2): (-cos(u)*cos(v), -cos(v)*sin(u), -sin(v))}
Returns a vector in the second-order frame of the surface, i.e.
computes the second-order derivatives of the parametric expression
of the surface with respect to the parameters listed in the
argument.
INPUT:
- index - a 2-tuple (i, j) specifying the element of the second-order frame.
OUTPUT:
- The second-order derivative $r_{ij}$.
EXAMPLES:
sage: u, v = var('u, v', domain='real')
sage: sphere = ParametrizedSurface3D([cos(u)*cos(v),sin(u)*cos(v),sin(v)],[u,v],'sphere')
sage: sphere.second_order_natural_frame_element((1, 2))
(sin(u)*sin(v), -cos(u)*sin(v), 0)
Returns the shape operator of the surface as a matrix. The shape operator is defined as the derivative of the Gauss map, and is computed here in terms of the first and second fundamental form by means of the Weingarten equations.
OUTPUT:
- Matrix of the shape operator
EXAMPLES:
sage: R = var('R')
sage: assume(R>0)
sage: u, v = var('u,v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere')
sage: S = sphere.shape_operator(); S
[-1/R 0]
[ 0 -1/R]
The eigenvalues of the shape operator are the principal curvatures of the surface:
sage: u, v = var('u,v', domain='real')
sage: paraboloid = ParametrizedSurface3D([u, v, u^2+v^2], [u, v], 'paraboloid')
sage: S = paraboloid.shape_operator(); S
[2*(4*v^2 + 1)/(4*u^2 + 4*v^2 + 1)^(3/2) -8*u*v/(4*u^2 + 4*v^2 + 1)^(3/2)]
[ -8*u*v/(4*u^2 + 4*v^2 + 1)^(3/2) 2*(4*u^2 + 1)/(4*u^2 + 4*v^2 + 1)^(3/2)]
sage: S.eigenvalues()
[2*sqrt(4*u^2 + 4*v^2 + 1)/(16*u^4 + 16*v^4 + 8*(4*u^2 + 1)*v^2 + 8*u^2 + 1), 2/sqrt(4*u^2 + 4*v^2 + 1)]
Returns the components of the shape operator of the surface as a dictionary. See shape_operator for more information.
OUTPUT:
- Dictionary where the keys are two-tuples (i, j), with values the corresponding component of the shape operator.
EXAMPLES:
sage: R = var('R')
sage: u, v = var('u,v', domain='real')
sage: assume(cos(v)>0)
sage: sphere = ParametrizedSurface3D([R*cos(u)*cos(v),R*sin(u)*cos(v),R*sin(v)],[u,v],'sphere')
sage: sphere.shape_operator_coefficients()
{(1, 1): -1/R, (1, 2): 0, (2, 1): 0, (2, 2): -1/R}
Returns the components of a tangent vector given the intrinsic coordinates of the base point and the components of the vector in the intrinsic frame.
INPUT:
- coords - 2-tuple specifying the intrinsic coordinates (u, v) of the point.
- components - 2-tuple specifying the components of the tangent vector in the intrinsic coordinate frame.
OUTPUT:
- 3-vector specifying the components in
of the vector.
EXAMPLES:
We compute two tangent vectors to Enneper’s surface along the coordinate lines and check that their cross product gives the normal vector:
sage: u, v = var('u,v', domain='real')
sage: eq = (3*u + 3*u*v^2 - u^3, 3*v + 3*u^2*v - v^3, 3*(u^2-v^2))
sage: e = ParametrizedSurface3D(eq, (u, v),'Enneper Surface')
sage: w1 = e.tangent_vector((1, 2), (1, 0)); w1
(12, 12, 6)
sage: w2 = e.tangent_vector((1, 2), (0, 1)); w2
(12, -6, -12)
sage: w1.cross_product(w2)
(-108, 216, -216)
sage: n = e.normal_vector().subs({u: 1, v: 2}); n
(-108, 216, -216)
sage: n == w1.cross_product(w2)
True