1

I am trying to draw equal sectors of a circle by using <svg> and <path> elements. I did some searching to find the maths on how to calculate the coordinates of a point on a circles circumference given the radius and the angle of the sector that you are moving through and I found a good answer here. I have modified it slightly to use the "percentage around the circle" which essentially just sums up the previous sectors angles.

It looks as if the x and y coordinates that I am calculating are incorrect when looking at the rendered page, but using console.log() shows that the values are correct and match up to what I have done by hand (with a calculator of course).

Here is my React component code:

export default function CircleEqualSectors({ radius, numSectors }) {

  const diameter = radius * 2

  /* Using 2Pi Radians here, not 360 degrees */
  function getCoordinatesForPercent(percent) {
    const x = Math.cos(2 * Math.PI * percent) * radius
    const y = Math.sin(2 * Math.PI * percent) * radius
    return [x, y]
  }

  var sectors = []
  let cumulativePercent = 0
  const percentRoundCircle = 1 / numSectors
  for (let i = 0; i < numSectors; i++) {
    const [startX, startY] = getCoordinatesForPercent(cumulativePercent)
    cumulativePercent += percentRoundCircle
    const [endX, endY] = getCoordinatesForPercent(cumulativePercent)

    const xAxisRotation = 0
    const largeArcFlag = percentRoundCircle > 0.5 ? 1 : 0
    const sweepFlag = 0
    const pathData = [
      `M ${radius} ${radius}`, /* Move to centre of circle */
      `L ${startX} ${startY}`, /* Draw line to first point */ 
      `A ${radius} ${radius} ${xAxisRotation} ${largeArcFlag} ${sweepFlag} ${endX} ${endY}`, /* Draw arc to next point */
      `L ${radius} ${radius}` /* Draw line back to centre of circle */
    ].join(' ')
    sectors.push({ key: i, pathData: pathData })
  }

  console.log(sectors)

  return (
    <div>
      <svg height={diameter} width={diameter}>
        <circle r={radius} cx={radius} cy={radius} fill="grey"/>
        <path d={sectors[0].pathData} stroke="red"/>
        <path d={sectors[1].pathData} stroke="red"/>
        <path d={sectors[2].pathData} stroke="red"/>
        <path d={sectors[3].pathData} stroke="red"/>
        <path d={sectors[4].pathData} stroke="red"/>
        <path d={sectors[5].pathData} stroke="red"/>
        <path d={sectors[6].pathData} stroke="red"/>
        <path d={sectors[7].pathData} stroke="red"/>
        <path d={sectors[8].pathData} stroke="red"/>
        <path d={sectors[9].pathData} stroke="red"/>
        <path d={sectors[10].pathData} stroke="red"/>
        <path d={sectors[11].pathData} stroke="red"/>
        {/* {sectors.map((sector) => {
          <path d={sector.pathData} stroke="red"/>
        })} */}
      </svg>
    </div>
  )

Use the code above and only render individual sectors to see their odd shape. The sector that looks "the most correct" is sector[1] but that still doesn't go out to the full radius of the circle. I'm really not too sure what is incorrect here as I have calculated the coordinates myself and printed them to console and they match up.

I used this documentation to see how to use the Arc command in <path>

EDIT: Here are some results (not all of them, the code is there if you want to see each individual sector that is generated. I want 12 sectors.)

The screenshots are individual sectors 0 to 4 and the final image is of all the sectors rendered at the same time.

sector 0 sector 1 sector 2 sector 3 All sectors (0-11)

Mo0rBy
  • 165
  • 2
  • 15
  • It would be easier to answer if we could see what this generates. – James Apr 02 '23 at 17:25
  • @James I've added some screenshots of some of the individual sectors as well as all of the sectors. If you want to see each individual sector, the code is all there for you to copy/paste. The question would be far too large if I added screenshots for each individual sector (aiming for 12) – Mo0rBy Apr 02 '23 at 17:45
  • `getCoordinatesForPercent` should add the center-x/center-y values (probably equivalent to `radius`) - see https://stackoverflow.com/a/18473154/535480 – James Apr 02 '23 at 18:17
  • @James Ahhhh thank you kind sir! That was the problem! – Mo0rBy Apr 02 '23 at 18:50

1 Answers1

0

As James pointed out in the comments of the question, I needed to add the the x and y coordinates of the center of the circle in the getCoordinatesForPercent() function so it looks something like this: (in my case, the radius gives this coordinate as the edge of the circle is at the edge of my page)

  function getCoordinatesForPercent(percent) {
    const x = radius + (Math.cos(2 * Math.PI * percent) * radius)
    const y = radius + (Math.sin(2 * Math.PI * percent) * radius)
    return [x, y]
  }

enter image description here

Mo0rBy
  • 165
  • 2
  • 15