Skip to content

Commit bc192c6

Browse files
authored
Merge pull request #3142 from radarhere/ellipse
Changed ellipse point calculations to be more evenly distributed
2 parents 3674fdf + 8d8d00f commit bc192c6

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

Tests/test_imagedraw.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ def test_ellipse_edge(self):
169169
self.assert_image_similar(
170170
im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1)
171171

172+
def test_ellipse_symmetric(self):
173+
for bbox in [
174+
(25, 25, 76, 76),
175+
(25, 25, 75, 75)
176+
]:
177+
im = Image.new("RGB", (101, 101))
178+
draw = ImageDraw.Draw(im)
179+
draw.ellipse(bbox, fill="green", outline="blue")
180+
self.assert_image_equal(im, im.transpose(Image.FLIP_LEFT_RIGHT))
181+
172182
def helper_line(self, points):
173183
# Arrange
174184
im = Image.new("RGB", (W, H))

src/libImaging/Draw.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,29 @@ ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void* ink,
732732
#define CHORD 1
733733
#define PIESLICE 2
734734

735+
static void
736+
ellipsePoint(int cx, int cy, int w, int h,
737+
float i, int *x, int *y)
738+
{
739+
float i_cos, i_sin;
740+
float x_f, y_f;
741+
double modf_int;
742+
i_cos = cos(i*M_PI/180);
743+
i_sin = sin(i*M_PI/180);
744+
x_f = (i_cos * w/2) + cx;
745+
y_f = (i_sin * h/2) + cy;
746+
if (modf(x_f, &modf_int) == 0.5) {
747+
*x = i_cos > 0 ? FLOOR(x_f) : CEIL(x_f);
748+
} else {
749+
*x = FLOOR(x_f + 0.5);
750+
}
751+
if (modf(y_f, &modf_int) == 0.5) {
752+
*y = i_sin > 0 ? FLOOR(y_f) : CEIL(y_f);
753+
} else {
754+
*y = FLOOR(y_f + 0.5);
755+
}
756+
}
757+
735758
static int
736759
ellipse(Imaging im, int x0, int y0, int x1, int y1,
737760
float start, float end, const void* ink_, int fill,
@@ -781,8 +804,7 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
781804
if (i > end) {
782805
i = end;
783806
}
784-
x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5);
785-
y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5);
807+
ellipsePoint(cx, cy, w, h, i, &x, &y);
786808
if (i != start)
787809
add_edge(&e[n++], lx, ly, x, y);
788810
else
@@ -812,8 +834,7 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
812834
if (i > end) {
813835
i = end;
814836
}
815-
x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5);
816-
y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5);
837+
ellipsePoint(cx, cy, w, h, i, &x, &y);
817838
if (i != start)
818839
draw->line(im, lx, ly, x, y, ink);
819840
else

0 commit comments

Comments
 (0)