Skip to content

Instantly share code, notes, and snippets.

@flowernert
Last active December 26, 2018 10:47
Show Gist options
  • Save flowernert/f392cd9fbdc44604df9567227504b329 to your computer and use it in GitHub Desktop.
Save flowernert/f392cd9fbdc44604df9567227504b329 to your computer and use it in GitHub Desktop.
class PlotContour(PlotBase):
... #some other methods generating the simplices plotting them and calling the contour method
@classmethod
def contour(cls, simplices, ax):
"""
:param simplices: the list of 3D simplices
:param ax: the Axes3D object
"""
# inner functionality
def _compute_2D_outline(outlines):
if outlines:
for outline in outlines:
try:
outline.remove()
except ValueError:
pass
proj = ax.get_proj()
rot = np.vstack(tuple([proj[3, :3] * np.sign(proj[0, 3]),
proj[0, :3] * np.sign(proj[1, 3]),
proj[1, :3] * np.sign(proj[3, 3])]))
inv_rot = np.linalg.inv(rot)
poly = None
for sim in simplices:
sim2D = np.dot(rot, sim.T)[1:].T
hull2D = sim2D[ConvexHull(sim2D, qhull_options="Qs").vertices]
if poly is None:
poly = Polygon(hull2D)
else:
poly = poly.union(Polygon(hull2D))
if type(poly) is Polygon:
poly = MultiPolygon([poly])
for p in poly:
if type(p) is Polygon:
contour2D = np.array(p.exterior.coords.xy)
contour3D = np.concatenate([[np.zeros(contour2D.shape[1])], contour2D])
contour3D_invrot = np.dot(inv_rot, contour3D)
outline = Line3DCollection([contour3D_invrot.T],
alpha=1, colors="b", linewidths=2, zorder=-5)
ax.add_collection3d(outline)
outlines.append(outline)
return outlines
# handler for figure moved
def _on_move(event):
if event.button and event.inaxes:
cls.contour_outlines = _compute_2D_outline(cls.contour_outlines)
# init
try:
cls.contour_outlines
except AttributeError:
cls.contour_outlines = []
ax.get_figure().canvas.mpl_connect("motion_notify_event", _on_move)
# outer
cls.contour_outlines = _compute_2D_outline(cls.contour_outlines)
@flowernert
Copy link
Author

This is the code allowing to find and draw the 2D contour of a 3D polygon.
It updates the display at each figure movement triggered by interactivity.

More context in
https://stackoverflow.com/questions/53652749/matplotlib-extract-2d-contour-of-a-3d-polygons-plot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment