-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add arcVertex() for creating arcs with beginShape()/endShape() #6459
Comments
Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, please make sure to fill out the inputs in the issue forms. Thank you! |
Thanks @GregStanton for the suggestion. I'm inviting the current p5.js Core Stewards to this discussion @limzykenneth, @davepagurek, @ChihYungChang, @teragramgius, @tuminzee, @Zarkv, @robin-haxx, @Gaurav-1306. Please feel free to leave your comments about this feature request. Thank you! |
Great suggestion. I would like to work on this one. Let me get back with details of implementation. |
Amazing! Thank you so much @Gaurav-1306! And thank you to @Qianqianye for bringing the others into the conversation! Verbal version of the tutorial Specification for out-of-range parameters I hope this helps! |
I think this makes sense as a way to increase consistency between modes of drawing shapes. Do you have thoughts on the current API, based on SVG path arc commands, vs something more like the vanilla J's canvas |
Thanks for your feedback @davepagurek! I'm glad you like the naming. I'm also glad you asked about other APIs. I asked myself the same question, and I think it's good to document the rationale here. The problem with SVG's arc command, and how to mitigate it The problem with canvas's The problem with canvas's The benefits of SVG's arc command Footnotes
|
That makes sense. In the MDN example, they also follow up arcTo with lineTo to ensure it always ends at the target point. That might be a way of using an API like the native canvas one while still preserving the quality of ending at the specified point? Aside from the API of arcTo appearing simpler, I'm mostly considering it further because I assume we'll have to end up translating our API into an arcTo command for 2D mode anyway. Although it'll have to be turned into line segments for WebGL, so we'll be doing that part from scratch regardless. I don't have a strong preference, so if there are more issues with a combined arcTo + lineTo, I'm happy to go with the API that you suggested! |
@davepagurek I really appreciate you helping to vet this idea! I think it's always good to thoroughly vet an addition to an API, especially a core feature like this. I'll respond with some additional downsides of Downsides of
In general, I think Implementing As always, I'm eager to hear feedback on any of this! Footnotes
|
Thanks for the link, this will be helpful for implementing later! It looks like
This is a good point. Do you think we can make a version of the API where the elliptical aspects of the command come last and are optional, so that if they're missing we can default them to circular arcs? I assume that will likely be the most common use.
I'm actually not sure why the 2D mode uses Bezier paths. The WebGL mode version just uses trig functions. |
Replying to #6459 (comment) by @davepagurek:
Sure thing! I'm glad that helped.
The The only other option that's obvious to me is to do something like p5's
I got curious, so I did a little digging. It looks like the use of Bézier curves in p5's 2D implementation of Would it make sense to create a separate issue to update p5's implementation of Footnotes
|
I think that all makes sense, thanks for bearing with me and fur such thorough explanations! I think this API looks good to me then. For the 2d implementation of ellipse, making another issue for that would be great, thanks! |
Replying to #6459 (comment) by @davepagurek:
Absolutely! I'm glad I'm not the only one considering the design from various perspectives.
Done: #6485 Do you have a recommendation for the next step? I'm not sure if @Gaurav-1306 has been following the discussion, but they expressed interest in working on the implementation. Hopefully, our discussion will help with that. Here are the most relevant parts:
|
Hey I have been following your discussions and would still like to implement this. Let me understand all that you guys discussed and get back with the implementation details. |
Just a little update |
hello So I have been reading your discussions. I have a few doubts that can help me write a better code.
@GregStanton in your original implementation detail you stated to use the SVG arc command but after the discuss has been over, the conclusion was to use canvas's api
Now the Implementation.
Now regarding the 2D and 3D implementation of the function, do we need to add more parameter(a third vertex to know the location to end in 3D space) to the function or this implementation detail can be understood with SVG api? again sorry for so many doubts and thanks for the help! |
Hi @Gaurav-1306! Thanks for taking a look, and I appreciate your questions! The short answer: I originally suggested that we base the Parameterizations of elliptical arcs: SVG vs. canvasElliptical arcs can be drawn with SVG. They can also be drawn with the native canvas API. However, SVG and the canvas use different sets of parameters.
|
Thanks, @GregStanton for such a great replay, all my confusion is gone. I will start working on the 2D implementation as of now. One last thing, do you think choosing option 1 can help with performance in any way, in option 2 we are using the API two times one for conversation and another one for drawing ellipses. I am comfortable either way but I feel that direct conversation can benefit performance because we are not calling the API two times. |
Hello everyone, while I have been working on the implementation I came up with the following code. Do give your feedback. a request form @davepagurek can you explain to me how should I draw on the canvas, more formally when we use Canvas API, we have to call the
|
@davepagurek
there are few think i don't understand, like if i |
@GregStanton can you can pitch in too, need help🙂 |
Hi @Gaurav-1306! I'll try to answer your questions by walking you through the steps I took to understand the relevant parts of the codebase. I haven't studied all the code in detail yet, but hopefully this will point you in the right direction. Note: I wish I could explain these implementation details more concisely! To help you understand it all, I'll include links to the exact lines of code that I refer to, when possible. Where to put the codeWe can start by investigating the implementations of the existing functions: The 2D caseThe main job of each function:
To be consistent with this organization, you would define Where the drawing happens: To understand how things actually get drawn, we need to track down the 2D version of When we find it, we see that it contains a lot of code. However, much of the code is dedicated to the different modes (POINTS, LINES, TRIANGLES, etc.). Those apply only to What this means for you:
Note: The existing implementation seems to contain dead code. The 3D caseSince you're just working on the 2D case (at least for now), I won't say much about this. I'll just mention where most of the relevant code lives, so that we have a convenient reference for both the 2D and 3D cases. Each function in vertex.js calls out to an internal 3D version by the same name, defined on p5.RendererGL, but these definitions are found in different places:
The 3D versions of How to implement the actual drawing codeEarlier, you asked about performance in relation to the two options I proposed above for converting between parameterizations. In both options, the conversion has to occur. It's just a matter of whether you do it yourself, or whether you call a native canvas function that does it for you. I'm not sure that performance is a major consideration here, but others may have more insight. Regarding your code snippets, I'll make separate comments on each of your approaches below. Automatic conversion: Your snippet with the automatic conversion, which we previously called Option 2, looks like it may work with a few changes:
Mathematical conversion: Your snippet with the mathematical conversion, which we previously called Option 1, is more problematic. One of the problems is that the calculation you're using for Thanks so much for working on this! I know I didn't address every detail, but I hope this comment clears up some confusion! |
@GregStanton I can't thank you enough you take the time to explain things in so much detail. This is not going to be as easy as I thought it would be. Let me read and understand everything. ✌🏻 |
@Gaurav-1306 I'm really glad to help! |
Hi @Gaurav-1306! I just wanted to let you know that I submitted issue #6560, which should help us simplify this part of the codebase. It will probably make sense to resolve that issue first. It'll make it easier to implement Also, if you check out the proof of concept that I shared along with that issue, you'll see that I did already include an implementation of |
Thanks for the update @GregStanton, i will work on that issue and then as you said will come back for the arcvector. |
Update: Oh, wow. I just had a new idea for a different Specifically, we should be able to let the user specify an elliptical arc with commands as simple as
(Just for now, I'm ignoring the 3D case and texture coordinates, for simplicity.) This would be a very nice simplification, and if we adopt the proposal in #6766, it'd mean that
|
I think this is a cool idea, I like the symmetry it has with other APIs! Maybe for comparison, how would it look to draw a rounded rectangle corner with this API? Does it offload a lot of math onto users to generate the three points in a case like that? Also, since beginShape();
vertex(x0, y0);
arcVertex(x1, y1);
arcVertex(x2, y2);
arcVertex(x3, y3);
arcVertex(x4, y4);
endShape(); |
Thanks for your feedback @davepagurek! I'll try to answer your questions concisely. First question
Task 1: Round the corner of a rectangle The original API seems easier to use in this case, as we’d expect, but it's still manageable with the new API for users who know a bit of math. The essential lines of code in each case are copied below, from a couple of quick sketches I made. (The second sketch just uses the Original API: In general, when the user is already thinking of an ellipse in terms of parameters like width, height, and rotation angle, the new API will require them to use extra math to generate points along that ellipse. Task 2: Click on points, and generate an ellipse that passes through them This would be simple with the new API, but for most users, it would be prohibitively difficult with the original API. Summary: Although the new API offloads more math in a common use case, it makes it more likely that users will be able to accomplish both tasks above. Second question
For the sake of this discussion, I'm assuming we'll implement the proposal for the new vertex function API. In that proposal, there is no Another possible benefitWith the new API for Edit: Added the |
For the first question, it seems like we won't really be able to handle both use cases in the same API cleanly, and neither choice would be a regression, so I'm good going with either option. For the second question, I think I may have missed some details about connected segments of different types, so I've left a comment on the vertex function proposal with more info there. The main concern is that by having variable numbers of function calls per segment, it requires something else to mark the start/end of segments (and I think |
Thanks @davepagurek! I'll respond to your points and summarize some of the discussion so far.
|
Reminder: This p5.js tutorial opens by saying "This short tutorial introduces you to the three types of curves in p5.js: arcs, spline curves, and Bézier curves." In the summary, it specifies that "You can’t make continuous arcs or use them as part of a shape." This is something we'd want to update. |
Any progress to push this forward? It would be so useful. |
@TheWhoove We currently plan to implement this feature along with larger vertex refactor in p5.js 2.0. What can be helpful would be to work on a potential proof of concept in the |
Increasing Access
This feature increases access in two main ways:
Most appropriate sub-area of p5.js?
Feature request details
Proposal
Add
arcVertex()
to the set of vertex functions in p5, to address a limitation ofbeginShape()
/endShape()
.The problem
Two of p5’s curve-vertex pairs are incomplete. In the table below, asterisks indicate missing items.
line()
vertex()
quadratic()
*quadraticVertex()
bezier()
bezierVertex()
curve()
curveVertex()
arc()
arcVertex()
*Of the missing items,
arcVertex()
is the most important. Arcs are the only type of SVG subpaths not supported by p5’sbeginShape()
/endShape()
. Without them, p5's most powerful shape-making feature cannot make some of the most basic shapes (e.g. lines and Bézier curves can only approximate circles). This leads to complications for both users and developers.The solution
Provide a new function called
arcVertex()
based on SVG’s arc command. Applications include the following:beginShape()
/endShape()
.Specification of
arcVertex()
The following may serve as a draft reference page and usage tutorial.
Description
Used to draw an arc along a circle or ellipse (oval), from one vertex (point) to another. The arc may be drawn along any ellipse, even one that’s been rotated. (If the ellipse is too small to connect the two vertices, its size is automatically adjusted.)
The first vertex is specified with
vertex()
. The second vertex is specified witharcVertex()
. Both are specified withinbeginShape()
andendShape()
, with no parameter passed tobeginShape()
.The arc itself is specified by indicating the shape and rotation of the ellipse (
w
,h
, andangle
), together with its type (MINOR
orMAJOR
) and its direction (COUNTERCLOCKWISE
orCLOCKWISE
).If
DEGREES
is passed toangleMode()
,angle
may be specified in degrees; otherwise,angle
should be specified in radians. IfRADIUS
is passed toellipseMode()
, the shape parameters are interpreted as half of the width and half of the height:arcVertex(20, 50, ... )
results in an arc drawn along an ellipse of width 40 and height 100.Usage
Syntax
Parameters
Tutorial
Related issues
The text was updated successfully, but these errors were encountered: