p5.js icon indicating copy to clipboard operation
p5.js copied to clipboard

Refactor arc and rect to use canvas methods rather than curves

Open ksen0 opened this issue 1 year ago • 2 comments

Resolves #6485

Changes:

  • in Renderer2D arc, use canvas ellipse, removing the need for _acuteArcToBezier
  • in Renderer2D rect, use canvas roundRect when there are rounded corners, rater than ArcTo

Screenshots of the change:

image

SCREENSHOT: Same code running with current p5 (left) and locally (right) demonstrating visual equivalence for rect with different rounded corners, one of them clipped.

PR Checklist

  • [x] npm run lint passes
  • [x] [Inline documentation] is included / updated
  • [ ] [Unit tests] are included / updated

No additional unit tests have been included*. Manual testing was done with all the standard examples from the p5 documentation on both arc and rect as well as some additional edge cases, like too-big corner radii (as in the screenshot above) and arc start/end values outside of (0, TWO_PI) range (this is currently not breaking usage and so should not become breaking usage).

Where out-of-domain parameters to canvas rendering context method is the source of the error, the error provided by p5 will reflect the different function usage:

image

SCREENSHOT: ~Same code running with current p5 (left) and locally (right) demonstrating difference between bad rect input of negative radius. The p5 error provides the canvas error, which is different due to refactor, and the new error is not caught correctly. I am not sure where to update the corresponding code.~ Edited to add: sorry, the nice error is just in the p5 editor. In plain browser, both errors are equally uncaught, just the name of the function is different.

*There is an idea in the original issue discussion to use visual automated tests (https://github.com/processing/p5.js/issues/6485#issuecomment-1783671690: "...the idea is to run sample input through p5's current implementation of ellipse and create an image from that. Let's call this the base image. Then, you run the same input through your implementation and create another image. Let's call that the compare image. The test does a pixel-by-pixel comparison of the base image and the compare image. If there's a difference, the test fails.") which I think would be really good, and I would be happy to work on that, but it seems like a separate Issue/PR for workflow enhancement.

ksen0 avatar Sep 03 '24 05:09 ksen0

🎉 Thanks for opening this pull request! Please check out our contributing guidelines if you haven't already. And be sure to add yourself to the list of contributors on the readme page!

welcome[bot] avatar Sep 03 '24 05:09 welcome[bot]

I added some more inline comments, as it was a bit confusing to think about intended stroke behavior. Here are some of my test cases for comparison:

// rotates around, does not fail despite increasing angle values
// no stroke to close the "pie"
arc(200,150,50,80, frameCount/10, PI * 1.5 + frameCount/10); 

// there is no line, it is visually equivalent to an ellipse or CHORD mode
arc(500, 580, 200, 80, 0+0.3, 2*PI+0.3, PIE);

// there is a line from center to the right. No visible sliver of the pie
arc(300, 580, 200, 80, 0, 2*PI-0.001, PIE);

And of course pacman example:

let biteSize = PI / 16;
let startAngle = biteSize * sin(frameCount * 0.1) + biteSize;
let endAngle = TWO_PI - startAngle + TWO_PI*8;
arc(500, 500, 200, 80, startAngle, endAngle, PIE); 

ksen0 avatar Sep 03 '24 06:09 ksen0

Looks good. Thanks!

limzykenneth avatar Sep 12 '24 16:09 limzykenneth