Modeling rotating hanging bead chains

HOLY CRAP - I’m simply blown away! Thanks so much!! I know I have a long ways to go before I even remotely grasp what’s going on, and the limitations of accurately modeling real world objects like bead chain - but the speed with which you created and shared this is amazing. I’m new to Kangaroo, and have only limited experience with Grasshopper, but I’m looking forward to diving in. I haven’t been able to leave my computer all day since I started messing with it:


There’s a plugin for Grasshopper that lets you connect to devices called FIREFLY

It would be cool to see the real thing move alongside the Kangaroo simulation all from the same slider!

Thanks for that suggestion! I am very comfortable with Arduino for control of both LEDs and actuators. It would indeed be cool to see real and simulation from the same slider.

Now that I’ve played with your routine a bit, I’m starting to get a “feel” for the parameters of the Bouncy Solver and Collider. And I think, given your C# script, as well as @dave_stasiuk’s example, I could devise a scheme to stream in a list of anchor moves (but still on the circle) that would emulate my “profile playlist” strategy with the real prototype. But one thing seems to be missing - i.e. a centripetal acceleration factor. While the simulated strand behavior looks remarkably like the real thing, it does not splay with increasing angular velocity like real strands do. Since centripetal accel is independent of mass (like gravity), I think I need an accel that always points to the center of rotation, proportional to the radius of the rotating point and the square of the angular velocity. Could Vortex or Spin Force work for this?

Since you posted your example, I’ve been spending more time with Kangaroo than my “real” work :face_with_raised_eyebrow:. What spurs me on is the uncanny resemblance of the simulation to the real thing:

vs. Dervish prototype with 5m bead chains (from below).

