Anemone - How to loop a set of data once, then loop the output of that instead?

Hello! I am trying to use Anemone to loop through a set of points, finding the closest point pairs, and drawing a line between them. Then I want to take the midpoints of those lines, and repeat the process.

The problem I am having is how to switch the looping from the original random points (the pop 3d component) to looping the new set of points (points produced by the evaluate curve component). I have tried to figure this out with a nested loop, but I had trouble with that and am not sure that’s the right way anyways.

The way it works is if I create 16 points, 8 lines are created between the closest neighboring pairs. Then I want the midpoints of those lines (8 points), and create 4 lines between them. Then I want the midpoints of those lines (4 points), and create 2 lines between them. Then I want to create the last line between the last 2 midpoints.

However I would like this to work for any even amount of points, or any amount of points. But I am not even sure if it can work if it isn’t an n^2 amount of points. (IE 32 points creates 16 lines creates 8 lines creates 4 lines creates 2 lines creates 1 line) If it is 60 points it would start with 30 lines, then 15 lines, then what? 15/2=7.5…

I actually did get the result I wanted by copying+pasting the anemone loop and feeding the output into it as you can see here:

but obviously this is not a real solution, as it means I need to add or take away whole loops based on the original amount of points. (The amount of copy+pasted loops = sqrt(number of original points) ie. 16 points requires 4 loops. I’m pretty sure.)

There must be a way to do this without copying+pasting! I have attached both .gh files pictured here and would greatly appreciate any help on this problem. If anyone needs any further info from me I will provide it.

James Looping (9.9 KB)
James Looping Problem Anemone manually looped_not a scalable (20.3 KB)

1 Like

Double (11.4 KB)

1 Like

Well … I can’t help you on the Anemone thingy since I use solely code for baking my beans … but given the opportunity here’s some tips:

  1. If you are after some Steiner graph for artistic purposes then I would strongly advise to do the inverse: grow recursively (in your case: try to do it with A) from a node 0 (any pt, that is) and get a graph that “looks” like a SG. If on the other hand this is a project even remotely related with real-life (are you in the tele-comm business?) then indeed a weighted SG is the only solution.

Here’s what I mean (shown 2 random solutions depending on the deployment angle [Note: 0 yields a T graph]). When someone observes a result like this is impossible to tell if is a real SG. This approach is very fast (a couple of milliseconds for reasonable amount of end nodes, say 3-5K):

  1. If on the other hand you want a similar C# either just for fun or as an iginition point to walk the coding walk, notify. You can get LOL stuff as well like this biased random result - if you apply a force, that is):

BTW: If you opt for plain lines as result then you just need 10 milliseconds for 10K connections:



You have to use loop twice, but a loop start can’t go with 2 loop end. so one of the priotity loop should be the fast loop. When you use the fast loop, the data you want to collect should be embedded the loop because the processing data can’t be recorded.

1 Like

Dandan, thank you so much for this definition. I’m working to understand how the double loop works, especially the differences between the normal and fast loops. You mentioned I need to embed the data as it loops - do you mean using the [data recorder] component?

While trying to get nice results from your definition I keep getting networks that aren’t fully connected, and I’m struggling to figure out why. As you see in this image, the highlighted lines aren’t connected fully to the rest of the lines.

I tried messing around to fix it but having never used a double loop in Anemone before I’m a little lost.

Peter - that is extremely impressive. 10k connections in 10 milliseconds is ridiculous. I am not in the telecommunications business - just curious about this new thing I learned about (Steiner Trees) and have been searching for a way to use grasshopper to generate the base network, and then use Kangaroo to relax the network to get 120degree angles between all nodes. I can do the second part - it is just generating the base network in an elegant way that eludes me.

I’m starting to think I may be approaching this the wrong way. In my hack-y definition with copy+pasted loops, I was able to generate the base network and relax them with kangaroo, but still get valence 4 nodes occasionally. I think I may need to use Galapagos in the first step to minimize the total network length (thus finding the optimal base network prior to relaxing). But combining Galapagos and Anemone is another thing for me to learn.

Maybe I should drop down to 2D first. This problem has surprised me with how difficult it is!
Anyways, thank you for sharing, again very impressive.

James, sorry I forgot to clean the null data. Because I ignore the times of iteration, It has so many null dataDouble Looping (15.4 KB)

1 Like

that means if index 1 is a point, index 2 is a null, index 3 is a point. There is no line between those 2 points.

1 Like

that means embed, everytime loop runs, the data from the last time will be added to the output.

1 Like

Well … if we are talking real weighted ST (I have 3 C#'s that do that in comparable Elapsed times with the inverse thing: 10K for 10 ms that is - or half that if you don’t mess with the angle [user controllable as well]) … then the relax part is odd (so you are after graph aesthetics more or less) … but you don’t need K2 for that. Anyway in the inverse example shown the deployment angle is user controllable … thus … any angle is OK etc etc.

See the angle going from neg (outwards grow) … to 0 … to pos (the other thing):

But since you are not after 100% real stuff … the inverse approach could cut the mustard quite effectively with an “identical” visual result. I could explain the basic logic … but following a very strict coding way of thinking (and using custom classes for the prox pairs in the recursion required) and I’m not sure if translating all that into native components could be an easy-busy task (if it’s possible at all).

So … if and when some time in the future you decide to take the walk to the wild side (I would strongly suggest C#) … just drop me a note.

You make a strong argument. I have been trying to teach myself Python, and I have some experience with Processing, but I have a hard time overcoming things I get stuck on since I don’t come from a computer science / programming background. If I move along to C# I will surely reach out. Thank you.

Dandan, I am studying the definition and comparing it to the first one so that I can learn from it. Thank you, this seems to work!

Here are some results I have gotten after running the Anemone output through Kangaroo

4, 8, 16, 32, 64

And here is the final file for anyone interested: (15.8 KB)

especially the differences between the normal and fast loops.

Fast loops are multi-threaded and only output after the entire loop sequence is done (so with a fast loop for instance you won’t see an animation of the loop process) - displaying loops on each iteration looks cool but is very processor and graphics heavy, think of it like the difference between the kangaroo 2 solver vs the bouncy solver. Also, recording the data makes things very heavy as well.


2 in fact: Other than the C# thingy (a MUST in the years to come) … using a real Steiner … well … the aesthetics (if we are after graph aesthetics here and not connectivity games, routing and the likes) are not on par with the other thing.

Turn upside down your logic (and forget K2). Shown a SG that optionally srinks towards the node 0 … if this LOL stuff has any meaning at all (it hasn’t … but anyway).

1 Like

BTW: Haven’t checked your def (components is not my game at all) but this is the classic S algo (Loops are zero indexed as always). Note: any orphan node could classify as mid pt for the next loop depending on the best pair policy:

1 Like