.. _base_surfaces:
.. role:: raw-html(raw)
:format: html
***************
Base Surfaces
***************
The grid structure for the four surface classes are developed from sets of base surface
geometries. These base surfaces are composed of a grid of connected triangles.
All grid surfaces are normalized and centered in a cube in the domain of -1 to 1.
The constructors of a xxxxxSurface class have two arguments controlling
the grid; *rez* and *basetype*. ( xxxxxSurface represents either PlanarSurface,
PolarSurface, CylindricalSurface, or SphericalSurface class names). A *surface*
object is constructed as::
surface = xxxxxSurface(rez,basetype)
The surfaces are generated by recursively subdividing the base surfaces triangles into
four smaller triangles controlled by the *rez* argument.
As a result, the number of triangular surfaces for a surface object is :raw-html:`4rez`
times the number of faces of the basetype. This argument is an
integer ranging from 0, no subdivisions, to 7 with a default value of 0. The *basetype*
argument is a string, the label for one of the class's basetypes. The basetypes
and corresponding default values
for each class are described in the following sections of this tutorial.
The number of faces, edges and vertices for a xxxxxSurface can be determined from
the class method::
values = xxxxxSurface.fev(rez,basetype)
which returns a 3D array of integers corresponding to these *values* for
a xxxxxSurface of *rez* and *basetype*. If no arguments are given, defaults are used.
In addition, the *surface* object string representation, *str(surface)*, contains the
class name, rez, basetype, number of faces and number of vertices.
General Geometries
=========================================================================================
Each surface class has several basetypes which can be used to construct the surface object.
In this section, all surface objects were generated with a default *rez* of 0 using::
surface = xxxxxSurface(basetype)
For any surface class, any basetype will produce similar geometries.
However, a specific type may have axial or planar symetries which may be applicable
to a specific function used for mapping.
These symetries can also be adjusted using the object *transform* method before functional mapping.
Selecting a specific basetype can also be particulary beneficial when several overlapping surfaces
are combined to form a final surface geometry, or when surface clipping is applied.
Planar Surface
-----------------------------------------------------------------------------------------
The default basetype for PlanarSurfaces is *quad*. Both the *oct1* and *oct2* will have
vertices along the x and y axis. At the origin, *oct2* has eight neighboring faces, whereas *oct1* has four.
The *quad* will have vertices along :raw-html:`|x|=|y|`, but have faces that will cross the axis.
With increasing values of *rez*, planar surfaces are subdivided into smaller triangles and maintain
the square plate shape.
======================================== ======================================== ======================================= ==================================
======================================== ======================================== ======================================= ==================================
coordinate system :ref:`planar_coor_tut`
default basetype **quad**
vertex domain :raw-html:`-1 ≤ x ≤ 1` :raw-html:`-1 ≤ y ≤ 1` :raw-html:`z = 0`
======================================== ======================================== ======================================= ==================================
.. image:: images/base_planar.png
:class: sphx-glr-single-img
============= ============= ============= =============
basetype faces edges vertices
============= ============= ============= =============
quad 4 8 5
oct1 8 16 9
oct2 8 16 9
============= ============= ============= =============
Polar Surface
-----------------------------------------------------------------------------------------
The default basetype for PolarSurfaces is *hex*. The two basetypes of *squ* and *hex* have 4 and 6 fold symetry about the z-axis, respectively.
With increasing *rez*, triangles are subdivided to expand the grid to approximate a circular disk of unit radius.
======================================== ======================================== ======================================= ==================================
======================================== ======================================== ======================================= ==================================
coordinate system :ref:`polar_coor_tut`
default basetype **hex**
vertex domain :raw-html:`0 ≤ r ≤ 1` :raw-html:`0 ≤ θ < 2π` :raw-html:`z = 0`
======================================== ======================================== ======================================= ==================================
.. image:: images/base_polar.png
:class: sphx-glr-single-img
============= ============= ============= =============
basetype faces edges vertices
============= ============= ============= =============
squ 4 8 5
hex 6 12 7
============= ============= ============= =============
Cylindrical Surface
-----------------------------------------------------------------------------------------
The default basetype for CylindricalSurfaces is *tri*. These base surfaces have 3 and 4 fold symetry about the z-axis.
Although the *tri2* and *squ2* basetypes have elongated triangular faces in the vertical direction, this basetype has vertices at the x and y axis
without faces crossing these axis.
With increasing *rez*, triangles are subdivided to expand the grid to approximate a circular cylinder of unit radius and length 2.
======================================== ======================================== ======================================= ==================================
======================================== ======================================== ======================================= ==================================
coordinate system :ref:`cylindrical_coor_tut`
default basetype **tri**
vertex domain :raw-html:`r = 1` :raw-html:`0 ≤ θ < 2π` :raw-html:`-1 ≤ z ≤ 1`
======================================== ======================================== ======================================= ==================================
.. image:: images/base_cylindrical.png
:class: sphx-glr-single-img
============= ============= ============= =============
basetype faces edges vertices
============= ============= ============= =============
tri 12 21 9
squ 16 28 12
tri2 12 21 9
squ2 16 28 12
============= ============= ============= =============
Spherical Surface
-----------------------------------------------------------------------------------------
The default basetype for SphericalSurfaces is *icosa*. All basetypes are based on the five Platonic solids.
The *cube* basetype is a cube with the cubic faces subdivided into 4 triangles. The
*dodeca* basetype is a dodecahedron with the pentagon faces subdivided into 5 triangles.
With increasing *rez*, triangles are subdivided to expand the grid to approximate a sphere of unit radius.
======================================== ======================================== ======================================= ==================================
======================================== ======================================== ======================================= ==================================
coordinate system :ref:`spherical_coor_tut`
default basetype **icosa**
vertex domain :raw-html:`r = 1` :raw-html:`0 ≤ θ < 2π` :raw-html:`0 ≤ φ ≤ π`
======================================== ======================================== ======================================= ==================================
.. image:: images/base_spherical.png
:class: sphx-glr-single-img
============= ============= ============= =============
basetype faces edges vertices
============= ============= ============= =============
tetra 4 6 4
octa 8 12 6
icosa 20 30 12
cube 24 36 14
dodeca 60 90 32
============= ============= ============= =============
Split Geometries
=========================================================================================
For the general surfaces with radial coordinates, the coordinates are cyclic with
:raw-html:`θ` = 0 and :raw-html:`θ = 2π` being the same coordinate vertex position.
For polar and spherical surfaces, there is no unique coordinate mapping for :raw-html:`(r,θ)` at
the origin, i.e. :raw-html:`(0,θ)` is the same point, regardless of :raw-html:`θ`.
The 'split' geometries described in this section provide grids which overcome these restrictions.
These geometries are defined so that two distinct vertices are located
at :raw-html:`θ` equal to 0 and :raw-html:`2π`.
The triangular faces at these vertices are not connected, hence the name 'split geometries'.
For the polar and spherical basetypes, there are two types of basetype split geometries.
Based on the general surface basetype names, the basetypes are labeled using a suffix, *_s* and *_c*
to identify the two types:
* **_s** - Multiple vertices, not a single point, 'near' the origin are used to construct the base surface.
These basetypes are useful when mapping is dependent on :raw-html:`θ` at the origin.
* **_c** - The minimum annular position of vertices can be specified in the constructor with the *minrad* argument.
These basetypes are particularly useful when mapping functions have a singularity at the origin.
This restricts function evaluation of coordinates at minimum distance from the origin.
The *minrad* is a named parameter in the surface object constructor as::
surface = xxxxxSurface(rez,basetype,minrad=mr)
The *minrad* argument default is 0.01 and should be reasonably set no larger than 0.75.
.. note::
Since these base surfaces are not cyclic in :raw-html:`θ`, functional mapping of the geometry is not restricted
to extending the upper bound of :raw-html:`θ` beyond :raw-html:`2π`. This type of mapping has been used
in numerous :ref:`functional-maps` examples.
In the following figures for these surfaces, slight mapping of the surface was used to accentuate the split in the surface geometry.
A *rez* = 3 was used to further enhance the geometries for these surfaces.
These split geometries are very useful when describing non-orientable surfaces. Numerous examples
are shown for such surfaces, including a :raw-html:`Möbius` strip and a Klein bottle.
( See :ref:`twistribbon` and :ref:`klein_bottle` )
Polar Surface
-----------------------------------------------------------------------------------------
Usage of these basetypes are demonstrated in the examples :ref:`screw` (hex_s) and :ref:`bour` (hex_c)
======================================== ======================================== ======================================= =========================================
======================================== ======================================== ======================================= =========================================
coordinate system :ref:`polar_coor_tut`
squ_s, hex_s :raw-html:`0 ≲ r ≤ 1` :raw-html:`0 ≤ θ ≤ 2π` :raw-html:`z = 0`
squ_c, hex_c :raw-html:`minrad ≤ r ≤ 1` :raw-html:`0 ≤ θ ≤ 2π` :raw-html:`z = 0`
======================================== ======================================== ======================================= =========================================
.. image:: images/base_polar_s.png
:class: sphx-glr-single-img
============= ============= ============= =============
basetype faces edges vertices
============= ============= ============= =============
squ_s 7 15 9
hex_s 11 23 13
squ_c 16 29 14
hex_c 12 22 11
============= ============= ============= =============
Cylindrical Surface
-----------------------------------------------------------------------------------------
Usage of these basetypes are demonstrated in the examples :ref:`order_operation` (tri_s) and :ref:`orange_peel` (squ_s)
======================================== ======================================== ======================================= =========================================
======================================== ======================================== ======================================= =========================================
coordinate system :ref:`cylindrical_coor_tut`
tri_s, squ_s :raw-html:`r = 1` :raw-html:`0 ≤ θ ≤ 2π` :raw-html:`-1 ≤ z ≤ 1`
======================================== ======================================== ======================================= =========================================
.. image:: images/base_cylindrical_s.png
:class: sphx-glr-single-img
============= ============= ============= =============
basetype faces edges vertices
============= ============= ============= =============
tri_s 12 22 11
squ_s 16 29 14
============= ============= ============= =============
Spherical Surface
-----------------------------------------------------------------------------------------
Usage of these basetypes are demonstrated in the examples :ref:`roman` (octa_c) and :ref:`klein_bottle` (octa_s)
======================================== ======================================== ======================================= =========================================
======================================== ======================================== ======================================= =========================================
coordinate system :ref:`spherical_coor_tut`
octa_s, cube_s :raw-html:`r = 1` :raw-html:`0 ≤ θ ≤ 2π` :raw-html:`0 ≲ φ ≲ π`
octa_c, cube_c :raw-html:`r = 1` :raw-html:`0 ≤ θ ≤ 2π` :raw-html:`φmin ≤ φ ≤ φmax`
======================================== ======================================== ======================================= =========================================
The *minrad* argument offsets the range of :raw-html:`φ by ±sin-1(minrad)` for the *octa_c* and *cube_c* basetypes.
.. image:: images/base_spherical_s.png
:class: sphx-glr-single-img
============= ============= ============= =============
basetype faces edges vertices
============= ============= ============= =============
octa_s 14 26 13
cube_s 48 80 33
octa_c 16 29 14
cube_c 12 22 11
============= ============= ============= =============
.. _base_selection:
Selecting a Base
=========================================================================================
With the variety of native coordinates and surfaces, selecting the optimal base surface
may not be obvious. Intuitively, if the surface 'looks' like a squashed sphere,
a SphericalSurface object would probably be the best choice. However, for complex functional
relationships, optimal selection will depend on:
#. The native coordinate system
* functional description
* functional domain
* surface symetry
* degree of local surface curvature
#. Optimal uniformity in
* triangular face areas and shapes
* vertex distribution
The surface subclass bases have been formulated so that the surface faces are of uniform shape and
size. As a result, using a subclass object that transforms to preserve the overall 'shape'
is often the best starting object. For example, a surface with axial symetry about the z-axis
is best represented using a surface object with and axial coordinate, rather than a PlanarSurface object.
Also, the functional
description is easier to apply and to interpret if it is described in the native coordinates.
Instead of interpreting the subclass objects as surface geometries, it can be advantageous to consider
the objects in terms of a graph of interconnected vertices and edges. The set of vertices are defined
within the domain of two dependent variables points. For the subclass objects:
======================= ================================
Graph (Class) Dependent Variable
======================= ================================
PlanarSurface ( x,y )
PolarSurface ( r, :raw-html:`θ` )
CylindricalSurface ( :raw-html:`θ`, z )
SphericalSurface ( :raw-html:`θ , φ` )
======================= ================================
With appropriate mapping, each of these 'graphs' can be transformed into a similar surface.
Consider the simple example of a sphere. A usual method of developing a grid to construct the surface is to
uniformly subdivide the angular and azimuthal coordinates. Alternatively using S3Dlib, the four different 'graphs' can
be used to visualize the sphere, as shown below. The number in each plot title represents the number of vertices.
.. image:: images/sphere_plane_1.png
:class: sphx-glr-single-img
Using a SphericalSurface object, vertices are distributed so that
the triangular faces are relatively uniform by design, without a concentration of elongated faces near the poles.
For the other three objects, faces are not uniform and face anomalies may also occur at the poles since multiple vertices
are formed at these two locations.
The vertex distribution of these four surfaces is
.. image:: images/sphere_plane_2.png
:class: sphx-glr-single-img
For complex functional mapping involving parametric equations, a uniform vertex distribution may be
preferable. The above two figures were constructed from the script:
.. literalinclude:: source/gu_sphere_plane.py
:language: python
:emphasize-lines: 37,41,45
Notice in the above functions *plane2sphere* and cylinder2sphere*, the T variable is set negative. This is
to have a consistent outward normal to the faces using a right-hand rule definition.
.. _planarKlein:
Planar Klein Bottle
-----------------------------------------------------------------------------------------
A major advantage of using S3Dlib is that surface geometries are set in one expression.
Therefore, during code development, effects of geometry can be easily evaluated and alternatives
can be made. In addition,
each subclass has the *coor_convert* method to transform among planar, polar, cylindrical
and spherical coordinates.
This provides flexibility to evaluate the visualization for different grids. For example,
the :ref:`klein_bottle` example uses a SphericalSurface object. It can just as easily
be constructed uing a PlanarSurface object with the function slightly modified as:
.. literalinclude:: source/gu_klein_planar.py
:language: python
:lines: 10-28
:emphasize-lines: 3-4
Where now, the surface is simply defined as:
.. literalinclude:: source/gu_klein_planar.py
:language: python
:lines: 35,36
Resulting in a similar visualization as:
.. image:: images/klein_planar.png
:class: sphx-glr-single-img
This visualization is 'smoother' than the example due to the uniform distribution of vertices in the parametric
dependent variables. This use of the planar and cylindrical base and split surfaces is often useful for parametric functions
for this reason, even though the functions may be expressed in other native coordinates.