Generative Design Variations M.1.6 Agents in space

The Generative Design book starts this example with the following text: ‘For the last example in this chapter, the use of the noise () function as a way to determine the direction of agents’ movement is carried into the third dimension. The swarm of agents leaves the flat area and moves in three-dimensional space. An agent is represented by a ribbon composed of its previously executed positions. The agent class is adjusted.’ Here are the two tools which I have changed and used during this assignment.
M_1_6_01_TOOL
M_1_6_02_TOOL

I have created a Flickr Album with all the images I made during this exercise. There was no JavaScript involved because JavaScript does not support the Processing controlp5 library. So if you click on the previews of the loftmatic page you get the Processing code. Clicking the program numbers under each paragraph will also take you to the Processing code.

First thing that attracted my eye was: hint (ENABLE_DEPTH_TEST); What does that mean? I found some useful information here: https://www.andrew.cmu.edu/course/60-257/reference/hint_.html Not that it is now clear to me but I know now a bit more of what it does. It allows you to combine 2d and 3d drawing? Anyway… I am using it and maybe I will find out why it is there later. I think I am going to need an on/off-key for the blue box which is around the agents. It might be handy for orientation purposes. But I don’t need to see that box always. Especially when I make screendumps. I define the variable ShowBox for that. And pressing the ‘b’ / ‘B’ key toggles between ShowBox and do not ShowBox. Made the usual adjustments of global variable names and wordspaces. And I have put the menu name outside the display screen. Otherwise that name will show up during the animation or screendumps. I did not change anything in Marius Watz’s TileSaver’s tab. That would take an extra week to find out how it works.  Instead I played with the controlp5 settings for a while. Ah… same problem as the earlier examples with the png’s. It’s creating a transparent file. So I have to import it into Photoshop to make it full color. Make the background a color of my choice and save it as a copy. Or save it as a jpg. Which might lead to lower image quality. Does the TileSaver class make any sense or does it produce the same transparency problem? No it doesn’t. It gives me a perfect 2400 x 2400 pixels png file. No transparency at all. Just a very large screendump. But how do I get it smaller. What does the global variable QualityFactor 3 do? My display window size is 800 x 800. Hmmm… 3 x 800 = 2400. So maybe if I make the QualityFactor just 1 it spits out an 800 x 800 png. And this is the case! So QualityFactor = the size of the image. As a result I have renamed that global variable to ImageSize.
M_1_6_01_GDV_01

I would like to bring in some color. Where can I do that? I saw that color is used in the next example. And the color is generated in the Agent class. I copied that piece of code and adapted the colors to my needs. Also added transparency. Strange enough the setting does not give me an idea of a 3d environment. Are those lights working? Even if I switch them off the scene seems to be lighted. And because I don’t know why they are on I leave them off (like in te real world).
M_1_6_01_GDV_02

Cranked up the AgentsCount to 10000. Made a few examples with rectangles.
M_1_6_01_GDV_03

Slowed down the animation to 10 frames per second. Otherwise it is difficult to get an impression of what is really going on in the display window. Created long rectangles.
M_1_6_01_GDV_04

In the Agents tab I repeated the ribbon.drawMeshRibbon twice. One with a width of 10 and one with a width of 50 (pixels?). Not sure about that size.
M_1_6_01_GDV_05

Used very small rectangles. Almost particles size.
M_1_6_01_GDV_06

I found a few lines of code in the Ribbon3d tab which were commented out. Just put them in again to see what would happen. It creates triangles.
M_1_6_01_GDV_07

Continuing with replacing PVectors. PuhVector! As Daniel Shiffman mentions it in the accompanying videos of his ‘Nature of code’ book. I did not finish his book yet but I noticed that you can use a lot of methods with PVector. I will try to use some of them. A PVector is a way to store two values. Or in this case three values because I’am working in 3d. Talking about PVector I have thrown away all my vertices and replaced them by curve-vertices.
M_1_6_01_GDV_08

Made every movement very relaxed and easy. Slow changing lines which render for 3000 pixels. So they render outside the box. Eventually they stop in the box. If you put the box upside down and looking into it you get a total different view of the same object. I let it render for fifteen minutes while cleaning my espresso machine.
M_1_6_01_GDV_09

1500 AgentCounts. It is still rendering very slow. But it delivers interesting images in the display window (if you let it render for fifteen minutes).
M_1_6_01_GDV_10

