-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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 randomX
and randomY
functions
#7671
Comments
Thanks for the idea @quinton-ashley ! I've edited the description slightly to make it more precise, hope that's alright: that the aspect of access being addressed in beginner-friendliness. Other aspects of access include web accessibility and internationalization. I'm not sure if beginner-friendliness for new contributors and for new users should be separately stated, but I think this idea affects both! Status: Discussion is open and input is welcome!For all those reading and new to this topic: Please read the below and chime in. Please do not make PRs before there is a decision to implement this and before an assignment (read more in the contribution guidelines) Potential feature for next minor release of p5.js 2.0Right now, we are close to releasing p5.js 2.0 (see timeline), and no new features can be considered for that initial release. After this, new features will be considered for p5.js 2.1 (or later minor releases, like 2.2 and 2.3). Except bugfixes (or similar exceptions), new features will not be considered for p5.js 1.x (even though it will continue to be supported and available until summer 2026). What potential benefits and drawbacks do you see?The prioritization of a feature is not based on popularity directly, but if you want to see this implemented, please do comment! Besides popularity: it matters what the benefits/drawbacks of adding the feature, and the benefits/drawbacks of not adding it. For example, for this one, my thoughts are as follows: 🌸 It sounds like the biggest benefit is that it would make picking a random spot in the sketch the same in WEBGL and in Canvas mode, which is a big plus for beginner-friendliness. 🌸 If we agree to include it, it would also be a Good First Issue for new contributors. especially if it includes adding tests and so on. 🐛 As far as I can tell, the only drawback is that in general adding new features creates more chances for bugs in the future, and more maintenance load. This particular feature is super small, and in canvas mode 🌸 The drawback of not adding this feature would be that switching between WEBGL and canvas mode changes random canvas point behavior. Here's a sketch Do add yours below! |
@ksen0 @quinton-ashley |
@VANSH3104 Good point about |
@ksen0 For randomX(min, max), the idea is to allow users to specify a custom range within the canvas instead of always using the full width. it become easy if we want to positioning elements within a specific section of the sketch. |
@VANSH3104 with min and max, what are the values, what's the range? If values are in pixels, then the Canvas/WEBGL modes will have different interpretations, because |
@VANSH3104 Did you see in the feature request details section that the functions could accept a margin? See example use of https://q5js.org/learn/#randomY Are you suggesting |
@quinton-ashley @ksen0 Thanks for the clarification! I see your point about how Canvas and WEBGL interpret coordinates differently. |
So an alternate use when two number parameters are provided?
Making leftMargin -50 would expand the range from the left edge to the left by 50 and making rightMargin 80 would expand from the right edge to the right. EDIT: The problem is that users might confuse it with min and max bounds given the similarity to |
It's great to see new ideas, and all this discussion! Since this proposal would extend the API, I think this is a good test case for the six API criteria I proposed previously:
The main benefit of the proposed features, to me, is writability (here I'm quoting the proposal):
However, my concern is that this benefit is outweighed by a number of significant costs, which are clearer when we look at the other criteria; @quinton-ashley I'm sorry that this is our first major interaction... I bet you have a ton of other ideas that I'd love! I'm just hesitant about this particular idea. I'll explain why below. ConsistencySingle-argument versionIn Two-argument versionThe issue with Readability, PredictabilityAlthough more concise function calls may seem more readable to those who already understand the functions involved, I think there's an overall loss of readability, since the
ExtensibilityThere is no canvas boundary in the Z direction, so the concept of EconomyThere are always costs whenever we add to the API, so we need to consider whether the benefits outweigh those costs. In addition to technical costs like bug fixing and maintenance, there's a conceptual cost to users. Imagine a software library with only 10 functions. You might think, I can learn this library in a day! Now imagine a library with 10,000 functions. You might quickly be overwhelmed, assuming it will take years to learn the basics. The cost I'm describing is extra conceptual weight. To be clear, a tiny feature count isn't necessarily good. That might mean that a lot of functionality is packed into a small number of features, making those features hard to learn. What we want is a good power-to-weight ratio, meaning roughly that we want to empower users to do a lot without requiring them to learn a lot. Actually, p5's On the other hand, I think that if users can understand a coordinate system, they'd be able to figure out how to get the same effect as |
@GregStanton I agree with your assessment of the two argument use, which I didn't propose and I don't think it should be included. I was struggling to articulate that point more clearly and thankfully you've laid it out nicely. I didn't make a mistake in my explanation though, because range extension from the left margin would require subtraction from the left margin position. Whether -50 or positive 50 would cause expansion from the left margin would be a point of confusion with how it works in CSS. I've since edited the comment to make it clearer that I was merely trying to flesh out that idea, you seem to be under the assumption that I wanted to add that onto the proposal which I don't. You're making a strawman argument. You also didn't sufficiently address 0 argument use, which I'm sure you'd agree is very readable and intuitive: randomX(). Also with single arg use, such as randomX(50), at first glance it's reasonable to assume that the 50 represents something other than just an upper bound extension (not surprising). The margin concept of expanding or contracting from the edges is conceptually straightforward. There's significantly less conceptual weight to what I'm proposing compared to most of the existing math related functions in p5. There are also plenty of functions in p5 that don't offer much additional functionality, but rather are simple shortcuts for common tasks. Though adding functions also adds more for beginners to learn, I think that if we keep the randomX and randomY API simple, the benefits outweigh the cons in this case. Respectfully, I wouldn't have added these functions to q5.js if they didn't meet the criteria for good API. |
@GregStanton I want to clarify that the two-argument version randomX(leftMargin, rightMargin) was my idea. I thought it would help generate random numbers within dynamic margins rather than fixed bounds, making positioning easier in some cases.I agree that it is confusing Simplicity – randomX() is easy to use and adapts to WebGL and canvas modes. I understand @GregStanton concerns about consistency and predictability, and he makes a great point about avoiding confusion. However, I believe that randomX() remains intuitive and useful if kept simple, without the two-argument version. |
I'll try to summarize the current proposed idea, thanks to @VANSH3104 and @quinton-ashley for clarifications, please correct me if I missed something.
@quinton-ashley I think it's really important to be mindful that "criteria for good API" is context specific. @GregStanton's criteria make a lot of sense for p5.js more generally, even if for q5.js a different prioritization makes sense. I really agree with Greg's suggestion to carefully consider adding any functions, even small ones, because it makes the whole library more challenging to maintain with a wide and varied contributor base. This is not to say that the function is not useful - I can see myself using this all the time! - but in the case of p5.js, I think the requirements of economy (in terms of API design) is relatively higher priority than it might be in another situation. Specifically: "It’s a small addition with big usability benefits" - also with additional implementation/maintenance costs of adding unit tests, and updating FES, tutorials, reference potentially with extra explanations to disambiguate with usage of
@GregStanton I feel like potentially there is a benefit to being able to more easily switch WEBGL vs Canvas, but maybe that means we should rather think about how other parts of the API could make that switch more straightforward? Or whether this is a common challenge? SummaryThis seems like a useful feature, and it would be relatively straightforward to add (code + tests + FES updates + associated documentation). However, I do think that the potential for confusion about parameters (even with a single margin parameter) is not dismissable. I think it would be useful to get some more voices in this thread on whether the single-parameter use is useful enough to justify risk of confusion. For those reading: to make this a bit more concrete, here is a sketch that does random placement using |
Good point about z! randomZ is possibly a little different, since there's a clear minimum (has to be in front of the camera!) but the maximum can be quite far away. Is a uniform distribution correct for that? I'm not sure what the answer is there, might take some thought. One other observation is that if you start adjusting depth, the x/y range that is visible changes (less range closer to the camera, more farther.) My thought is that if there's not a clear answer, it's ok to just do x and y at first, since the "correct" range for z might vary per sketch, so we can ask users to do their own range manually at first with the usual random(). |
@ksen0 I agree that any addition to the library should be considered carefully and also appreciate the discussion of additional ideas from @VANSH3104 I understand that whether this proposal is something worth implementing in p5 depends on other factors too. I'd consider these functions as useful shortcuts rather than solving a common "challenge" like @GregStanton I've seen firsthand how I think what's important to consider then, is whether these are shortcuts that users would remember and prefer to use for this task. For example, users could fill a background with |
@davepagurek I hadn't considered that these functions could take rotation into account. In case it isn't clear why they shouldn't, for example in WebGL mode users could rotate the y axis such that the canvas contains an x axis that stretches out to infinity, like the z axis does at the default camera position. My description of the margin parameter "expanding or contracting the range from the canvas edges" is incorrect though if scaling or rotation is applied. Hmm I'll need to think of how to better phrase that. |
@quinton-ashley good point! in a lot of my own sketches where one might apply rotation, I end up using a depth values based on width/height (maybe a max or min.) In that scenario, we already have x/y versions of this function, so someone could maybe just use those. |
This is a great point to consider. I think the sketch you shared clearly shows that, when using the proposed features to generate random coordinates within the bounds of the canvas, it's easier to switch between Canvas and WebGL. I'm not sure how common it is to switch a sketch between renderers like that. Do you have any thoughts on this @davepagurek? If we want to facilitate that kind of switch, I think that considering other parts of the API is a terrific idea, since it opens up many possibilities. As an initial example, the Although I'm not sure whether switching a sketch between P2D and WebGL renderers is common, I do think that conceptual compatibility between Canvas (i.e. the So far, @davepagurek and I have discussed conceptual compatibility on a case-by-case basis, and I took a similar approach in the API audit proposal. For now, I set a reminder to myself to consider incorporating a sub-issue or top-level agenda item aimed at identifying and resolving Canvas vs. WebGL tensions more generally (to the extent possible). |
@VANSH3104 Thanks so much for sharing your thoughts based on the API criteria for p5 that I shared. It's very helpful to see how different people interpret them! I think this shows how they work best as a framework for discussion. |
I think it might be helpful to do a "friendly vibe check" (a helpful phrase I learned from @nickmcintyre a while back). A straw man, by definition, is based on bad intent. I'll assume you didn't mean to imply that, but I'm hoping we can avoid terms like that. I do think I described the proposed ideas accurately, and I did attribute the two-argument idea to @VANSH3104. If I inadvertently implied that you were advocating for the idea, rather than just brainstorming, that's my mistake! Similarly, I hope I didn't imply anything about the API decisions made for q5, as that project exists in a different context. It's always hard to disagree in writing, and in a public forum no less! In general, I think the best we can do is to interpret intentions as generously as possible. Of course, that's easier said than done, especially when our brainchildren are involved 😅 I hope you understand where I'm coming from, and I do look forward to future discussions! With those preliminaries out of the way, I'll try to address each of your points. Margin confusion?
I think this is part of the confusion. In the examples on the q5 site, it looks like a single negative argument causes the range on both sides to be restricted. I think it's reasonable to interpret this to mean that -50 is being applied to the left and to the right. That would imply that applying a negative value to the left edge results in a contraction, rather than an expansion. On the other hand, if we interpret -50 as being added to the left bound, the result would be an expansion. (There's also the possible confusion with CSS padding that we discussed.) Zero-argument case
That's a good point. I do think I'm not sure yet about WebGL mode. In 3D sketches, rotations are an additional complication. Also, In any case, Useful, yes! Also, costs to consider.I agree with @ksen0's assessment completely: "This is not to say that the function is not useful - I can see myself using this all the time! - but in the case of p5.js, I think the requirements of economy (in terms of API design) is relatively higher priority than it might be in another situation." On that note, I'll share a few thoughts about shortcuts in the context of p5. Using existing p5 shortcuts as design guides: benefits and pitfalls
Helpful examplesI think your example of I don't think the functional fixedness issue applies to PitfallsAlthough I think General costs of shortcuts for beginners
I appreciate you being candid about this! I think that whether users would remember and prefer these shortcuts is a great question. My current thinking is that these convenience features might not be a net gain for beginners. This is partly because novices and experts think differently. An expert may see a problem, effortlessly select the most convenient approach from several possible strategies, and execute the approach without mistakes. A beginner may see a problem and struggle to remember one approach without sufficient practice. Or, they might have no strategies to begin with, in which case presenting them with multiple approaches may create more work for them, rather than saving work. I'll expand on each of these points briefly. Cognitive interferenceIntroducing additional approaches may produce cognitive interference effects. For example, in retroactive interference, new memories make it hard to retrieve old memories. Here, learning about Extra workA user who peruses the reference looking for a way to handle randomness will have multiple reference entries to consider; they'll need to assess which is best for their use case and make a decision. This cuts both ways. Although a user looking precisely for the functionality provided by Here's an example. Suppose a user wants to generate random points inside a circle and is looking for a way to do this in p5. The most convenient function for this, in general, would be SummaryI think |
@davepagurek I see your point, and I agree with you. My idea of randomX() can technically be achieved using random() with some additional calculations. While it provides a shortcut, it might not be necessary to extend the API if the same result can be obtained with existing methods. But we should think about it too. Your example about teaching Math.random() vs. random() is a great illustration of how simplifying functions can improve usability. Even if users can figure out the logic with random(), providing a direct and readable function like randomX() could enhance their workflow. @ksen0 whether switching between Canvas and WebGL is a common challenge, I believe that conceptual compatibility between the two is an ongoing issue. Your suggestion to address Canvas vs. WebGL inconsistencies at a broader level is a great idea, as it would help ensure a smoother experience for developers working across both modes. Instead of modifying p5.Renderer, we can provide a helper function to handle this
|
@GregStanton Thanks for the appreciation. Margin Confusion & InterpretationYou bring up a valid point about the ambiguity in margin handling. If a negative argument both reduces the left bound and contracts the range on both sides, that could be confusing. Zero-Argument Case & WebGL Considerationsagree that randomX() and randomY() are intuitive in P2D mode, aligning with random(). However, WebGL introduces additional complexity with dynamic coordinate systems, especially when transformations are involved. Balancing Convience and ApiI align with the concern that while shortcuts can improve usability, they also come with trade-offs:
|
@GregStanton I didn't use the term "strawman argument" to imply ill intent. Although I didn't expect to have such an in-depth discussion on this, I do appreciate it! On the point of adding extra work, that could be said of any part of the API. Users looking to have an image set as the background may be disappointed to find that On the point of cognitive interference, would you agree that generating random values with My question was whether users would remember and prefer to use |
@VANSH3104 That still doesn't make sense. The edges are not fixed in P2D mode either since scaling and rotation can be applied. When the canvas is rotated 90 degrees the x axis doesn't go left to right. What you're suggesting is also longer to write than the current way.
I'd like if we could keep the conversation here focussed on the proposed |
I'm closing this and will make a new proposal based on the feedback you've all given. |
@GregStanton After reflecting more, I think you're right that Even if I avoided false generalization in the function description by adding something like "when no transformations are applied", perhaps not taking transformations into account makes these functions too limited, since then we're back to using I had thought of a new idea that the single input param could be an absolute distance from the initial center of the canvas, but same issue with transformations, interoperability between P2D and WEBGL would go out the window. if (usingP2D) {
$.randomX = (v = $.halfWidth) => $.random(-v, v) + $.halfWidth;
$.randomY = (v = $.halfHeight) => $.random(-v, v) + $.halfHeight;
} else {
$.randomX = (v = $.halfWidth) => $.random(-v, v);
$.randomY = (v = $.halfHeight) => $.random(-v, v);
} Maybe what I was really after was a more convenient way to generate symmetric random values. |
Just catching up on this @quinton-ashley and for what it's worth, the parameter-free version of this I could still imagine being a really nice "Good First Issue" that could help someone add a helpful utility while getting started with contribution (writing tests etc). I feel that beginner-friendliness for contributors as well as users is important, and that includes both creating approachable implementation tasks, as well as inviting folks into the discussion of language/API decisions. So if anyone on this thread wants to open the discussion to a wider conversation and/or if someone thinks something else that could create some sense of interoperability/parity between P2D and WEBGL, please feel free to open a new issue! This was a very interesting discussion, recapping it in any new issue I'm sure could also be a really interesting read. |
Increasing access
This feature could increase beginner-friendliness by making it a bit easier to generate such values as well increase interoperability between P2D and WEBGL mode.
Most appropriate sub-area of p5.js?
Feature request details
I'd like to make a suggestion to add two new functions to p5:
randomX
andrandomY
, which would get random values relative to the dimensions of the canvas and the coordinate system origin (which differs between P2D and WEBGL mode).A margin could be passed as an optional parameter, the distance to extend (positive) or contract (negative) the range from the edges of the canvas.
In WEBGL mode it'd reduce the amount of code needed to do so from this
random(-width / 2, width / 2)
to justrandomX()
which in a large file where this is done many times would make user's code smaller and easier to read imo since the function is intuitively named.The text was updated successfully, but these errors were encountered: