Reputation: 3614
I've drawn an arc made up of individual wedges:
I need to draw an image at the center of each wedge. Using drawImage()
I need to find the canvas coordinates of the center of each wedge.
Initially I thought I could begin drawing another arc that only reaches to the center of the wedge and retrieve the context position, but I don't think that's possible.
I'm no math wiz and I assume this will involve some trig, but I'm not quite certain where to start here. Any advice?
Upvotes: 2
Views: 1196
Reputation:
Here is one way you can do this:
Calculate the average radius by ar = (r1 + r2) / 2
. This will give the center perpendicular to arc's center point.
Calculate the average angle by aa = (a1 + a2) / 2
. This will give the center point between the two wedge edges. Note that this has edge cases (no pun) where the second angle may be smaller than the first angle which will cause the average to "wrap around". Always use a1
for the smallest angle and if a2
is smaller add 360° (or 2 x π in radian) to a2
.
With these two values we can calculate center x and y using:
x = centerX + cos(aa) * ar;
y = centerY + sin(aa) * ar;
var ctx = c.getContext("2d");
var r1 = 100; // inner radius
var r2 = 140; // outer radius
var a1 = Math.PI + 0.1; // start angle
var a2 = Math.PI + 0.6; // end angle
var cx = 150; // arc center point
var cy = 150;
// render the wedge
ctx.arc(cx, cy, r1, a1, a2);
ctx.arc(cx, cy, r2, a2, a1, true);
ctx.closePath();
ctx.stroke();
// calculate center point
var r = (r1 + r2) * 0.5; // avr. radius
var a = (a1 + (a2 > a1 ? a2 : a2 + Math.PI*2)) * 0.5; // avr. angle + special case
var x = cx + Math.cos(a) * r; // use angle and radius for
var y = cy + Math.sin(a) * r; // new center point in wedge
// plot center point
ctx.fillStyle = "red";
ctx.fillRect(x-1, y-1, 3, 3);
<canvas id=c></canvas>
Edge case:
var ctx = c.getContext("2d");
var r1 = 100;
var r2 = 140;
var a1 = Math.PI * 2 - 0.2;
var a2 = 0.4;
var cx = 150;
var cy = 75;
// render the wedge
ctx.arc(cx, cy, r1, a1, a2);
ctx.arc(cx, cy, r2, a2, a1, true);
ctx.closePath();
ctx.stroke();
// calculate center point
var r = (r1 + r2) * 0.5;
var a = (a1 + (a2 > a1 ? a2 : a2 + Math.PI*2)) * 0.5;
var x = cx + Math.cos(a) * r;
var y = cy + Math.sin(a) * r;
// plot center point
ctx.fillStyle = "red";
ctx.fillRect(cx, cy, 200, 1);
ctx.fillText("0°", cx, cy - 2);
ctx.fillRect(x-1, y-1, 3, 3);
<canvas id=c></canvas>
Upvotes: 3