
























Chapter_4_Transformation
47	Transformations















Chapter_4_Transformation


Transformations are essential operations in modelling and generating 
geometries. They can enable
us  to  get  variations  from  the  initial  simple  geometries.  
Transformations  help  us  to  scale  and orientate our objects, move, copy 
and mirror them, or may result in accumulation of objects, that could be 
the desired model we. There are different types of transformations but to 
classify it, we can divide it to main branches, the first division is 
linear and the second is spatial transformations. Linear transformations 
perform on 2D space while spatial transformations deal with the 3D space 
and all possible object positioning.

In other sense we can classify transformations by status of the initial 
object; transformations like translation, rotation, and reflection keep the 
original shape but scale and shear change the original state of the object. 
There are also non‐linear transformations. In addition to translation, 
rotation and reflection we have different types of shear and non‐uniform 
scale transformations in 3D space, also spiral and helical transformations 
and projections which make more variations in 3D space.

In  order  to  transform  objects,  conceptually  we  need  to  move  and  
orientate  objects  (or  part  of objects like vertices or cage corners) in 
the space and to do this we need to use vectors and planes
as  basic  constructs  of  these  mathematical/geometrical  operations.  We 
 are  not  going  to  discuss
about basics of geometry and their mathematical logic here but first let’s 
have a look at vectors and planes because we need them to work with.





Fig.4.1.  Transformations  provide  great  potential  to  generate  forms  
from  individuals.  Nature  has some great examples of transformations in 
its creatures.
48	Transformations


4_1_Vectors and planes


Vector is a mathematical/geometrical object that has magnitude (or length) 
and direction and sense.
It starts from a point, go toward another points with certain length and 
specific direction. Vectors have wide usage in different fields of science 
and in geometry and transformations as well.

























Fig.4.2. A: Basic elements of a Vector, B: point displacement with a 
vector.




Simply if  we have  a point  and a  vector,  this vector could displace  
the point  with the  distance  of vector’s  magnitude  and  toward  its  
direction  to  create  a  new  position  for  the  point.  We  use  this 
simple  concept  to  generate,  move,  scale  and  orientate  geometries  
in  our  associative  modelling method.

Planes are another useful set of geometries that we can describe them as 
infinite flat surfaces which has an origin point. Construction planes in 
Rhino are these types of planes. We can use these planes
to put our geometries on them and do some transformations based on their 
orientation and origin. For example in the 3D space we cannot orientate an 
abject on a vector! but we need two vector to make a plane to be able to 
put geometry on it.

Vectors  have  direction  and  magnitude  while  planes  have  orientation  
and  origin.  So  they  are  two different types of constructs that can 
help us to create, modify, transform and articulate our models.

Grasshopper  has  some  of  the  basic  vectors  and  planes  as  
predefined  components.  These  are including X, Y and Z vectors and XY, 
XZ, and YZ planes. There are couple of other components which we can 
produce and modify them which we talk about them in our experiments. So 
let’s jump into design experiments and start with some of the simple usage 
of vectors and go step by step forward.
49	Transformations


4_2_On curves and linear geometries


As we have experimented with points that are 0‐Dimension geometries now we 
can start to think
about  curves  as  1‐Dimensional  objects.  Like  points,  curves  could  
be  the  base  for  constructing  so many different objects. We can extrude 
a simple curve along another one and make a surface, we can connect 
different curves together and make surfaces and solids, we can distribute 
any object along a curve with specific intervals and so many other ways to 
use a curve as a base geometry to generate other objects.




Displacements

We  generated so  many  point  grids  in  chapter  3.  There  is  a  
component  called  <Grid  rectangular>
(Vector > Point > Grid rectangular) which produces a grid of points which 
are connected together make some cells also. We can control the number of 
points in X and Y direction and the distance between points.





Fig.4.3. a simple <Grid Rectangular> component with its predefined values.




