.. _line_filled_surface:
.. role:: raw-html(raw)
:format: html
******************************************
Line Filled Surfaces
******************************************
The ColorLine3DCollection lines may be used to construct a variety of surface objects by utilizing the
line as bounding edges of a surface. The methods below describe the various methods of setting
the geometry and coloring of the surface. Any surface constructed using the methods may be further
operated on using the Surface3DCollection methods.
Line Projections to a Cartesian Axis Plane
=========================================================================================
Any ColorLine3DCollection object may be projected to a
Cartesian planar surface, cylindrical surface or spherical surface to create a *surface* object using the *line* object method::
surface = line.get_filled_surface(**kwargs)
where the keyword arguments are:
========== ========================== ================================= ====================
key assignment values control default
========== ========================== ================================= ====================
dist number projection surface from origin 0.0
direction 3 element list or tuple projection surface orientation dependent on coor
coor integer or string projection surface type 0
lrez integer >= 0 projection subdivisions 0
color Matplotlib format color surface color line color
alpha 0 <= number <= 1.0 surface opacity 1.0
name string identifier None
========== ========================== ================================= ====================
The *coor* argument is an integer
or string that specifies the surface to which the line is projected, as indicated
in the table below:
======================== ========================================= ==================== ====================
Projection Surface coor value direction (default) projection To
======================== ========================================= ==================== ====================
planar (default) 0, ‘p’, ‘P’, ‘planar’,’xyz’ [ 0, 0, 1 ] plane
cylindrical 1, ‘c’, ‘C’, ‘cylinder’, ‘cylindrical’ [ 0, 0, 1 ] vertical cylinder
spherical 2, ‘s’, ‘S’, ‘sphere’, ‘spherical’ not used sphere at origin
y-z plane 3, ‘x’, ‘X’ [ 1, 0, 0 ] constant x plane
x-z plane 4, ‘y’, ‘Y’ [ 0, 1, 0 ] constant y plane
x-y plane 5, ‘z’, ‘Z’ [ 0, 0, 1 ] constant z plane
======================== ========================================= ==================== ====================
The *dist* argument is the distance from the origin to the plane in the direction of the plane normal.
The default vaule is 0.0, or at the origin.
For cylindrical and spherical projections, the *dist* is the radius of the projection surfaces.
The *direction* argument is the planar surface normal, whereas for cylindrical surface projections,
the *direction* is the axial direction of the cylindrical surface.
Unlike clipping, the surface which the line is being projected to does not need to contain
the line. See for example :ref:`filled_octa_edges`.
The following shows various projected line surface constructed from a simple 3D line
normal to the x, y and z planes.
.. image:: images/filled_surface_0.png
:class: sphx-glr-single-img
For 'c' or 's', the *dist* is the radial distance of the surface from the origin.
The following shows a line projection for planar, cylindrical
and spherical projections using the indicated values for *direction* and *dist*.
.. image:: images/filled_sph_cyl.png
:class: sphx-glr-single-img
Surface faces are 2D trapezoids with parallel sides along the projection direction.
The surface face lengths are set by the distance from the segment vertices to the projection plane.
Hence, the segment lengths of the line set the face widths. Note that for ParametricLine objects,
the *rez* argument in the constructor sets the segment sizes. For the above examples,
a *rez* of 3 was used for the ParametricLine object.
Surface face normals are dependent on the segment order and projection direction to the
plane. The surface method *evert* can be used to change the resulting surface normals
without requiring changes to the projection line.
Line projections are demonstrated in the :ref:`para_line_surface_2` example.
Surface Color from Line Color
-----------------------------------------------------------------------------------------
By default, face color of surfaces takes the color of the projected line. This is shown
in the following example where the line is color mapped using the default colormap
along the X or Z direction.
.. image:: images/filled_surface_1.png
:class: sphx-glr-single-img
The line segment color will be used for the color of the adjacent trapezoid surface face. This includes
the line color resulting from using the *shade* and *fade* line color methods.
In this example, the lines are projected along the z direction and as a result the surface is
uniformly colored along the z direction.
Surface Color Mapping
-----------------------------------------------------------------------------------------
Once a surface is constructed from projecting a line, any of the surface color mapping
methods may be applied. For the following example, the surface is color mapped using the default colormap
along the X or Z direction.
.. image:: images/filled_surface_2.png
:class: sphx-glr-single-img
For the line colors,
color mapping uses the relative position of the segment centers. For surface colors,
color mapping uses the relative position of the face centers.
These surface plots are identical to the above line-colored plots since the relative
position of the face centers have the same relative position as that for the line segment centers.
Even the Z directions maps are identical since only one face extends along the Z surface direction.
.. _ss43dcr:
Surface Subdivision for 3D Color Rendering, *lrez*
----------------------------------------------------------------------------------------
To provide color variations along the surface in the direction of the line projection,
the single trapezoidal surface faces must be subdivided along the projection direction.
Subdivisions are specified by the additional *lrez* parameter in the surface construction method.
The *lrez* parameter is an integer which specifies the number of recursive face divisions along
the projection direction. The following figure shows the color distributions for various *lrez* values
using colormapping in the Z direction.
.. image:: images/filled_surface_3.png
:class: sphx-glr-single-img
The surface with lrez=1 exemplifies the effect of face center positions identifying the coloring
values for cmap surfaces. For this case, the face centers of the lower faces are lower than
most of the upper faces of the bisected faces. Only until subdividing each into 8 faces,
lrez=3, does the visual representation appear as smooth bands across the surface.
The previous example uses a ParametricLine object.
For lines constructed directly from segments, the uniform color along each segment may
be more visually pronounced, as shown below for a three-segment line object.
.. image:: images/filled_surface_3a.png
:class: sphx-glr-single-img
Again, as a result of face center position controlling color, there is a marked color transition
between surface planes. This visual color transition is even apparent for higher face
subdivisions shown for a lrez=6.
To smooth the transition, each line segment must be subdivided prior to creating a projected
surface. For ParametricLine objects, increasing the number of subdivisions is made by increasing
the *rez* argument in the constructor, i.e. ::
line = ParametricLine(rez,.....)
Further subdivisions of any line object can be made using the line *shred* method as::
line.shred(rez)
Using the *shred* method may be the only option to smooth the surface for lines other
than surfaces projected from ParametricLine objects. In this case, line *shred* is analogous
to a line *rez*. This is demonstrated in the following example using the previous two example
surfaces.
.. image:: images/filled_surface_3b.png
:class: sphx-glr-single-img
.. _rend_cntl:
Surface Rendering Control
----------------------------------------------------------------------------------------
Various surface Matplotlib renderings may develop anomalous visualizations due to
surface face center locations relative to the view orientation. For example, consider
a surface placed behind a surface relative to the view. As shown below, an incorrect
render may occur.
.. image:: images/filled_surface_4a.png
:class: sphx-glr-single-img
For the left figure in this case, several of the rear surface face centers are relatively
closer in the view than the front surface face centers. To eliminate this anomaly, the number of surface
faces must be increased in the direction of the projection. This is accomplished by increasing
the value for the *lrez* argument used to create the projected surface. This result is exemplified below
by emphasizing the surfaces edges.
.. image:: images/filled_surface_4b.png
:class: sphx-glr-single-img
In other cases when flat surface planes intersect, the number of surface faces along the
segments must be increased. This is exemplified below for two projected surfaces which
intersect due to the line geometries.
.. image:: images/filled_surface_5a.png
:class: sphx-glr-single-img
Subdivisions along the line segments using the *shred* line method may
correct this anomaly. Changes in the view orientation may provide a further
correction. Finally, further adjustments may be needed for the surface using
the *lrez* surface construction parameter.
.. image:: images/filled_surface_5b.png
:class: sphx-glr-single-img
In summary, surface grid constructed from projecting lines should be sufficiently
detailed to provide the required distribution of surface color and
to allow visually correct rendering of overlapping surface faces.
These are controlled by:
============= ================================ ======================
parameter method subdivisions along
============= ================================ ======================
rez ParametricLine constructor line
rez shred line
lrez get_filled_surface projected surface
============= ================================ ======================
.. note::
These intersecting surface face anomalies will depend on the view orientation,
which is set by the axis *elev* and *azim* values. These values may be changed from
the default values using the *view_init* axis method.
Increasing the number of surface faces will, in general, eliminate this type
of anomaly. However, for rendering multiple surfaces, the surfaces must be
added together to create one composite surface where the *Z-order* is set for all
faces of a single surface.
Line Projections to a Line
=========================================================================================
Surfaces may be constructed from projections between two ColorLine3DCollection objects
connecting the line vertices. For example, using ParametricLine lines::
lineA = ParametricLine(REZ,....)
lineB = ParametricLine(REZ,....)
surface = lineA.get_surface_to_line(lineB,lrez)
The two lines must have the same number of segments, i.e., the same REZ or number of segment indices and, if used, the same shred method
argument value. Surface face vertices are constructed
in the same sequential vertex order of the two lines. Surface color will be taken from the segment coloring
of object which calls the method, in this case *lineA*.
.. image:: images/filled_surface_6.png
:class: sphx-glr-single-img
Line to line projection surfaces should be subdivided into smaller faces prior to rendering
the surface using the *shred* or setting the *lrez* parameter during surface construction.
.. warning::
Depending on the lines being projected, quadrilateral faces may be created which are
not planar. These warped faces may produce anomalies which may 'possibly' be eliminated by
triangulating the surface or using the rez or lrez parmeters.
This method of surface construction is particularly useful for *ruled* surface geometries.
The :ref:`hyperboloid` and :ref:`mobius_lines` are two examples of using this surface
construction method.
Source Code
=========================================================================================
Line-Plane Surface
--------------------------------------------------------------------------
The following is the script for generating the surface from projections of a line
to a plane, cylinder or sphere.
.. literalinclude:: source/gu_line_filled_1.py
:language: python
Colormapping Line-Plane Surface
--------------------------------------------------------------------------
The following is the script for colormapping the surface from projections of a line.
.. literalinclude:: source/gu_line_filled_2.py
:language: python
Line Plane Surface
--------------------------------------------------------------------------
The following is the script demonstrating surface rendering control.
.. literalinclude:: source/gu_line_filled_3.py
:language: python