Graphics 3D Object for Representing and Triangulating Isosurfaces.

AUTHORS:

  • Robert Hanson (2007): initial Java version, in Jmol.

  • Carl Witty (2009-01): first Cython version.

  • Bill Cauchois (2009): improvements for inclusion into Sage.

class sage.plot.plot3d.implicit_surface.ImplicitSurface

Bases: sage.plot.plot3d.index_face_set.IndexFaceSet

bounding_box()

Return a bounding box for the ImplicitSurface, as a tuple of two 3-dimensional points.

EXAMPLES:

Note that the bounding box corresponds exactly to the x-, y-, and z- range:

sage: from sage.plot.plot3d.implicit_surface import ImplicitSurface
sage: G = ImplicitSurface(0, (0, 1), (0, 1), (0, 1))
sage: G.bounding_box()
((0.0, 0.0, 0.0), (1.0, 1.0, 1.0))
color_function
colormap
contours
f
gradient
jmol_repr(render_params)

Return a representation of this object suitable for use with the Jmol renderer.

json_repr(render_params)

Return a representation of this object in JavaScript Object Notation (JSON).

obj_repr(render_params)

Return a representation of this object in the .obj format.

plot_points
region
smooth
tachyon_repr(render_params)

Return a representation of this object suitable for use with the Tachyon renderer.

threejs_repr(render_params)

Return a represention of the surface suitable for plotting with three.js.

EXAMPLES:

sage: from sage.plot.plot3d.implicit_surface import ImplicitSurface
sage: _ = var('x,y,z')
sage: G = ImplicitSurface(x + y + z, (x,-1, 1), (y,-1, 1), (z,-1, 1))
sage: G.threejs_repr(G.default_render_params())
[('surface',
  {'color': '#6666ff',
   'faces': [[0, 1, 2],
    ...
   'opacity': 1.0,
   'vertices': [{'x': ...,
     'y': -0.9743589743589...,
     'z': -0.02564102564102...},
    ...
    {'x': -1.0, 'y': 0.9487179487179..., 'z': 0.05128205128205...}]})]
triangulate(force=False)

The IndexFaceSet will be empty until you call this method, which generates the faces and vertices according to the parameters specified in the constructor for ImplicitSurface.

Note that if you call this method more than once, subsequent invocations will have no effect (this is an optimization to avoid repeated work) unless you specify force=True in the keywords.

EXAMPLES:

sage: from sage.plot.plot3d.implicit_surface import ImplicitSurface
sage: var('x,y,z')
(x, y, z)
sage: G = ImplicitSurface(x + y + z, (x,-1, 1), (y,-1, 1), (z,-1, 1))
sage: len(G.vertex_list()), len(G.face_list())
(0, 0)
sage: G.triangulate()
sage: len(G.vertex_list()) > 0, len(G.face_list()) > 0
(True, True)
sage: G.show() # This should be fast, since the mesh is already triangulated.
vars
xrange
yrange
zrange
class sage.plot.plot3d.implicit_surface.MarchingCubes

Bases: object

Handles marching cube rendering.

Protocol:

  1. Create the class.

  2. Call process_slice once for each X slice, from self.nx > x >= 0.

  3. Call finish(), which returns a list of strings.

Note

Actually, only 4 slices ever exist; the caller will re-use old storage.

color_function
colormap
contour
finish()

Return the results of the marching cubes algorithm as a list.

The format is specific to the subclass implementing this method.

gradient
nx
ny
nz
region
results
smooth
transform
xrange
yrange
zrange
class sage.plot.plot3d.implicit_surface.MarchingCubesTriangles

Bases: sage.plot.plot3d.implicit_surface.MarchingCubes

A subclass of MarchingCubes that returns its results as a list of triangles, including their vertices and normals (if smooth=True).

And also their vertex colors if a vertex coloring function is given.

add_triangle(v1, v2, v3)

Called when a new triangle is generated by the marching cubes algorithm to update the results array.

process_cubes(_left, _right)
process_slice(x, slice)

Process a single slice of function evaluations at the specified \(x\) coordinate.

EXAMPLES:

sage: from sage.plot.plot3d.implicit_surface import MarchingCubesTriangles
sage: import numpy as np
sage: cube_marcher = MarchingCubesTriangles((-2, 2), (-2, 2), (-2, 2), 4, (10,)*3, smooth=False)
sage: f = lambda x, y, z: x^2 + y^2 + z^2
sage: slices = np.zeros((10, 10, 10), dtype=np.double)
sage: for x in reversed(range(0, 10)):
....:     for y in range(0, 10):
....:         for z in range(0, 10):
....:             slices[x, y, z] = f(*[a * (4 / 9) -2 for a in (x, y, z)])
....:     cube_marcher.process_slice(x, slices[x, :, :])
sage: faces = cube_marcher.finish()
sage: faces[0][0]
{'x': 1.555555555555..., 'y': -1.111111111111..., 'z': -0.555555555555...}

We render the isosurface using IndexFaceSet:

sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
sage: IndexFaceSet([tuple((p['x'], p['y'], p['z']) for p in face) for face in faces])
Graphics3d Object
slices
x_vertices
y_vertices
y_vertices_swapped
z_vertices
z_vertices_swapped
class sage.plot.plot3d.implicit_surface.VertexInfo

Bases: object

sage.plot.plot3d.implicit_surface.render_implicit(f, xrange, yrange, zrange, plot_points, cube_marchers)

INPUT:

  • f - a (fast!) callable function

  • xrange - a 2-tuple (x_min, x_max)

  • yrange - a 2-tuple (y_min, y_may)

  • zrange - a 2-tuple (z_min, z_maz)

  • plot_points - a triple of integers indicating the number of function evaluations in each direction.

  • cube_marchers - a list of cube marchers, one for each contour.

OUTPUT:

A representation of the isosurface, in the format specified by the individual cube marchers.