You can change the size of grid by a <number slider>. I want to change the 
Z coordinates of the points as well. So I need to change the base plane of 
the grid. To do this, I introduced a <XY plane> component (Vector > 
Constants > XY plane) which is a predefined plane in the orientation of the 
X and Y axis and I displaced it in Z direction by a <Z unit> component 
(Vector > Constants > Z unit) which is a vector along Z axis with the 
length (magnitude) of one. I can change the height of this displacement by 
the size of the vector through a <number slider> that I connected to the 
input of the <Z unit> component. So by changing the position of the <XY 
plane> along the Z axis the height of the grid also changes.
50	Transformations



Fig.4.4.  Manipulated  Grid  (selected  in  green)  with  one  <number  
slider>  for  scale  of  the  grid  and another with a <Z unit> and <XY 
plane> to change the Z coordinate of the grid’s points. (Further you can 
just connect the <Z> vector component to the <Grid rectangular> component 
and get the same result).




Now if you look at the output  of the <grid rectangular> you can  see that 
we have access to  the whole points as well as grid cells and cell centres. 
I am looking for a bunch of lines that start from the grid cells’ centre 
points and spread out of it to the space. Although we can simply connect 
these points from the two <grid> component M part to a <line> component, 
the length of lines in this case would be different. But as I want to draw 
lines with the same length, I need another strategy. Here, I am going to 
use a <line SDL> component. This component draws a line by Start point(S), 
Direction
(D), and Length (L). So exactly what I need; I have the start points 
(cell’s midpoint), and length of my lines. What about the direction? Since 
the direction of my lines are in the direction of the lines that connect 
the mid points of the cells of the two grids, I am going to make a set of 
vectors by these to point sets.





Fig.4.5. Making vectors from the cells midpoints of the first grid toward 
the cells midpoints of the second  grid  by  <vector  2pt>  component  
(Vector  >  Vector  >  vector  2pt).  This  component  makes vectors by the 
start and end point of vectors.
51	Transformations








Fig.4.6. The <line SDL> component generates bunch of lines from the grid 
cell midpoints that spread out into space. I can change the length of lines 
by <number slider>.












Fig.4.7. By simply using an <end points> component (Curve > Analysis > End 
points) and using these
‘end  points’  as  the  ‘base points’  for  a  set  of  <circle>  
components  (Curve >  Primitive >  Circle)  and extruding  these  circles  
by  <extrude  point>  component  we  can  generate  a  set  of  cones,  
pointing toward same direction and we can finish our first experiment.
52	Transformations


Random displacements

I decided to make a set of randomly distributed pipes (lines) with random 
length, woven to each
other, make a funny element. I sketched it like Figure.4.8.





Fig.4.8. First sketches of model












There are different ways to design this model. I am thinking of making a 
circle as the base curve,
divide it into desire parts and then generate some random curves from these 
points and then make
pipes by these curves. But let’s see how we can do it in Grasshopper.

As I said, first I want to do it with a circle to divide it and create the 
base points. I used a <circle>
component (Curve > Primitive > Circle) and I attached a <number slider> for 
further changes of its
radius. Then we attach our circle to a <divide curve> component (Curve > 
Division > Divide curve) to
divide the circle. Again we can control the number of divisions by an 
integer <number slider>. The
<Divide curve> component gives me the points on the curve (as the division 
points). These are the
first set of points for generating our base lines.
53	Transformations



Fig.4.9. Dividing the base circle.




In this step, for some reasons! I want to generate these base lines in 
different segments. In order to draw our first step, I  need the second  
set of  points, above  the first set (to make  the lines  semi‐ horizontal  
!!!!)  and  in  a  randomly  distributed  field.  To  do  this,  I  want  
to  make  a  set  of  random vectors in Z direction and displace the first 
set of points with these random vectors. By connecting the first and second 
sets of points we would have our first part of our lines.

Because I need the same amount of vectors as the base points, I used the 
value of the <number slider> that controls the amount of base points 
(circle divisions), to generate the same amount of random  vectors.  So  I  
connect  the  <number  slider>  of  <divide  curve>  component  to  a  
<random> component N part to generate N random values. Then I used a <unit 
Z> component but I feed this
<Unit Z> vector component with the <random> component so it produces N 
random length vectors
in Z direction accordingly.





