I have the following problem:
I have multiple 3D scanned treelogs and I want to arrange them on top of each other like a loghome wall.
The goal is to end up with a horizontal line at the top. So I have two lists of values, one with diameter on side A and one with the diameter of the treelog on side B. The two lists diameters should be added up and have the same height in the end. So I think I need to have a loop interchanging the diameter A and B of each tree until it`s lets say equal within 5percent tolerance. I would than orient the 3D scanned logs according to these values in 3D space.
I have a script to evalute the diameters of the logs and end up with diameter A and B. But don`t know exactly how to proceed from there.
How do i setup the loop? Or do I work with gates or?
My approach would be:
Mass Addition of two lists of values (a1;a2;a3…)(b1,b2,b3…) exchange a1 with b1,a2 with b2… until I have the two sums to be similar(within 2-5percent range).
I´m not an expert so I might be doing stuff completely wrong, sorry for that.
Help would be extremely appreciated
This is my script for finding the approximate diameters of the scanned treelogs (and later Orienting them with the help of bounding boxes). At the end I have two "fictional " diameter lists to work with.
OrientTreelog_withDiameter_2.gh (8.7 MB)
basically the problem you need to solve is:
you have 2 lists of values. Their total sum is X, so target sum per list is X/2
Then keep swapping values until each sum is as close to X/2 as possible.
You could start with swapping one value that gets you closest to your end goal and then repeat the process. Probably best to script this. Attached a .gh of the first iteration
swap_value.gh (30.4 KB)
here’s one that keeps swapping until a minimum has been found
swap_values_python.gh (23.3 KB)
@lukaskirschnick, your problem intrigued me. So I made a solution that should be able to handle what ever you throw at it.
I don’t have a ton of time to do a proper right up right now, so I’ll come back to do it later. But here is a brief description of what i’m doing.
I’m using a random number generator to create a list of trees to swap. Then I swap them, and add up the sides and compare the values. I can randomly change the list of tress to swap by changing the seed.
Using Galapagos, I can test hundreds of possible seeds to either maximize or minimize the height difference. Using the annealing method we can brute force an answer that works. Since this is all simple math, you can run through thousands of variations a minute.
OrientTreelog_withDiameter_2.gh (8.7 MB)
Thanks a lot for your solution that helped me significantly. The 5 numbers on the out are the values that have been swapped right?
Correct, the logic is to stop the swapping process when in the next iteration the same index is swapped. I tried a few combinations and it seems to converge quickly all the time.
ah okay so the last two indexes are always the same and I can exclude those.
Thanks a lot, I had thought about trying galapagos too but I´m not really familiar with it. Its always so helpful to read and analyze others peoples code to learn from it
One last question, I have a similar problem now with the same two lists but instead of wanting two equal sums I want to be able to set two target sums and swap the values around until they are as close as possible to these target sums. Is that possible or way too complicated?
How about showing us your “loghome wall” using one or both of the solutions already provided?
Do the two target sums add up to the total of both lists combined? And the point is a sloped wall?
What is so special about your genRandom cluster?
Here’s a solution that has two sliders (blue groups):
- a ‘Seed’ value for Random Reduce
- an ‘Index’ value for the sorted difference between the two lists
The initial lists are Entwined and paired (as “logs”) using Flip Matrix, then grouped (as points). Reduce and Set Difference are used to randomly swap between 1 and “all” logs. Etc., etc.
Among the random swaps, you choose the sorted difference you want and that pair of lists is the result, ‘List A’ and ‘List B’.
Nothing is special about it, my actual data comes from a way bigger file where I analyze 3D scanned treelog meshes and this is just to simplify my question.
Thank you Joseph if I understand correctly I have no control over the final result but I can play around with the index and seed slider. So I could maybe use Galapagos and these two values would be changed until they come close to my desired two sums of the MassAddition Result.
I would say that the two sliders give you complete control over the final result.
It’s true that the method could be extended to evaluate all possible combinations of the two sliders to find an optimal result but on the second slider, you would have to avoid exceeding the number of logs (as indicated by wrap = false). But it doesn’t take long at all to manually find a very small difference between the two lists, where both ends are nearly the same height.
I tried using galapagos and I easily got the maximum and minimum results after a very short time. Unfortunately I have no idea how to get specific mass addition results of for example 530 (or any other number) within 5percent tolerance.
But thats fine you helped me get an idea on how else to approach it.
Nevermind if I manually enter the desired number that works with galapagos
The white group has a ‘diff_goal’ slider that compares all the differences and finds the closest one, shown as ‘variance’. The Sort was a human convenience, not needed anymore and could be removed. The next step would be to add an Anemone loop to try all values of ‘Seed’ to find the lowest variance.
The cyan group is an Anemone loop to test ‘Seed’ values from 0 to 499. You could make the limit larger if you like but it gets way below 5 percent tolerance as is.
I had to use the “Classic” Anemone components because “Fast” didn’t work, I’m not sure why? Perhaps because of text panels that report results along the way? With the “Classic” components, you can see the progress as it finds smaller and smaller ‘variance’ values. Change the ‘diff_goal’ slider and the loop will restart.
What I didn’t do this time is to use the resulting ‘Seed’ value to show the two lists that give the minimum variance… That would be a lot of code duplication, probably best done by clustering it. Then use it within the loop and again after the loop ends. Another twenty minutes or so would do it.
OK, did that. Here is the cluster that is used twice, once within the loop and once more after to show the resulting lists:
I haven’t taken the time to test it extensively or optimize it further, such as avoiding the unneeded Sort and trying again to use “Fast” instead of the slower “Classic” Anemone components, which might work better with no text output within the loop this time.
P.S. The “Classic” Anemone components take ~60 seconds as posted but can be sped up to ~38 seconds by right-clicking Loop End and enabling “Output after the last”. The “Fast” components (which always “Output after the last”) take ~19 seconds.
P.P.S. Here is the “Fast” Anemone loop version, with a Data Dam added after ‘diff_goal’, though it’s still probably best to double-click and type a value instead of adjusting the slider, because “Fast” is less forgiving about being interrupted.
Treelog_2020Mar2d.gh (52.6 KB)
Thanks Joesph that`s great, I really love all the work you put in there. There is a lot of grasshopper functions that I never used so I have to take my time and analyze what exactly is going on everywhere. But I´m learning a lot