Search code examples
svgbezier

Is it accurate to conclude the radius of a circle given 4 bazier curves in svg?


I have used svg2paths2, and wanted to figure out what is the position and radius of a circle, I have noticed the circle is consructed by 4 CubicBezier, as follow:

Path(CubicBezier(start=(127.773+90.5469j), control1=(127.773+85.7656j), control2=(123.898+81.8906j), end=(119.121+81.8906j)),
 CubicBezier(start=(119.121+81.8906j), control1=(114.34+81.8906j), control2=(110.465+85.7656j), end=(110.465+90.5469j)),
 CubicBezier(start=(110.465+90.5469j), control1=(110.465+95.3281j), control2=(114.34+99.1992j), end=(119.121+99.1992j)),
 CubicBezier(start=(119.121+99.1992j), control1=(123.898+99.1992j), control2=(127.773+95.3281j), end=(127.773+90.5469j)))

I have read the standard approach is to divide the circle into four equal sections, and fit each section to a cubic Bézier curve.

So I was wondering is it accurate to say the Radius of the circle is

(q1.start.real - q3.start.real)/2

or

(q2.start.imag - q4.start.imag)/2

And the center of the circle is:

c_x = (q1.start.real + q1.end.real) / 2
c_y = (q1.start.imag + q1.end.imag) / 2

Thank you!


Solution

  • I'm assuming you are using svg.path library in python, or svg2paths2 is related.

    from svg.path import Path, Line, Arc, CubicBezier, QuadraticBezier, Close
    
    path = Path(CubicBezier(start=(127.773+90.5469j), control1=(127.773+85.7656j), control2=(123.898+81.8906j), end=(119.121+81.8906j)),
     CubicBezier(start=(119.121+81.8906j), control1=(114.34+81.8906j), control2=(110.465+85.7656j), end=(110.465+90.5469j)),
     CubicBezier(start=(110.465+90.5469j), control1=(110.465+95.3281j), control2=(114.34+99.1992j), end=(119.121+99.1992j)),
     CubicBezier(start=(119.121+99.1992j), control1=(123.898+99.1992j), control2=(127.773+95.3281j), end=(127.773+90.5469j)))
     
     q1 = path[0]
     q2 = path[1]
     q3 = path[2]
     q4 = path[3]
     
    

    .real is the X coordinate
    .imag is the Y coordinate

    There's a very slight error in accuracy in the drawing program you are using and it's not at all an issue unless you want extreme accuracy.

    (q1.start.real - q3.start.real) / 2 # 8.6539 is the radius in this case.
    (q4.start.imag - q2.start.imag)/2 # 8.6543 is also the radius.

    (q1.start.real - q1.end.real) # 8.6539 is again also the radius.
    This accesses the same property, q1 of path and I' prefer it to the two above ways because it's accessing one property not two.

    Below shown by green circle in diagram
    c_x = (q1.start.real + q1.end.real) / 2 # 123.447 not center x
    c_y = (q1.start.imag + q1.end.imag) / 2 # 86.21875 not center y

    Below shown by red circle in diagram
    c_x = q1.end.imag # 119.121 this is center x
    c_y = q1.start.real # 90.5469 this is center y

    To explain how serious the error in accuracy, the pink circle uses 8.6543 radius, below it is 8.6539 in green, perhaps viewable with an extreme zoom. But this does illustrate how important or not the decimal points can be.

    Consider using numbers under 100 and as few decimal points as possible, especially understanding a new idea. Shorter text-length numbers vastly improves readability, understanding no end.
    I often use just numbers below ten.
    Note: you are drawing the circle counter-clockwise. Clockwise is the usual way.

    showing a circle made from four cubic beziers