//a class for the rectangles in draw mode 0
class Shape {
//initialize attributes
float centerx;
float centery;
float shapeWidth;
float shapeHeight;
float speed;
color shapeStroke;
///////////PROPERTIES
Shape(float x, float y, float w, float h){
centerx = x;
centery = y;
w = shapeWidth;
h = shapeHeight;
shapeWidth = random(0, width/2);
shapeHeight = random(0, height/2);
//grey stroke
shapeStroke = color(80);
//constrain center position
x = constrain(x, 0, width-shapeWidth);
y = constrain(y, 0, height-shapeHeight);
}
///////////BEHAVIORS
//move the shape with the mouse cursor
void move(){
centerx = mouseX;
centery = mouseY;
}
//draw the shape
void display() {
//disable fills
noFill();
//grey stroke
stroke(shapeStroke);
//our lovely, fine lines
strokeWeight(0.1);
rectMode(CENTER);
rect(centerx, centery, shapeWidth, shapeHeight);
}
}
///////////INSTRUCTIONS/USAGE
/*
to draw, move your mouse around the window.
the machine will draw a series of lines from your mouse position
to a [series of] set point[s].
to save a frame/screen shot AND clear the screen, press a key.
to change between drawing modes (there are three), press the mouse button.
have fun with watching straight lines create curves!
*/
////////////READY,
//create 1 shape (draw mode 0)
Shape shape1;
//noise variable for mountains/birds (draw mode 1)
float xoff = 0.0;
//declare arrays to store curve points for bezier curve (draw mode 2)
float [] curvePointsX;
float [] curvePointsY;
int currentStep = 0;
//declare & intialize drawing mode
int drawMode = 0;
///////////SET,
void setup() {
size(600, 400);
smooth();
noCursor();
strokeWeight(0.1); //for very fine linework
background(0, 15, 40); //a nice navy for white lines.
frameRate (45); //the speed
//initialize the three rectangles for mode 0
shape1 = new Shape(width/2-50, height/2 -150, random(0, width/2), random(0, height/2));
//initialize/create the bezier curve array with 100 elements for mode 2
curvePointsX = new float[100];
curvePointsY = new float[100];
}
///////////DRAW!
void draw() {
//DRAW MODE 0 //A SHAPE/SET OF LINES => OBJECT, FIGURE, PERSPECTIVAL SPACE
if(drawMode == 0){
shape1.display();
shape1.move();
}
//DRAW MODE 1 //2 RANDOM EDGE POINTS + 1 USER INPUT POINT => MOUNTAINS. OR BIRDS.
else if(drawMode == 1){
xoff = xoff + .01;
float n = noise(xoff) * width;
//white lines on the left side of the screen/mouse
stroke(255, 100);
line(0, n, mouseX, mouseY);
//grey lines on the right side of the screen/mouse
stroke(180, 100);
line(600, n, mouseX, mouseY);
}
//DRAW MODE 2 //LINES DRAWN BETWEEN POINTS ON 2 LINES OR CURVES => PARABOLIC CURVES
else if(drawMode == 2){
//CURVE #1
//draw bezier curve #1 in dark grey
stroke(80);
//call custom bezier function
generateBezier (450, 100, 200, 300, 150, 20, 75, 200);
//disable fills
noFill();
beginShape();
//loop through bezier points stored in memory
for (int i=0; i<100; i++){
vertex(curvePointsX[i], curvePointsY[i]);
}
endShape();
//animate a transparent, black ellipse along the bezier curve
fill(0, 80);
noStroke();
ellipse(curvePointsX[currentStep], curvePointsY[currentStep], 3, 3);
//increment currentStep variable
currentStep++;
//cause ellipse to go back to beginning of curve when it reaches the end
if(currentStep >= 100){
currentStep = 0;
}
//draw a transparent, white line from the points CURVE #1
//to the points on CURVE #2
stroke(255, 100);
beginShape(LINES);
vertex(mouseX, mouseY);
vertex(curvePointsX[currentStep], curvePointsY[currentStep]);
endShape(LINES);
}
}
/////////////FUNCTIONS
// bezierCurve - draw a bezier line to the screen
void bezierCurve(float p0x, float p0y, float cp0x, float cp0y, float cp1x, float cp1y, float p1x, float p1y) {
// B(t) = ((1-t)^3 * P0) + (3t(1-t)^2 * P1) + (3(t^2)(1-t) * P3) + (t^3 * P4)
float delta = 0.01;
// the starting point
float lx = p0x, ly = p0y;
float cx, cy;
for(float t = 0; t <= 1.0; t += delta)
{
// calc the next point
cx = (pow(1-t,3)*p0x) + (3*t*pow(1-t,2)*cp0x) + (3*pow(t,2)*(1-t)*cp1x) + (pow(t,3)*p1x);
cy = (pow(1-t,3)*p0y) + (3*t*pow(1-t,2)*cp0y) + (3*pow(t,2)*(1-t)*cp1y) + (pow(t,3)*p1y);
// draw a segment
line(lx, ly, cx, cy);
// store the last points
lx = cx;
ly = cy;
}
}
// generateBezier - create a bezier & save the points to disk
void generateBezier(float p0x, float p0y, float cp0x, float cp0y, float cp1x, float cp1y, float p1x, float p1y) {
// B(t) = ((1-t)^3 * P0) + (3t(1-t)^2 * P1) + (3(t^2)(1-t) * P3) + (t^3 * P4)
float delta = 0.01;
// the starting point
float cx, cy;
int step = 0;
for( step = 0; step < 100; step++)
{
float t = float(step)/100;
// calc the next point
cx = (pow(1-t,3)*p0x) + (3*t*pow(1-t,2)*cp0x) + (3*pow(t,2)*(1-t)*cp1x) + (pow(t,3)*p1x);
cy = (pow(1-t,3)*p0y) + (3*t*pow(1-t,2)*cp0y) + (3*pow(t,2)*(1-t)*cp1y) + (pow(t,3)*p1y);
curvePointsX[step] = cx;
curvePointsY[step] = cy;
}
}
//change drawing mode by pressing mouse button
void mousePressed(){
drawMode++;
drawMode %=3;
background(0, 15, 40);
}
//save screenshot & clear screen/reset drawing by pressing keyboard key
void keyPressed(){
saveFrame();
background(0, 15, 40);
}
///////////CREDITS
/*
all of these exercises were trying to get me closer to figuring out how to code
something conceptually similar to camille utterback's linescape.app
for the Whitney Museum's CODeDOC project.
See the project here:
http://artport.whitney.org/commissions/codedoc/utterback.shtml
code for draw mode 1 (and color scheme) adapted from:
générateur de montagnes by quentin Aurat, licensed under Creative Commons Attribution-Share Alike 3.0 and GNU GPL license.
Work: http://openprocessing.org/visuals/?visualID=8165
License: http://creativecommons.org/licenses/by-sa/3.0/
http://creativecommons.org/licenses/GPL/2.0/
bezier functions for draw mode 2 from dmgs fall 2010 week 05 sample code.
*/
Press the mouse button to toggle between drawing modes.
Press a key to clear the screen and save the frame.
See code for credits.