Vector Field with Drawn Vectors – Example 6.6
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.
In 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, and then using “Vector2Pt” to find the vector between the start and the end.
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. 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 are found. The “Closest Points” identifies the item index of these six points, but these also correspond to the item index of the vectors associated with those six closest points (if I set it up right in the previous step). I use “List Item” to identify these six vectors, in these images shown anchored to each of the points in pop geo. 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 “VectorPreview” 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.
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 “LineSDL”, etc. You can also introduce a “Cull” to get rid of geometry that is either too small or too large. 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.