Curve Attractors – Example 2.3
In the last two examples, we looked at point attractors, but you can also use attractors with curves (think paths). In this example we will use the concept of an attractor to scale geometry based on the distance of the geometry to the centerline of a path.
Step One – Initial Setup
Setup your initial surface and divide using Isotrim (SubSrf) as in the previous example. This time we will have our divisions in roughly rectangular proportions instead of squares.
Step Two – Dispatch and Offset “Pavers”
Many contemporary projects (in Landscape, but also in Architecture) show paving with the joints aligned, (see example 1.5 but often it is better construction practice to offset courses of bricks. Part of the reason for this contemporary aesthetic, I think, is the designers don’t know how to offset the bricks when they are drawing them in the computer. OK, there are other reasons, but sometimes, or most times, you may want to have some offset.
To do this, you can do a simple True / False dispatch on your Subdivided Surfaces list and Move the True values an amount of your choosing. Note, for this to work properly, you need to have an even number in your Bricks V (Y) direction. You can even in Grasshopper under the slider options click a button to force only even numbers as your output. Why? Well, due to the data structure, it applies the True / False values per the logic explained in example 1.1. If you have an odd value, the bottom element of column one will have a True value, while the bottom of column 2 will have False, and so on. Unless you force it to only count in Even increments that is.
This time, instead of doing the typical dispatch, I am doing an alternative, which uses the components Sift and Combine. Sift and Combine is useful when you want to separate a list, do an operation on a subsection of the elements, and then bring the elements right back together again. This has the advantage over dispatch of preserving the original data structure of the elements. In this particular example, this is not so important, as we could just dispatch and then bring them back together into one container of surfaces. In fact, this is what I do in the overall script image at the end. But Sift and Combine will have their uses later.
Step 3 – Setup Attractor Curve
Here we find the center point of each paver with an Area component, and then using the “Curve CP” (closest point) component to measure the distance from each paver’s center to the curve. This was drawn in Rhino and input into grasshopper with a Curve parameter Container.
Step 4 – Mathematical Operations to determine Scale Factor
We now have to do a bit of math to determine scale factor.
The first thing I have done, before doing the math, is I have “Remapped” the domain of distances. If you enlarge and look closely at the image above, you will see two sets of numbers on each paver. The top number is the “raw distance” and the second is this distance remapped to fall between 0 and 1. So the largest distances, in the top left corner, for example, are 22.91, 22.25, etc and these get remapped to .98 and .99 respectively. The smallest distances, very close to the curve, are remapped to at or near 0. Why I do this should become clear later.
To remap the numbers, the first thing I do is use a “Bounds” component to tell me the smallest and largest distance. You can see that the smallest is 0.0128 and the largest is 23.35 from the panel. This bounds gets plugged into the “Remap Numbers” component into the “S” for Starting Domain Slot. I then tell what the target domain is, which in this case is between 0 and 1.
Now that the numbers are remapped, we need to use these remapped distances to come up with a decent scale factor. In the previous examples, smaller objects were associated with smaller distances to the attractors. In this case, however, I want to invert this logic so that a smaller distance will correspond to a larger scale factor. to do this, we subtract our remapped distances from a constant. Since our maximum scale factor will be 1 (we don’t want anything getting bigger, only smaller), we could subtract from 1, but the problem with this is the pavers will start scaling down right away. In this example I want a “path” with no scaled down pavers for a certain distance before the pavers start scaling down. To solve this, I subtracted the remapped numbers from 1.5 (this can be adjusted up or down to get a thicker or thinner “path”). And then after this subtraction, I use the “Minimum” component to set a maximum value of one. This prevents any value larger than 1 from getting through to the scaling component. To help understand what is going on I will give two examples.
Example 1 – A relatively close paver might have a remapped distance of 0.3. The math calculates 1.5 – 0.3 to give 1.2. This value is lowered to 1 through the minimum component to 1. In other words this paver will not be scaled down at all. If we had not used the minimum component, the paver would have been scaled up.
Example 2 – A relatively far paver might have a remapped distance of .8. The math calculates 1.5-0.8 to give 0.7. So this paver will become smaller by a scale factor of x 0.7
One more thing to note. If I had not remapped the numbers, the range of scale factors would be not very useful. I would have extreme negative numbers (-25 maybe). To solve this I would use a maximum component to get a floor, but only pavers in a very limited range would be scaled.
Well, that was a lot of mental gymnastics. It is worthwhile to try and understand this logic, however, since I will use it on a few more scripts in the future. But you should be able to apply this reversed logic to point attractors as well.
Step Five – Scale the Pavers
If you did the math for your scale factors correctly, you can simply input the result into a scale component. The geometry is scaled around its own center, so you can take your surfaces and use an “Area” component to find its center again, and plug the result into the scale component.
Step Six – Cull Pavers that are too small
Here I decided to cull pavers that are too small. This is clear, but I don’t want the minuscule pavers in this example, so I simply cull any paver that was scaled down above a certain factor (.52 in the script example at the end)
Variations
OK, so once this is setup, I can play around. In these particular examples, the “Curve” could be a polyline, or any kind of Nurbs curve, etc, which I draw in Rhino. You can also have a parametrically generated curve… but enough of that for now…
And here is the Grasshopper script…
Click Here to Download GH Script
Hi,
I didn’t get a few things:
The dispatch – what does it do? It basically takes for example 1000 surfaces, and gives back the same 1000 surfaces into it’s List A output.. why do we need it?
Also, in your example images above I didn’t see the “movement on Y axis” you mentioned…..where is that seen or evident?
Cheers
LikeLike
Hi, I think I see the source of the confusion. In step two, the dispatch should put things into two lists based on a True / False pattern, as explained in the text. The problem is in my screenshot the “Panel” only shows “True”… but there is a scrollbar next to it, and there is a ‘False’ hiding in the panel too Sorry about the confusing Image. I will update it soon! So go into the Panel, type “True” then on the next line type “False” – You will have to also go into the Options and make sure “Multiline data” is checked. (right click, line 2)
LikeLike
As far as movement in the “Y” axis, you may have misunderstood. i was referring to the number of Values in the “Y” direction
LikeLike
Very nice all your manuals are glorious, could you explain me how to add custom pattern like KEIO UNIVERSITY ROOF GARDEN to have a little control into the shape I’ll really to appreciate it.
please.
regards
LikeLike
Hello,
I see you’re showing us paver numbers and hidden lines from closest curves, how would you do that?
Thank you and great work!
LikeLike
You even have the distance and the scale factors, how to do so? That would be a huge step to understand your definition.
LikeLike
the understanding of MY definitions* sorry
LikeLike
Hello, I would like to know if there is any way to get this same effect of gradient, but with another form of tile that is not a rectangle, a more organic form,
Thank you!
LikeLike
yes I suppose so. Any form should be able to scale down incrementally based on a distance attractor. Most regular tessellations (tiling patterns), however, tend to be geometric.
LikeLike
Quick question. Say we have a defined border, we create our paver pattern. I want to control the x and y direction location of the pattern to match say an opening or existing condition. But move moves the whole pattern and leaves gaps,
LikeLike
Well I’m not sure how to answer without more information, but it sounds like what you are trying to do would require a lot more scripting intelligence than what this simple example is trying to convey. Maybe you only move pavers that are in a certain region?
LikeLike
Thank you for putting this together, really great stuff!
I was wondering if you would know of a way to make the gradient go quicker?
LikeLike
It certainly should be possible. You could attach a multiplication slider with a number less than 1 to your bounds maybe but I would need to test it to be sure.
LikeLike