Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pieslice draws very thin sectors incorrectly #5432

Closed
hwjsnc opened this issue Apr 23, 2021 · 4 comments · Fixed by #5460
Closed

pieslice draws very thin sectors incorrectly #5432

hwjsnc opened this issue Apr 23, 2021 · 4 comments · Fixed by #5460

Comments

@hwjsnc
Copy link

hwjsnc commented Apr 23, 2021

What did you do?

I drew a circle sector with a very small central angle using pieslice.

What did you expect to happen?

I expected to get a shape approximating a line from the edge of the (imagined) disk to its center.

What actually happened?

The (approximate) line extends past the disk's center.

The effect is more pronounced for smaller central angles and less pronounced for arcs starting/ending near 0° and 180°.

The following images show 1° arcs drawn using pieslice and a small red circle marking the center of the corresponding disk. The script creating them is given at the end.

These results are as expected (base angles 0°, 180°):
test0 test180

The following demonstrate the problem (base angles 15°, 45°, 90°, 270°):
test15 test45 test90 test270

What are your OS, Python and Pillow versions?

  • OS: archlinux
  • Python: 3.9.3
  • Pillow: 8.1.2
# This code creates several files, only a few selected ones are shown above.
from PIL import Image, ImageDraw

r = 100 # radius in px
angle = 1 # in degrees
stepsize = 15

for angle_offset in range(0, 360+stepsize, stepsize):
    img = Image.new(mode="RGB", size=(2*r, 2*r), color=(255, 255, 255))

    # draw a sector
    draw = ImageDraw.Draw(img)
    draw.pieslice((0, 0, 2*r, 2*r), start=angle_offset, end=angle_offset+angle, fill=(0, 0, 0))

    # draw a small circle to mark the center
    draw.ellipse((r-1, r-1, r+1, r+1), fill=(255, 0, 0))

    img.save(f"test{angle_offset}.png")
@radarhere
Copy link
Member

Testing, this worked as expected before #4523

@xtsm did you have any thoughts on this?

@xtsm
Copy link
Contributor

xtsm commented Apr 24, 2021

https://github.com/xtsm/Pillow/blob/17d83d6a7c619e87fab84c59860989772fdcdb7d/src/libImaging/Draw.c#L1342
this function builds clipping semiplane tree for pies, the quick and dirty solution would be just add another semiplane that cuts off that spike

xtsm added a commit to xtsm/Pillow that referenced this issue May 2, 2021
xtsm added a commit to xtsm/Pillow that referenced this issue May 2, 2021
@radarhere
Copy link
Member

Thanks for #5460. That is the 'quick and dirty solution' you mention. For the record, does that mean you're aware of a better solution?

@xtsm
Copy link
Contributor

xtsm commented May 3, 2021

Nope. I just don't like the entire "clip ellipse down to an arc with semiplanes" stuff because I suspect there is a better algorithm for drawing arcs. Not sure which exactly though, maybe some generalized path drawing like in cairo, don't have much time to research rn.

If we stick with the current approach, this seems to be a legit solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants