{"id":122,"date":"2020-01-01T19:43:25","date_gmt":"2020-01-01T19:43:25","guid":{"rendered":"http:\/\/amydyer.art\/wp\/?p=122"},"modified":"2021-08-22T18:57:22","modified_gmt":"2021-08-22T18:57:22","slug":"drawing-with-ants-generative-art-with-ant-colony-optimization-algorithms","status":"publish","type":"post","link":"http:\/\/amydyer.art\/wordpress\/index.php\/2020\/01\/01\/drawing-with-ants-generative-art-with-ant-colony-optimization-algorithms\/","title":{"rendered":"Drawing with Ants: Generative Art with Ant Colony Optimization Algorithms"},"content":{"rendered":"<h3>Why I wanted to draw with ants<\/h3>\n<p style=\"text-align: left;\">I wanted to make a piece of art that explores the complexity of software engineering. When I imagine a huge codebase, I think of its emergent complexity and tangled, inter-connected parts. Its overall shape, if it can be said to have one, emerges from the actions of many individuals.<\/p>\n<p style=\"text-align: left;\">I thought about how to represent this, and one image that resonated with me was that of the ants&#8217; nest. Ants are a perfect example of emergent complexity. No individual ant is an architect, but together, they build beautiful, complicated structures.<\/p>\n<figure style=\"width: 483px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/commons.wikimedia.org\/wiki\/Category:Ant_nests#\/media\/File:Appareil_pour_l'observation_des_fourmis.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"mw-mmv-final-image jpg mw-mmv-dialog-is-open\" src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/1\/1e\/Appareil_pour_l%27observation_des_fourmis.jpg\/800px-Appareil_pour_l%27observation_des_fourmis.jpg\" alt=\"Appareil pour l'observation des fourmis.jpg\" crossorigin=\"anonymous\" width=\"483\" height=\"637\"><\/a><figcaption class=\"wp-caption-text\">Formicarium diagram. Source: <a href=\"https:\/\/commons.wikimedia.org\/wiki\/Category:Ant_nests#\/media\/File:Appareil_pour_l'observation_des_fourmis.jpg\">Wikimedia Commons<\/a>.<\/figcaption><\/figure>\n<p style=\"text-align: left;\">I started by looking for information about simulating ants&#8217; nests. Apparently there&nbsp;<em>is<\/em> <a href=\"https:\/\/www.pnas.org\/content\/113\/5\/1303\">literature about this, and it&#8217;s fascinating<\/a>. But the trick was that ant nests emerge, in part, based on the physics of the sand and dirt they&#8217;re built out of &#8211; exactly how a particle settles when placed by an ant. I wanted to build something in 2D, and I wanted to get right into the simulation without writing a lot of sand-physics, which meant I had to scrap the physical ant-nest simulation.<\/p>\n<p style=\"text-align: left;\">This led me back to searching, and searching led me to an entirely <em>different<\/em> class of ant simulations: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ant_colony_optimization_algorithms\">ant colony optimization algorithms<\/a>.<\/p>\n<p style=\"text-align: left;\">Ant colony optimization is an agent-based algorithm used to solve for the shortest path between two points in a graph. Agent-based simply means it&#8217;s an algorithm composed of individual routines (in this case, the &#8216;ants&#8217;), whose emergent behavior solves the problem.<\/p>\n<p style=\"text-align: left;\">How it works is very simple. Each ant leaves a trail of &#8216;pheremone&#8217; along the path it walks. Ants leave one kind of pheremone after they leave the nest, and a different one after they find food. Ants looking for food try and find a trail of &#8216;food&#8217; pheremone to follow, and ants looking for the nest try to follow the &#8216;home&#8217; pheremone.<\/p>\n<p style=\"text-align: left;\">Ants that happen along a shorter path will be able to make the round-trip between nest and food faster. That means they&#8217;ll lay down a denser layer of pheremone. Ants arriving later preferentially follow the denser trail, and they will take this shorter route. Each individual ant works with very simple rules, but over time, the ants will find a better path between the two points.<\/p>\n<h3>The Simulation<\/h3>\n<p style=\"text-align: left;\">I wrote my ant simulator in Processing 3. I started my implementation by emulating the code <a href=\"https:\/\/practicingruby.com\/articles\/ant-colony-simulation\">in this great blog post by Gregory Brown<\/a>.<\/p>\n<p style=\"text-align: left;\">Once I had the ants moving, I started to expand and modify the code to work better on larger grids of pixels. I wanted interesting looking simulations &#8211; not necessarily <em>effective<\/em> ones &#8211; which guided how I iterated the simulation. I added very rudimentary ant vision, so that each ant could look a few pixels ahead. I added ant death and ant respawning, to keeps the ants from loosely diffusing over the entire space. Finally, I made the ants a little dumber: they would leave pheremone constantly, even if a search is unsuccessful, which is similar to real ant behavior.<\/p>\n<p><a id=\"simulation\"><\/a><br \/>\nYou can play with a p5.js port of the simulation in your browser here!<\/p>\n<p><a href=\"http:\/\/amydyer.art\/ants\/index.html\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-202\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/start_ant_sim_button-1.png\" alt=\"\" width=\"1190\" height=\"406\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/start_ant_sim_button-1.png 1190w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/start_ant_sim_button-1-300x102.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/start_ant_sim_button-1-1024x349.png 1024w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/start_ant_sim_button-1-768x262.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/start_ant_sim_button-1-880x300.png 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/start_ant_sim_button-1-220x75.png 220w\" sizes=\"auto, (max-width: 1190px) 100vw, 1190px\" \/><\/a><\/p>\n<p>You can also take a peak at the <a href=\"https:\/\/github.com\/oxling\/p5js_ants\/\">ported source code on Github.<\/a><\/p>\n<p style=\"text-align: left;\">What fascinated me about this simulation are the lovely, weird, and complicated shapes that the ants made. They don&#8217;t march in straight lines, but start to form loops, whorls, and branches. Even more fun, you can control the sort of shapes the ants make by altering different variables in their world. You can change the decay rate of the pheremone, for example, or how many pixels ahead the ants can &#8216;see&#8217;.<\/p>\n<h3>Turning ants into art<\/h3>\n<p style=\"text-align: left;\">With my simulation working, the next step was to explore the actual output. My goal was to make a two dimensional image of some kind, which means I had to capture and draw the shapes made by the ants.<\/p>\n<p style=\"text-align: left;\">I ended up writing multiple kinds of output: several types of raster output, and one in vector. To capture raster output, I tracked which cells the ants had visited, and how often. By tinkering with filters on this output, you could get a ghostly trace of where the ants had been.<\/p>\n<figure id=\"attachment_130\" aria-describedby=\"caption-attachment-130\" style=\"width: 345px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/strict_pheremones.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-130\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/strict_pheremones-1.png\" alt=\"\" width=\"345\" height=\"400\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/strict_pheremones-1.png 539w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/strict_pheremones-1-259x300.png 259w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/strict_pheremones-1-220x255.png 220w\" sizes=\"auto, (max-width: 345px) 100vw, 345px\" \/><\/a><figcaption id=\"caption-attachment-130\" class=\"wp-caption-text\">An example of raster output. The traces are much denser along popular ant trails, and where ants randomly walked around the nest.<\/figcaption><\/figure>\n<p style=\"text-align: left;\">The raster output was attractive, but I wanted the individual paths to be clearer, so I also explored exporting as svg. For the vector output, I stored a history for each ant, and when they reached either home or the nest, saved that history to a list. To render, I sampled each saved path and drew it as a series of curves.<\/p>\n<figure id=\"attachment_131\" aria-describedby=\"caption-attachment-131\" style=\"width: 496px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-131\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1.png\" alt=\"\" width=\"496\" height=\"400\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1.png 1360w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1-300x242.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1-1024x825.png 1024w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1-768x619.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1-880x709.png 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/svg_simple_example_crop-1-220x177.png 220w\" sizes=\"auto, (max-width: 496px) 100vw, 496px\" \/><\/a><figcaption id=\"caption-attachment-131\" class=\"wp-caption-text\">An example of vector output. You can see the individual ant paths here. Where many ants traveled, the slightly overlapping lines make thicker paths.<\/figcaption><\/figure>\n<h3>Connecting the dots<\/h3>\n<p style=\"text-align: left;\">I knew I wanted to draw the ants traveling between many points, so one of the first things I wrote was code to composite multiple simulations into a single image. But then, what to draw?<\/p>\n<p style=\"text-align: left;\">My first idea was to represent some very literal graphs: starting simple, with binary trees, and then moving on to more complex visualizations. It seemed a natural fit, given that ant colony optimization is used to solve pathing problems in graphs. I also thought it would be an interesting way to visualize complexity in code: why not take a UML diagram or dependency graph, and render it with ants?<\/p>\n<p>I was already familiar with <a href=\"https:\/\/www.graphviz.org\/\">Graphviz<\/a>, so I decided to use that suite of tools and the <a href=\"https:\/\/graphviz.gitlab.io\/_pages\/doc\/info\/lang.html\">DOT graphing language<\/a> to lay out nodes and edges for my simulation. Graphviz has a mode that will output a DOT file annotated with pixel locations. I wrote a very ugly DOT file parser and used that, with my annotated DOT file, to simulate the locations of my ant nests and food.<\/p>\n<p>My experiments with binary trees seemed promising, and had a very natural, organic quality to them.<\/p>\n<figure id=\"attachment_138\" aria-describedby=\"caption-attachment-138\" style=\"width: 500px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_simple_tree-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-138 size-full\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_simple_tree-1.png\" alt=\"\" width=\"500\" height=\"500\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_simple_tree-1.png 500w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_simple_tree-1-300x300.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_simple_tree-1-150x150.png 150w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_simple_tree-1-220x220.png 220w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_simple_tree-1-50x50.png 50w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><figcaption id=\"caption-attachment-138\" class=\"wp-caption-text\">A simple binary tree. Someone told me it looked like an angiogram.<\/figcaption><\/figure>\n<figure id=\"attachment_137\" aria-describedby=\"caption-attachment-137\" style=\"width: 241px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_bigger_tree-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-137\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_bigger_tree-1.png\" alt=\"\" width=\"241\" height=\"400\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_bigger_tree-1.png 369w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_bigger_tree-1-181x300.png 181w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_bigger_tree-1-220x365.png 220w\" sizes=\"auto, (max-width: 241px) 100vw, 241px\" \/><\/a><figcaption id=\"caption-attachment-137\" class=\"wp-caption-text\">A slightly more complex binary tree, this one fairly deep.<\/figcaption><\/figure>\n<p style=\"text-align: left;\">Next, I started to build bigger graphs, using a few different codebases as input. I wrote a few simple python scripts: one that turned a git tree into a DOT file, and another that turned C import dependencies into a DOT file.<\/p>\n<figure id=\"attachment_140\" aria-describedby=\"caption-attachment-140\" style=\"width: 998px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-140\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1.png\" alt=\"\" width=\"998\" height=\"600\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1.png 1440w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1-300x180.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1-1024x616.png 1024w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1-768x462.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1-880x529.png 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/first_really_big_graph_small-1-220x132.png 220w\" sizes=\"auto, (max-width: 998px) 100vw, 998px\" \/><\/a><figcaption id=\"caption-attachment-140\" class=\"wp-caption-text\">Objects in a git object tree, graphed by ants.<\/figcaption><\/figure>\n<figure id=\"attachment_139\" aria-describedby=\"caption-attachment-139\" style=\"width: 1000px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-139\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1.png\" alt=\"\" width=\"1000\" height=\"600\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1.png 1390w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1-300x180.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1-1024x614.png 1024w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1-768x461.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1-880x528.png 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/linux_kernel_square_graph_small-1-220x132.png 220w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/a><figcaption id=\"caption-attachment-139\" class=\"wp-caption-text\">Dependencies between files in the Linux kernel. Nodes and edges were laid out using the square graph style in Graphviz. Not much more interesting than random graphs, really.<\/figcaption><\/figure>\n<p style=\"text-align: left;\">While both of these were interesting &#8211; and certainly complex &#8211; I was disappointed that neither really said anything about the overall form of the codebases they were built from. The more I experimented with code visualization, the more I realized that building an interesting graph from a codebase was really its own, bigger problem. However, I did like the complexity of the very large graphs, and came back to that later.<\/p>\n<p>My next experiment was to play with simple forms. I plotted lines, circles, sine waves, and other shapes that were easy to describe with nodes and edges.<\/p>\n<figure id=\"attachment_146\" aria-describedby=\"caption-attachment-146\" style=\"width: 533px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-146\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1.png\" alt=\"\" width=\"533\" height=\"400\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1.png 3600w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1-300x225.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1-1024x768.png 1024w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1-768x576.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1-1536x1152.png 1536w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1-2048x1536.png 2048w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1-880x660.png 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_23_10_9_54-1-220x165.png 220w\" sizes=\"auto, (max-width: 533px) 100vw, 533px\" \/><\/a><figcaption id=\"caption-attachment-146\" class=\"wp-caption-text\">Points in a line, where the points are closer together on the right side of the line.<\/figcaption><\/figure>\n<figure id=\"attachment_147\" aria-describedby=\"caption-attachment-147\" style=\"width: 533px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-147\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1.png\" alt=\"\" width=\"533\" height=\"400\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1.png 3600w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1-300x225.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1-1024x768.png 1024w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1-768x576.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1-1536x1152.png 1536w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1-2048x1536.png 2048w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1-880x660.png 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sine-squiggles-1-220x165.png 220w\" sizes=\"auto, (max-width: 533px) 100vw, 533px\" \/><\/a><figcaption id=\"caption-attachment-147\" class=\"wp-caption-text\">Different frequencies of sine wave. I guess the ants make an OK oscilloscope.<\/figcaption><\/figure>\n<p style=\"text-align: left;\">What I found most interesting were simple triangulated spaces. I generated a set of well-distributed points &#8211; either randomly, or by drawing shapes &#8211; and then used a Processing library to turn those points into a Delaunay triagulation or a Voronoi diagram. I used the resulting edges for the ant simulation, with each edge representing one &#8216;nest&#8217; and one &#8216;food&#8217;.<\/p>\n<figure id=\"attachment_150\" aria-describedby=\"caption-attachment-150\" style=\"width: 533px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_24_21_27_52-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-150\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_24_21_27_52-1.png\" alt=\"\" width=\"533\" height=\"400\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_24_21_27_52-1.png 864w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_24_21_27_52-1-300x225.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_24_21_27_52-1-768x576.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_24_21_27_52-1-220x165.png 220w\" sizes=\"auto, (max-width: 533px) 100vw, 533px\" \/><\/a><figcaption id=\"caption-attachment-150\" class=\"wp-caption-text\">Voronoi diagram drawn by ants.<\/figcaption><\/figure>\n<p style=\"text-align: left;\">This led to a nice, full space of complicated ant squiggles, which did a better job representing the complexity I was interested in.<\/p>\n<p style=\"text-align: left;\">Finally, I went on one other tangent. A friend took a look at the simulation, and asked what would happen if the ants hit a wall &#8211; could they route around simple obstacles? I already handled walls as an edge case, so I added interior walls, and then spend a lot of time trying to coax the ants to solve mazes.<\/p>\n<figure id=\"attachment_151\" aria-describedby=\"caption-attachment-151\" style=\"width: 500px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_3_19_53_25_farm-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-151 size-full\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_3_19_53_25_farm-1.png\" alt=\"\" width=\"500\" height=\"500\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_3_19_53_25_farm-1.png 500w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_3_19_53_25_farm-1-300x300.png 300w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_3_19_53_25_farm-1-150x150.png 150w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_3_19_53_25_farm-1-220x220.png 220w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/ant_graph_output_3_19_53_25_farm-1-50x50.png 50w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><figcaption id=\"caption-attachment-151\" class=\"wp-caption-text\">Paths of ants attempting to solve a simple 9&#215;9 maze. You can start to see the shape of the maze based on where the ants couldn&#8217;t go.<\/figcaption><\/figure>\n<p>I had a vision where the ants would solve a simple maze, and I would stitch them together into a larger piece of work. I spent a lot of time trying to adjust the simulation variables so that the ants could solve it, but I never was never able to get them to solve it consistently. &nbsp;Ultimately, it just ended up being ant-path squiggles bounded by the shape of the maze itself.<\/p>\n<h3>The completed art<\/h3>\n<p>At this point, I took a step back and looked at the output from all of the different experiments. I realized that the most interesting images had been from the large fields of semi-random points and edges. I decided to make that my final approach, and set up the simulation to draw lines between a Delaunay triangulation of random points.<\/p>\n<figure id=\"attachment_156\" aria-describedby=\"caption-attachment-156\" style=\"width: 480px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-156\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1.png\" alt=\"\" width=\"480\" height=\"600\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1.png 1200w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1-240x300.png 240w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1-819x1024.png 819w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1-768x960.png 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1-880x1100.png 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/raw_vector_example-1-220x275.png 220w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><figcaption id=\"caption-attachment-156\" class=\"wp-caption-text\">A completed simulation run. It has a lot of overlapping paths, which kind of resolve into fuzzy blobs.<\/figcaption><\/figure>\n<p>The final problem was then how to turn my SVG squiggles into a finished piece.&nbsp;I knew from some experiments that I wanted to sort the paths &#8211; somehow &#8211; so I could emphasize the paths that had nice shapes. But the final simulation took an hour or two to run, which made tinkering with variables for each run an impractical way to experiment.<\/p>\n<p>What I decided to do was write a <em>second<\/em> Processing program, which would load the simulation&#8217;s SVG output, and then apply the visual effects I wanted. Even better, I could make the post-processing script interactive, so I could experiment with different line weights, colors, and sorting thresholds.<\/p>\n<p>I tried out a few separate ways of scoring which paths should be in the foreground, and which should be in the background. I calculated a few different factors: how many times each line intersected itself; how many times the line crossed over its slope line; and how likely each was to follow the slope predicted by the previous two points.<\/p>\n<p>I used the post-processing script to experiment with different weights and values for these scores, until I landed on an appearance I was happy with.<\/p>\n<figure id=\"attachment_159\" aria-describedby=\"caption-attachment-159\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-159 size-full\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/10\/sort_threshold_slow-1.gif\" alt=\"\" width=\"400\" height=\"400\"><figcaption id=\"caption-attachment-159\" class=\"wp-caption-text\">Adjusting the threshold for foreground and background lines.<\/figcaption><\/figure>\n<p>I found it very helpful at this point to save one image for each variable change. As I got closer to an image I was happier with, it was much easier to compare a film strip of slight variations, than to change multiple things at once.<\/p>\n<p>After a lot of tinkering and slight adjustments, I created this&nbsp; image from my simulation:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-173\" src=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/11\/ant_processed_output_green_for_web-1.jpg\" alt=\"\" width=\"480\" height=\"600\" srcset=\"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/11\/ant_processed_output_green_for_web-1.jpg 960w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/11\/ant_processed_output_green_for_web-1-240x300.jpg 240w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/11\/ant_processed_output_green_for_web-1-819x1024.jpg 819w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/11\/ant_processed_output_green_for_web-1-768x960.jpg 768w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/11\/ant_processed_output_green_for_web-1-880x1100.jpg 880w, http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2019\/11\/ant_processed_output_green_for_web-1-220x275.jpg 220w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p>I zoomed in on an area I thought was particularly interesting, and cropped to create a good balance between open and filled space.<\/p>\n<p>The last, and final step, is deciding how to turn this image into a physical artifact. So far I&#8217;ve printed it digitally, as a 16&#215;20&#8243; poster, and made a (failed) attempt at screen printing it on colored paper. The digitally printed poster looks great, but next I want to try copying the image as a part of painting. I find complex drawings sort of meditative, and I think I could do some interesting things rendering it by hand.<\/p>\n<p>This project took much longer than I expected, and became&nbsp; more complex than I imagined. But it was a great way to experiment with all sorts of interesting computational geometry and algorithmic problems. I think there&#8217;s some irony that I wrote a few thousand lines of code for a work about complexity, but I&#8217;m happy that the work looks cool and can speak for itself.<\/p>\n<form style=\"border: 1px solid #ccc; padding: 3px; text-align: center;\" action=\"https:\/\/tinyletter.com\/amydyerart\" method=\"post\" target=\"popupwindow\"><em>Thanks for reading! Join my mailing list, and we can stay in touch. Get a little more art in your inbox, and find out when I have new prints for sale.<br \/>\n<\/em><label for=\"tlemail\">Enter your email address here:<\/label><input id=\"tlemail\" style=\"width: 140px;\" name=\"email\" type=\"text\"><\/p>\n<p><input name=\"embed\" type=\"hidden\" value=\"1\"><input type=\"submit\" value=\"Subscribe\"><\/p>\n<p><a href=\"https:\/\/tinyletter.com\" target=\"_blank\" rel=\"noopener\">powered by TinyLetter<\/a><\/p>\n<\/form>\n","protected":false},"excerpt":{"rendered":"<p>Why I wanted to draw with ants I wanted to make a piece of art that explores the complexity of software engineering. When I imagine a huge codebase, I think of its emergent complexity and tangled, inter-connected parts. Its overall shape, if it can be said to have one, emerges from the actions of many [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":211,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-122","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-posts"],"jetpack_featured_media_url":"http:\/\/amydyer.art\/wordpress\/wp-content\/uploads\/2020\/01\/Screen-Shot-2020-01-01-at-3.01.35-PM-1.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":3,"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"predecessor-version":[{"id":184,"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/122\/revisions\/184"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/media\/211"}],"wp:attachment":[{"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/amydyer.art\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}