So GUI's are great. Instead of having to remember complicated command line combinations and formulas, we can use a mouse to click on icons that make our computer do what we want, when we want it to.
Easy, comfortable, and uncomplicated, using visual languages to manipulate the computer is a best practice that people seem to generally agree with across the board. One industry where this has had a pretty interesting impact is graphic design. Just consider what the Adobe creative suite represents to the industry and our case for the GUI’s is made.
But while we can all admit that the 80's and 90's saw a jump in graphic artist’s productivity, can we really argue that there was any measurable improvement against the quality of the same work done by hand?
When the Internet happened, networked communities starting sprouting. This meant that many different people could simultaneously work on individual parts of a singular project. Hence the jump in productivity. But with file sharing and version control came a increasingly loud conversation about what it was people were using computers to make.
Now, we know that a computer can model objects, relationships, and behaviors that we recognize as being true and real. Just consider what Photoshop actually is: a graphic representation of your basic graphic tool set and all the interactions and reactions that the tools and your digital content subsequently have.
So if a computer can model what we can confirm as real, what can it do for what we can't yet even imagine?
And that's where code comes into play: modelling the unknown.
To understand how code is used to do this on a basic level, we have to get comfortable with the way the computer manipulates form. When it comes to placing things on the screen, there are really two main things to understand:
>> Part 1 • Cartesian Coordinates
We can use our senses to understand the forms we encounter around us, so there's no need for us to consider the math and physics that each form presupposes in order for us to be able to manipulate them. And we can refer to IRL forms indirectly, without fear of being missunderstood.
However, a computer needs to know every single position of every single mark that it produces on screen. It does this by using cartesian coordinates measured against the grid of pixels that makes up your computer screen.
I've been working through the exercises on Kadenze's "Introduction to Programming for the Visual Arts with p5.js". Offered by the University of California, Los Angeles, Department of Arts, it teaches a creative approach to coding. What's more, the teachers are themselves the library's creators, so we have the opportunity to learn direct from the source (!! squee !!)
One of the first exercises involves porting an image to code and is a great example of how we can use information from the Cartesian coordinate system to create and manipulate form with code:
Select a crop of Paul Klee's "Dream City" and draw it using p5js as a 1024 x 768 pixel program. First select an interesting/ambitious crop, then load it into a program such as Photoshop or Illustrator to read the color and coordinate data.
Use integer values for coordinates and only use the following functions for drawing:
line(), triangle(), quad(), rect(), ellipse(), and arc().
You must also use the stroke(), fill(), and background() functions in your sketch as well.
The idea seemed straight forward enough but proved tricky when it came to the exact placement of each graphic on the screen. The coordinate system didn't feel as natural as I expected so plotting out the placement of each type of form using nested for loops was really helpful in figuring out how things fit and move around on the screen.
So here I've isolated and duplicated a specific part of the artwork, since I had selected a portion not quite wide enough for the 1024 x 768 dimensions given.
Then I outlined the shapes I could make out in the image and identified their color codes.
What's interesting to notice here is that while the nested for loops are placing an x based on the canvas' width and height, it's actually also placing each x on a specific part of a coordinate system.
All shapes drawn to the screen have a position that is specified as a coordinate. All coordinates are measured as the distance from the origin in units of pixels. The origin [0, 0] is the coordinate in the upper left of the window and the coordinate in the lower right is [width-1, height-1].
Kind of like if you took the top right portion of the Cartesian coordinate system (figure 1) and flipped it on it's head (figure 2).
Once you understand how the coordinates system works in the p5.js library, all that's left to do is create the shapes you want, and loop them into place.
There are two important things to keep in mind when deciding how to space everything out in your canvas (aka your browser):
1. The top left corner is equal to the position of 0,0 pixels, and grows out in positive increments (figure 2).
2. Any plotted or set position on the canvas has it's own cartesian coordinate 'sub-plane'*, however this cartesian 'sub-plane' resembles the OG coordinate system (figure 1). So within figure 2's spaciality, you can have many smaller system's resembling figure 1.
If that makes no sense to you, give this a look and see if anything clicks:
As you can tell, in the above case, my canvas isn't the size of my whole browser - I've restricted it to 400 pixels by 400 pixels to keep the example simple. In the draw section, I've done three things:
1. used nested for loops to plot out the pixel location for every 50 pixels across the canvas' width (x) and the canvas' length (y) up to 50 pixels before the edge of each.
2. marked each plotted pixel location with an X, which I've drawn by generating two lines.
3. calculated the location of each line's start and end point using the plotted pixel location as the center of the sub-plane (aka the position of 0,0 pixels in relation to the plotted pixel location || the center of the X, where the two lines cross)
With that in mind, take a look at the code I've written to port my image:
Once again, the original:
And here is the ported version:
*for lack of a better term.