





























Chapter_3_Data sets and Math
20	Data sets and Math















Chapter_3_Data sets and Math


Although in 3D softwares we used to select our geometry from menus and draw 
them explicitly by
clicking  without  thinking  of  the  mathematical  aspects  of  what  we  
design,  in  order  to  work  with Generative Algorithms, as the name 
sounds, we need to think a bit about data and math to make inputs  of  
algorithm  and  generate  multiple  objects.  Since  we  do  not  want  to  
draw  everything manually, we need some sources of data as the basic 
ingredients to make this generation possible.

The way algorithm works is simple and straightforward. As I said, instead 
of copying by clicking 100
times in the screen, we can tell the algorithm, copy an item for 100 times 
in X positive direction. To
do that you need to define the 100 as number of copying and X Positive 
direction for the algorithm, and it performs the job automatically. All we 
are doing in geometry has some peace of math behind. We can use these 
simple math functions in our algorithms, in combination of numbers and 
objects, generate infinite geometrical combinations.

Let’s have a look; it is easier than what it sounds!




3_1_Numerical Data sets


First  of  all  we  should  have  a  quick  look  at  numerical  components 
 to  see  how  we  can  generate
different numerical data sets and then the way we can use them.




One numerical value

The  most  useful  number  generator  is  <Number  slider>  component  
(Params  >  Special  >  Number
slider) that generates one number which is adjustable manually. It could be 
integer, real, odd, even and with limited lower and upper values. You can 
set them all by ‘Edit’ part of the context menu.

For setting one fixed numeric value you can go to the Params > Primitive > 
Integer / Number to set one value.
21	Data sets and Math


Series of numbers

We  can  produce  a  list  of  discrete  numbers  by  <series>  component  
(Logic  >  Sets  >  Series).  This
component produces a list of numbers which we can adjust the start point, 
step size of the numbers, and the number of values.

0, 1, 2, 3, … , 100

0, 2, 4, 6, … , 100

10, 20, 30, 40, … , 1000000





Rang of numbers

We  can  divide  a  numerical  range  between  a  low  and  high  value  by 
 evenly  spaced  numbers  and
produce a range of numbers. We need to define an interval to set the lower 
and upper limit and also the number of steps between them (Logic > Sets > 
Range).

1, 2, 3, … , 10

1, 2.5, 5, … , 10

1, 5, 10





Intervals

Intervals  provide  a  range  of  all  real  numbers  between  a  lower  
and  upper  limit.  There  are  one
dimensional and  two  dimensional  intervals  that we  talk about  them 
later. We  can  define  a  fixed interval by using Params > Primitive  > 
Interval/interval2  component or we  can go to the Scalar  > Interval which 
provides a set of components to work with them in more flexible ways.

Intervals by themselves do not provide numbers, they are just extremes, 
upper and lower limits. As you now there are infinite real numbers between 
any two numbers. We use different functions to divide them and use division 
factors as the numerical values.
22	Data sets and Math


3_2_On Points and Point Grids


Points are among the basic elements for geometries and Generative 
Algorithms. As points mark a
specific position in the space they can be a start point of a curve or 
multiple curves, centre of a circle, origin of a plane and so many other 
roles. In Grasshopper we can make points in several ways.

‐ We can simply pick a point/bunch of points from the scene and introduce 
them to our workplace
by <point> component (Params > Geometry > point) and use them for any 
purposes (These points could  be  adjusted  and  moved  manually  later  on 
 in  Rhino  scene  and  affect  the  whole  project. Examples on 
chapter_2).

‐  We  can  introduce  points  by  <point  xyz>  component  (vector  >  
point  >  point  xyz)  and  feed  the coordinates of the points by 
different datasets, based on our needs.

‐ We can make point grids by <grid hexagonal> and <grid rectangular> 
components.

‐ We can extract points from other geometries in many different ways like 
endpoints, midpoints, etc.

‐ Sometimes we can use planes (origins) and vectors (tips) as points to 
start other geometries and vice versa.

You have seen the very first example of making points in chapter_2 but 
let’s have a look at how we can produce points and point sets by <series>, 
<range> and <number slider> components and other numerical data providers.


Fig.3.1.  feeding  a  <point  xyz>  component  by  three  <number  slider>  
to  make  a  point  by  manually feeding the X,Y and Z coordinates.


Fig.3.2.  Making  a  grid  of  points  by  <series>  and  <point  xyz>  
components  while  the  first  <number sliders> controls the distance 
between points and the second one controls the number of points by 
controlling the number of values in <series> component (The data match of 
the <pt> set into cross reference to make a grid of points but you can try 
all data matching options).
23	Data sets and Math



Fig.3.3. Dividing a numerical range from 0 to 1 by 5 and feeding a <pt> 
component with ‘Longest list’ data  match.  You  can  see  we  have  6  
points  which  divided  the  range  by  5  and  all  points  drawn between 
the origin point and (1, 1) on the Rhino workplace (you can change the 
lower and upper limit of the <range> to change the coordinates of the 
point).




Since  the  first  experiments  look  easy,  let’s  go  further,  but  you  
can  have  your  own  investigations around these components and provide 
different point grids with different positions and distances.




3_3_Other Numerical Sets


Random data sets

I was thinking of making a randomly distributed set of points for further 
productions. All I need is a
set of  random  numbers  instead  of  a  <series> to  feed  my  <pt>  
component  (I  use  <pt>  instead  of
<point xyz> because it is shown on the component). So I pick a <random> 
component from Logic >
sets. To avoid the same values for X,Y and Z, I need different random 
numbers for each.


Fig.3.4. Making a random point set.

The <random> component  produces 10  random numbers which  is controlled  
by <number  slider> and then  this  list  is shuffled  by  <jitter> 
component  (Logic >  Sets  >  Jitter) for  Y  coordinate  of  the points 
once, and again for Z coordinates, otherwise you could see some sort of 
pattern inside your grid (check it!). The data match set to longest list 
again to avoid these sorts of patterns in the grid.

In the figure 3.4 all points are distributed in the space between 0 and 1 
for each direction. To change the  distribution  area  of  the  points  we  
should  change  the  numerical  domain  in  which  random component  
produces  the  numbers.  This  is  possible  by  manually  setting  the  
“domain  of  random numeric range” on Rhino command line or by defining the 
domain intervals adjustable by sliders.
(Fig.3.5)
24	Data sets and Math



Fig.3.5. Setting up a domain by an <interval> component (Scalar > Interval 
> Interval) to increase the distribution area of the points (look at the 
density of the scene’s grid in comparison with the Fig.3.4).
If you connect only one <number slider> to the domain of the <random> 
component it just adjusts the upper interval of the domain (with lower as 
0).




Fibonacci series

What  about  making  a  point  grid  with  non‐evenly  spaced  increasing  
values?  Let’s  have  a  look  at
available components. We need series of numbers which grow rapidly and 
under Logic tab and Sets section we can see a <Fibonacci> component.

A Fibonacci is a series of numbers with two first defined numbers (like 0 
and 1) and the next number
is the sum of two previous numbers.

N(0)=0, N(1)=1, N(2)=1, N(3)=2, N(4)=3, N(5)=5, … , N(i)=N(i‐2)+N(i‐1)

Here are some of the numbers of the series: 0, 1, 1, 2, 3, 5, 8, 13, 21, 
34, 55, 89, … As you see the numbers grow rapidly.
Here I use <Fibonacci> series (Logic > Sets > Fibonacci) to produce 
incremental numbers and feed the <pt> component with them.





Fig.3.6.  Using  <Fibonacci>  series  to  produce  increasing  distances  
(none‐evenly  spaced  series  of numbers) to make points. The number of 
points could be controlled with a <number slider>.
25	Data sets and Math


3_4_Functions


Functions are components that are capable of performing math functions. 
There are functions from
one to eight variables (Scalar > Expressions).   You need to feed a 
function with different data (not always numeric but also Boolean, 
coordinate, etc) and it performs the user defined function on the input 
data. To define the function you can right‐click on the (F) part of the 
component and type it or
go to the Expression Editor. Expression editor has so many predefined 
functions  and a library of
math functions for help.




Math functions

Using the predefined components is not always what we aimed for, but in 
order to get the desired
result  we  can  use  mathematical  functions  to  change  the  data  sets  
and  feed  them  for  making geometries.

A simple example is the mathematical function of a circle that is X=Sin(t) 
and Y=Cos(t) while (t) is a range of numbers from 0 to 2 Pi. I am producing 
it by a <range> of numbers which is starts from 0 to
1 by N number in between, times 2Pi by <function> that means a range of 
numbers from 0 to 2pi
that makes a complete circle in radian.


Fig.3.7.  Parametric  circle  by  mathematical  functions.  You  have  
<Sin>  and  <Cos>  functions  in  the
Scalar > Trig. (F(x)=x * 2Pi).


Fig.3.8. Series of points which is defined by <Fibonacci> series and simple 
mathematical functions
(x‐>F(x)=x/100, y‐>F(x)=x/10). The selected green F(x) is a simple function 
to add 1 to the <number slider> (x+1) in order to make the values of 
<series> numbers equal to the Fibonacci numbers. The aim is to show you 
that we can simply manipulate these data sets and generate different 
geometries accordingly.
26	Data sets and Math


Fig.3.9. A <range> of numbers from 0 to 2 times by 2Pi with <Function> that 
make it a numerical range   from   0   to   4Pi   that   feeds   the   <pt> 
  component   by   the   following   math   function
(X=t * Sin(t), Y=t * Cos(t)).

You can reduce all components between <range> and <pt> by two functions to 
feed the <pt> by defining the whole process in Expression Editor.

X of pt > F(x)=X * Sin (x*2*Pi) Y of pt > F(x)=X * Cos(x*2*Pi)











Fig.3.10.  Inter  tangent  spirals  from  two  inverted  spiral  point  
sets  (<range>  interval  from  0  to  4 multiplied by 2Pi, makes the data 
set from 0 to 8Pi which is inverted for the second spiral by <Reverse list> 
component from Logic > Lists as 8pi to 0).

First <pt>: X=t * Sin(t), Y=t * Cos(t)	in which t=0 to 8Pi

Second <pt>: X=t’ * sin(t), Y=t’ * Cos(t)	in which t’=8Pi  to 0 (<reverse 
list>)
27	Data sets and Math



Fig.3.11. Moebius by points

X= Sin(u)*(‐2+v*sin(u/2)) Y= Cos(u)*(‐2+v*sin(u/2)) Z= v*Cos(u/2)
While u=0 to 8Pi and v=‐2 to 2




Playing around the math functions could be endless. You can find so many 
mathematical resources
to match your data sets with them. The important point is that you can 
manipulate the original data sets and generate different numerical values 
and feed other components by them.

So as you see by some simple set of numerical data we can start to generate 
different geometries. Since we need to work with these data sets as a 
source of our geometries lets go further with them.



















Fig.3.12.Enneper surface, by Rhino’s Math function plug‐in. Designing 
surfaces with mathematical equations.
28	Data sets and Math


3_5_Boolean Data types


Data is not limited to Numbers. There are other data types that are useful 
for other purposes in
programming  and  algorithms.  Since  we  are  dealing  with  algorithms,  
we  should  know  that  the progress  of  an  algorithm  is  not  always  
linear.  Sometimes  we  want  to  decide  whether  to  do something  or  
not.  Programmers  call  it  conditional  statements.  And  we  want  to  
see  whether  a statement meets certain criteria or not to decide what to 
do next. The response of the conditional
‘question’ is a simple yes or no. in algorithms we use Boolean data to 
represent these responses. Boolean values are data types which represent 
True (yes) or False (no) values only. If the statement meets the criteria, 
the response is True, otherwise False. As you will see later, this data 
type is very useful in different cases when you want to decide about 
something, select some objects by certain criteria, sort objects, etc.


Fig.3.13. Here I generated ten <random> values and by a <function> 
component I want to see if these numbers are less than a certain 
<Upper_limit> or not. As you see the <function> is simply X>Y and whenever 
the numbers meet the criteria, the function passes True to the <panel>.





Fig.3.14.a. For the next step, I used a <Modulus> component (Scalar > 
Operators > Modulus) to find the remainder of the division of the Random 
values by <2> and I pass the result to a <function> to see
if this remainder =0 or not (f(x)=x=0), simply means whether the number is 
even or not. As you see the result is another <panel> of True/False values.
29	Data sets and Math





Fig.3.14.b.Here I used a <Gate And> component (Logic > Boolean > Gate And) 
and I attached both
<function>s to perform Boolean conjunction on them. The result is True when 
both input Boolean values are True, otherwise it would be False. As you 
see, those numerical values which are both even and bigger than the 
<Upper_limit> are meeting the criteria and pass True at the end. We will 
discuss how to use these Boolean values later.






There are multiple Boolean operators on Boolean section of the Logic tab 
that you can use to create your criteria and combine many of them.







Fig.3.15. we can manually define a set of Boolean data by <Boolean> 
component from Params tab under Primitive section or use <Boolean Toggle> 
in Special section to use one manually changeable Boolean value.
30	Data sets and Math


3_6_Cull Patterns


There are many reasons that we might want to select some of the items from 
a given data set and
do not apply a function to all elements. To do this we either need to 
select some of the specific items from a list or omit other items. There 
are different ways to achieve this but let’s start with omitting or culling 
lists of data.

Up to now there are two <cull> components to cull a list of data in 
Grasshopper. While <cull Nth>
omit  every  N  item  of  the  given  list  of  data,  <cull  pattern>  
takes  a  pattern  of  Boolean  values
(True/False) and cull a list of data, based on this pattern, means any item 
of the list that associates with True value in Boolean list will pass and 
those that associate with False will omit from the list.

If the number of values in the data list and Boolean list are the same, 
each item of the data list being evaluated  by  the  same  item  in  the  
Boolean  list.  But  you  can  define  a  simple  pattern  of  Boolean 
values  (like  False/False/True/True  which  is  predefined  in  the  
component)  and  <cull>  component would repeat the same pattern for all 
items of the data list.




Distance logic

I am thinking of selecting some points from a point set based on their 
distance to another point
(reference point). Both point set and the reference point are defined each 
by a <point> component. First of all what we need is a <distance> component 
(Vector > Point > Distance) that measures the distance between points and 
the reference. I compared these distances by a user defined number
(<number  slider>)  with  a  <F2>  component.  This  comparison  generates  
Boolean  values  as  output
(True/False) to show whether the value is smaller (True) or bigger (False) 
than the upper limit. I am going  to  use  these  Boolean  values  to  feed 
 the  <Cull  pattern>  component  (the  function  of  <F2> component 
defined as f=x>y).

As mentioned before, <Cull pattern> component takes a list of generic data 
and a list of Boolean data and omits the members of the generic list of 
data who associate with the false value of the Boolean list. So the output 
of the <Call pattern> component is a set of points that associate with True 
values which means they are closer than the specified number shown on the 
<number slider>,
to the reference point, because the X>Y function always pass True for the 
smaller values. To show
them better I just connected them to the reference point by a simple line.


Fig.3.16. Selection of points from a point set based on their distance from 
a reference point with <Cull pattern> component.
31	Data sets and Math


Topography

Having tested the first distance logic, I am thinking of selecting some 
points which are associated
with contour lines on a topography model, based on their height.





Fig.3.17. Topography with points associated with contour lines.




I want to select these points based on their height. What I have is a point 
set which is defined by a
<point> component (named topography). I need the height of the point with 
the same logic as the above example to select the specific points. Here I 
used a <Decompose> component (Vector > Point
> Decompose) to get the Z values of these points. I compared these values 
with a given number
(<number slider>) with a <F2> component to produce a list of associative 
Boolean values. The <Cull pattern> component passes those who associated 
with the True values which means selected points are higher than the user 
defined height value (the function of <F2> component defined as f=x>y).







Fig.3.18. Selected points which are higher than 4.7550 units! (A user 
defined value). These points are now ready to plant your Pine trees!!!!
32	Data sets and Math


Connectivity logic: Triangles

Let’s have another example of culling this time with <Cull Nth>. Imagine we 
have a network of points
and we want to draw lines to make triangles with a pattern like 
Figure.3.19.


Fig.3.19. Making triangles by a network of points.




The first step is to simply create a grid of points by <series> and <pt> 
components. The next step is
to find the proper points to draw lines in between. Each time we need a 
line starts from a point and ends at the next point on the next column, 
then another line goes from there to the back column but
at the next row and final line goes back to the start point. To do this, it 
seems better to make three different lists of points, one for all first 
points, one for all second points and another for all third points and then 
draw line between them.

I can use the original points as the list for all start pints.

The first second point is the second point on the point set and then the 
list goes on one by one. So to select the second points I just shifted the 
original list by <Shift list> component (Logic > List > Shift list) by 
shift offset=1 to shift the data set by one value and make the second 
points list. (Go to the
<shift list> help to learn more about component). Since the original data 
is a set of points which make the start points in our example, the shifted 
data would be the second point of the triangles (all second points in the 
network).

The third point of triangles is in the same column as the start point but 
in next row, so I shifted the original  list  of  points  again  by  shift  
offset=the  number  of  columns  (the  value  comes  from  the
<number slider>) to find these points for all point set and make a list of 
all third points.
33	Data sets and Math



Fig.3.20.  Selected  item  is  the  shifted  points  by  the  shift  offset 
 value  of  equal  to  the  number  of
columns which produces all third points of the triangles.




To complete the task I need to omit some points in each set. First of all 
the points in the last column
never could be first points of triangles so I need to omit them from the 
list of start points. The points
on the first column also never could be the second points, so I need to 
omit them from the list of
second points and the same for last column again as third points. So 
basically I attached all points’
lists each to one <Cull Nth> component which omits specific members of a 
data set by a number
which is cull frequency (Fig.3.17). In this case all data sets culled by 
the number of columns which is
clear why. So I just connected the <number slider> to each <Cull Nth> 
component as freque
cy.







Fig.3.21.  Using  <Cull  Nth>  to  omit  A.  last  column,  B.  first  
column  and  c.  last  column  of  the  first,
second and third points’ lists.




The next step is just to feed three <line> components to connect first 
points to the second, then
second points to the third and finally third points to the first again.
34	Data sets and Math



















Fig.3.22. Making lines by connecting culled lists of points to the <Line> 
component.






Now by changing the <number slider> you can have different grids of points 
which produces these triangles accordingly.

Although there are still some problems with our design and we now that we 
should not start any triangle from the points of the last row, but the 
concept is clear…… so let’s go further. We will come back to this idea 
while talking about mesh geometries and then I will try to refine it.
35	Data sets and Math


3_7_2D Geometrical Patterns


Geometrical  Patterns  are  among  the  exciting  experiments  with  the  
Generative  Algorithms  and  in
Grasshopper. We have  the potential to  design a  motif and then  
proliferate it as  a pattern which could be used as a base of other design 
products and decorations. In case of designing patterns we should have a 
conceptual look at our design/model and extract the simple geometry that 
produces the  whole  shape  while  being  repeated.  So  by  producing  the 
 basic  geometry  we  can  copy  it  to produce the pattern as large as we 
need (Fig.3.23).


Fig.3.23. Extracting the concept of a pattern by simple geometries.




I still insist on working on this models by data sets and simple 
mathematical functions instead of other useful components just to see how 
these simple operations and numerical data have the great potential to 
generate shapes, even classical geometries.
36	Data sets and Math



Fig.3.24.  Complex  geometries  of  Sheikh  Lotfolah  Mosque’s  tile  work  
comprises  of  simple  patterns
which created by mathematical‐geometrical calculations. Sheikh Lotfolah 
Mosque, Isfahan, Iran.







Simple linear pattern

Here I decided to make a simple pattern by some intersecting lines and my 
aim is to draw some
patterns similar to Figure.3.25.













Fig.3.25. Examples of simple concepts to make patterns.




I started my definition by a <series> which I am able to control the number 
of values (here points)
and the step size (here distance between points). By this <series> I 
generated a set of points and I
also generated another three different sets of points with different Y 
values which I am adjusting
them relatively by a <number slider> and <F1> components (y=‐x/3, y=x, 
y=x/3, y=x+(x/3) if x is the
number coming from the <number slider>).
37	Data sets and Math



Fig.3.26. Generating four set of points, all associated with a one <series> 
component which controls the number and distance of points and another 
<number slider> which controls the Y value of the point sets (I am using 
longest list for points data matching).




To get the “zig‐zag” form of the connections I need to cull the point sets 
with <cull pattern> one with
True/False and another one with False/True pattern and then connect them 
together (Fig.3.20).






















Fig.3.27. Cull pattern and selected points as a base for “zig‐zag” pattern.






Since I want to draw poly line on this culled point sets, I cull all point 
sets with the same logic and merge these points to make a one merged stream 
by <merge 02> component (Logic > Streams > Merge 02).
38	Data sets and Math



