
I decided to come back to vector fields with one more example. First, I’ve set the goal on this blog to have six posts in each category, and Vector Fields has been at five for a long time, despite being one of my favorite things! I also wanted to come up with a new starting logic for example 11.3 where agents are steered through a field. I was quite happy with 11.3, but sometimes not pleased with the sudden change of direction when the vectors move from one cell to another.
Agent Movement Using User Drawn Vectors – Example 11.3In this script, a vector field is controlled through lines drawn in Rhino. The vectors at any given point are an average of several nearby vectors. The closer you are to a particular drawn line, the more influence that particular line will have over nearby conditions. The field though changes gradually and not too suddenly, as it does in example 11.3. The field is then used at the end to draw particular geometry, in this case, egg-like shapes.
Step One – Initial Setup

Before going into grasshopper, a few pieces of geometry are drawn in Rhino. The first is a closed “Field Boundary Curve”. Then several lines are drawn which will be used to identify the general direction of the field in a particular region. Note, the direction or order in which these lines are drawn will be important in determining how the field works.

Once this is done, I do the basic setup of my script. The objects in the field will be anchored to a random population of 1000 points generated by PopGeo (grey X’s). A second step in the setup will be to translate the linear geometry in Rhino into vector information. This is done by using the Endpoints component to get the start and end of each line drawn in Rhino, and then using Vector2Pt to find the vector between the start and the endpoints of each line.
The last part of the initial setup is to Merge the start points and the endpoints into one point list. The vectors are merged in the same way to make a list of identical length. If you duplicate the image above, it should work, but what is important is that each item in the vector list has an item index which corresponds to the same item index of its associated point.
Step Two – Associate Nearby Vectors with each point from PopGeo

This step is the heart of the script, where each of the 1000 points generated by PopGeo gets a vector assigned to it. This would be very hard to show graphically, so for this step I temporarily reduced popGeo to 40 points and hopefully it will make graphic sense in the logic shown in the image above.
The script uses the closest point component to find the 6 closest start and endpoints of my vector lines to each of the PopGeo points. This number doesn’t have to be six, but based on trial and error this seemed to work. Fewer than four doesn’t really generate the results I want, and more than six doesn’t seem to improve the results. This can be changed later though. Anyways, the six closest points can be found using the Closest Points component which identifies the item index of these six points, but these can also be used to correspond to the item index of the vectors associated with those six closest points, assuming I set it up correctly in the previous step. I then use List Item to identify these six vectors. To help show this graphically, I’ve identified the six vectors graphically using Vector Display with the vectors of the six closes points ‘Anchored’ to each of my points in the initial population.
Now I want to sum these vectors together to find an average, but before doing this, I am going to scale the vectors down based on their distance from my PopGeo point. In other words, far away vectors have less weight in the summation than closer vectors. To do this, I use the VectorLength component to get the strength of each vector, and then I divide this by the distance, which was also conveniently generated by ClosestPoints. Now that the distances are scaled down, I rebuild my vectors with the Amplitude component, where the Vector Direction remains the same, but where the Amplitude (vector strength) is reset with the scaled down Vector Length. These much smaller scaled down vectors are represented by the little red arrows in the second image above. Finally, I use the Mass Addition component to sum the six vectors associated with each point, giving me a resultant vector (shown in black). I put the results of “Mass Addition” into a final “Vector” parameter container. Note these need to then be flattened for the next step.
Step Three – Draw Geometry based on Resultant Vectors

Note, even if you went through all these steps, you won’t see anything yet since vectors are forces, not geometry. You can use Vector Display to visualize what they are doing, but in the end, we want to translate them into some sort of geometric expression. There are many possibilities, but in this case, I am going to draw some eggs. The process is pretty straightforward. First, I start by drawing a Line with the Line SDL (Start/Direction/Length) component. The start are the points from PopGeo (which are now back up to 1000 in this image), the “D” direction is governed by my vectors, and the “L” is determined by multiplying the “Vector Length” by a scaling factor.

The eggs are finished by the script above. I won’t explain the details, but it is using components which already should be familiar to you.
Varying the Pattern
There are a few parameters you can change to vary the pattern, but the most important way to change it is to go back to your curves drawn in Rhino, and to edit them by moving the control points around. You can also add or delete curves. Below are two variations of curves drawn in Rhino (shown in Blue) and the resulting field conditions.

Another way to vary the script is to change the initial point population, change the amount that geometry is scaled with Line SDL, etc. You can also introduce a Cull Pattern to get rid of geometry that is either too small or too large, measuring Area to determine the Boolean values for the Cull. Below are a few possibilities.

It wasn’t my intention while making the script, but in the end it looked a bit like one of my favorite landform phenomena, the “Drumlin Swarm. You can read bit more about it on this page here.


Comments
8 responses
Hi,
Thanks for your website, it’s an amazing resource! I’m learning Grasshopper for my Landscape Architecture degree in Australia and I’m having a bit of trouble replicating the example on this page.
‘Step One – Initial Setup’ works fine, except that I can’t see the black dots at the end of the Vector Direction Lines.
‘Step Two – Associate Nearby Vectors’ isn’t working at all for me. After the Closest Points module the wires become dashed, whereas they’re solid on your screenshot. I also don’t get any changes in the Rhino file.
One thing I’m not understanding is when you say: “what is important is that each item in the vector list has an item index which corresponds to the same item index of its associated point.” Can you please explain this in another way, as I think this maybe where I’m going wrong?
Thanks again,
Matthew
Hi Matthew. As far as the black dots not showing up, some of the things won’t show up on your screen. The black dots and dashed lines I added myself to show what is going on since the screenshot of points and vectors was quite cluttered.
As far as not seeing anything, vectors are “invisible”, that is you will not see anything unless you use them to draw geometry, or if you use the vector preview component.
In answer to your last comment, this has to do with lists, and it is a somewhat advanced topic. Basically you have a list of points and a list of vectors (which you can preview with a “Panel” component). The key is to have your data structured so that your list of points is structured exactly like your list of vectors, so that the point with Index item “21” for example corresponds in a similar list of vectors with item “21”.
Hi Josclag,
Thanks for your response. I understand now what you mean by the the vectors being invisible. I continued following your instructions and screen shots and I was able to get the definition working perfectly.
Thank you!
Matthew
Hi Josclag,
I got it almost working except in Step 3, the “0.5” that connects from the L of “Ln” to “pt”, which component is that?
I kinda by-passed it by connecting “S” from End directly into the “Pt”, so the eggs are slightly tilted in on my rhino.
thank you
CS
Hello CS,
that component is “Point on Curve”
Best,
Joseph
what are you using for your parameter of color gradient…I fed all the interpolated curves into Boundary (flattened & simplified) then Boundary to Bake Attributes.
I then have Color Gradient -> Split AHSV -> HSL -> Bake Attributes
What are you using for your upper / lower limits and parameter of Color Gradient?
The color gradient here is determined by the area of the shapes. The upper and lower limits are determined by using the Bounds followed by Deconstruct Domain component.
thanks! got it work now.