Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 11827f7

Browse files
committed
added ellipse rotation to Agg
svn path=/trunk/matplotlib/; revision=2744
1 parent 3145747 commit 11827f7

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

lib/matplotlib/patches.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,11 @@ def __init__(self, xy, radius=5,
523523
class Ellipse(Patch):
524524
"""
525525
A scale-free ellipse
526+
527+
xy - center of ellipse
528+
width - length of horizontal axis
529+
height - length of vertical axis
530+
angle - rotation in degrees (anti-clockwise)
526531
"""
527532
def __init__(self, xy, width, height, angle=0.0, **kwargs):
528533
Patch.__init__(self, **kwargs)

src/_backend_agg.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#endif
3939
#endif
4040

41+
#define M_PI 3.14159265358979323846
42+
#define M_PI_4 0.785398163397448309616
43+
#define M_PI_2 1.57079632679489661923
44+
4145
/* ------------ RendererAgg methods ------------- */
4246

4347

@@ -377,23 +381,38 @@ RendererAgg::draw_ellipse(const Py::Tuple& args) {
377381
GCAgg gc = GCAgg(args[0], dpi);
378382
facepair_t face = _get_rgba_face(args[1], gc.alpha);
379383

380-
381384
double x = Py::Float( args[2] );
382385
double y = Py::Float( args[3] );
383386
double w = Py::Float( args[4] );
384387
double h = Py::Float( args[5] );
385388
double rot = Py::Float( args[6] );
389+
390+
double r; // rot in radians
386391

387392
set_clipbox_rasterizer(gc.cliprect);
388393

389394
// Approximate the ellipse with 4 bezier paths
390395
agg::path_storage path;
391-
path.move_to(x, height-(y+h));
392-
path.arc_to(w, h, 0.0, false, true, x+w, height-y);
393-
path.arc_to(w, h, 0.0, false, true, x, height-(y-h));
394-
path.arc_to(w, h, 0.0, false, true, x-w, height-y);
395-
path.arc_to(w, h, 0.0, false, true, x, height-(y+h));
396-
path.close_polygon();
396+
if (rot == 0.0) // simple case
397+
{
398+
path.move_to(x, height-(y+h));
399+
path.arc_to(w, h, 0.0, false, true, x+w, height-y);
400+
path.arc_to(w, h, 0.0, false, true, x, height-(y-h));
401+
path.arc_to(w, h, 0.0, false, true, x-w, height-y);
402+
path.arc_to(w, h, 0.0, false, true, x, height-(y+h));
403+
path.close_polygon();
404+
}
405+
else // rotate by hand :(
406+
{
407+
// deg to rad
408+
r = rot * (M_PI/180.0);
409+
path.move_to( x+(cos(r)*w), height-(y+(sin(r)*w)));
410+
path.arc_to(w, h, -r, false, true, x+(cos(r+M_PI_2*3)*h), height-(y+(sin(r+M_PI_2*3)*h)));
411+
path.arc_to(w, h, -r, false, true, x+(cos(r+M_PI)*w), height-(y+(sin(r+M_PI)*w)));
412+
path.arc_to(w, h, -r, false, true, x+(cos(r+M_PI_2)*h), height-(y+(sin(r+M_PI_2)*h)));
413+
path.arc_to(w, h, -r, false, true, x+(cos(r)*w), height-(y+(sin(r)*w)));
414+
path.close_polygon();
415+
}
397416

398417
_fill_and_stroke(path, gc, face);
399418
return Py::Object();

0 commit comments

Comments
 (0)