Skip to content

Commit 94e1969

Browse files
committed
Refactored p5 arc to use canvas ellipse
1 parent cc17b64 commit 94e1969

File tree

1 file changed

+24
-83
lines changed

1 file changed

+24
-83
lines changed

src/core/p5.Renderer2D.js

Lines changed: 24 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -532,42 +532,6 @@ class Renderer2D extends p5.Renderer {
532532
// SHAPE | 2D Primitives
533533
//////////////////////////////////////////////
534534

535-
/**
536-
* Generate a cubic Bezier representing an arc on the unit circle of total
537-
* angle `size` radians, beginning `start` radians above the x-axis. Up to
538-
* four of these curves are combined to make a full arc.
539-
*
540-
* See ecridge.com/bezier.pdf for an explanation of the method.
541-
*/
542-
_acuteArcToBezier(
543-
start,
544-
size
545-
) {
546-
// Evaluate constants.
547-
const alpha = size / 2.0,
548-
cos_alpha = Math.cos(alpha),
549-
sin_alpha = Math.sin(alpha),
550-
cot_alpha = 1.0 / Math.tan(alpha),
551-
// This is how far the arc needs to be rotated.
552-
phi = start + alpha,
553-
cos_phi = Math.cos(phi),
554-
sin_phi = Math.sin(phi),
555-
lambda = (4.0 - cos_alpha) / 3.0,
556-
mu = sin_alpha + (cos_alpha - lambda) * cot_alpha;
557-
558-
// Return rotated waypoints.
559-
return {
560-
ax: Math.cos(start).toFixed(7),
561-
ay: Math.sin(start).toFixed(7),
562-
bx: (lambda * cos_phi + mu * sin_phi).toFixed(7),
563-
by: (lambda * sin_phi - mu * cos_phi).toFixed(7),
564-
cx: (lambda * cos_phi - mu * sin_phi).toFixed(7),
565-
cy: (lambda * sin_phi + mu * cos_phi).toFixed(7),
566-
dx: Math.cos(start + size).toFixed(7),
567-
dy: Math.sin(start + size).toFixed(7)
568-
};
569-
}
570-
571535
/*
572536
* This function requires that:
573537
*
@@ -577,64 +541,41 @@ class Renderer2D extends p5.Renderer {
577541
*/
578542
arc(x, y, w, h, start, stop, mode) {
579543
const ctx = this.drawingContext;
580-
const rx = w / 2.0;
581-
const ry = h / 2.0;
582-
const epsilon = 0.00001; // Smallest visible angle on displays up to 4K.
583-
let arcToDraw = 0;
584-
const curves = [];
585-
586-
x += rx;
587-
y += ry;
588-
589-
// Create curves
590-
while (stop - start >= epsilon) {
591-
arcToDraw = Math.min(stop - start, constants.HALF_PI);
592-
curves.push(this._acuteArcToBezier(start, arcToDraw));
593-
start += arcToDraw;
594-
}
595544

596-
// Fill curves
545+
const centerX = x + w / 2,
546+
centerY = y + h / 2,
547+
radiusX = w / 2,
548+
radiusY = h / 2;
549+
550+
// Determines whether to add a line to the center, which should be done
551+
// when the mode is PIE or default, as well as when the start and end
552+
// angles do not form a full circle.
553+
const createPieSlice = ! (
554+
mode === constants.CHORD ||
555+
mode === constants.OPEN ||
556+
(stop - start) % constants.TWO_PI === 0
557+
);
558+
559+
// Fill
597560
if (this._doFill) {
598561
if (!this._clipping) ctx.beginPath();
599-
curves.forEach((curve, index) => {
600-
if (index === 0) {
601-
ctx.moveTo(x + curve.ax * rx, y + curve.ay * ry);
602-
}
603-
/* eslint-disable indent */
604-
ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry,
605-
x + curve.cx * rx, y + curve.cy * ry,
606-
x + curve.dx * rx, y + curve.dy * ry);
607-
/* eslint-enable indent */
608-
});
609-
if (mode === constants.PIE || mode == null) {
610-
ctx.lineTo(x, y);
611-
}
562+
ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, start, stop);
563+
if (createPieSlice) ctx.lineTo(centerX, centerY);
612564
ctx.closePath();
613565
if (!this._clipping) ctx.fill();
614566
}
615567

616-
// Stroke curves
568+
// Stroke
617569
if (this._doStroke) {
618570
if (!this._clipping) ctx.beginPath();
619-
curves.forEach((curve, index) => {
620-
if (index === 0) {
621-
ctx.moveTo(x + curve.ax * rx, y + curve.ay * ry);
622-
}
623-
/* eslint-disable indent */
624-
ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry,
625-
x + curve.cx * rx, y + curve.cy * ry,
626-
x + curve.dx * rx, y + curve.dy * ry);
627-
/* eslint-enable indent */
628-
});
629-
if (mode === constants.PIE) {
630-
ctx.lineTo(x, y);
631-
ctx.closePath();
632-
} else if (mode === constants.CHORD) {
633-
ctx.closePath();
634-
}
571+
ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, start, stop);
572+
if (createPieSlice) ctx.lineTo(centerX, centerY);
573+
if (mode !== constants.OPEN) ctx.closePath();
635574
if (!this._clipping) ctx.stroke();
636575
}
576+
637577
return this;
578+
638579
}
639580

640581
ellipse(args) {
@@ -659,7 +600,7 @@ class Renderer2D extends p5.Renderer {
659600
radiusX = w / 2,
660601
radiusY = h / 2;
661602
if (!this._clipping) ctx.beginPath();
662-
603+
663604
ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, 2 * Math.PI);
664605

665606
if (!this._clipping && doFill) {

0 commit comments

Comments
 (0)