Information nesting 3
Last updated
Last updated
This demonstration aims at generating grid tiles as surfaces and as closed polygonal loops. It uses some of the above mentioned operations. For practice, let’s say we wish to force the grid into the [0, 1]2 range i.e. both x and y directions in [0, 1].
First, we create a point grid based on the grafting technique seen earlier. However, instead of using integer increments we use the one over the grid size per direction. This generates the bottom-left points of the tile grid. We use geometric translation to generate the bottom-right points using [1 / nx, 0, 0]; top-right points using [1 / nx, 1 / ny, 0]; and top-left points using [0, 1 / ny, 0]; applied to the entire “base” grid.
If this logic is confusing, you may think of it as if we are trying to construct the points around a single rectangle with its lower-left point at “pa = [0, 0, 0]”, with width “dx = 0.25” and height “dy = 0.2”. We can express the lower-right point as “pb = pa + [dx, 0, 0]”, the upper-right point as “pc = pa + [dx, dy, 0]” and “pd = pa + [0, dy, 0]”. The use of the “series” component just replicates this multiple times.
While the surface component “laces” the inputs into multiple tiles, to create polylines requires a bit data manipulation. First we “entwine” the points to package all point lists into a table of four columns by as many number of rows as the number of tiles. The we transpose the table such that each column contains the four points of each tile. This we can supply to the “polyline” component which will happily produce as many loops as the tiles.
Practice
The simplest way to create grids is using one of the ready-made “grid” components. Nevertheless, here we will take a more circuitous approach in order to learn about sequence folding.
We start with integer division i.e. the elementary school division prior to real numbers. We use of the “//” symbol to denote integer as opposed to real division using “/”. We can compute “20 // 5 = 4” or “4 x 5 = 20” but “20 // 6 = 3” with a remainder of “2” or “3 x 6 + 2 = 20”.
In general, “A = B * Q + R” where “A” is the dividend, “B” is the divisor, “Q” is the quotient and “R” is the remainder; all integers. This is so useful that there two components for computing “Q” and “R”, namely “integer division” and “modulus”.
Synonyms for modulus include modulo and mod. It is symbolically represented in expressions with the percent symbol “%” or “mod”. For example in python we use “%” while in spreadsheets “mod”.
It seems that the concept of integer division between two numbers A, B is a process that produces two outputs, namely Q, R. Let’s create a component that captures this logic as seen the black-box diagram below
In the construction below we use both the quotient and remainder to plot points of the form [R, Q, 0]. This produces a point grid without list grafting!
The picture below contains the results of performing integer division of the sequence in column A, with 2, 3, 4, 5 and 6.
The quotient produces a sense of grouping while the modulo expresses a sense of cycling (also known as clock or modular arithmetic behaviour). The idea of inducing periodicity over the unbound sequence of integers using just division is pretty interesting. Notice also how an integer modulo 2 tells us whether the number is even or odd, where 0=even, 1=odd.
To visualize the folding logic we can display the sequence number of each point on screen using the “text tag 3d” component. We can now observe that the grid points march in the Y-direction every 6 steps ie. the number of columns. We have “folded” the sequence every 6 items. To move horizontally we need to take a step of +1 but to move vertically we need to take a stride of +6.
Moreover, we can combine the sequence index with the column, row numbers using the “format” component and visualize the relationship between them. So for example a grid of 6 columns and 5 rows, the point at sequential index 15 is located at the grid location of ( 15 // 6, 15 % 6 ) = ( 2, 3 ). In general, we can can express this relationship as “index ⟶ ( index // cols, index % cols ) ⟶ ( row, col )”.
In the same manner but reverse order, the index of the point at grid location ( 3, 1 ) is 3 * 6 + 1 = 19 or in general terms “( row, col ) ⟶ row * cols + col ⟶ index”. In this sense we can unfold a 2D grid into linear 1D list. Surprisingly, this logic generalizes to any number of dimensions!
Practice
Create a component that inputs the column index, row index and number of columns and outputs the grid serial index number.
Create a component that inputs a grid’s serial index and grid’s number of columns and outputs the column and row indices.
In this session we looked at the concept of data nesting, i.e. placing lists within lists, through the lens of tabular data generation. Geometrically we linked this idea to point grids as means to visualize the concept. We also viewed an alternative way of understanding “flat” versus “multi-dimensional” data shapes using the concept of indexing and folding.
From experience this is one of the most confusing parts of computing in general and in all fairness the way nesting is implemented in this particular visual programming environment is not ideal either. To avoid further confusions we will work exclusively with 2D data shapes for which our spreadsheet analogy works well.
Try creating a different kinds of grids such as an iso-grid [], dia-grid [], golden-ratio-grid [], brick-grid [], herringbone-grid [], hex-grid [].