Parameterize: WAVE
Parameters are powerful tools for controlling a series of objects. The behavior or form of each object can be connected to the value of one or more variables. The designer can think about more than just the individual objects—in this case a rectangle—and instead consider how a population of those objects could combine to create a larger form. Here, the rotation of each rectangle is linked to the rotations of its neighbors. This type of parameterization lends itself to the creation of complex patterns.
The pattern begins with a row of rectangles, each slightly rotated to a random angle. The rotation of each row is determined by the rotation of the rectangle above it. At first, the rotations proceed clockwise, but to prevent overlap, the direction reverses if the new rotation value is too large or small.
/**
* Parameterize: Wave
* from Form+Code in Design, Art, and Architecture
* by Casey Reas, Chandler McWilliams, and LUST
* Princeton Architectural Press, 2010
* ISBN 9781568989372
*
* This code was written for Processing 1.2+
* Get Processing at http://www.processing.org/download
*/
int brickWidth = 40;
int brickHeight = 15;
int cols = 20;
int rows = 24;
int columnOffset = 60;
int rowOffset = 30;
float rotationIncrement = 0.15;
void setup() {
size(1200, 768);
background(255);
smooth();
noFill();
stroke(0);
noLoop();
}
void draw() {
translate(30, 30);
for (int i=0; i<cols; i++) {
pushMatrix();
translate(i * columnOffset, 0);
float r = random(-QUARTER_PI, QUARTER_PI);
int dir = 1;
for (int j=0; j<rows; j++) {
pushMatrix();
translate(0, rowOffset * j);
rotate(r);
rect(-brickWidth/2, -brickHeight/2, brickWidth, brickHeight);
popMatrix();
r += dir * rotationIncrement;
if (r > QUARTER_PI || r < -QUARTER_PI) dir *= -1;
}
popMatrix();
}
}
Contributed Examples
-
Go
/** * Parameterize: Waves from Form+Code in Design, Art, and Architecture * implemented in Go by Anthony Starks * * Requires the go programming language available at http://golang.org * and the SVGo libraray available at http://github.com/ajstarks/svgo * * Create SVG file from command line with: make * * For more information about Form+Code visit http://formandcode.com */ package main import "github.com/ajstarks/svgo" "os" "fmt" "rand" "time" ) var canvas = svg. os.Stdout) width = 1200 height = 768 brickWidth = 40 brickHeight = 15 cols = 20 rows = 24 columnOffset = 60 rowOffset = 30 rotationIncrement float64 = 8.55 // original was 0.15, for Pi/4, we use degrees )
-
OpenFrameworks
/** * Parameterize: Waves from Form+Code in Design, Art, and Architecture * implemented in OpenFrameworks by Anthony Stellato <http://rabbitattack.com/> * * Requires OpenFrameworks available at http://openframeworks.cc/ * * For more information about Form+Code visit http://formandcode.com */ // =========================================================== // - Parameterize_Waves.h // =========================================================== #include "ofMain.h" class testApp : public ofBaseApp{ public: void setup(); void draw(); void mousePressed(int x, int y, int button); }; // =========================================================== // - Parameterize_Waves.cpp // =========================================================== #include "Parameterize_Waves.h" int brickWidth = 40; int brickHeight = 15; int cols = 20; int rows = 24; int columnOffset = 60; int rowOffset = 30; float rotationIncrement = 0.15; static float QUARTER_PI = PI/4.0f; float r = ofRandom(-QUARTER_PI, QUARTER_PI); //-------------------------------------------------------------- void testApp::setup(){ ofSetFrameRate(60); ofEnableSmoothing(); ofNoFill(); } //-------------------------------------------------------------- void testApp::draw(){ ofBackground(255, 255, 255); ofSetColor(0, 0, 0); ofTranslate(30, 30, 0); for(int i = 0; i < cols; i++){ ofPushMatrix(); ofTranslate(i * columnOffset, 0, 0); int dir = 1; for(int j = 0; j < rows; j++){ ofPushMatrix(); ofTranslate(0, rowOffset * j, 0); ofRotate(ofRadToDeg(r), 0, 0, 1); ofRect(-brickWidth/2, -brickHeight/2, brickWidth, brickHeight); ofPopMatrix(); r += dir * rotationIncrement; if(r > QUARTER_PI || r < -QUARTER_PI) dir *= -1; } ofPopMatrix(); } } //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ r = ofRandom(-QUARTER_PI, QUARTER_PI); }
-
Cinder
/** * Parameterize: Waves from Form+Code in Art, Design, and Architecture * implemented in C++ by Sven Steinbauer <http://www.unlogic.co.uk/> * * Requires Cinder 0.8.2 available at http://libcinder.org * And the SimpleGUI Cinder block available at https://github.com/vorg/MowaLibs * * Project files are located at https://github.com/Svenito/parameterize-waves * * For more information about Form+Code visit http://formandcode.com */ #include "cinder/app/AppBasic.h" #include "cinder/CinderMath.h" #include "cinder/Rand.h" #include "cinder/Rect.h" using namespace ci; using namespace ci::app; #include <list> using namespace std; #include "SimpleGUI.h" using namespace mowa::sgui; static float QUARTER_PI = M_PI/4.0f; #define WINDOW_WIDTH 700.0 #define WINDOW_HEIGHT 600.0 class Parameterize_Waves : public ci::app::AppBasic { public: void prepareSettings(Settings* settings); void setup(); void draw(); void seed1(float dotSize, float angle, float x, float y); void seed2(float dotSize, float angle, float x, float y); void mouseDown( MouseEvent event ); private: SimpleGUI *gui; Rand rand; int brickWidth; int brickHeight; int cols; int rows; int columnOffset; int rowOffset; float rotationIncrement; float r; int _dir; }; void Parameterize_Waves::prepareSettings(Settings* settings) { settings->setWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); settings->setFrameRate(24.0f); } void Parameterize_Waves::setup() { brickWidth = 20; brickHeight = 15; cols = 17; rows = 14; columnOffset = 40; rowOffset = 40; _dir = 1; rand.randomize(); r = rand.randFloat(-1.0f * QUARTER_PI, QUARTER_PI); gui = new SimpleGUI(this); gui->addParam("Rot Increment", &rotationIncrement, 0.0f, 1.0f, 0.1f); } void Parameterize_Waves::draw() { gl::setMatricesWindow(getWindowSize()); gl::clear(Color::black()); gl::color(ColorA(0.6, 0.2, 0.2, 1)); gl::translate(Vec3f(30.0f, 30.0f, 0.0f)); float tmp_rot = r; for(int i = 0; i < cols; i++) { gl::pushMatrices(); gl::translate(Vec3f(i * columnOffset, 0.0f, 0.0f)); int dir = 1; for(int j = 0; j < rows; j++){ gl::pushMatrices(); gl::translate(Vec3f(0.0f, rowOffset * j, 0.0f)); gl::rotate(Vec3f(0.0f, 0.0f, toDegrees(tmp_rot))); RectT<float> rec = RectT<float>(-brickWidth/2, -brickHeight/2, brickWidth, brickHeight); gl::drawSolidRect(rec, false); gl::popMatrices(); tmp_rot += dir * rotationIncrement; if(tmp_rot > QUARTER_PI || tmp_rot < (-1 * QUARTER_PI)) dir *= -1; } gl::popMatrices(); } gui->draw(); } void Parameterize_Waves::mouseDown( MouseEvent event ) { r = rand.randFloat(-1 * QUARTER_PI, QUARTER_PI); } CINDER_APP_BASIC( Parameterize_Waves, RendererGl )
We are looking for implementations of the code examples in other programming languages to post on the site. If you would like to submit a sample, or if you find a bug, please write to