Fig.3.28. Cull pattern for the middle points inverted to make the mirrored 
pattern of the first set.

To make the second rows of points, I used the same points of the first row 
and merge them again with the second row to have four merged data streams 
at the end. If you connect these merged data sets to a <poly line> 
component you will get a z‐shaped poly line and that is because the points 
are not in a desired order and the <merge> component just add the second 
list of points at the end of first one. So I need to sort the points in the 
desired way. A <Sort> component sorts some generic data based on a sortable 
key. What do we have as a sortable key?

If  we  look  at  the  order  of  the  points  we  can  see  that  the  X  
dimension  of  the  points  increases incrementally,  which  seems  
suitable  as  an  item  to  sort  our  points  with.  To  do  this,  we  
need  to extract  the  X  coordinate  of  the  points.  The  <decompose>  
component  make  it  possible.  So  we connect the X coordinate of the 
points as a sortable key to the <sort> component and then sort the points 
with that. Finally we can use these sorted points to feed <polyline> 
components, make our pattern with them (Fig.3.29).


Fig.3.29. Sorting points by their X component as key and then making 
polyline with them. I sorted mirrored geometry by another <sort> component 
because they are from different cull pattern.
39	Data sets and Math






Fig.3.30. Later on we will discuss how we could create repetitive patterns 
by simple components and the way we can array the simple motif to create 
complex geometries.
40	Data sets and Math


Circular patterns

There are endless possibilities to create motifs and patterns in this 
associative modelling method.
Figure.3.31 shows another motif which is based on circular patterns rather 
than the linear one. Since there are multiple curves which all have the 
same logic I will just describe one part of the algorithm and keep the rest 
for you.























Fig.3.31. Circular geometrical patterns which is repeated in the second 
picture.




The start point of this pattern is a data set which produces a bunch of 
points along a circle, like the example we have done before. This data set 
could be rescaled from the centre to provide more and more circles around 
the same centre. I will cull these sets of points with the same way as the 
last example. Then I will generate a repetitive ‘zig‐zag’ pattern out of 
these rescaled‐circular points to connect them to each other, make a star 
shape curve. Overlap of these stars could make motifs and using different 
cull patterns make it more interesting.





Fig.3.32. Providing a range of 0 to 2Pi and by using Sin/Cos functions, 
making a first set of points. The second <number slider> changes the radius 
of the circle (power of the X and Y).
41	Data sets and Math



Fig.3.33. Increasing the numbers of Sin/Cos functions by a <number slider> 
making the second set of points with bigger radius.





Fig.3.34. First and second circles made by points.




In order to cull the points, we can simply use the <Cull pattern> for the 
points and use True/False like the last example. But how we can sort the 
list of points after all? If you connect the culled points
to a <poly line> component you will not get a star shape poly line but two 
offset polygon connected
to each other. Here I think it is better to sort the points based on their 
index number in the set. Because I produced the points by a <range> 
component, here we need a <series> component to provide  the  indices  of  
the  points  in  the  list.  The  N  parameter  of  the  <range>  factor  
defines  the number of steps of the range so the <range> produces N+1 
number. I need a <series> with N+ 1 value to be the index of the points 
(Fig.3.34) and cull and sort these points based on their indices.
42	Data sets and Math



Fig.3.35. Generating index number of the points.







Fig.3.36. We need to cull indices and points the same and merge them 
together. Although the result
of the merging for <series> could be again the numbers of the whole data 
set, the order of them is like the points, and so by sorting the indices as 
sortable keys we can sort the points as well. The only thing remain is to 
feed a <polyline> component by sorted points.
43	Data sets and Math



Fig.3.37. Generating Polyline by sorted points.







Fig.3.38. Star‐shaped polyline.






The same logic could be used to create a more complex geometry by simply 
generating other point sets,  culling  them  and  connecting  them  
together  to  finally  produce  patterns.  We  can  use  these patterns as 
inputs for other processes and design other decorative shapes.
44	Data sets and Math



Fig.3.39.  You  can  think  about  different  possibilities  of  the  
patterns  and  linear  geometries  in applications.









Although I insisted to generate all previous models by data sets and simple 
mathematical functions, we will see other simple components that made it 
possible to decrease the whole process or change the way we need to provide 
data.
45	Data sets and Math
















Fig.3.40. Final model.