Fig.4.10. Generating random length vectors in Z direction. The <number 
slider> which is connected to the S part of the <random> component differs 
the random numbers as ‘seed’ of random engine.




So now we are ready to displace the points by these vectors. Just bring a 
<move> component (XForm
>  Euclidian  >  Move)  to  the  canvas.  Basically  a  <move>  component  
moves  geometries  by  given vectors. You can move one object/a group of 
objects with one vector/a group of vectors. Since you still  have  the  
component  of  the  source  geometry,  the  <move>  component  works  like  
a  ‘copy’ command in Rhino. To see how these vectors displaced the points, 
we can use a <line> component
to see the result.
54	Transformations





Fig.4.11. The first set of lines that made by the randomly displaced 
points.




As you see in the Figure.4.11 the lines are vertical and I am looking for 
more random distribution of points to make the whole lines penetrating each 
other. I will do it by a <jitter> component to simply shuffle the end 
points.


Fig.4.12. Shuffling the end points and making totally random lines.




The rest of the process is simple. I think three segments of lines would be 
fine. So I just repeat the move and shuffling concept to make second and 
third set of displaced points.
55	Transformations



Fig.4.13. Generating 3 line segments for each path to be converted to 
pipes. To clean up the scene you can uncheck the other components and just 
preview the lines.




Ok. We have the base geometry. Now just add a <pipe> component (Surface > 
Freeform > pipe) and attach all <line> components (by holding shift key!) 
to the ‘base curve’ part of the component and use a <number slider> to 
control the radius of pipes.


Fig.4.14. Final pipes. Uncheck the preview of lines. It speeds up your 
processing time.




That’s it. Now you can change the radius of the base circle to distribute 
the pipes in larger/smaller areas, you can change the number of pipes 
(curves), you can change the random seed and pipe’s radius. To do all and 
check the result you can go to the ‘View’ menu of the Grasshopper and 
select
‘Remote Control Panel’ to have the control panel for your adjustments which 
is much more easier than  the  sliders  inside  the  canvas  when  you  
want  to  observe  the  changes  in  Rhino  scene.  To hide/Unhide the 
canvas, just double‐click on its window title bar.
56	Transformations


















Fig.4.15. Remote Control Panel (from view menu) and observing the changes 
of the model.















Fig.4.16.  Although  the  connections  of  pipes  need  a  bit  more  
elaboration,  for  an  experiment  it  is enough.
57	Transformations


4_3_Combined Experiment: Swiss Re


Today it is very common to design the concept of towers with this 
associative modelling method. It
allows the designer to generate differentiated models simple and fast. 
There are so many potentials
to vary the design product and find the best concepts quiet quickly. Here I 
decided to model a tower and I think the “Swiss Re” tower from ‘Foster and 
partners’ seems sophisticated enough to start, for some modelling 
experiments.

Let me tell you the concept. I am going to draw a simple plan of the tower 
and copy it to make the floors.  Then  I  will  rescale  these  floors  to  
match  the  shape,  and  then  I  will  make  the  skin  of  the surface 
and finally the façade’s structural elements. I will do the process with 
very simple geometries
for this step and also to save time.




Let’s start with floors. I know that the Swiss Re’s floors are circles that 
have some V‐shaped cuts around it, but I just use a simple circle to make 
the section of the tower. Since I know that it has 41 floors I will copy 
this section for 41 times In Z direction with 4 meters space in between and 
I will play around the proportions because I don’t know the real 
dimensions, but I will try to manage it visually.





Fig.4.17.  The  <circle>  component  (plan_section)  with  radius  of  20  
which  is  copied  by  <move>
component along Z direction by a <Z unit> vector component for 41 times 
above. To get this I used a
<series> component (floors) starts from 0 and has the step size=4 with 41 
values. (I renamed  the components to recognize them easily).
58	Transformations