I’ve tried multiple ways to add centripetal force to the simulation - alas without success. While I know that a sim will never be exact for something as messy as whirling chains, I think this missing component might make a big difference in my being able to glean types of interesting choreography more rapidly than my current trial and error methods with prototypes. Here is my very crude model of the centripetal effect, showing the chain angle from vertical increasing with rotational speed: (19.2 KB)
The name is apt in that actual speed vs. angle-from-vertical relation is not linear as in my sketch - (it’s proportional to arctan(angular velocity squared * length of chain). I tried numerous ways to figure out how to feed this relationship of Theta (angle from vertical) as a goal for the solver, but to no avail. Here’s my latest “combined” attempt: (32.2 KB)

Though frustrating at times, this “exercise” has helped improve my familiarity with both GH and Kangaroo. I’m not sure if my goal is achievable with the current components available - but if you or others have suggestions, I’d be very grateful for pointing me in the right direction (C# is not the language I use for my motion control coding, but I have written GH scripts using it before).

Deep thanks to you, both for your initial example and your amazing plugin!



Hi @Bruce_Shapiro,
Sorry I didn’t reply to your last post yet - I started writing something earlier, but it’s tricky to describe without going into a bit more detail about the way the Kangaroo solver works.
First off - there’s definitely no need to add any special goals or calculations for centripetal or centrifugal forces. One great thing about simulating physics is that many more complex phenomena emerge naturally without more coding needed once the basics are set up right. In the case of centripetal force, it’s just the result of the momentum and tension of the chain.
The reason for the difference in behaviour between the simulated and real world behaviour will have more to do with the damping.
A solver like the one in Kangaroo needs a method for stepping through time, and ideally the algorithm for this should have several properties:

  1. Stability - it should not explode when high stiffness materials are used.
  2. Numerically accurate deformations - it should be possible to control precisely how strongly each of the goals are enforced relative to each other in the final result, particularly if we want to use it for structural analysis.
  3. Fast convergence to the equilibrium solution. For form-finding applications, we are mainly interested in reaching the final static form, and should be able to get there without needing millions of tiny time steps, or waiting for it to bounce around for a long time.
  4. Energy preservation control. If we want to simulate accurate dynamic behaviour, it is good to be able to control how much energy gets converted from kinetic to heat with each step.

In the first versions of Kangaroo, items 1-3 were often problematic - if you wanted to use high stiffness materials, it often required impractically small time steps to avoid making the whole simulation explode, meaning it would take forever to converge.
The new mathematical method I used for Kangaroo2 largely solved these issues, but at some cost to item 4. The new solver can use much bigger steps, even with extremely high stiffness materials, without exploding, which is great for example if you want to see how much a loaded steel truss deforms with real numbers for Young’s modulus and weight of the material, or enforce strict planarity in a panelisation, or quickly find a minimal surface for a given boundary.

However, it does tend to remove a small amount of energy from one frame to the next. Note that this is separate from the actual damping input setting - that gives you the option to add more damping, but there is always some level which is inherent to the time stepping method used, and it is currently not possible to reduce this to zero.
For form-finding (which is the primary purpose of Kangaroo), damping is actually good - we want to quickly get rid of all the kinetic energy so we can find a stable minimum of the total potential energy. What we definitely never want is simulations that artificially gain energy out of nowhere.

Of course in the real world total energy is conserved, but when simulating things happening on earth, in air, there is always some amount of damping, both from the internal friction of elastic materials and from air resistance, and for some dynamic applications where the inherent solver damping is close to or lower than this we can get a good approximation of the behaviour, adding even more damping if necessary.

For something like this relatively stiff, elastic, dense, and thin chain of your sculptures though, the real natural energy losses are probably quite a bit lower than the inherent damping of the currently available solver options.
One other example of something which is not really possible to do so well in Kangaroo2 is orbital simulation of planetary systems. The old solver was really good at this because it used a symplectic integration method. This was a fairly tangential and rarely used application though, so I’d considered it an acceptable sacrifice.

I have been working on ways of improving the solver methods to try and get the best of both - ideally Kangaroo would include options allowing you to precisely control damping, with the possibility to take it all the way down to exactly zero (with separate numerical controls for internal elastic friction and air resistance), while still always remaining stable, still with the option of making materials arbitrarily stiff, or even absolute constraints, and still giving numerically accurate deformations, all while keeping the goal interface simple (so custom goals can still be created just with target positions and weights, without having to mess about with Hessians and higher derivatives). This is all easier said than done though! Even cutting edge simulation research always seems to fall down on at least one of these. It may end up that multiple solver options are needed with different trade-offs, but I’d like to avoid making things too complicated.

So… perhaps more information than really needed! and I realise it doesn’t give a solution to the immediate issue, but hopefully at least gives a bit of insight.


What’s the ultimate goal of this project, to see the pattern from the underside, where the chains are mounted in the ceiling?

I started trying to add a centripetal force and you can create a vector Load goal using Vector2pt from the central axis of rotation to each point on the chain but you can only give it a static amplitude. I don’t think you can change the load according to what is happening in the solver. What you need to do is set that Load amplitude to be, as you say, proportional to angular velocity.

After reading through what Daniel said, tweak the damping setting… maybe use a slider with 4 digit resolution. (15.8 KB)

Just to be clear - adding a special ‘centripetal force’ will not help here.
It’s just a way of looking at the force stopping the chain from flying away from the centre, which in this case is provided by the tension in the chain (the length goal). The force is already there, there’s no need to add anything extra.
I’m afraid higher resolution for the damping value isn’t going to help much here either. Even with zero added damping, the solver is still removing more energy from the system than we want here.

One idea for another possible way to tweak this.
When using the bouncy solver, there is essentially another goal included inside the solver for each particle which tries to move it to where it would end up if it kept the same velocity it had in the previous step (i.e. inertia). There isn’t currently an explicit user control for the strength of this goal - it defaults to 1.0 for all particles. However, since it is only the weights of the goals relative to each other that actually matters, decreasing the weights of all the other goals has the effect of increasing this inertia, so the motion of the particles is damped less. (12.0 KB)

1 Like

I just meant give it a higher resolution (i.e. 4 digits instead of 3) so it can be changed in smaller increments. It did seem to be sensitive and make a difference so I wondered if it could get closer to what Bruce was aiming for.

It will be interesting to see how close he can get it by tweaking the inertia as you describe plus the damping, load value etc.

Hi @DanielPiker,
No need to apologize! Had you immediately replied with yet another great example, I’d never have spent so much time with Kangaroo (and at the same time, added to my Grasshopper skills). You have again blown me away - not only with your second, “improved” routine, but with your very thorough explanation of how Kangaroo works, including the difference between 1 and 2, and the strategies driving them. While I am comfortable with math basics enough to be a reasonable spectator when you refer to “Hessians” and “symplectic integration” (thank you, Wikipedia), the meat of your explanation, with respect to my grasping it, is your very understandable prose related to how the solver works, and why/how damping is so key. And most important (for me) - why centripetal/centrifugal force is already contained within the dynamic model.

I have just begun to play with your “”, and already the stuff I’m able to produce makes the hairs on the back of my neck stand up! It’s hard to describe my feelings, after spending so much time watching twirling 16’ strands of steel bead chain twining and splaying and dancing, while trying to tease out some reproducible choreography - all the while cursing their inertia (which of course is why their movements are so interesting) - when I see identical types of movements in the simulations you’ve enabled me to view on my Rhino screen. It’s going to take me a while - real world stuff to attend to and all - but I intend to share videos that demonstrate just how close your simulation is to the real thing. It may be a feeble expression of the gratitude I owe you - but I will do my best. Again - deep thanks!

Hi @martynhogg,
Thanks for sharing your exploration! I just tried it (connecting your centripetal force to the solver), and it does indeed cause the strands to splay more with increased speed. Playing with these sims takes me a lot of time for things to sink in and make sense - looking forward to seeing what I can learn from your addition, and will report back!

Hi Ethan,

What’s the ultimate goal of this project, to see the pattern from the underside, where the chains are mounted in the ceiling?

As with all my work, I’m never exactly sure what the “ultimate goal” is until I see it ;). Initially (2008) my goal was to see if I could create a compelling example of how cool “motion control” as an art medium is, by using just a single motor. The idea lay dormant for over a decade until a recent potential art-gig rekindled my desire to experiment with it. And now I have a shop/studio with a small area that has a 22’ foot ceiling. The idea of looking up at it might not have occurred to me otherwise. When the choreography is “on” - both under, over, and side views are all pretty interesting.

image Hi my kangaroo 2 is missing a component, but i don’t know how to get back the missing component

Hi - as I said on your previous post - you need to update to a more current service release to get all the components.
That said, you should be able to work around it in this case by replacing the missing component with the older version of the Load goal:

Some progress:


and Sim-

I can now read the same “derv files” (distance, velocity, ac/decel text I use for the prototype) into GH and use these to move the top “anchors-hoop” - the result sometimes being similar to real :).

