Description
Increasing access
Improve writability and readability for generating random positions
Most appropriate sub-area of p5.js?
- Accessibility
- Color
- Core/Environment/Rendering
- Data
- DOM
- Events
- Image
- IO
- Math
- Typography
- Utilities
- WebGL
- Build process
- Unit testing
- Internationalization
- Friendly errors
- Other (specify if possible)
Feature request details
Proposal to add a function to p5.js that'd make it a bit easier for users to generate random positions.
In P2D mode, generating random positions anywhere within the bounds of the canvas, when no transformations are applied, is pretty simple.
circle(random(width), random(height), 10);
But generating symmetric random values around a point, such as the transform origin (initially at the center of the canvas in WEBGL mode), requires subtraction (ex. random(10) - 5
) or defining lower and upper bound params in random
(ex. random(-5, 5)
). With small numbers this is a non-issue, but when working with variables, you can see that the length of the equation or function call increases linearly.
circle(random(width) - width / 2, random(height) - height / 2, 10);
The length of the line could be cut down by defining variables like this:
let hw = width / 2;
let hh = height / 2;
circle(random(-hw, hw), random(-hh, hh), 10);
If the user wanted to add a margin of 100 pixels from the canvas edges, where random points should not be placed, they could do so like this:
let hw = width / 2 - 100;
let hh = height / 2 - 100;
circle(random(-hw, hw), random(-hh, hh), 10);
Here's another approach using the existing p5.Vector
API:
let pos = p5.Vector.random2D();
circle(pos.x * width / 2, pos.y * height / 2, 50);
But I'd prefer if this effect was achievable inside a function like circle
as a clean one liner.
Previously I'd proposed randomX
and randomY
functions, with separate implementations for P2D and WEBGL mode to attain the same visual result of making a random point within the bounds of the canvas, when no transformations are applied.
circle(randomX(), randomY(), 10);
Margin of 100 pixels:
circle(randomX(-100), randomY(-100), 10);
But to summarize the discussion in issue #7671, numerous problems with the proposal were found:
- the functions could not be described in simple enough terms
- zero param use is very limited in its applicability, considering it doesn't account for transformations
- when a single param (margin) is given, it could be mistaken for an upper bound like with
random
- the effect of margin signage (whether it causes the range to expand or contract) was another point of confusion given that CSS margins kinda work the opposite way
Now I also think it's strange in principle for math functions to have different implementations and return different values depending on which renderer is being used. So perhaps interoperability shouldn't be a goal here and seemingly can't be if greater flexibility is a priority.
I've thought up another function that simply generates symmetric random values. Yet, the name randomSymmetric
is too long, it'd defeat the purpose. The short form randSym
is also awful due to its similarity to the words "rancide" and "ransom".
jit(amount)
What about the name jit
?
The full name jitter
would be a fine too but ideally the shorter the better for this. No other words in English start with "jit" besides "jitney". For the seasoned programmers among us the acronym JIT Just-In-Time will come to mind but it'll be clear from how the function is used that that meaning doesn't apply.
Jitter is uncontrolled deviation from a signal. I think it's a fitting metaphor for random variation around 0 or whatever the result of jit
is being added to.
EDIT: Jitter is also common vernacular: "First day jitters", "do the jitterbug", "the camera is jittering", etc.
Implementation
function jit(v) {
return random(-v, v);
}
Examples
Example of adding circles within a jitter range around the mouse position.
// using `random`
function setup() {
createCanvas(200, 200);
}
function draw() {
circle(mouseX + random(-3, 3), mouseY + random(-3, 3), 5);
}
// using `jit`
function setup() {
createCanvas(200, 200);
}
function draw() {
circle(mouseX + jit(3), mouseY + jit(3), 5);
}
Creating a random x position in p5's WEBGL mode.
// using `random`
function setup() {
createCanvas(200, 100, WEBGL);
}
function draw() {
circle(random(width) - width / 2, 0, random(50));
}
// using `jit`
function setup() {
createCanvas(200, 100, WEBGL);
}
function draw() {
circle(jit(width / 2), 0, random(50));
}
Summary
Though not as common as using random
to generate values within a range with defined lower and upper bounds, jit
would be a very small but useful addition to p5.js that provides a more convenient way to fulfill a common need with broad applications. Though jit
is certainly something users could easily implement manually as a helper function in their own code, my guess is they probably wouldn't consider doing so (I never have either). If jit
was a p5 library function that becomes familiar to the community, using it could become a no-brainer though.
jit
is one dimensional for simple use when specifying input params for other functions. EDIT: (mistake removed)
However, functions for generating a random point within a unit circle or unit sphere could be worth adding to p5 as well.
https://docs.unity3d.com/6000.0/Documentation/Manual/class-random.html
Thoughts on this?