We are about to switch to a new forum software. Until then we have removed the registration on this forum.
hi guys,
I'm trying to draw a grid (sort of) with p5js, but I'm not sure what to look for. Right now I'm just double looping through an array of particles and displaying them, but perhaps vertices work better(?).
Anyhow, I have this picture:
As you can see it's not a grid, because on the left the particles are bigger then on the right and there are more. I'm sure some tricky math is involved, any pointers would be appreciated :)
the actual goal is to draw them, apply forces and dynamically animate them with the p5 sound library
Answers
It's just 3d, so all the tricky maths you're worried about would be handled by p5: just spread your grid along the z axis and position the 'camera' as required.
Having said that using full 3d may be more computationally expensive, and producing pseudo 3d to match this isn't so hard...
Hi blindfish, thanks for answering! I heard 3d before, so this might be easiest way to accomplish it. What do you mean with pseudo 3d?
ok so i changed the renderer which makes other functionality unavailable (like stroke, ellipse, etc). Does anyone have a mathematical solution to this? :-B
@flowen - what I meant by 'pseudo 3d' is using a simple formula to give the impression of 3d; but rendering with the 2d graphics engine. IIRC 3d in p5js is still in its early stages (haven't looked into it as it's not a priority); which may explain the limitations you discovered.
If you don't need things like 3d shading; complex depth sorting etc. (looking at your example image you don't) then pseudo 3d is a good option as it's relatively simple to implement and probably less processor intensive. I've used it in the past in Flash and there's an excellent explanation in Actionscript Animation: a book I can't recommend enough since many of the principles apply whatever the language you're coding in...
@blindfish thanks so much for your answer! Right now i'm diving into the nature of code books and courses on Kadenze. I don't think it covers pseudo 3d, but I'll have a look at your recommendation. Thanks again!
Since I like to put the advice I give to the test; here's a simplified implementation that could do with some refinement (using instance mode):
Remove noStroke() in draw and move the mouse to the left to see why this won't always deliver convincing 3d. Even that issue can be resolved if need be...
You'll want to shift the 'vanishing point' down to get the effect you want; but I didn't get as far as incorporating that...
edit: updated code with comments...
Here is an example of a sphere in different Z pos using 3D:
I hope this helps,
Kf
@blindfish wow thanks so much for that answer, I'm trying to wrap my head around the code. So I commented it and have some further questions if you don't mind :)
offtopic: for some reason I can't get the syntax highlighter to work, I'm using this one https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code
@kfrajer thanks! But I'm looking for a 2d solution in p5
@flowen. I've updated my code example above with some explanatory comments. The vanishing point code is doing the reverse of what I would expect. It's a while since I did anything in Flash so I'll have to remind myself if there are any differences in its coordinate system that would explain this.
Ultimately you're just applying fairly arbitrary calculations to do linear, consistent scaling (of size and position) along a separate 'axis'.
If the intention is minimize global context "pollution", why create another global property called $p? :-/ Simply instantiate p5 w/
new
w/o assigning the returned object to any variable or property. B-)@GoToLoop: I imagine you already know that this is accepted practice for most JS libraries: jQuery
$
, underscore_
etc. give you a single global variable from which you access their methods.From what I've seen of your code you avoid the need for a single global by passing references to the p5 instance around as a parameter in function calls. I prefer a single global variable...
Yup! The parameter p from
new p5(function (p) {
is itself a reference to thenew p5
object instance.Therefore parameter p is sketch's
this
. And we can usethis
in place of p if we wanna.So when some external class needs to access the sketch's reference or canvas too, it should request it from its constructor & store it. That's exactly what 3rd-party libs do in Processing's Java Mode btW. ~O)
AFaIK
$
&_
are function constructors rather than instances of those corresponding libraries. :-?And they're still constructors even though keyword command
new
isn't necessary for them btW. :PIn the same vein, p5.js'
p5
is also a constructor for the library. :>That makes your global
$p
an instance of class p5, not an actual constructor like the others.Another issue is that external classes would need to assume there's some global variable named $p instead of choosing its name internally. A serious coupling issue. 8-X
Even worse, if we create another p5 instance object, what'd be the name for that next global variable now? How would external 3rd-party classes get access to that new instance same way as the 1st $p? :-O
Interesting discussion, having p5 run in it's own scope is important I guess, but kinda offtopic ;)
Still trying to find how to shift the 'vanishing point', but I have the feeling it requires a totally different formula. Although if we multiply the scale var with a negative 1 we get the reversed result, I don't seem to get it when mapping the values to -.5 and .5.
Right now i'm faking it, by making 2 grids and stack them on top of each other ;)
@flowen: haven't had a chance to look into this until now. The solution was to apply and offset - based on the vanishing point - to the 3D coordinate system:
This produces quite nice results. Probably not super-accurate 3D; but good enough :)
As to the off-topic discussion: IMHO it's all a question of personal coding style. The global reference works well enough for me when I'm only working with a single sketch (most of the time) and is analogous to how I work with other libraries; regardless of what's happening internally. I find it odd to create an object instance without having an explicit reference... Others don't :-?
@blindfish - this is so awesome, thanks so much! I was thinking of an offset, but didn't do it in the proper way so just assumed it must be some other formula. Learned a lot from you, thanks again!