JuliaGraphics / Luxor.jl

Simple drawings using vector graphics; Cairo "for tourists!"

Home Page:http://juliagraphics.github.io/Luxor.jl/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Small circles does not have enough precision

hyrodium opened this issue · comments

MWE

using Luxor

@svg begin
    setline(0.1)
    for r in 1:10
        circle(Point(0, 0), r, action = :stroke)
    end
    sethue(1,0,0)
    rotate(deg2rad(22.5))
    for r in 1:10
        circle(Point(0, 0), r, action = :stroke)
    end
end 50 50 "b.svg"

Generated image:
b

Magnified image:
image

There are 10 circles in the image, and the small five circles does not have enough precision.

Detail

There are four bezier segments for circles with a radius larger than 5, but if the radius is less or equal to 5, the number of segments will be two.

The following image is a screenshot with Inkscape.
image

I think this behavior is due to Cairo because the circle function just calls Cairo.arc(_get_current_cr(), x, y, r, 0, 2pi).

Luxor.jl/src/curves.jl

Lines 3 to 11 in 375bb99

function circle(x::Real, y::Real, r::Real;
action = :none)
if action != :path
newpath()
end
Cairo.arc(_get_current_cr(), x, y, r, 0, 2pi)
do_action(action)
return (Point(x, y) - (r, r), Point(x, y) + (r, r))
end

How to fix

Update the definition of circle will solve the problem.

function circle(x::Real, y::Real, r::Real;
    action = :none)
    if action != :path
        newpath()
    end
    Cairo.arc(_get_current_cr(), x, y, r, 0, pi/2)
    Cairo.arc(_get_current_cr(), x, y, r, pi/2, pi)
    Cairo.arc(_get_current_cr(), x, y, r, pi, 3pi/2)
    Cairo.arc(_get_current_cr(), x, y, r, 3pi/2, 2pi)
    do_action(action)
    return (Point(x, y) - (r, r), Point(x, y) + (r, r))
end

image

If this fix is the right way, I'm happy to make a PR!

Good idea! These circles are pretty small - I wonder whether the Cairo routines (https://github.com/ImageMagick/cairo/blob/main/src/cairo-arc.c might be the one) aren't so accurate for very small radii...

Anyway, your suggested code/fix looks good!

@hyrodium I'm going to get another release out this week - do you want to make a PR for these circles?

Sorry for the late reply. I opened #269!

Cool! Thanks!

I'll add a closepath() as well so that the path ends are correctly mitred...

Screenshot 2023-09-06 at 09 15 55