Search code examples
svggeometryclipping

Draw a circle divided in two by chord


I want to create an svg like that:

enter image description here

So, a circumference divided into two parts by a chord. The two sections must have different colors.

I want to draw this object in SVG. I think I need to use the PATH tag, right? Or is there another way to do it? What points do I need to draw the object? I'm a bit confused..


Solution

  • Yes. It is a <path> element that you will need.

    Paths always start with an M (move) command. You'll also need an A (arc) command, and probably an L line command for the line that bisects the circle.

    For the arc command, you just need to know the X and Y coordinates of the start and end points (B and C). Plus the radius of the circle. It is important to have accurate coordinates for the start and end points of an arc command. Small discrepancies can cause the position of the circle to move around quite a bit.

    In the following demo, I have chosen to calculate the B and C positions based on their angle from the centre. Plus setting the path description attribute from code, allows me to document for you what each of the parameters are for.

    // Radius of the circle
    var radius = 80;
    
    // Centre coordinate of the circle
    var Ox = 100;
    var Oy = 100;
    
    // Angles of each point from which we calculate their X and Y coordinates.
    // Here, 0 degrees is East, and angle increases in a clockwise direction.
    var angleB = 285;  // degrees
    var angleC = 35;
    
    var B = angleToCoords(angleB, Ox, Oy, radius);
    var C = angleToCoords(angleC, Ox, Oy, radius);
    
    // Get the "major segment" path element
    var majorPath = document.getElementById("major");
    
    // Set the path description for the "major segment"
    majorPath.setAttribute("d", ['M', B.x, B.y,         // Move to point B
                                 'L', C.x, C.y,         // Line to point C
                                 'A', radius, radius,   // X radius and Y radius of the arc
                                      0,                // ellipse angle
                                      1,                // large arc flag (1 indicates we want the larger of the two possible arcs between the points
                                      1,                // clockwise direction flag
                                      B.x, B.y,         // arc end point is back at point B
                                 'Z'].join(" "));       // Z command closes the path
    
    // Get the "minor segment" path element
    var minorPath = document.getElementById("minor");
    
    // Set the path description for the "minor segment"
    minorPath.setAttribute("d", ['M', B.x, B.y,         // Move to point B
                                 'A', radius, radius,   // X radius and Y radius of the arc
                                      0,                // ellipse angle
                                      0,                // large arc flag (0 indicates we want the smaller of the two possible arcs between the points
                                      1,                // clockwise direction flag
                                      C.x, C.y,         // arc end point is at point C
                                 'L', B.x, B.y,         // Line to point B
                                 'Z'].join(" "));       // Z command closes the path
    
    
    // Function to convert from an angle to an X and Y position
    function angleToCoords(angleInDegrees, centreX, centreY, radius)
    {
      var angleInRadians = angleInDegrees * Math.PI / 180;
      return {
        'x': centreX + (radius * Math.cos(angleInRadians)),
        'y': centreY + (radius * Math.sin(angleInRadians))
      }
    }
    path {
      stroke: black;
      stroke-width: 1;
    }
    
    #major {
      fill: #78dcdc;
    }
    
    #minor {
      fill: #aaffaa;
    }
    <svg width="200" height="200">
    
      <path id="major" d="" />
      <path id="minor" d="" />
    
    </svg>