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)


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…