# Base Surfaces¶

All surface objects use, or are derived from, the **Surface3DCollection** class. This class object
is generally constructed as:

```
import s3dlib.surface as s3d
surface = s3d.Surface3DCollection(vertexCoor,faceIndices)
```

where *vertexCoor* is an array-like set of N number of 3D Cartesian coordinates and *faceIndices* is
a list of vertex index lists for each surface polygon face.
The length of each vertex index list may range from 3 to 6 indices corresponding to the type of polygon, e.g., triangle, quadrilateral,
pentagon and hexagon. When the *faceIndices* list is composed of different types of polygons, the
surface polygon faces are subdivided into triangular faces. For example, Base Class Surface 2.

To simplify surface construction, several classes are derived from this super class. These derived classes provide predefined vertex and indices for geometries which can then be functionally transformed to more complex geometries. In addition, each derived classes use a specific ‘native’ coordinate for functional operations. Depending on the class, the native coordinates are either Cartesian, polar, circumferential or spherical. See the Coordinates and Functions tutorial for the coordinate definitions.

The structure for the derived surface classes is developed from sets of base surface geometries. These geometries are composed of a network of connected triangles or squares. All grid surfaces are normalized and centered in a cube in the domain of -1 to 1.

With the exception of the ‘circumferential’ and ‘grid’ base classes identified in the following sections, all
constructors have two arguments controlling the network structure: *basetype* and *rez*.
The *basetype* sets the structure among the faces.
The *rez* argument sets the number of faces for the geometry.
The *basetype* argument is a string, the label for one of the class’ basetypes.
The basetype geometries for each derived class are described in the following
sections of this guide.

The surfaces are generated by recursively subdividing the base surface faces into
four smaller faces controlled by the *rez* argument.
As a result, the number of face surfaces for a surface object is 4^{rez}
times the number of faces of the basetype. This argument is an
integer ranging from 0, no subdivisions, to 8. The default value for *rez* is 0.

Since all class objects are derived from the super class, objects may be combined using simple addition, as:

```
surface = surface_A + surface_B
```

to form a single compound objects. For example, Surface Addition. All compound objects use Cartesian coordinates, regardless of the individual object native coordinates. Also, the added surface objects must have the same type of faces, triangular or quadrilateral, for addition.

## General Geometries¶

Each surface class has several basetypes which can be used to construct the surface object.
In this section, all surface object figures were generated with a default *rez* of 0 using:

```
surface = s3d.xxxxxSurface(rez,basetype)
```

where *xxxxxSurface* refers to PlanarSurface,
PolarSurface, CylindricalSurface, or SphericalSurface class names.
For any surface class, any basetype will produce similar geometries.
However, a specific type may have axial or planar symmetry which may be applicable
to a specific function used for mapping.
Each of these class have a ‘native’ coordinate system such that use of any mapping
function for these class can be scripted in the ‘native’ coordinates.

### 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 |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 | Planar | ||

default basetype | quad |
||

vertex domain | -1 ≤ x ≤ 1 | -1 ≤ y ≤ 1 | z = 0 |

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 symmetry 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 | Polar | ||

default basetype | hex |
||

vertex domain | 0 ≤ r ≤ 1 | 0 ≤ θ < 2π | z = 0 |

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 symmetry 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 | Cylindrical | ||

default basetype | tri |
||

vertex domain | r = 1 | 0 ≤ θ < 2π | -1 ≤ z ≤ 1 |

basetype | faces | edges | vertices |
---|---|---|---|

tri | 12 | 21 | 9 |

squ | 16 | 28 | 12 |

tri2 | 12 | 21 | 9 |

squ2 | 16 | 28 | 12 |

Cylindrical surfaces enclosing a volume are as follows:

basetype | faces | edges | vertices |
---|---|---|---|

tri_v | 18 | 27 | 11 |

squ_v | 24 | 36 | 14 |

tri2_v | 18 | 27 | 11 |

squ2_v | 24 | 36 | 14 |

### 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 | Spherical | ||

default basetype | icosa |
||

vertex domain | r = 1 | 0 ≤ θ < 2π | 0 ≤ φ ≤ π |

basetype | faces | edges | vertices |
---|---|---|---|

tetra | 4 | 6 | 4 |

octa | 8 | 12 | 6 |

icosa | 20 | 30 | 12 |

cube | 24 | 36 | 14 |

dodeca | 60 | 90 | 32 |

## Platonic Geometries¶

The five platonic solid surfaces are constructed from the SphericalSurface class using
the *platonic* SphericalSurface class method:

```
surface = s3d.SphericalSurface.platonic(rez,basetype)
```

where *rez* and basetype are identical to the SphericalSurface constructor parameters given above.
As the *rez* is increased from 0, unlike the previous spherical surfaces, the faces
do not extend to the spherical configuration, but retain the original flat face plane.
In the following example figure, all surfaces were constructed using a *rez* of 2.

basetype | faces | edges | vertices |
---|---|---|---|

tetra | 4 | 6 | 4 |

octa | 8 | 12 | 6 |

icosa | 20 | 30 | 12 |

cube | 6 | 12 | 8 |

dodeca | 12 | 30 | 20 |

cube_a | 6 | 12 | 8 |

For the cubes and dodecahedron, a rez of 0 (default), will form faces with 4 and 5 edges per face,
respectively. For *rez* set greater than 0, the faces for these surfaces will be triangulated
upon further subdivisions. All these geometries are a spherical coordinate system.

## Split Geometries¶

