incredi_imp
incredi_imp

Reputation: 75

How to find the centroid of an arc slice when the slice does not start at angle 0?

I'm trying to find the centroid of each slice in a pie chart. Assuming the center of the circle is the origin, how do I calculate the x and y coordinates of the centroid of each slice?

I have the radius, start angle, and end angle of each slice.

I know how to calculate the centroid of a slice when that slice's starting angle is 0; that's answered here. But this assumes you have the angle alpha of the slice, starting at 0 (which JavaScript assumes is the place normally thought of as pi/2). I want the coordinates of, for example, the centroid of the red slice in this photo:

pie chart.

Let's say the angle alpha of the red slice is 1 radian (for simplicity, startAngle = 6 and endAngle = 5, this isn't exact but close to the actual angles in the photo) and the radius of the chart is 400px. Using the formula, xbar = (2/3)(r/a)sin(a) = (2/3)(400/1)(.84147) = 224.39226px which would be ~225px to the right of the origin, nowhere near the actual x coordinate of the centroid because the formula assumes the start angle of the slice is 0.

Also, the starting point being the coordinates of pi/2 and not 0 may contribute to the problem? I'm not sure.

How do I find the actual x coordinate of the centroid?

Upvotes: 1

Views: 893

Answers (1)

incredi_imp
incredi_imp

Reputation: 75

Thanks to Ben West's comment, I was able to determine the answer. You have to rotate the point around the center point of the circle startAngle radians.

Also note if using JavaScript that the circle starts at pi/2 and rotates clockwise instead of counterclockwise like the sin and cos functions, so you have to account for that.

Code:

computeCentroid(slice, chart) {
    const startAngle = slice.startAngle - (Math.PI / 2), endAngle = slice.endAngle - (Math.PI / 2);
    const alpha = endAngle - startAngle;
    const radius = chart.radius;

    // get coordinates of centroid if startAngle = 0
    const xbar = (2 / 3) * (radius / alpha) * Math.sin(alpha);
    const ybar = (-2 / 3) * (radius / alpha) * (Math.cos(alpha) - 1);

    // rotate coordinates about (0, 0) by startAngle
    const xCoord = xbar * Math.cos(startAngle) - ybar * Math.sin(startAngle);
    const yCoord = ybar * Math.cos(startAngle) + xbar * Math.sin(startAngle);

    return [xCoord, yCoord];
}

Upvotes: 1

Related Questions