LabyrinthMaker - You Go, You Get The Story, You Come Back
This work draws a single continuous path around an arrangement of objects, filling the environment around the objects completely, and binding them together into something sacred.
produced by: Isaac Clarke
I this work I have been exploring how wayfaring, pathfinding, and knowledge of an environment can be reimagined in the digitally rearranged and calculative landscapes we live in. I have been considering how objects are transformed into songs, and how symbols and objects teach us alternative ways of seeing, and alternative ways of living.
The work consists of an interactive table which calculates a single path which completely fills the space around an arrangement of objects, which can be removed and added to. This “watching” surface draws you in and then stops with you, presenting you with stillness and a journey that can be undertaken, to follow the path around these objects as they transform into something sacred and special. Through holding, seeing and creating journeys, I hope to show how we can reimagine our connection to the natural world.
Full source code: https://github.com/isaac-art/LabyrinthMaker
Photo and Video Documentation: https://www.dropbox.com/sh/x1ir01t795r16l6/AAAknGpLe3jFAxue-ewCb3xia?dl=0
Concept and background research
Labyrinths are not the same as mazes. In English the two are regularly muddled up together, but they present significantly different stories. In a maze there are dead ends and loops, you don’t know if you will end up lost forever, there is no clear direction and you left with confusion. A Labyrinth is almost the opposite. A labyrinth (or uni-cursal maze) has only one possibility, you follow the path and it leads you through the environment, safely to the end. You are bound to a particular story, to follow a path laid out before you. It is a lesson to be learned. You can’t go wrong in a labyrinth, and you will end up exactly where you are meant to be.
“knotting is the fundamental principle of coherence” – Tim Ingold
In past projects I have looked at braids and knots [https://github.com/isaac-art/BraidLab], and how they can hold information and tell stories [https://github.com/isaac-art/quipuMaker]. I am interested in Labyrinths for a similar reason, like knots, they are direct and self-explanatory. They appear confusing at a glance, but they are instead clear and coherent. They explain their own process in their form. They are programmes, they are calculative and computational. They are, like this world we live in, winding, textural, and ever-unspooling.
Earlier in the year I presented a research project on Esoteric Programming Languages [https://isaac-art.github.io//2017-11-11/Linguistic_Relativity]. The variety of dialects and designs allow us alternative ways of understanding computation. There have been studies that have shown a strong correlation between linguistic diversity and natural diversity, and I am interested in how variety of language allows us to see more of the world around us, to care for our environment as wholly as we can. The esoteric programming languages present to me the possibility of extending this diversity of knowing into a computational space, and through the 'calculative ambience' (Clough, P. (2015) Computational Aesthetics) of our world we can bridge that seeing and holding into a knowledge that can help us reimagine our connections to the natural world.
The need for art comes from a need to create new ways to explain to others what we know, or at least the knowledge we hold even if we don’t quite know it. There are ideas that can’t be said in one language that another communicates easily. Visual language, interaction, and calculation offer different ways into an idea. Recently I have been reading the poet Moya Cannon’s collection Hands [2011, Carcanet Press] in which her attentiveness to objects or situations transform them into something else. The last line of her poem Crater really captured this for me and was something I wanted the objects on my table to be doing too.
This is what apples are for,
to be turned into song.
Considering this, and the presence of the labyrinth iconography that would be in the work, I began to look into what Cannon calls “carrying the songs”. How the things around us carry their songs of being, and how we carry the songs of others how have been here before us.
In his PhD Thesis titled “Latin Labyrinths, Celtic Knots: Modernism and the dead in Irish and Latin American Literature” [2017, University of Iowa] Jacob Bender explores writers like James Joyce and Jorges Luis Borges and how their writing holds onto the voices of the dead as a political force, an idea that empowers and creates anxiety in the work. Joyce spoke about how his work was written in the form of the Celtic knot, an endless entanglement. In a similar way Borges took the form of the Labyrinth to explore death and infinity. Both writers absorbed those who had written before them and absorbed the forms themselves, meshes and woven tales, winding paths and corridors, and these forms held the stories in some kind of holographic totality.
A writer who I came across during this project who ties together my interested in all these multiple strands is Máirtín Ó Cadhain, whose book Cré Na Cille (Graveyard Clay) [1949, Sáirséal agus Dill] explores this labyrinthine-knotting of the voices of the dead as a “imagined political community” [Anderson, B (1983) Imagined Communities], Irish as a language that could see and say a different world being lived in and to be lived in (the presence of the dead undermining economic utility as social value), and the carrying of songs through language, behaviour, and iconography.
Labyrinths have been used to tell stories both as a setting and structure. Our story telling follows a repeated path, we begin, we journey to the underworld, we come back, we write it down, and the next person reads our words and they are taken on the same journey there and back again.
One last note on my desire to draw labyrinths would be my own coming into an awareness of knowing another in love and remembrance. In bereavement I have found a closeness and an entanglement that is endless, warm, and caring.
What’s true of labyrinths is true of course
Of love and memory. When you start remembering.
- Jack Spicer 2008
For this project I decided to use python so that I could develop my graphics programming skills in a different environment to openframeworks or processing. I wanted to push what I had already learned in other languages and really get a good understanding on opengl and opencv without all the addons provided in openframeworks.
The main set up was the camera processed into the labyrinth and draw on the screen each frame.
|Kinect Depth Camera -> opencv -> labyrinth mask -> recursive backtracker -> opengl -> glfw
|Kinect RGB Camera -> opencv -> opengl -> glfw
The Labyrinth Algorithm
I began searching for maze generation algorithms online, to generate a single path through a space. led me to a few different solutions.
The first possibility was using morphogenesis, replicating natural phenomena of reaction-diffusion to create paths. I was unsure about how well I could mask, the speed of the algorithm, and also not having straight lines. I think having straight lines in the labyrinth pushes us towards seeing it as calculated and digital, I wanted that break from something natural, although on reflection I would now be very interested to see my work using this algorithm.
The second was space-filling curves. These use a formula to draw a line through a space. My concern here was if I could mask an image, it seems that formula required would be very difficult to develop.
After looking into variations of path-finding algorithm, often used in robotics to navigate a space, I came across a book called Mazes for Programmers by Jamis Buck [2015, Pragmatic Bookshelf], a core developer of Ruby on Rails. This book explains maze generation algorithms, and importantly masked maze creation. It explains the difference in algorithms showing how they vary in speed and aesthetics. The book does not cover uni-cursal labyrinth generation, but it seemed a good place to start. I began porting the Ruby examples into Python, with occasional help from reading others who had already done this. The github user Kartones had code that was particularly helpful in translating the trickier parts on the edge of my Python knowledge and led me to a better understanding of the Python yield and generator expressions, as well as overriding the default functions of getting and setting lists. I found the type checking a little excessive so did without in my version.
Briefly, this algorithm works by building a grid of cells, we toggle cells active or inactive with the mask, and then run a recursive backtracker which travels across the cells joining them to neighbouring cells, this the gives us a list of connections we can draw. The recursive backtracker is important to use instead of another algorithm as is creates orthogonal “perfect” mazes, mazes in which there are no loops only dead ends.
My main contribution to this is creating the unicursal labyrinth. By adding in extra points to each cell, essentially splitting them down the middle, we can adapt an orthogonal maze into one continuous path (think how people say to find your way out of a maze keep your hand against one wall and follow it). I was very pleased that I was able to solve this in a way that still allowed me to make use of the masking.
From here I went on to convert the algorithm from taking one static image for a maze, and instead use a camera feed to constantly update the labyrinth. The immediate problem I faced was speed. The maze algorithm could take up to 10 seconds per frame, for a smooth interaction I would like it to be at least 20fps. By playing with image resolution and labyrinth cell size I could get this down to 1 frame per second, but I was hitting the limitation of the python image library drawing function. This is where I really saw the power of opengl, I converted the drawing function to instead return a list of pairs of points and then used opengl to draw and successfully had it running at an acceptable speed. I use the GLFW window manager to create a full screen window on the correct monitor on start up. I also wanted the drawing to pause when the interaction stopped, so I would store the last frame and compare it to the current one to see if the change was large enough and if not would not update the labyrinth just draw the same thing again. This also helped the frame rate as it would cut the incoming feed down to a lower refresh rate.