Now the first thing we need is to rescale these circles to make the proper 
floors. I need a <scale> component (XForm > Affine > Scale) to rescale 
them. The <scale> component needs the geometry to scale, centre for scaling 
and the factor of scaling. So I need to feed the geometry part of it by our 
floors or circles which is <move> component.

The predefined centre of scaling is the origin point, but if we scale all 
our floors by the origin as centre, the height of the tower would rescale 
and the plane of each floor would change. So we need the centre of 
rescaling at the same level at the floor level and exactly at the centre of 
it. So I used a
<Centre>  component  (Curve  >  Analysis  >  Centre)  which  gives  me  the 
 centre  of  the  circles.  By
connecting  it  to  the  <scale>  you  can  see  that  all  circles  would  
rescale  in  their  level  without movement.





Fig.4.18.  Rescaling  floors  from  their  centre  point  as  the  centre  
of  scaling,  using  a  <centre>
component. The scaled circles are selected in green.




Although I rescaled the whole circles the same, but we know that all floors 
are not in the same size,
so we need to rescale our floors different from each other; and we know 
that from the circle which
is grounded  on earth they first become bigger  up to  certain height,  
look constant  on the  middle parts and then become smaller and smaller up 
to the top point of the tower. So I need to provide a
list of scale factors for all floors which are 41 and again I now that this 
list has three different parts that if we say starts from 1 then increases 
up to certain factor, then remain constant in some floors and then 
decreases. If you look at Figure 4.19 you cans see the pictures that give 
you a sense of these  scaling  factors.  So  basically  I  need  to  
provide  a  list  of  data  (41  values)  which  is  not  strait forward 
this time.
59	Transformations