At this point starts the second part of the agents in space. The functionality of the ribbon is summarized in the class Ribbon3d. But at that moment I was so annoyed by the fact that I did not find a way how to control the lights in the previous example. because they just didn’t have any effect. So I tried it once more. Switched off all lights. And created a spotlight. On a certain moment I saw that spotlights light fall on a small part of a ribbon. So I tried to manipulate the spotlight so that it had more effect on every ribbon which was rendered. And… succes! I now have to uncomment the coloring of the ribbons because to get an ideal coloring by light I have to color all ribbons white. So that is my next step.
M_1_6_02_GDV_01

I have the impression that the lights are not working on lines. In the Agent’s draw block I have changed drawMeshRibon for drawLineRibbon. And I get white lines. Which is the real color of the line. Another thing is that these spotlights do not give enough light. So I used an old trick which I used when I was using Lightwave 3D. I duplicated the spotlights exactly at the same coördinates. And that helped. The brightness of the spotlights is now twice as high.
M_1_6_02_GDV_02

Just playing with the controlp5 settings for now. Added a green light on the 200, 200, 200 position. It seems that this is not in the middle of the display window. Ok… the light positions are calculated within the display window. Which seems logical to me. I have increased the agents count to 10000. That makes the rendering again very slow. But that is not interesting because I do not make animations (yet). I only have to render one frame.
M_1_6_02_GDV_03

Increased the noise-scale to 10000. Added one blue light at the top left corner.
M_1_6_02_GDV_04

Going to put four lights on each cornerpoint. Doubled those lights to increase the brightness.
M_1_6_02_GDV_05

NoiseSticking? What does that do? Doubled it from 0.9 to 1.8. Hmmm… I did a search through the sketch but NoiseSticking seems to be nowhere else than at the top of the program were all variables are being declared. It is nowhere else being used. Changed angleY for angleX. Which did not deliver anything new of course. Changed offset from 1000 to 1. Played with stepSize.
M_1_6_02_GDV_06

Uncommented the Arrow mesh code in the Ribbon3d tab.
M_1_6_02_GDV_07

Reduced the agentsCount to 700. And strokewidthrange to 20. The camera points right into the box!
M_1_6_02_GDV_08

Increased MaxStroke to 200.
M_1_6_02_GDV_09

I used the camera to get very close into the box. Weird things are going on in there.
M_1_6_02_GDV_10

Finally I think that Marius Watz’s TileSaver class worked out very fine. I will use that from now on (if I can). By using it I can always make very large images without losing lots of image quality.

Generative Design Variations M.1.5 Noisy motion

I start with a copy of the Generative Design book’s introduction: ‘As you can see, the possibilities of the noise () function’s character are diverse. Until now, the generated values were always applied directly to a visual parameter (curve point, pixel color, or height position of the grid points). In the following examples the noise function is used to control dynamic parameters. The generated values now define the direction of movement of a swarm of agents. This example uses the same principle employed in the previous programs. The only difference is that noise () is applied to the rotation of grid elements. In the following programs, the arrows are no longer drawn but are used to control the movement of the elements.’ Until this point the book’s introduction. Here are the four programs I worked with:
M_1_5_01
M_1_5_02
M_1_5_03
M_1_5_04

As usual I have created a Flickr Album with most of the images I made during this assignment. Alas there was only a little JavaScript involved because the controlp5 Processing library is not supported by JavaScript. Instead you get the Processing code when you click on the previews of this loftmatic page. The first ten previews (from the top) will work with JavaScript but very slow.

I started with making the background black. That leaves you with an image without an arrow because that is already black. Made it white in Adobe Illustrator. I lowered the TileSize from 40 to 20. That means you can see the noise pattern better. But the arrow symbol is getting less recognizable. I also changed the strokeweight of the arc from 1 to 16. And made the color red with a transparency of 128. I think that arrow is of no use anymore as it is now. So I commented those program lines out. But they might come in later. Slow JavaScript ahead 🙂
M_1_5_01_GDV_01

Commented out the nofill in the arc section. I noticed that the arc was not fully closed at a certain point. So I increased the radians of the local angle variable to 450. Tweaked the colors somewhat to green and blue. Changed the background to red. The program runs in JavaScript but the behaviour is very slow.
M_1_5_01_GDV_02

Introduced some numbers. But because noiseValue produces a float I had to use round to make the number a bit more comprehensible for me. I only need to do something about the calculation. That doesn’t make sense yet. I think that noiseValue is ok but it delivers some non-data. So maybe I can use map to fill a  full circle which is 100% noise value.
M_1_5_01_GDV_03

Replaced the arrow by a white line. Why is there a stroke and strokeweight command in the Arrow section? I don’t think that has any effect. Maybe I added that in an earlier version. Checked the original program. No. It was already in it before I began working on it. Anyway I commented it out. This program also runs slow in JavaScript.
M_1_5_01_GDV_04

I doubled the length of the white line. And I think it might be doubled again. Or maybe I can use disableStyle and change the properties of the lines. That worked. Changed the color of the lines until it has a tilesize of 10 pixels. That image has hairy qualities at a certain setting.
M_1_5_01_GDV_05

Replaced the rectangle with a cross. The pattern is getting more chaotic by hitting the arrow-up-key on your keyboard. The arrow-down-key has the opposite effect.
M_1_5_01_GDV_06

When you increase the size of one of the two rectangles which make the cross you get totally different end results. But again the pattern is getting more chaotic by hitting the arrow-up-key on your keyboard. The arrow-down-key still has the opposite effect.
M_1_5_01_GDV_07

Increasing both rectangles (wich make the cross) give almost cloth-like images. Arrow-up and down-keys still have the same functionality.
M_1_5_01_GDV_08

Putting the cross on its side (in Adobe Illustrator) did not make much of a difference. So I used a rectangle with rounded corners.
M_1_5_01_GDV_09

Replaced the rectangle with a star-like image. Which makes very subtile nuances in the pattern.
M_1_5_01_GDV_10

Agents in two-dimensional space
‘In order to animate a swarm of agents in this way, all the agents are moved in the direction defined by the noise () function to assume their positions. The only remaining consideration is what to do with the agents that migrate out of the display window.’

From here on all upcoming programs work with the controlp5 library. Controlp5 is a GUI library written by Andreas Schlegel for the programming environment Processing. Now I did not work much with classes and libraries before. So this could be getting interesting. As usual I start with changing the names of the global variables. And added wordspaces to the program for better readability. And as a result nothing was working. I got a stream of particles on the screen but they did not react on the controlp5 sliders. I found out that the global variable names were the problem. So I replaced those into the program settings of the controlp5 library. Another thing was that saveframe did not work properly. It gave me a kind of grayish screendump. This was because it creates a png-file with transparency. So I changed that to .jpg. And yet another thing is the menu button. When you make a screendump it is captured too. That is not what you (and I) want. So I display the menu button outside the display window. I’ve got a shortcut by pressing the ‘m’ key anyway. I studied the controlp5 library for a while. And I changed the line function into a point. That gives me the possibility to use the full range of strokewidth without losing the speed of the vectors. I also checked if JavaScript supports controlp5. Found this information on the GitHub sojamo/controlp5 site: ‘Currently there is no JavaScript version of controlp5, though I had started implementing a slimmed down version for processing.js but since it is now unclear which JavaScript version – processing.js or p5.js – will become the default js version of processing, controlP5.js is on hold. There is a tendency that p5.js will become the primary JavaScript environment.’ So as a result there is no working version in JavaScript. I will put the code online for the rest of the programs. Just played with the settings for a while.
M_1_5_02_GDV_01

I could be going on changing settings but what can I do to change the images the program delivers. Added two different colors, blue and yellow for each mode as a start.
M_1_5_02_GDV_02

Switched off noisestrength for a while. Saved frames during mode switching.
M_1_5_02_GDV_03

Would it be possible to define another group? Ok… I have made a mistake in my if structure. But it gives an interesting image because it now triggers two blocks of code instead of 1. But key 2 and key 3 are now behaving the same. Except for the color. What to do to change that behaviour? Added a new group under the 3-key.
M_1_5_02_GDV_04

I changed the color behaviour for the three modules. They are now using the HSB colormode. Although brightness is not so relevant because there is an alpha channel used.
M_1_5_02_GDV_05

Made a function called colorCycler. It cycles very slowly through the HSB colormode. in fact it does the same thing as the previous version of this program. Added a new DrawMode variation under the 4-key.
M_1_5_02_GDV_06

Added some growing corn-fields under the 5-key.
M_1_5_02_GDV_07

Used ColorCounter for the directionAngle.
M_1_5_02_GDV_08

Defined the 7-key for some concentrated ellipses. hitting the space bar creates a new noise seed.
M_1_5_02_GDV_09

