SVG donut slice as path element (annular sector)

Viewed 5071

Ok so granted, its not a bug, but I am confounded by how to get a perfect circle arc between points via Bézier curve.

I need a shape like this:

enter image description here

So I've been calculating the four corner points like this from the center point, radius and angle with the following formula: (x?,y?)=(x+d cos α,y+d sin α), which in my coffeescript looks something like this:

x1 = centerPointX+outerRadius*Math.cos(currentAngle)
y1 = centerPointY+outerRadius*Math.sin(currentAngle)
x2 = centerPointX+innerRadius*Math.cos(currentAngle)
y2 = centerPointY+innerRadius*Math.sin(currentAngle)
x3 = centerPointX+outerRadius*Math.cos(currentAngle2)
y3 = centerPointY+outerRadius*Math.sin(currentAngle2)
x4 = centerPointX+innerRadius*Math.cos(currentAngle2)
y4 = centerPointY+innerRadius*Math.sin(currentAngle2)

How can I take the information I have and result in a path element with perfect circular curves?

(PS I am newish to SVG and if you want to help me out with the proper syntax for d= that would be cool, but I can always just write it myself. The challenge I would like help with is really more to do with Bézier.

UPDATE / SOLUTION

Using the answer below a guidance below is the function I actually used:

annularSector = (centerX,centerY,startAngle,endAngle,innerRadius,outerRadius) ->               
    startAngle  = degreesToRadians startAngle+180
    endAngle    = degreesToRadians endAngle+180
    p           = [ 
        [ centerX+innerRadius*Math.cos(startAngle),     centerY+innerRadius*Math.sin(startAngle) ]
        [ centerX+outerRadius*Math.cos(startAngle),     centerY+outerRadius*Math.sin(startAngle) ]
        [ centerX+outerRadius*Math.cos(endAngle),       centerY+outerRadius*Math.sin(endAngle) ]
        [ centerX+innerRadius*Math.cos(endAngle),       centerY+innerRadius*Math.sin(endAngle) ] 
    ]
    angleDiff   = endAngle - startAngle
    largeArc    = (if (angleDiff % (Math.PI * 2)) > Math.PI then 1 else 0)
    commands    = []

    commands.push "M" + p[0].join()
    commands.push "L" + p[1].join()
    commands.push "A" + [ outerRadius, outerRadius ].join() + " 0 " + largeArc + " 1 " + p[2].join()
    commands.push "L" + p[3].join()
    commands.push "A" + [ innerRadius, innerRadius ].join() + " 0 " + largeArc + " 0 " + p[0].join()
    commands.push "z"

    return commands.join(" ")   
1 Answers
Related