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