|
From: <dmk...@us...> - 2008-11-05 14:02:13
|
Revision: 6362
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6362&view=rev
Author: dmkaplan
Date: 2008-11-05 14:02:07 +0000 (Wed, 05 Nov 2008)
Log Message:
-----------
Added a method to class Transforms in transform.py that transforms
angles. The generic method uses a generic algorithm involving pushing
off from a group of locations to determine new angles. This should
work with almost any transform, but much quicker algorithms can be
found for affine transforms. These algorithms have not yet been added
though, so the generic method will be used until they are.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/transforms.py
Modified: trunk/matplotlib/lib/matplotlib/transforms.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/transforms.py 2008-11-04 13:38:15 UTC (rev 6361)
+++ trunk/matplotlib/lib/matplotlib/transforms.py 2008-11-05 14:02:07 UTC (rev 6362)
@@ -1131,6 +1131,63 @@
"""
return Path(self.transform_non_affine(path.vertices), path.codes)
+ def transform_angles(self, angles, pts, radians=False, pushoff=1e-5):
+ """
+ Performs transformation on a set of angles anchored at
+ specific locations.
+
+ The *angles* must be a column vector (i.e., numpy array).
+
+ The *pts* must be a two-column numpy array of x,y positions
+ (angle transforms currently only work in 2D). This array must
+ have the same number of rows as *angles*.
+
+ *radians* indicates whether or not input angles are given in
+ radians (True) or degrees (False; the default).
+
+ *pushoff* is the distance to move away from *pts* for
+ determining transformed angles (see discussion of method
+ below).
+
+ The transformed angles are returned in an array with the same
+ size as *angles*.
+
+ The generic version of this method uses a very generic
+ algorithm that transforms *pts*, as well as locations very
+ close to *pts*, to find the angle in the transformed system.
+ """
+ # Must be 2D
+ if self.input_dims <> 2 or self.output_dims <> 2:
+ raise NotImplementedError('Only defined in 2D')
+
+ # pts must be array with 2 columns for x,y
+ assert pts.shape[1] == 2
+
+ # angles must be a column vector and have same number of
+ # rows as pts
+ assert np.prod(angles.shape) == angles.shape[0] == pts.shape[0]
+
+ # Convert to radians if desired
+ if not radians:
+ angles = angles / 180.0 * np.pi
+
+ # Move a short distance away
+ pts2 = pts + pushoff * np.c_[ np.cos(angles), np.sin(angles) ]
+
+ # Transform both sets of points
+ tpts = self.transform( pts )
+ tpts2 = self.transform( pts2 )
+
+ # Calculate transformed angles
+ d = tpts2 - tpts
+ a = np.arctan2( d[:,1], d[:,0] )
+
+ # Convert back to degrees if desired
+ if not radians:
+ a = a * 180.0 / np.pi
+
+ return a
+
def inverted(self):
"""
Return the corresponding inverse transformation.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|