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[source]¶
Bases:
IndexFaceSet
- bounding_box()[source]¶
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))
>>> from sage.all import * >>> from sage.plot.plot3d.implicit_surface import ImplicitSurface >>> G = ImplicitSurface(Integer(0), (Integer(0), Integer(1)), (Integer(0), Integer(1)), (Integer(0), Integer(1))) >>> G.bounding_box() ((0.0, 0.0, 0.0), (1.0, 1.0, 1.0))
- jmol_repr(render_params)[source]¶
Return a representation of this object suitable for use with the Jmol renderer.
- json_repr(render_params)[source]¶
Return a representation of this object in JavaScript Object Notation (JSON).
- tachyon_repr(render_params)[source]¶
Return a representation of this object suitable for use with the Tachyon renderer.
- threejs_repr(render_params)[source]¶
Return a representation 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...}]})]
>>> from sage.all import * >>> from sage.plot.plot3d.implicit_surface import ImplicitSurface >>> _ = var('x,y,z') >>> G = ImplicitSurface(x + y + z, (x,-Integer(1), Integer(1)), (y,-Integer(1), Integer(1)), (z,-Integer(1), Integer(1))) >>> 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)[source]¶
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.
>>> from sage.all import * >>> from sage.plot.plot3d.implicit_surface import ImplicitSurface >>> var('x,y,z') (x, y, z) >>> G = ImplicitSurface(x + y + z, (x,-Integer(1), Integer(1)), (y,-Integer(1), Integer(1)), (z,-Integer(1), Integer(1))) >>> len(G.vertex_list()), len(G.face_list()) (0, 0) >>> G.triangulate() >>> len(G.vertex_list()) > Integer(0), len(G.face_list()) > Integer(0) (True, True) >>> G.show() # This should be fast, since the mesh is already triangulated.
- class sage.plot.plot3d.implicit_surface.MarchingCubes[source]¶
Bases:
object
Handles marching cube rendering.
Protocol:
Create the class.
Call
process_slice
once for each X slice, from self.nx > x >= 0.Call
finish()
, which returns a list of strings.
Note
Actually, only 4 slices ever exist; the caller will re-use old storage.
- class sage.plot.plot3d.implicit_surface.MarchingCubesTriangles[source]¶
Bases:
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)[source]¶
Called when a new triangle is generated by the marching cubes algorithm to update the results array.
- process_slice(x, slice)[source]¶
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...}
>>> from sage.all import * >>> from sage.plot.plot3d.implicit_surface import MarchingCubesTriangles >>> import numpy as np >>> cube_marcher = MarchingCubesTriangles((-Integer(2), Integer(2)), (-Integer(2), Integer(2)), (-Integer(2), Integer(2)), Integer(4), (Integer(10),)*Integer(3), smooth=False) >>> f = lambda x, y, z: x**Integer(2) + y**Integer(2) + z**Integer(2) >>> slices = np.zeros((Integer(10), Integer(10), Integer(10)), dtype=np.double) >>> for x in reversed(range(Integer(0), Integer(10))): ... for y in range(Integer(0), Integer(10)): ... for z in range(Integer(0), Integer(10)): ... slices[x, y, z] = f(*[a * (Integer(4) / Integer(9)) -Integer(2) for a in (x, y, z)]) ... cube_marcher.process_slice(x, slices[x, :, :]) >>> faces = cube_marcher.finish() >>> faces[Integer(0)][Integer(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
>>> from sage.all import * >>> from sage.plot.plot3d.index_face_set import IndexFaceSet >>> IndexFaceSet([tuple((p['x'], p['y'], p['z']) for p in face) for face in faces]) Graphics3d Object
- class sage.plot.plot3d.implicit_surface.VertexInfo¶
Bases:
object
- sage.plot.plot3d.implicit_surface.render_implicit(f, xrange, yrange, zrange, plot_points, cube_marchers)[source]¶
INPUT:
f
– a (fast!) callable functionxrange
– 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 directioncube_marchers
– list of cube marchers, one for each contour
OUTPUT:
A representation of the isosurface, in the format specified by the individual cube marchers.