Købmagergade, Copenhagen – Karres en Brands – Case Study 3
This example is inspired by a project by the Dutch Landscape Architecture Firm Karres en Brands in Copenhagen, Denmark, the pedestrian street Købmagergade. I saw the project in its initial stages during a visit in 2009 but haven’t yet seen the final results. The concept is fairly simple. The designer wanted to create an effect like walking through a field of stars. This is done through a random distribution of 3 different colors of pavers. The effect is enhanced as the distribution is not uniform throughout the pedestrian street. It gets very light in some parts, and mostly black in others. The “Kultorovet” plaza, for example, is largely black, referncing an earlier history of coal trade. In the areas described as “the Milky Way”, light paving dominates.
I’m not sure Grasshopper or a parametric process was involved in their design process, but I do know that Karrens en Brands have used digital methods and parametric processes in some of their projects in the past, especially in some of their urban design projects. Anyways, this was an idea for a script I came up with while looking at their project.
This script basically combines the logic of two fairly simple processes. The first is using a random dispatch to assign pavers to different color classes as explained in example 1.5. The second is using attractor points to change the ratios that are assigned to dark pavers, light pavers, medium pavers, etc. The logic of attractor points is explained in example 2.1 and more thoroughly in example 2.2. These two processes are then bought together to create a factor that will assign a color to a paver.
Step One – Setting up Surface Divisions
The first step is to take a surface and divide it using the “Isotrim” component and “Divide Domain2”. Since I now want to offset every other row of pavers, I need to give the unstructured results of Isotrim a Grid-like data structure. This is done by using “Partition” list with the size of the partitions being equal to the “V” values in the “Isotrim” command.
Step Two – Offset Every other Row
I could skip this step if I want pavers without offset joints, but in this case I want to use them. This is very similar to what I did in the beginning of Example 2.3. if my surface is oriented directly up and down, this will work with a simple X vector plugged into the Move component. If you are using more complex surfaces, or surfaces with other orientations, however, we need to make the script a bit more intelligent. Let’s assume for a minute I have a surface rotated 30° If I run the script above, the results will look like the image below.
This can be a problem going forward, so I am going to adapt the script a bit to solve this problem. The basic idea is to find the vector 90° to the surface orientation. There are a number of ways to go about this, but my solution is to divide the surface into just two parts, to find the two counterpoints of these divisions (using “Area”, and to then base the vector on this using the “Vector2Pt” component.
The vector between the two points is then rescaled using the “Amplitude” component, with the new Amplitude equal to the amount of paver offset. The overall results look like the image below.
Step Three – Cull Pavers outside Boundary
If we have a simple rectangular surface, this step would not be necessary, but in this case I want to make it so my script can deal with irregular paved areas. lets assume for a minute the area I am paving is shaped based on the purple area in the image above. When I use “Divide Domain 2” and “Isotrim”, the component produces a rectangular grid of surfaces equal to the “U” and “V” value. So a surface based on the purple curve above would have divisions equal to both the pink and the grey pavers. To get rid of the necessary pavers, I can use the “PointInCurve” component as explained in example 4.1. Here the Containment Curve is determined by taking the edges of a referenced surface, joining the edges together using a “Join” component, the running the conatinment test and Culling the pavers whose center points fall outside of the edges.
Step Four – First Dispatch
I am going to continue the script assuming a rectangular surface for now, but with the previous two steps, this should also work with any irregular planar surface. This step is at the core of what this example is trying to show, however, combining the logic of the Attractors with that of a Random Dispatch. This is achieved in this case by simply adding together the results of a random number generator which contributes one value, and the results of the “Closest Point” component, and its associated distance. The distances are remapped and weighted to be added in with the results of the random number generator. Then a dispatch is done to separate Color 1 pavers from a second set of pavers (which will become color 2 or Color 3).
Step Five – Second Dispatch
Once it is up and working, I can play with the parameters to create variations. I can make the attractor dominante, as in the second image, make the random distribution dominate, as in the third image, or add new attractor points, as in the fourth image.
Applying it to our site
If you followed all the previous steps, you can now test it out in the “site”. Here I created a simple model of the Købmagergade using data from open street map explained here. One thing to be aware of, you can’t model Every.Single.Paver There are simply too many, approaching the millions probably. You will have to be a bit abstract. One strategy is to take small segments, as in the image above where I took just one part of the alley, and to run a test there.
Another thing you can do is take larger areas and to scale appropriately so you can explain the concept and experience the effect, but not so much that you crash your computer. The image below shows a bit larger part of the Købmagergade, but maintains the look and feel of the script from smaller scales of exploration. You can compare the image below to the image from the Karres en Brands site. It isn’t exact, but is close. I already have some ideas to improve the script to get better results, but this should be enough to get you started!