Revision: 4679
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4679&view=rev
Author:   mdboom
Date:     2007-12-10 06:50:40 -0800 (Mon, 10 Dec 2007)

Log Message:
-----------
Use an 8-spline approximation of an ellipse instead of a 4-spline one.

Modified Paths:
--------------
    trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
    trunk/matplotlib/lib/matplotlib/patches.py

Added Paths:
-----------
    trunk/matplotlib/unit/ellipse_large.py

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py      2007-12-09 
00:48:27 UTC (rev 4678)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py      2007-12-10 
14:50:40 UTC (rev 4679)
@@ -1644,11 +1644,15 @@
     } bind def""",
     """/unitcircle {
     newpath
--1. 0. moveto
--1.0 0.552284749831 -0.552284749831 1.0 0.0 1.0 curveto
-0.552284749831 1.0 1.0 0.552284749831 1.0 0.0 curveto
-1.0 -0.552284749831 0.552284749831 -1.0 0.0 -1.0 curveto
--0.552284749831 -1.0 -1.0 -0.552284749831 -1.0 0.0 curveto
+0. -1. moveto
+0.2652031 -1.0 0.519579870785 -0.894633691588 0.707106781187 -0.707106781187 
curveto
+0.894633691588 -0.519579870785 1.0 -0.2652031 1.0 0.0 curveto
+1.0 0.2652031 0.894633691588 0.519579870785 0.707106781187 0.707106781187 
curveto
+0.519579870785 0.894633691588 0.2652031 1.0 0.0 1.0 curveto
+-0.2652031 1.0 -0.519579870785 0.894633691588 -0.707106781187 0.707106781187 
curveto
+-0.894633691588 0.519579870785 -1.0 0.2652031 -1.0 0.0 curveto
+-1.0 -0.2652031 -0.894633691588 -0.519579870785 -0.707106781187 
-0.707106781187 curveto
+-0.519579870785 -0.894633691588 -0.2652031 -1.0 0.0 -1.0 curveto
 closepath
     } bind def""",
 

Modified: trunk/matplotlib/lib/matplotlib/patches.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/patches.py  2007-12-09 00:48:27 UTC (rev 
4678)
+++ trunk/matplotlib/lib/matplotlib/patches.py  2007-12-10 14:50:40 UTC (rev 
4679)
@@ -201,7 +201,7 @@
 
         if cbook.is_string_like(self._edgecolor) and 
self._edgecolor.lower()=='none':
             gc.set_linewidth(0)
-        else:        
+        else:
             gc.set_foreground(self._edgecolor)
             gc.set_linewidth(self._linewidth)
 
@@ -764,32 +764,46 @@
     """
     A scale-free ellipse
     """
-    offset = 4.0 * (npy.sqrt(2) - 1) / 3.0
+    MAGIC = 0.2652031
+    SQRT2 = npy.sqrt(0.5)
+    MAGIC45 = npy.sqrt((MAGIC*MAGIC) / 2.0)
 
-    circle = npy.array([
-        [-1.0, 0.0],
+    circle = npy.array(
+        [[0.0, -1.0],
 
-        [-1.0, offset],
-        [-offset, 1.0],
-        [0.0, 1.0],
+         [MAGIC, -1.0],
+         [SQRT2-MAGIC45, -SQRT2-MAGIC45],
+         [SQRT2, -SQRT2],
 
-        [offset, 1.0],
-        [1.0, offset],
-        [1.0, 0.0],
+         [SQRT2+MAGIC45, -SQRT2+MAGIC45],
+         [1.0, -MAGIC],
+         [1.0, 0.0],
 
-        [1.0, -offset],
-        [offset, -1.0],
-        [0.0, -1.0],
+         [1.0, MAGIC],
+         [SQRT2+MAGIC45, SQRT2-MAGIC45],
+         [SQRT2, SQRT2],
 
-        [-offset, -1.0],
-        [-1.0, -offset],
-        [-1.0, 0.0],
+         [SQRT2-MAGIC45, SQRT2+MAGIC45],
+         [MAGIC, 1.0],
+         [0.0, 1.0],
 
-        [-1.0, 0.0]
-        ],
-                       npy.float_)
+         [-MAGIC, 1.0],
+         [-SQRT2+MAGIC45, SQRT2+MAGIC45],
+         [-SQRT2, SQRT2],
 
-    
+         [-SQRT2-MAGIC45, SQRT2-MAGIC45],
+         [-1.0, MAGIC],
+         [-1.0, 0.0],
+
+         [-1.0, -MAGIC],
+         [-SQRT2-MAGIC45, -SQRT2+MAGIC45],
+         [-SQRT2, -SQRT2],
+
+         [-SQRT2+MAGIC45, -SQRT2-MAGIC45],
+         [-MAGIC, -1.0],
+         [0.0, -1.0]],
+        npy.float_)
+
     def __str__(self):
         return 
"Ellipse(%d,%d;%dx%d)"%(self.center[0],self.center[1],self.width,self.height)
 
@@ -823,9 +837,9 @@
         width, height = self.width, self.height
 
         xcenter = self.convert_xunits(xcenter)
-        width = self.convert_xunits(width)        
+        width = self.convert_xunits(width)
         ycenter = self.convert_yunits(ycenter)
-        height = self.convert_xunits(height)        
+        height = self.convert_xunits(height)
 
 
 
@@ -871,8 +885,8 @@
             mpl.verbose.report('patches.Ellipse renderer does not support path 
drawing; falling back on vertex approximation for nonlinear transformation')
             renderer.draw_polygon(gc, rgbFace, self.get_verts())
             return
-        
 
+
         x, y = self.center
         x = self.convert_xunits(x)
         y = self.convert_yunits(y)
@@ -887,14 +901,14 @@
 
 
 
-        
+
         S = npy.array([
             [w, 0, 0],
             [0, h, 0],
             [0, 0, 1]])
 
 
-        
+
         # rotate by theta
         R = npy.array([
             [npy.cos(theta),  -npy.sin(theta), 0],
@@ -903,8 +917,8 @@
 
         # transform unit circle into ellipse
         E = npy.dot(T, npy.dot(R, S))
-        
 
+
         # Apply the display affine
         sx, b, c, sy, tx, ty = self.get_transform().as_vec6_val()
 
@@ -918,25 +932,19 @@
 
         C = npy.ones((3, len(self.circle)))
         C[0:2,:] = self.circle.T
-        
+
         ellipse = npy.dot(M, C).T[:,:2]
 
         path =  agg.path_storage()
         path.move_to(*ellipse[0])
-        verts = ellipse[1:4].flat
-        path.curve4(*verts)
-        verts = ellipse[4:7].flat
-        path.curve4(*verts)
-        verts = ellipse[7:10].flat
-        path.curve4(*verts)
-        verts = ellipse[10:13].flat
-        path.curve4(*verts)
+        for i in range(1, 25, 3):
+            path.curve4(*ellipse[i:i+3].flat)
         path.close_polygon()
 
         renderer.draw_path(gc, rgbFace, path)
 
-                              
 
+
 class Circle(Ellipse):
     """
     A circle patch