Couple questions:
1- how does “timing” work, in terms of using the timer and/or the “counter” C# script? I have to empirically determine a correction factor to get the sim to match (i.e. if speed is set to 1 rev/sec, it moves at 1 rev/sec).
2- is there a way to get the current zoom factor of the Rhino viewport? Since the beads on the sim chains are actually 2D points, they don’t scale as I zoom in. By changing the number of points per chain segment, I can make things look decent at different scales - but I’d like to automate that so that it looks better during zooming. I found GH_Viewport.Zoom, but can’t figure out how to use it (or if it’s relevant).

Now that we’re officially ordered to “shelter in place” in Sonoma County, it appears I may be spending a whole lot more time with my whirling bead chains - real and sim!


Hi @DanielPiker,
Since you generously provided this “twizzler” definition a year and half ago, I’ve been spending a lot of my waking hours playing with ball chain, and trying to understand its kinetics with the help of Kangaroo. Though not a magic bullet, it has definitely been a great help for visualizing various permutations of chain length and number, before committing to the materials and assembly time. A recent experiment resulted in a happy accident.

Mounting the actuator on a crude gimbal opens even more possible kinetic “forms” - and so I set off to model it. But I keep running into brick walls. The problem seems that there is feedback: The actuator’s orientation is affected by the whirling chains, which in turn affects the whirling chains, … As I’ve discovered, like other GH components, your solvers don’t allow recursive data streams. This is as far as I’ve been able to get: (23.6 KB)

Is what I’m trying to do feasible? It seems like the same as having an unbalanced wheel rotating on a flexible shaft.

1 Like

To have the chains spinning around a moving axis where that axis is also driven by physics needs motors.
So I added a simple motor goal.
There’s a lot that would need tuning to get the right dynamics, but here’s something to start playing with: (38.3 KB)


Motors come in handy for other stuff too :slight_smile: