I’m trying to simulate magnets in grasshopper using kangaroo. I found that magnetic snap is not suitable for my need because it does not work in real time. For example I’ve two points and I need them to act like ‘like poles’. Using magnetic snap(with negative strength) and bouncy solver, the simulation only runs once and the points reach their equilibrium state. Now, if I move one of the points closer to the other, there is no effect of the repulsion. I have to reset the simulation to see any effect. Is it possible to simulate my requirement in kangaroo?(real time magnetic attraction/repulsion)
Here’s an example of an attraction/repulsion goal.
PLaw_example.gh (14.8 KB)
(you’ll need to set the referenced assembly location of KangarooSolver.dll when you open it - usually this will be in
C:\Program Files\Rhino 6\Plug-ins\Grasshopper\Components
if you are on 6, or
C:\Program Files\Rhino WIP\Plug-ins\Grasshopper\Components
if you are using the WIP)
You can make it negative for repulsion or positive for attraction.
The exponent controls how quickly the force falls off with distance.
Playing a bit more with this using pointclouds:
attraction.gh (10.0 KB)
Did you try the file in the first link? (PLaw_example.gh)
That is a goal that lets you set the interaction between pairs of particles.
Thanks a lot Daniel! After a few modifications the first link was really helpful.
Btw, just started using Rhino, grasshopper and kangaroo and I feel its a great piece of software, kudos for that!
Hi Daniel! I downloaded your script and found it incredibly useful for simulating magnetic forces in Rhino. However, I was hoping to modify it so that it would be able to account for individual charges being positive and negative as opposed to the bulk attraction / repulsion that the current “charge strength” parameter allows for right now.
Reading through your script, I get that I should be modifying the Strength variable, but I am not sure what is going on with the Rhino vector operations. It seems that making certain objects have a positive charge and others have a negative charge might introduce more complexity than I expect–unless there is a simpler solution.
Do you have any tips / recommendations for modifying your script to implement what I am talking about? Any help is appreciated.
Here’s a modification where like charges repel, and opposites attract. It’s quite fun to see it form crystals!
PLaw_polarities.gh (20.8 KB)
Thank you so much Daniel that was super helpful. We managed to make this work in 3D as well which is very exciting. One issue that we’ve been running into with this type of simulation work is performance related–perhaps you might have useful input on scaling up simulations optimally.
Generally, when we have multiple features turned on (i.e. gravity, collisions between objects, and magnetic attraction) performance drops drastically and some of the goals stop being carried out. We are testing how disabling goals one at a time can help. Do you think that this magnet physics is contributing to this performance issue significantly, and is there any way to make the code more efficient?
Glad it was helpful.
This custom attraction/repulsion goal will be the reason your simulation is slowing down so much.
It currently calculates the interaction of all points with all other points, so the number of interactions quickly gets huge as you increase the number of points.
I can think of some ways to speed it up, but it would be helpful to understand more about the application.
I think the biggest relatively easy improvement would be to have a distance above which the repulsion/attraction forces cut off.
Since they are based on negative powers of distance, the influence between far apart points becomes extremely small, and treating them as zero beyond some cut-off distance can skip lots of calculation without any noticeable change in behaviour.
Further to this, but a bit more involved, you can also do some sorting of all the points first, such as sweep-and-prune, or an RTree, which lets you quickly rule out many distant interaction pairs without actually calculating the distances (as used in some of the collision goals).
Also, if you don’t need to be able to adjust the exponent for the attraction/repulsion during runtime and it is an integer, I think using eg
d*d*d instead of
Math.Pow(d,3) can be quicker.
There’s more that could be done, such as as changing the method of parallelization, or a big one would be to implement something like Barnes-Hut, which partitions the points and lets it treat distant groups of particles as one big one. That would be a bigger project though.
Like I say though, understanding how you want to use it would help.
Here’s a version with some of the improvements mentioned above
polarity.gh (12.7 KB)
The patterns that can emerge can vary a lot from just small changes to the parameters, such as the strengths and exponents of the attraction/repulsion.