Merge pull request #3142 from radarhere/ellipse

Changed ellipse point calculations to be more evenly distributed
This commit is contained in:
Hugo 2018-07-01 08:44:17 +03:00 committed by GitHub
commit bc192c6cfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 4 deletions

View File

@ -169,6 +169,16 @@ class TestImageDraw(PillowTestCase):
self.assert_image_similar( self.assert_image_similar(
im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1) im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1)
def test_ellipse_symmetric(self):
for bbox in [
(25, 25, 76, 76),
(25, 25, 75, 75)
]:
im = Image.new("RGB", (101, 101))
draw = ImageDraw.Draw(im)
draw.ellipse(bbox, fill="green", outline="blue")
self.assert_image_equal(im, im.transpose(Image.FLIP_LEFT_RIGHT))
def helper_line(self, points): def helper_line(self, points):
# Arrange # Arrange
im = Image.new("RGB", (W, H)) im = Image.new("RGB", (W, H))

View File

@ -732,6 +732,29 @@ ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void* ink,
#define CHORD 1 #define CHORD 1
#define PIESLICE 2 #define PIESLICE 2
static void
ellipsePoint(int cx, int cy, int w, int h,
float i, int *x, int *y)
{
float i_cos, i_sin;
float x_f, y_f;
double modf_int;
i_cos = cos(i*M_PI/180);
i_sin = sin(i*M_PI/180);
x_f = (i_cos * w/2) + cx;
y_f = (i_sin * h/2) + cy;
if (modf(x_f, &modf_int) == 0.5) {
*x = i_cos > 0 ? FLOOR(x_f) : CEIL(x_f);
} else {
*x = FLOOR(x_f + 0.5);
}
if (modf(y_f, &modf_int) == 0.5) {
*y = i_sin > 0 ? FLOOR(y_f) : CEIL(y_f);
} else {
*y = FLOOR(y_f + 0.5);
}
}
static int static int
ellipse(Imaging im, int x0, int y0, int x1, int y1, ellipse(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink_, int fill, float start, float end, const void* ink_, int fill,
@ -781,8 +804,7 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
if (i > end) { if (i > end) {
i = end; i = end;
} }
x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5); ellipsePoint(cx, cy, w, h, i, &x, &y);
y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5);
if (i != start) if (i != start)
add_edge(&e[n++], lx, ly, x, y); add_edge(&e[n++], lx, ly, x, y);
else else
@ -812,8 +834,7 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
if (i > end) { if (i > end) {
i = end; i = end;
} }
x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5); ellipsePoint(cx, cy, w, h, i, &x, &y);
y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5);
if (i != start) if (i != start)
draw->line(im, lx, ly, x, y, ink); draw->line(im, lx, ly, x, y, ink);
else else