Skip to content

Commit

Permalink
Merge pull request matplotlib#8326 from TeamArmstrong/fix-537
Browse files Browse the repository at this point in the history
Orthographic projection for mplot3d
  • Loading branch information
WeatherGod authored Apr 10, 2017
2 parents 1805226 + cc425f6 commit 6f4cc13
Show file tree
Hide file tree
Showing 8 changed files with 648 additions and 2 deletions.
3 changes: 3 additions & 0 deletions doc/users/whats_new/axes3d_orthographic_projection.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Orthographic projection for mplot3d
-----------------------------------
:class:`~mpl_toolkits.mplot3d.axes3d.Axes3D` now accepts ``proj_type`` kwarg and has a method :meth:`~mpl_toolkits.mplot3d.axes3d.Axes3D.set_proj_type`. The default option is ``'persp'`` as before, and supplying ``'ortho'`` enables orthographic view.
23 changes: 21 additions & 2 deletions lib/mpl_toolkits/mplot3d/axes3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def __init__(self, fig, rect=None, *args, **kwargs):
*elev* Elevation viewing angle (default 30)
*zscale* [%(scale)s]
*sharez* Other axes to share z-limits with
*proj_type* 'persp' or 'ortho' (default 'persp')
================ =========================================
.. versionadded :: 1.2.1
Expand All @@ -78,6 +79,7 @@ def __init__(self, fig, rect=None, *args, **kwargs):
self.initial_elev = kwargs.pop('elev', 30)
zscale = kwargs.pop('zscale', None)
sharez = kwargs.pop('sharez', None)
self.set_proj_type(kwargs.pop('proj_type', 'persp'))

self.xy_viewLim = unit_bbox()
self.zz_viewLim = unit_bbox()
Expand Down Expand Up @@ -959,6 +961,23 @@ def view_init(self, elev=None, azim=None):
else:
self.azim = azim

def set_proj_type(self, proj_type):
"""
Set the projection type.
Parameters
----------
proj_type : str
Type of projection, accepts 'persp' and 'ortho'.
"""
if proj_type == 'persp':
self._projection = proj3d.persp_transformation
elif proj_type == 'ortho':
self._projection = proj3d.ortho_transformation
else:
raise ValueError("unrecognized projection: %s" % proj_type)

def get_proj(self):
"""
Create the projection matrix from the current viewing position.
Expand Down Expand Up @@ -1001,9 +1020,9 @@ def get_proj(self):
zfront, zback = -self.dist, self.dist

viewM = proj3d.view_transformation(E, R, V)
perspM = proj3d.persp_transformation(zfront, zback)
projM = self._projection(zfront, zback)
M0 = np.dot(viewM, worldM)
M = np.dot(perspM, M0)
M = np.dot(projM, M0)
return M

def mouse_init(self, rotate_btn=1, zoom_btn=3):
Expand Down
10 changes: 10 additions & 0 deletions lib/mpl_toolkits/mplot3d/proj3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ def persp_transformation(zfront, zback):
[0,0,-1,0]
])

def ortho_transformation(zfront, zback):
# note: w component in the resulting vector will be (zback-zfront), not 1
a = -(zfront + zback)
b = -(zfront - zback)
return np.array([[2,0,0,0],
[0,2,0,0],
[0,0,-2,0],
[0,0,a,b]
])

def proj_transform_vec(vec, M):
vecw = np.dot(M, vec)
w = vecw[3]
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 6f4cc13

Please sign in to comment.