Added: trunk/matplotlib/unit/ellipse_large.py
===================================================================
--- trunk/matplotlib/unit/ellipse_large.py                              (rev 0)
+++ trunk/matplotlib/unit/ellipse_large.py      2007-12-10 14:50:40 UTC (rev 
4679)
@@ -0,0 +1,107 @@
+
+# This example can be boiled down to a more simplistic example
+# to show the problem, but bu including the upper and lower
+# bound ellipses, it demonstrates how significant this error
+# is to our plots.
+
+import math
+from pylab import *
+from matplotlib.patches import Ellipse
+
+# given a point x, y
+x = 2692.440
+y = 6720.850
+
+# get is the radius of a circle through this point
+r = math.sqrt( x*x+y*y )
+
+# show some comparative circles
+delta = 6
+
+
+##################################################
+def custom_ellipse( ax, x, y, major, minor, theta, numpoints = 750, **kwargs ):
+   xs = []
+   ys = []
+   incr = 2.0*math.pi / numpoints
+   incrTheta = 0.0
+   while incrTheta <= (2.0*math.pi):
+      a = major * math.cos( incrTheta )
+      b = minor * math.sin( incrTheta )
+      l = math.sqrt( ( a**2 ) + ( b**2 ) )
+      phi = math.atan2( b, a )
+      incrTheta += incr
+
+      xs.append( x + ( l * math.cos( theta + phi ) ) )
+      ys.append( y + ( l * math.sin( theta + phi ) ) )
+   # end while
+
+   incrTheta = 2.0*math.pi
+   a = major * math.cos( incrTheta )
+   b = minor * math.sin( incrTheta )
+   l = sqrt( ( a**2 ) + ( b**2 ) )
+   phi = math.atan2( b, a )
+   xs.append( x + ( l * math.cos( theta + phi ) ) )
+   ys.append( y + ( l * math.sin( theta + phi ) ) )
+
+   ellipseLine = ax.plot( xs, ys, **kwargs )
+
+
+##################################################
+# make the axes
+ax = subplot( 211, aspect='equal' )
+ax.set_aspect( 'equal', 'datalim' )
+
+# make the lower-bound ellipse
+diam = (r - delta) * 2.0
+lower_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkgreen" )
+ax.add_patch( lower_ellipse )
+
+# make the target ellipse
+diam = r * 2.0
+target_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkred" )
+ax.add_patch( target_ellipse )
+
+# make the upper-bound ellipse
+diam = (r + delta) * 2.0
+upper_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkblue" )
+ax.add_patch( upper_ellipse )
+
+# make the target
+diam = delta * 2.0
+target = Ellipse( (x, y), diam, diam, 0.0, fill=False, edgecolor="#DD1208" )
+ax.add_patch( target )
+
+# give it a big marker
+ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red', 
markersize=10 )
+
+##################################################
+# now lets do the same thing again using a custom ellipse function
+
+# make the axes
+ax = subplot( 212, aspect='equal', sharex=ax, sharey=ax )
+ax.set_aspect( 'equal', 'datalim' )
+
+# make the lower-bound ellipse
+custom_ellipse( ax, 0.0, 0.0, r-delta, r-delta, 0.0, color="darkgreen" )
+
+# make the target ellipse
+custom_ellipse( ax, 0.0, 0.0, r, r, 0.0, color="darkred" )
+
+# make the upper-bound ellipse
+custom_ellipse( ax, 0.0, 0.0, r+delta, r+delta, 0.0, color="darkblue" )
+
+# make the target
+custom_ellipse( ax, x, y, delta, delta, 0.0, color="#BB1208" )
+
+# give it a big marker
+ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red', 
markersize=10 )
+
+##################################################
+# lets zoom in to see the area of interest
+
+ax.set_xlim(2650, 2735)
+ax.set_ylim(6705, 6735)
+show()
+
+savefig("ellipse")


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
SF.Net email is sponsored by: 
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to