Skip to content

Commit

Permalink
Merge pull request #5460 from xtsm/ellipse
Browse files Browse the repository at this point in the history
Remove spikes when drawing thin pieslices
  • Loading branch information
radarhere committed May 14, 2021
2 parents f027397 + ca67a0c commit 78406ed
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
30 changes: 30 additions & 0 deletions Tests/test_imagedraw.py
Expand Up @@ -538,6 +538,36 @@ def test_pieslice_wide():
assert_image_equal_tofile(im, "Tests/images/imagedraw_pieslice_wide.png")


def test_pieslice_no_spikes():
im = Image.new("RGB", (161, 161), "white")
draw = ImageDraw.Draw(im)
cxs = (
[140] * 3
+ list(range(140, 19, -20))
+ [20] * 5
+ list(range(20, 141, 20))
+ [140] * 2
)
cys = (
list(range(80, 141, 20))
+ [140] * 5
+ list(range(140, 19, -20))
+ [20] * 5
+ list(range(20, 80, 20))
)

for cx, cy, angle in zip(cxs, cys, range(0, 360, 15)):
draw.pieslice(
[cx - 100, cy - 100, cx + 100, cy + 100], angle, angle + 1, fill="black"
)
draw.point([cx, cy], fill="red")

im_pre_erase = im.copy()
draw.rectangle([21, 21, 139, 139], fill="white")

assert_image_equal(im, im_pre_erase)


def helper_point(points):
# Arrange
im = Image.new("RGB", (W, H))
Expand Down
16 changes: 16 additions & 0 deletions src/libImaging/Draw.c
Expand Up @@ -1347,6 +1347,22 @@ pie_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float
s->root->l = lc;
s->root->r = rc;
s->root->type = ar - al < 180 ? CT_AND : CT_OR;

// add one more semiplane to avoid spikes
if (ar - al < 90) {
clip_node *old_root = s->root;
clip_node *spike_clipper = s->nodes + s->node_count++;
s->root = s->nodes + s->node_count++;
s->root->l = old_root;
s->root->r = spike_clipper;
s->root->type = CT_AND;

spike_clipper->l = spike_clipper->r = NULL;
spike_clipper->type = CT_CLIP;
spike_clipper->a = (xl + xr) / 2.0;
spike_clipper->b = (yl + yr) / 2.0;
spike_clipper->c = 0;
}
}

void
Expand Down

0 comments on commit 78406ed

Please sign in to comment.