Fig.4.19.  Swiss  Re  HQ,  30  St  Mary  Axe,  London,  UK,  1997‐2004,  
(Photos  from  Foster  and  Partners  website, 
http://www.fosterandpartners.com).




Scale Intervals

As  I  mentioned  before,  intervals  are  numeric  ranges.  They  are  
real  numbers  from  lower  limit  to
upper  limit.  Since  I  said  real  numbers,  it  means  we  have  
infinite  numbers  in  between.  They  are different types of usage for 
these mathematical domains. As we experimented before, we can divide
a numerical interval by a certain number and get divisions as evenly 
distributed numbers between
two numbers.

As I also mentioned that we have three different parts for the scaling 
factors of the tower, we need three different set of numbers, the first and 
the last ones are intervals and the middle part is just a real  number  
which  is  constant.  Let’s  have  a  look  at  Figure  4.20.  Here  I  
used  two  <interval> component  (Scalar  >  Interval  >  Interval)  to  
define  two  numerical  range,  one  increasing  and  one decreasing. The 
increasing one starts from 1 which I assumed that the ground floor is 
constant and then increases up the number of the <number slider>. The 
second <interval> starts from <number slider> and ends at another <number 
slider> which is the lower limit. By using the same <number slider> for the 
middle part, I am sure that middle part of the data set is the same from 
both sides.
60	Transformations



Fig.4.20. Two <interval> components, top one increasing and the bottom one 
decreasing. I do this because I don’t know the exact proportions, but this 
help us to discuss about more interesting stuff!




Know I have the increasing and decreasing numeric intervals, but to produce 
the scaling factors I need  numbers  not  ranges.  So  I  am  going  to  
use  <range>  components  to  divide  these  numeric intervals up to 
certain numbers.




Because I don’t know the projects data, still I do not know in which floor 
it starts to remain constant and where it decreases. So in order to assign 
these factors correctly, I am going to split the floors in two  parts.  I  
am  using  a  <Split  list>  component  (Logic  >  List  >  Split  list)  
and  I  attach  the  <series> component which I named it floors to it to 
split the floors in two different parts. Then I need to know how many 
floors are there in each part that later on I can change it manually and 
correct it visually.
<List length> component (Logic > List > List length) do this for me and 
passes the number of items in
the  list,  so  I  know  that  how  many  floors  are  in  the  increasing  
scale  part  and  how  many  in  the decreasing scale part.

The only remaining part is the constant floors. I just assumed that there 
are 8 floors which their scale does not change and I need to omit them from 
the floors in the increasing and decreasing scaling part. Since two of 
these floors are included in increasing and decreasing lists as the maximum 
scale I need to omit another 6 floors. So I just need to get the number of 
the floors from <list length> and apply (‐3) function to each, to omit 
these 6 floors and distribute them between both two lists.

And the final trick! Since the <range> component divides the domain to N 
parts, it produces N+1
number at the  end  which  means  1  more  number  than we  need.  So  all  
together  I  need  to  add  a
<function>  component  by  (X‐4)  expression  to  reduce  the  number  of  
steps  that  each  <range>
component wants to divide its numeric range.
61	Transformations



Fig.4.21. Generating the scale factors.




And finally as you can see in the Figure.4.22, I merged all my data by a 
<merge 8> component to make a unified list of data which is the numeric 
factors for the increasing parts, 6 constant number just  coming  from  the 
 <  number  slider>    (the  constant  factor  between  the  two  range)  
and  the decreasing factor. The <merge 8> component includes 41 scaling 
factor that now I can attach to the
<scale> component and rescale all floors.







Fig.4.22. The <merge 8> component  includes  <range> of  increasing  
numbers, 6  constant  numbers
(which  is  the  maximum  number  of  the  increasing  and  decreasing  
parts),  and  the  <range>  of decreasing numbers as one unified list of 
data.
62	Transformations



Fig.4.23. Scaling factors





Fig.4.24. Rescaled floors. Now I can change the position of the constant 
floors and the scaling factors
to visually match the model by the original building.

Ok! Let’s go for façade elements.
63	Transformations


The  steel  elements  around  the  façade  are  helical  shapes  that  have 
 the  cross  section  like  two connected triangles but again to make it 
simple, I just make the visible part of it which is almost like
a triangle (in section). I want to generate these sections and then ‘loft’ 
them to make a surface.

I  started  with  a  <polygon>  component  (Curve  >  Primitive  >  
Polygon).  I  used  an  <end  points>
component  to  get  the  start/end  points  of  my  floors.  By  attaching  
these  points  as  the  base  for
<polygon> I can generate couple of polygons on the start points of my 
floors. I attached a <number slider> to  the <polygon>  to  control its  
radius  and  I  set the  number of  segments  to 3  manually.  I renamed 
the <scale> component to the <rescaled_floors>.







Fig.4.25. Polygons positioned on the facade.






Now I want to make the helical transformation for the polygons. For some 
reasons I think that every floors rotate for 5 degree! So I need to rotate 
all polygons for 5 degree around the centre of the floors. So I brought a 
<rotate> component to the canvas (XForm > Euclidian > Rotate). Geometry is 
my <polygon> and the base of rotation is the centre of the floors / 
<centre> of circles. To produce the rotation angle  I need  a list of  
incremental factors  that each  time adds 5  degree. So  I used  a
<series> starts from 0 with the step size of 5 and with 41 values which 
come from the floors and
number of <polygon> also. The only thing remain is because <rotate> 
component works with Radian
I need to convert Degree to Radian by a <function> which is Radian=Degree * 
Pi / 180 (There is a predefined function called RAD(x) that converts degree 
to radian also. Check the functions library).
64	Transformations



Fig.4.26. Rotating the polygons around the centre of floors, each for 5 
degree from the previous one.






Now just use a <loft> component to make a surface by connecting all these 
sections together. To make the scene clean, uncheck the preview of any 
unnecessary geometry.

As you can see, we don’t have the top point of the tower because we don’t 
have any floor there. We know that the height of tower is 180m. So I added 
a simple <point> component (0, 0, 180) to the canvas  and  I  attached  it  
to  the  <polygon>  component  (by  holding  shift).  So  the  <polygon> 
component produces another polygon at the top point of the tower and the 
number of polygons becomes 42. So I changed the <series> component to 
produce 42 numbers as well. I know that the top part of the “Swiss Re” is 
more elegant than this model but for our purpose this is fine.





Fig.4.27. one of the façade elements made by the <loft> component.
65	Transformations


To  generate  these  elements  all  around  the  building,  I  am  using  a 
 <rotate>  component  which  I
attached  the  <loft>  object  as  source  geometry  and  I  used  a  
<range>  from  0  to  2Pi  divided  by  a
<number slider> as the number of elements, to rotate it all around the 
circle. Since the centre of rotation is the Z axis at the centre of the 
tower, and it is pre‐defined on the component, I do not need to change it 
or introduce any plane for rotation.







Fig.4.28. first set of spiral elements around the tower.







Fig.4.29. I need to <mirror> (XForm > Euclidian > Mirror) the rotated 
geometry by <YZ plane> (Vector
> Constants > YZ plane) to have the lofted elements in a mirrored helical 
shape. So at the end I have a lattice shape geometry around the tower.
66	Transformations


Glass cover

To cover the whole tower simply with glass, I should go back to the floors 
component and <loft>
them. Again since we don’t have any floor at the top point of the tower, I 
used another <circle> component and I feed it by the top point as the 
position and I attached it to the <loft> object to make the loft surface 
complete up to top point.





Fig.4.30.a. lofting floor curves to make the façade’s glass cover.







Fig.4.30.b. The lofted surface covers the whole façade. In the Swees Re 
project, there is two colours
of glass. If once we decided to make this effect, we can use façade 
structure to produce different surfaces and render them differently.
67	Transformations


















4.31. Final model. Although it is not exactly the same, but for a sketch 
model in a short time, it would work.
68	Transformations


4_4_On Attractors


“Attractor is a set of states of a dynamic physical system toward which 
that system tends to evolve,
regardless of the starting conditions of the system. A point attractor is 
an attractor consisting of a
single state. For example, a marble rolling in a smooth, rounded bowl will 
always come to rest at the
lowest point, in the bottom center of the bowl; the final state of position 
and motionlessness is a
point attractor.”




































Fig.4.32. Strange Attractor.




In the case of design and geometry, attractors are elements (usually points 
but could be curves or
any other geometry) that affect the other geometries in the space, change 
their behaviour and make
them  displace,  re‐orientate,  rescale,  etc.
They  can  articulate  the
space  around  themselves  and
introduce  fields  of  actions  with  specific  radius  of  power. 
Attractors  have  different applications  in
parametric design since they have the potential to change the whole objects 
of design constantly.
Defining a field, attractors could also affect the multiple agent systems 
in multiple actions. The way
they  could  affect  the  product  and  the  power  of  attractors  are  
all  adjustable.  We  go  through  the
concept of attractors in different occasions so let’s have some very simple 
experiments first.
69	Transformations


Point Attractors

I have a grid of points that I want to generate a set of polygons on them. 
I also have a point that I
named  it  <attractor_1>  and  I  draw  a  <circle>  around  it  just  to  
realize  it  better.  I  want  this
<attractor_1> affects all my <polygon>s on its field of action. It means 
that based on the distance between  each  <polygon>  and  the  
<atractor_1>,  and  in  the  domain  of  the  <attractor_1>,  each
<polygon> respond to the attractor by change in its size.





Fig.4.33. Base <point_grid> and the <polygon>s and the <attractor_1>.




The algorithm is so simple. Based on the <distance> between <attractor_1> 
and the <Pt‐grid>, I want
to affect the radius of the <polygon>, so the ‘relation’ between attractor 
and the polygons define by their distance. I need a <distance> component to 
measure the distance between <attractor_1> and the polygon’s center or 
<pt_grid>. Because this number might become too big, I need to <divide>
(Scalar > Operators > Division) this distance by a given number from 
<number slider> to reduce the
power of the <attractor_1> as much as I want.





Fig.4.34. <Distance> divided by a number to control the ‘power’ of the 
<attractor_1>. I also made a Cluster by <attractor_1> and its <circle> to 
have one component as attractor in the canvas. You can convert any group of 
related geometries to clusters by selecting them and using ‘make cluster 
from selection’ from the canvas toolbar (or Arrange menu or Ctrl+G).
70	Transformations


Now if you connect this <div> component to the Radius (R) part of the 
<polygon> you can see that the radius of polygons increases when they go 
farther from the <attractor_1>. Although this could
be good for the first time, we need to control the maximum radius of the 
polygons, otherwise if they
go farther and farther, they become too big, intersecting each other 
densely (it also happens if the power of the attractor is too high). So I 
control the maximum radius value of the polygons manually.





Fig.4.35. By using a <minimum> component (Scalar > Util > Minimum) and a 
user defined number, I am  telling  the  algorithm  to  choose  the  value  
from  the  <div>  component,  if  it  is  smaller  than  the number that I 
defined as a maximum radius by <number slider>. As you can see in the 
pictures, those polygons that are in the power field of attractor being 
affected and others are constant.

Now if you change the position of the <attractor_1> in the Rhino workplace 
manually, you can see that all polygons get their radius according to the 
<attractor_1> position.



























Fig.4.36. The effect of the <attractor_1> on all polygons. Displacement of 
the attractor, affects all polygons accordingly.
71	Transformations



Fig.4.37. Wiyh the same concept, I can displace polygons in Z direction 
based on the numbers coming from the <Min> component or changing it by 
mathematical functions, if necessary.




Simple. I can do any other function on these polygons like rotate, change 
colour, etc. But let’s think what would happen if I would have two 
attractors in the field. I made another cluster which means another point 
in Rhino associated with a <point> and <circle> in Grasshopper.

It  seems  that  the  first  part  of  the  algorithm  is  the  same.  
Again  I  need  to  measure  the  distance between this <attractor_2> and 
the polygons’ center or <pt_grid> and then find the <min> of these 
distances and the previously defined maximum number for the radius.





Fig.4.38. Introducing second <attractor_2> to and applying the same 
algorithm to it.




Now we have two different data lists that include the distance from the 
polygon to each attractor. Since the closer attractor would affect the 
polygon more, I should find one which is closer, and use that one as the 
source of action. So I will use a <min> component to find which distance is 
minimum
or which point is closer.
72	Transformations




















4.39. Finding the closer attractor. After finding the closer one by <min> 
component, the rest of the process would be the same. Now all <polygon>s 
are being affected by to attractors.







Fig.4.40.  Again  you  can  change  the  position  of  the  attractors  and 
 see  how  all  polygons  reacting accordingly.




We can have more and more attractors. The concept is to find the attractor 
which is closer for each polygon  and  apply  the  effect  by  selecting  
that  one.  Selection  in  terms  of  distance  happens  with
<min> functions, but we will talk about other types of selection later.

There  are  other  ways  of  dealing  with  attractors  like  using  <cull> 
 component.  In  this  method  you need to provide different lists of data 
from the distance between points and attractors and then culls those  far,  
select the  closer  one by  simple  Boolean function  of  a>b. since  there 
 are  multiple examples on this topic on‐line, I hope you will do them by 
yourself.
73	Transformations


Curve Attractors: Wall project

Let’s complete this discussion with another example but this time by Curve 
attractors because in so
many cases you need to articulate your field of objects with linear 
attractors instead of points.

My aim here is to design a porous wall for an interior space to let me have 
a multiple framed view to the other side. This piece of work could be cut 
from sheet material. In my design space, I have a plane sheet (wall), two 
curves and bunch of randomly distributed points as base points of cutting 
shapes. I decided to generate some rectangles by these points, cutting them 
out of the sheet, to make this porous wall. I also want to organize my 
rectangles by this two given curve so at the end, my  rectangles  are  not  
just  some  scattered  rectangles,  but  randomly  distributed  in  
accordance  to these curves which have a level of organisation in macro 
scale and controlled randomness in micro scale.

What I need is to generate this bunch of random points and displace them 
toward the curves based
on the amount of power that they receive from these lines. I also decided 
to displace the points toward both curves so I do not need to select closer 
one, but I displace the points based on their distance  to  the  curve.  
Then  I  want  to  generate  my  rectangles  over  these  points  and  
finally  I  will define the size of these rectangles in relation to their 
distance to the attractors.










Fig.4.41. Generating a list of randomly distributed <point>s and 
introducing the attractors by two
<curve> component (Params > Geometry > Curve) over a sheet. I used an 
<interval> component to define the numeric interval between 0 and <number 
slider> for the range of random points. I will make a cluster by 
<interval>, <random>, <jitter> and <point> to make the canvas more 
manageable.
74	Transformations





Fig.4.42. When the attractor is a point, you can simply displace your 
geometry towards it. But when the  attractor  is  a  curve,  you  need  to  
find  a  relative  point  on  curve  and  displace  your  geometry towards 
that specific point. And this point must be unique for each geometry, 
because there should
be a one to one relation between attractor and any geometry in the field. 
If we imagine an attractor
like a magnet, it should pull the geometry from its closest point to the 
object. So basically what I first need is to find the closest point of 
<Rnd_pt_grid> on both attractors. These points are the closest points  on  
the  attractors  for  each  member  of  the  <Rnd_Pt_Grid>  separately.  I  
used  <Curve  CP> component  (Curve  >  Analysis  >  Curve  CP)  which  
gives  me  the  closest  point  of  the  curve  to  my
<Rnd_Pt_Grid>.










Fig.4.43. In order to displace the points towards the attractors, I need to 
define a vector for each point in <Rnd_Pt_Grid>, from the point to its 
closest point on the attractors. Since I have the start and end point of 
the vector I am using a <vector 2Pt> component to do that. The second point 
of the vector (B port of the component) is the closest point on the curve.
75	Transformations



Fig.4.44.  Now  I  connected  all  my  <Rnd_Pt_Grid>  to  two  <move>  
components  to  displace  them towards the attractors. But if I use the 
vector which I created in the last step, it displaces all points onto the 
curve and that’s not what I want. I want to displace the points in relation 
to their distance to the attractor curves. If you look at the <Curve CP> 
component it has an output which gives us the distance between the point 
and the relevant closest point on the curve. Good. We do not need to 
measure the distance by another component. I just used a <Function 2> 
component and I attached the  distance  as  X  and  a  <number  slider>  to 
 Y  to  divide  the  X/Log(Y)  to  control  the  factor  of displacement 
(Log function change the linear relation between distance and the resulting 
factor for displacement).









I just used a <multiply> component (Vector > Vector > Multiply), I attached 
the <vector 2P>as base vector and I changed its size by the factor I 
created by distance, and I attached the resulting vector
to the <move> components which displaces the <Rnd_Pt_Grid> in relation to 
their distance to the
attractors, and towards them.
76	Transformations














Fig.4.45.  The  <number  slider>  changes  the  power  with  which  
attractors  displace  objects  towards themselves.
77	Transformations



Fig.4.46. I used a <rectangle> component and I attached the <move>d or 
displaced points to it as the base point (planes) for my rectangle 
components. But as I told you, I want to change the size of the
<rectangle>s based on their distances to each <attractor>. So I used the 
same numerical values which
I used for vector magnitude and I changed them by two functions. I divided 
this value by 5 for the X value of the rectangles and I divided by 25 for 
the Y value. As you can see, rectangles have different dimensions based on 
their original distance from the attractor.







Fig.4.47. Manipulating the variables would result in differentiated models 
that I can choose the best one for my design purpose.
78	Transformations












Fig.4.48. Different shadow effects of the final design product as a porous 
wall system.
79	Transformations



Fig.4.49. Final design product.
