javascriptsvgautomatic-ref-countinground-rect

SVG arc zone in a circle


I'd like to get something like that in SVG. So far I've made the circles but I want to positionate correctly the black zone around.

An API returns four values:

Here is a scheme of what I want: enter image description here

I'm making the SVG with Javascript so my code is something like this:

    var myArc = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    myArc.setAttribute('fill', 'black');
    myArc.setAttribute('d', 'M-'+outer_radius+',32A'+outer_radius+','+outer_radius+' 0 0,1 -'+outer_radius+',-32L-'+inner_radius+',-30A'+inner_radius+','+inner_radius+' 0 0,0 -'+inner_radius+',30Z');// TODO
    arcs.appendChild(myArc);

This can draw a single zone but I don't know what values to put in. I've tried to determine the point to use but it doesn't work:

var pointA = [outer_radius * Math.cos(start_angle * 180 / Math.PI), outer_radius * Math.sin(start_angle * 180 / Math.PI)];
var pointB = [outer_radius * Math.cos(end_angle * 180 / Math.PI), outer_radius * Math.sin(end_angle * 180 / Math.PI)];
var pointC = [inner_radius * Math.cos(end_angle * 180 / Math.PI), inner_radius * Math.sin(end_angle * 180 / Math.PI)];
var pointD = [inner_radius * Math.cos(start_angle * 180 / Math.PI), inner_radius * Math.sin(start_angle * 180 / Math.PI)];

Could you help me to solve this issue ?

Thanks for your help.


Solution

  • I assume you can define the center point. If so, try the following(it uses degrees) and draws two seperate arcs, inner and outer. But you can get the start and end points of each. The path is drawn in 4 parts:

    1) the outer arc

    2) bridge between start outer and begin inner arc

    3) the inner arc

    4) the inner arc end to the outer arc end

    Note: the fill-rule=evenodd for the path

    Edit:Added ArcSweep

    function drawInnerOuterArcs()
    {
        var centerX=200
        var centerY=200
        var innerRadius=120
        var outerRadius=160
        var startAngle=310 //--degrees
        var endAngle=30 //--degrees
        var ArcSweep = endAngle - startAngle <= 180 ? "0" : "1";
    
        function polarToCartesian(centerX, centerY,radiusX, radiusY, angleInDegrees)
        {
            var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
            return {
            x: centerX + (radiusX * Math.cos(angleInRadians)),
            y: centerY + (radiusY * Math.sin(angleInRadians))
            };
        }
        //---outer points---
        var StartPnt1 = polarToCartesian(centerX, centerY, outerRadius, outerRadius, startAngle);
        var EndPnt1 = polarToCartesian(centerX, centerY,  outerRadius, outerRadius, endAngle);
    
        //---outer arc: begin path---
        var d1 = [
        "M", StartPnt1.x, StartPnt1.y,
        "A", outerRadius, outerRadius, 0,ArcSweep, 1, EndPnt1.x, EndPnt1.y
        ].join(" ");
    
        //---inner points---
        var StartPnt2 = polarToCartesian(centerX, centerY, innerRadius, innerRadius, startAngle);
        var EndPnt2 = polarToCartesian(centerX, centerY,  innerRadius, innerRadius, endAngle);
    
        //---start bridge--
        d1+="M"+ StartPnt1.x+" "+StartPnt1.y+"L"+StartPnt2.x+" "+StartPnt2.y
    
        //---inner arc---
        var d2 = [
        "A", innerRadius, innerRadius, 0,ArcSweep,1, EndPnt2.x, EndPnt2.y
        ].join(" ");
    
        //--end bridge--
        d2 +="L"+EndPnt1.x+" "+EndPnt1.y
    
        //---arc fill-rule="evenodd"
        myArc.setAttribute("d",d1+d2)
    }