edgeofinnerspace's Avatar


21 Feb, 2024 05:02 PM

Need your help with this one. Don't know what I am doing. Trying to make a cymatics plate but on a hexagonal plate not a square one. Currently, I really don't know how to use the random nodes. But ideally, you would set parameters in the top node under the arrow, then run a frame node into the random X and Y nodes inside that network to make the plate "vibrate" and the points all settle on parts that are... nodes! XD I have other equations for this I haven't implemented yet but didn't have time this morning. I am not aware that anyone is doing cymatics on a digital medium. At least I have searched high and low and found nothing. I can't even find the math behind it. Hence why I have mentioned wanted to use my sheet music or midi of it to render my music visually. I think I am onto something.

  1. 1 Posted by edgeofinnerspac... on 21 Feb, 2024 05:08 PM

    edgeofinnerspace's Avatar

    Right now the pattern is glued origin but I was trying to making it bound by edges - and maybe origin and axes too.

  2. 2 Posted by edgeofinnerspac... on 21 Feb, 2024 05:25 PM

    edgeofinnerspace's Avatar

    This is cleaner and I plotted the points with convert range instead.

  3. Support Staff 3 Posted by john on 22 Feb, 2024 03:45 AM

    john's Avatar

    What a cool idea!

    I have also not seen much about digital versions of this. Cymatics is such a delightfully analog phenomenon that most presentations celebrate the fact that no digital special effects are required.

    However, a quick web search did find this:

    I haven't read it yet, but might look into it when I get a chance. I'm not sure how much random input you will need. You could start with a random allocation of particle positions (which you can do with the scatter node or some other alternatives) and then just feed the frame node into some parameterized equations for each X,Y point to let them converge on harmonic lines. With sin waves in the equations they might continue to vibrate naturally. If not you could introduce a little noise with the wiggle node (using the frame as a seed).

    It looks like you've already made good progress, so I'm not sure exactly what you need from me. I suggest you keep noodling, then post again with your progress. If you get stuck on how to do something specific I can probably get you unstuck, but at the moment you are out in front of me.

    Happy vibrating!


  4. Support Staff 4 Posted by john on 22 Feb, 2024 05:51 AM

    john's Avatar


    I couldn't resist and made some modifications to your net to show you one way of getting this thing moving.

    First I published all the parameters from your ampavariance subnet so that we could change them from outside the move net.

    Then, without even trying to understand what any of those parameters control, I hooked up the A, B, M, and N parameters to wave nodes controlled by a frame node.

    This is a fundamental trick that you may find useful in a situation like this. The wave node allows you to gently vary the value of a parameter in a cyclic way. Look at each of the four wave nodes. You will see that each has its own min, max, and period. Each value will swing between its min and max, returning to its starting point every p frames (where p = phase).

    Just to show you how it works, I set phase A to 30, phase B to 40, phase M to 60, and phase N to 120. Notice that all of these divide evenly into 120. I then render the movie from 1 to 120; that way the pattern will seamlessly repeat every 120 frames, with A coming full cycle every 30 frames (a little over a second at 25 frames/sec), B every 40 frames, etc.

    You will get quite different effects depending on the phases you assign to each parameter and the mins and maxes.

    To set the mins and maxes I looked inside your ampavariance subnet and varied each one close to the values you were giving them. I also disconnected the aNet, bNet, mNet and nNet nodes because these were converting continuous values into integers. This is not a problem for a still image, but in an animation this caused the overall pattern to freeze for several frames then jump, resulting in a jerky motion. Removing them allowed a smooth, continuous evolution.

    I made one other change just below the ambivariance node, replacing a switch node with one of my this_or_that nodes. Because the switch node treats each input as a list, the conditionals you were feeding in would cause the overall number of items in the output list to fluctuate. This_or_that is what you really want in this situation. See my documentation of it for more information if you're curious. (Actually, you could simplify this even more by using one of my bounds nodes to place a lower bound on every value coming from Ampavariance.)

    I didn't muck with any of your random nodes, but I suspect you are overcomplicating that aspect. Using one random node to pick the seed of another doesn't give you any more randomness and you don't have to pick hundreds of random numbers if all you want are max values of that list. There are much simpler ways of generating a random scatter of points. Play with the scatter node. You can also try my scatter_bias node.

    I have attached my modified version of your code along with the animation it generates. This is not quite what you want, but should give you some ideas of what you might want to try next. The ultimate solution may look entirely different.

    I'm quite curious to see what you do with this!


  5. 5 Posted by edgeofinnerspac... on 05 Apr, 2024 05:47 PM

    edgeofinnerspace's Avatar

    You actually gave me the AHA moment for one thing I mentioned wanting to do when I first started posting on here. That about setting things at different values for that specific set of phase parameters would help me with the notes in a piece showing interacting with the rest of the notes all falling on a particular beat!

    I am having an off-day. Seems like when something agitates a symptom of one of the things blanketed un ASD another is at a deficit and today that is definitely my articulation...

    What would be a way of showing the geometry in each frame as points connected by lines? Whether it be lines along the nodes or (what I would like to figure out) lines connecting a point to its matching point on the other axis/nodes... so if the surface were a hexagonal plate, then not just an X and Y axis, obviously - and it wouldn't have to be simple regular geometry here.

    Am I correct to assume that if the number of points were greatly reduced and much higher randomness across a surface area larger relative to the point (not rendering point - visually) would even be a good way to find the most key points or - I hesitate to say most important but maybe they would be in terms of their role in actual structure...or is that just me rambling here while I wander inner space because I have no way of rambling in my head?

    And how do I make it to where I can label and treat input for parameters as actual hertz? Not just for musical purposes.

  6. Support Staff 6 Posted by john on 05 Apr, 2024 11:47 PM

    john's Avatar

    This is such an interesting challenge!

    You are in that "groping in the dark" phase where you can't quite articulate even to yourself exactly what you want, let alone think about how to get there. This is a frustrating place to be, but it also the wellspring of all creativity. This is the time when you have no choice but to open yourself to your subconscious and just play. Keep playing, keep stumbling, until light begins to dawn.

    You don't yet have any specific questions for me, so I can only throw out some vague generalities in the hope that will help something converge for you.

    One general observation. Nodebox is at a disadvantage here because it is stateless. I've talked about this in other threads, but I fear the concept may be hard to grasp. Being stateless means that Nodebox nodes can only respond to their direct inputs, with no memory of what happened that last time they fired. They have no internal states that persist and there are no global variables that can affect nodes (unless those variables are directly pumped into their inputs).

    This makes it harder to create a model of the analog wave interference that gives rise to a cymatics plate. With a model you can store each iteration of an evolutionary process and then, with each tick of the clock, create a new generation based on the current state of affairs captured in the previous generation. We can't do that in Nodebox.

    You can pass in a time variable (like a frame node) but you can't ask a node to add 1 to whatever it did last time - because a node had no idea what it did last time. And there are no loops in Nodebox, so you can't feed "last time" into "this time".

    So instead, everything has to parameterized. You have to plot the entire evolution of a process ahead of time as a predetermined equation or curve. THEN you can pass this curve along with the current frame to a node, and the node simply returns the value of that curve for that point in time.

    One (probably naive) way of parameterizing in this case would be to plot a set of fixed "convergence nodes" ahead of time, like maybe the corners of a hexagon, Then scatter dust points on your surface and have them move steadily towards those convergence nodes. Since there is no state, you can't take repeated distance measurements based on their "current position" because there is no current position. Instead, you. could supply a line from the initial position of each dust point to the nearest convergence node and a T value from 0 to 100% (based on the frame). The node then just uses a point_on_path node to calculate its position on that line for that T value.

    (If the predetermined paths are open lines or curves, not closed shapes, you should you instead use a point_in_path node from my node library so points don't snap back to 0 when you give them a T value of 100.)

    That's a basic approach, but to get good results you will probably need to make things a little more complicated. You may need multiple attraction lines for each node so that particles are endlessly pushed and pulled instead of simply sucked into black holes. And instead of linear progress along each attraction line you may need easing functions to accelerate progress as a point draws near the end of its line. (I have an easing node for just this purpose in my library.)

    You could also set up multiple flavors of convergence nodes, each pulling different subsets of particles, possibly cycling using the wave nodes I mentioned in one of my earlier comments but at different periods for each flavor.

    I have no idea if you could get all this to look like a cymatics plate. But even if you can't do that, you're likely to come up with something interesting.

    I hope that helps, at least a little. Keep playing. If I get a chance, I might try following my own advice and, if something interesting happens, share it with you.


Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:


Already uploaded files

  • 3.97 KB

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts


? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac

Recent Discussions

23 Apr, 2024 07:54 PM
19 Apr, 2024 04:41 AM
16 Apr, 2024 06:18 PM
16 Apr, 2024 04:23 AM
08 Apr, 2024 01:28 AM


07 Apr, 2024 11:50 PM
05 Apr, 2024 11:47 PM
05 Apr, 2024 12:30 AM
25 Mar, 2024 08:48 PM
14 Mar, 2024 07:40 PM
14 Mar, 2024 07:38 PM