The 8-key makes one great wave. Swiping all information to one side.
M_1_5_02_GDV_10

Three dimensional noise
‘The complexity of the agents behavior can be further increased when the three-dimensional variation of the noise () function is used to generate angle values. This three-dimensional noise can be thought of as a large cube of random numbers in which the individual values differ only slightly from their neighbors. If the agents still move about in the area, but the random numbers for their movement are selected from the different layers of this random number cloud they are no longer bound to the same paths. The closer these virtual z-coordinates lie to each other, the more they cluster together. The image becomes even more dynamic when the z-coordinates are changed slightly but continuously. The agent class has to be modified slightly to perform this new action.’

One of the first things I noticed that this 3D noise program is running in the P2D render mode. Strange. I thought P2D was 2D space and P3D was 3D space. So I looked that up. There are four render modes: the default renderer, P2D, P3D, and PDF. Switching to P2D or P3D is switching to 3D space? Default (‘slow’ but very accurate 2D render mode). P2D (OpenGL, faster but less accurate 2D render mode). P3D (OpenGL and well, 3D). PDF (for PDF output). Found this information on the GitHub Processing site. Meanwhile due to the changes in Processing 2.0, P2D and P3D have been replaced with variants of the OpenGL renderer. ‘We’ve removed the software-based (but speedy for some circumstances) versions of P2D and P3D. We feel that OpenGL rendering is probably the future for most Processing work, so we’re focusing our efforts there.’ So it is still unclear if P2D is the same as P3D but it might be better to run everything in OpenGL. I have changed the background color again. And did the same adjustments I did for the previous range of GDV’s. I also noticed that the space bar functionality for triggering the noise seed has disappeared in this range of programs. But I found that quite useful so I have put that back again. Tried the settings.
M_1_5_03_GDV_01

Played with the settings and introduced a blue color for DrawMode 2.
M_1_5_03_GDV_02

Did some testing with different file formats. The tif-format gives the best result. But also the largest file size. About 1.8 Mb per 800 x 800 pixels image. So I stick with jpg.
M_1_5_03_GDV_03

Made pairs of the points. A white and a blue point that work together.
M_1_5_03_GDV_04

Tripled the points and made them red, white and red.
M_1_5_03_GDV_05

Made flag-like objects. Assembled by red and blue lines.
M_1_5_03_GDV_06

The same thing but with more horizontal lines and blue, yellow and white colors.
M_1_5_03_GDV_07

Used the three RGB colors Red, Green and blue (although I am working in HSB). These images make you see things unclear and double.
M_1_5_03_GDV_08

Instead of enlarging the y-side I enlarged the objects on the x-side.
M_1_5_03_GDV_09

Finally put everything under an angle of 45 degrees by giving the same numbers to the x and y coördinates.
M_1_5_03_GDV_10

The bonus program
There was one more bonus program in the directory. It is not being discussed in the Generative Design book. But I’ve made some variations with it anyway.

Used a very small rect to create movements.
M_1_5_04_GDV_01

Replaced the rectangle by a bezier curve wave symbol. This makes the program behave very slow. But it delivers interesting images.
M_1_5_04_GDV_02

Used a pill-like shape as the main object.
M_1_5_04_GDV_03

Used a stairs like (could also be roof like) image as the main object.
M_1_5_04_GDV_04

That looks like sheets of paper running off a printing press.
M_1_5_04_GDV_05

Used text to make the structure. The program is reading the x-position and is dropping that information into the noise-stream.
M_1_5_04_GDV_06

Used the year, month, day, hour minute and second function as input. Something strange happened here. I defined the time and dat variables in the top of the program. But when I runned it the program did not refresh the seconds. After a while it was clear to me that you should initialize the date and time functions in the draw block of Processing. Otherwise the date and time functions will not update.
M_1_5_04_GDV_07

800 white swans. It’s not completely foolproof because some reflections overlap the real swans.
M_1_5_04_GDV_08

Another variation but now with arrows.
M_1_5_04_GDV_09

And one with red and colorized circles which might look more like tubes. But they are just circles.
M_1_5_04_GDV_10

GDV P.2.2.4 Growth structure from agents

In each frame, a new circle is generated at a random position and with a random radius (dashed circles). It is then determined which of the existing circles lies nearest to the new one. In the final step, the new circle docks with its closest neighbor via the shortest path. The Generative Design book shows two examples of so-called limited diffusion aggregation. Which sounds pretty scientific but here are the examples.
P_2_2_4_01
P_2_2_4_02