For the general surfaces with radial coordinates, the coordinates are cyclic with θ = 0 and θ = 2π being the same coordinate vertex position. For polar and spherical surfaces, there is no unique coordinate mapping for (r,θ) at the origin, i.e. (0,θ) is the same point, regardless of θ.

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 θ equal to 0 and 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 θ at the origin.

_c- The minimum annular position of vertices can be specified in the constructor with theminradargument.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 = s3d.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 θ, functional mapping of the geometry is not restricted to extending the upper bound of θ beyond 2π. This type of mapping has been used in numerous Surface Plots 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 Möbius strip and a Klein bottle. ( See Cylindrical Coordinates and Klein Bottle, Spherical to XYZ )

### Polar Surface¶

Usage of these basetypes are demonstrated in the examples Sliced Polar Surface (hex_s) and Polar Coordinates to XYZ 2 (hex_c)

coordinate system | Polar | ||

squ_s, hex_s | 0 ≲ r ≤ 1 | 0 ≤ θ ≤ 2π | z = 0 |

squ_c, hex_c | minrad ≤ r ≤ 1 | 0 ≤ θ ≤ 2π | z = 0 |

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 Order of Operation (tri_s) and Surface Texture (squ_s)

coordinate system | Cylindrical | ||

tri_s, squ_s | r = 1 | 0 ≤ θ ≤ 2π | -1 ≤ z ≤ 1 |

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 Spherical Coordinates to XYZ (octa_c) and Klein Bottle, Spherical to XYZ (octa_s)

coordinate system | Spherical | ||

octa_s, cube_s | r = 1 | 0 ≤ θ ≤ 2π | 0 ≲ φ ≲ π |

octa_c, cube_c | r = 1 | 0 ≤ θ ≤ 2π | φ^{min} ≤ φ ≤ φ^{max} |

The *minrad* argument offsets the range of φ by ±sin^{-1}(minrad) for the *octa_c* and *cube_c* basetypes.

basetype | faces | edges | vertices |
---|---|---|---|

octa_s | 14 | 26 | 13 |

cube_s | 48 | 80 | 33 |

octa_c | 16 | 29 | 14 |

cube_c | 12 | 22 | 11 |

## Circumferential Geometries¶

Circumferential geometries are those with a quadrilateral grid of vertices.
Unlike the previous geometries which use *rez* to set the number of faces, these
geometries are defined by the number of subdivisions along two surface coordinates.
The surface geometry is generated using the *grid* class method:

```
surface = s3d.xxxxxSurface.grid(argA,argB,basetype)
```

where *argA* and *argB* are the number of subdivisions of the surface coordinates,
which are tabulated below.

Class | argA divisions | argB divisions |
---|---|---|

PolarSurface | radial, r | azimuthal, θ |

CylindricalSurface | vertical, z | azimuthal, θ |

SphericalSurface | polar, φ | azimuthal, θ |

Triangular faces are constructed from quadrilateral subdivisions which are further subdivided
into triangles. The *basetype* is a string, ‘d’ for triangular faces. The default
value of ‘d’ extends the triangular faces over the entire surface domain.
Additional values for the *basetype* are described in the following sections for split
and quadrilateral face geometries.

In the following example figure, all surfaces were constructed using 8 and 16 as the two method argument values.

### Quadrilateral Face Geometry¶

All previously defined base geometries have triangular faces. The following describes geometries which have quadrilateral, four-sided faces.

For polar, cylindrical and spherical base geometries, the *grid* class method using
a *basetype* argument of ‘r’ or ‘x’ produces quadrilateral surface faces. The value
of ‘x’ produces the split geometry for these base surfaces. The parameter *minrad*
is used for both these basetypes since quadrilateral faces are not joined at the poles.

Examples for these basetypes is shown below:

### Base Types¶

The polar, cylindrical and spherical classmethod *grid* has six basetypes controlling
the grid geometry. These six are exemplified in the following figure using the SphericalSurface
grid method.

The ‘s’, ‘w’, and ‘x’ basetypes are all split geometries shown in the bottom row. The ‘r’ and ‘x’
basetypes have quadrilateral faces, shown in the right column. The ‘q’ and ‘w’ use the same
vertices as the ‘r’ and ‘x’ basetypes but have triangular faces. These last four basetypes
use the *minrad* grid method argument to the set minimum radius from the z-axis. The default
value for minrad is 0.01. The minimum radius and split size have been exaggerated in this
figure to clarify the distinction among the different basetypes.

The CylindricalSurface grid method also has six additional basetypes for cylindrical volume surfaces with top and bottom surfaces. The basetype specification string uses the previous six strings with the ‘v’ character added to the end of the string. The ‘dv’ and ‘rv’ surfaces are shown in the previous two figures in this section.

## Planar Grid Geometries¶

For the PlanarSurface class, rectangular faced surfaces can be created either by :

- creating a PlanarSurface object using a basetype of ‘squ’, which uses
*rez*to set the number of faces, or - using the
*grid*class method to set the x and y divisions.

In addition, the CubicSurface class is used to create a basic cubic geometry composed of square faces. The native coordinate system for the CubicSurface class is the xyz coordinates.

Examples of these surfaces are shown below.

Note: the distinction between the CubicSurface object and the
platonic spherical surface object with a basetype of *cube_a* is
the triangulated faces and the different native coordinate system
used for the class.

## Rand Geometries¶

Irregular grid geometries are those with uniform random positions of vertex coordinates
on the surface, resulting in triangular faces. The surface geometry is generated using
the *rand* static method:

```
surface = s3d.xxxxxSurface.rand(rez,seed)
```

where *rez* is the same as used for the previously defined surface constructors. The *seed*
is used to initialize the random generator. The resulting surface is the type of the calling
surface class. The following figures shows the examples for the four classes.