November 15th, 2016
So far, I've spent a lot of time reading over the chapter on graphics in the openFrameworks (oF) book. It's a pretty dense chapter and full of great techniques used to make compelling graphics.
As I go forward, I do want to stress -- these articles on openFrameworks are not meant to be a replacement for the source material. I absolutely recommend you take the time to read the chapters I reference here. They are far more thorough and contain links to even better documentation. The sole purpose of these articles is to capture some of the highlights. Reading the source material, hand coding the examples, and writing about the work is, for me, an act of gaining a deeper understanding of openFrameworks and, ultimately, C++.
This article references this section in the ofBook titled "Moving the World". The concept is fairly straight-forward. Until now, we've been referencing X and Y coordinates on a standard screen to draw raster an vector graphics. But, now, instead of our code moving to a specific point on the canvas, we can actually re-orient the canvas (rotate, scale, etc.) to the point we are currently at and get some interesting results. Why do this? Instead of hand-coding all the coordinates, inflating out code in the process, we can move entire coordinate systems to a new location on the canvas.
Let me explain.
First, let's look at
ofTranslate(...). This method takes an X and Y (and optional Z) argument and is capable of moving an existing coordinate system to the passed location.
Say, we draw a circle like this:
ofDrawCircle(30, 30, 30);
And, then, we want to draw that same circle in a new location on the canvas. We do:
ofTranslate(0, 150); ofDrawCircle(30, 30, 30);
This will take effectively move the canvas so that the registration point is no longer 0,0. It's 0,150. This code will appear to draw another circle 150px down on the canvas. Neat.
Programmatically moving the canvas, or re-orienting our coordinate system, can put us in a tough spot. We might actually begin drawing outside the canvas! Luckily, there are a couple useful methods for storing and restoring the effects of
We can store a coordinate system by using ofPushMatrix. This method will store the entire current coordinate system before we perform any other further movements. Once we have completed the movements and drawing steps, we use ofPopMatrix to restore the coordinate system to the place it was before
ofPushMatrix was called.
Ok, we can move, store, and restore coordinate systems, but what other options are available to us. These options include two methods that also effect our coordinate system. We can use ofRotate(...) and ofScale(...) as well.
ofRotate takes a single argument. The value we pass (float) is used to rotate the current origin.
ofScale takes two arguments and an optional 3rd . The values we pass (float, float, float) are between 0 and 1 and represent the percentage distance we want to scale the current x,y and z values.
ofBackground(255); ofPushMatrix(); // seems like best practise to indent the code between ofPushMatrix and ofPopMatrix // Original rectangle in blue ofSetColor(0, 0, 255); ofDrawRectangle(500, 200, 200, 200); // Scaled down rectangle in red ofTranslate(500, 200); ofScale(0.5, 0.5); // We are only working in x and y, so let's leave the z scale at its default (1.0) ofSetColor(255, 0, 0); ofDrawRectangle(0, 0, 200, 200); ofPopMatrix();
In the coded examples, there is a reference to ofGetElapsedTimef. This method, when called, will return a float representing the total elapsed time, in seconds, since the application started. They use it like this:
float time = ofGetElapsedTimef(); float timeScale = 0.5; // THIS is interesting; might do another post on this in the future. float noise = ofSignedNoise(time * timeScale) * 20.0; ofRotate(noise);
So, that's it! We've got a few new methods along with some basic techniques to help add to our designs.