And if you are not able to run JavaScript or Processing I have put all images that were generated on a Flickr summary page.

You can find all variations I made (including the code) on this page:
GDV P.2.2.4

The first thing I changed was the calculation of the original display-size. I still have no idea why the display size is calculated in such a complex way: size (167 * 3, 241 * 3); Changed that into: size (800, 800); Also inverted the background and the growing structure itself.
P_2_2_4_01_GDV_01

Changed the static fill function with a random fill. This gives an interesting effect to the animation. Which was, by the way, a happy accident.
P_2_2_4_01_GDV_02

Used that happy accident in a colored version. This looks more like a living structure.
P_2_2_4_01_GDV_03

Changed the ellipses into rectangles with rounded corners. To draw a rounded rectangle, I added a fifth parameter, which is used as the radius value for all four corners. You can find this information in the Processing reference (just in case).
P_2_2_4_01_GDV_04

This gave me the idea to draw simple leaf-shaped elements. To use a different radius value for each corner you have to include eight parameters.
P_2_2_4_01_GDV_05

Some rects are drawn which together form a gradient element. Now this doesn’t work as nice in JavaScript as it works in Processing. If you look into the code you will see that I programmed it pretty clumsy. But I will come back to that point.
P_2_2_4_01_GDV_06

Changed the rectangles into ellipses. But I liked the gradient idea. So I reduced the alpha value with 20% at every ellipse that is drawn.
P_2_2_4_01_GDV_07

Replaced the ellipses with arc’s.
P_2_2_4_01_GDV_08

Added bottom arcs (radians 45, radians 135) to the top arcs (radians 225, radians 315).
P_2_2_4_01_GDV_09

After the top and bottom arcs were added I placed left arcs (radians 135, radians 225) and right arcs (radians 315, radians 405) in a magenta color.
P_2_2_4_01_GDV_10

If the program is running and you hit the 1-key you will see that circles and lines are drawn at a random positions and with an alpha of 20%. The 1-key is an on-off switch and it doesn’t work anymore when the image is ready (ready as in done that is).
P_2_2_4_02_GDV_01

This one is running pretty slow. And it’s almost the same image as P_2_2_4_01_GDV_09. Except for the background image which you can switch on or off.
P_2_2_4_02_GDV_02

From here on I did not pay much attention to the background image. I tried to concentrate on the foreground image. And maybe this is the right time to come back to my remark of clumsy programming. Because in this way it is not efficient. I could have solved this with some for loops. This would definitely increase all those stroke and arc lines. I have spent some time on that but after an hour I thought that it would be better to continue in this way because it gave me some problems which needed even more time. And I was not sure that I would get this image (as it is now). Generally I take as a rule of thumb as it takes me more than one hour to optimize code than I do not optimize it. Another one is: if I am unsure that the end result is not the same as it is in the state it is now I do not optimize.
P_2_2_4_02_GDV_03

These shapes came along because I would like to make the arcs larger. During such a session I always check while I work on the program to see if the image has changed. Sometimes unexpected things happen. This variation is one of them.

P_2_2_4_02_GDV_04

Enlarged the blue arcs only.
P_2_2_4_02_GDV_05

And in this version all arc’s are enlarged. Which was the original idea.
P_2_2_4_02_GDV_06

I wondered what would happen if I enlarged the arc’s even more. In this case I only enlarged the magenta ones.
P_2_2_4_02_GDV_07

Here all arcs are enlarged at the same scale. Hmmm… while I am typing this I think it might have been better when I had used the scale function. Anyway there’s no point crying over spilt milk.
P_2_2_4_02_GDV_08

While the earlier programs used circles positioned in each other. The last two examples make use of a color spectrum in a circle. The circle is divided into colored segments. On top of that a black ellipse is displayed. The end result shows some simularity with the colors you see appear in detergent.
P_2_2_4_02_GDV_09

In this last proposal I made the circles bigger and the black circle smaller. You can also switch on the background image again by hitting the 1-key. In fact this is the best image of the range. It came to me when I had worked for two hours on the previous image. And I could not find a new variation because I had a kind of designers-block. So I had a talk with my friend. She advised me to take a step back. Just make the circles a bit bigger and make the black circles smaller. And here it is! I know! I added sloppy code and it’s not my idea. But taking everything into account it makes a fine image.
P_2_2_4_02_GDV_10

Henk Lamers