ported from Processing to SuperCollider
Parameterize_Waves.scd
/**
* 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
*/
//ported to SuperCollider by redFrik
(
var width= 1200, height= 768;
var win= Window("Parameterize: Wave", Rect(99, 99, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
var brickWidth= 40;
var brickHeight= 15;
var cols= 20;
var rows= 24;
var columnOffset= 60;
var rowOffset= 30;
var rotationIncrement= 0.15;
usr.background= Color.white;
usr.drawFunc= {
Pen.smoothing= true;
Pen.strokeColor= Color.black;
Pen.translate(30, 30);
cols.do{|i|
var r, dir;
Pen.push;
Pen.translate(i*columnOffset, 0);
r= rrand(-0.25pi, 0.25pi);
dir= 1;
rows.do{|j|
Pen.push;
Pen.translate(0, rowOffset*j);
Pen.rotate(r);
Pen.strokeRect(Rect(0-brickWidth/2, 0-brickHeight/2, brickWidth, brickHeight));
Pen.pop;
r= r+(dir*rotationIncrement);
if(r>0.25pi or:{r< -0.25pi}, {dir= dir* -1});
};
Pen.pop;
};
};
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
Repeat_Embedded.scd
/**
* Repeat: Embedded Iteration
* 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
*/
//ported to SuperCollider by redFrik
(
var width= 400, height= 300;
var win= Window("Repeat: Embedded Iteration", Rect(99, 99, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
var option= 1;
usr.background= Color.white;
usr.animate= true;
usr.drawFunc= {
Pen.smoothing= true;
Pen.strokeColor= Color.black;
if(option==1, {
//Option 1: Stitches
50.forBy(width-50, 20, {|x|
50.forBy(height-50, 20, {|y|
Pen.line(Point(x-5, y-5), Point(x+5, y+5));
Pen.line(Point(x+5, y-5), Point(x-5, y+5));
});
});
Pen.stroke;
}, {
if(option==2, {
//Option 2: Perspective
50.forBy(width-50, 20, {|x|
50.forBy(height-50, 20, {|y|
Pen.line(Point(x, y), Point(width/2, height/2));
});
});
Pen.stroke;
}, {
if(option==3, {
//Option 3: Overlapping circles
50.forBy(width-50, 20, {|x|
50.forBy(height-50, 20, {|y|
Pen.addOval(Rect(x-20, y-20, 40, 40));
});
});
Pen.stroke;
}, {
if(option==4, {
//Option 4: Rotating arcs
var count= 120;
50.forBy(width-50, 20, {|x|
50.forBy(height-50, 20, {|y|
var s= count.linlin(0, 120, 2pi*2, 0, nil);
Pen.addArc(Point(x, y), 7.5, s, pi);
count= count-1;
});
});
Pen.stroke;
}, {
if(option==5, {
//Option 5: Groups of five
50.forBy(width-50, 20, {|x|
50.forBy(height-50, 20, {|y|
//Pen.addRect(Rect(x-10, y-10, 22, 22));
0.forBy(15, 4, {|i|
Pen.line(Point(x+i, y), Point(x+i, y+12));
});
Pen.line(Point(x, y), Point(x+12, y+12));
});
});
Pen.stroke;
});
});
});
});
});
};
usr.mouseDownAction= {
option= option+1;
if(option>5, {
option= 1;
});
};
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
Repeat_RecursiveTree.scd
/**
* Repeat: Recursive Tree
* from Form+Code in Design, Art, and Architecture
* by Casey Reas, Chandler McWilliams, and LUST
* Princeton Architectural Press, 2010
* ISBN 9781568989372
*
* This program is based on Context Free program
* "Foggy Tree by Chris Coyne:
* http://www.contextfreeart.org/gallery/view.php?id=4
*
* This code was written for Processing 1.2+
* Get Processing at http://www.processing.org/download
*/
//ported to SuperCollider by redFrik
(
var dotSize= 9;
var angleOffsetA;
var angleOffsetB;
var width= 900, height= 600;
var frameRate= 1; // Redraw the tree once a second
var win= Window("Repeat: Recursive Tree", Rect(99, 99, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
var seed1, seed2;
angleOffsetA= 1.5.degrad; // Convert 1.5 degrees to radians
angleOffsetB= 50.degrad; // Convert 50 degrees to radians
usr.background= Color.white; // White background
usr.drawFunc= {
Pen.smoothing= true;
Pen.fillColor= Color.black;
Pen.translate(width/2, height); // Move to the center, bottom of the screen
seed1.value(dotSize, 270.degrad, 0, 0); // Start the tree
};
seed1= {|dotSize, angle, x, y|
var r, newx, newy;
if(dotSize>1, {
// Create a random number between 0 and 1
r= 1.0.rand;
// 98% chance this will happen
if(r>0.02, {
Pen.fillOval(Rect(x, y, dotSize, dotSize));
newx= x+(cos(angle)*dotSize);
newy= y+(sin(angle)*dotSize);
seed1.value(dotSize*0.99, angle-angleOffsetA, newx, newy);
}, {
// 2% chance this will happen
Pen.fillOval(Rect(x, y, dotSize, dotSize));
newx= x+cos(angle);
newy= y+sin(angle);
seed2.value(dotSize*0.99, angle+angleOffsetA, newx, newy);
seed1.value(dotSize*0.60, angle+angleOffsetB, newx, newy);
seed2.value(dotSize*0.50, angle-angleOffsetB, newx, newy);
});
});
};
seed2= {|dotSize, angle, x, y|
var r, newx, newy;
if(dotSize>1, {
// Create a random number between 0 and 1
r= 1.0.rand;
// 95% chance this will happen
if(r>0.05, {
Pen.fillOval(Rect(x, y, dotSize, dotSize));
newx= x+(cos(angle)*dotSize);
newy= y+(sin(angle)*dotSize);
seed2.value(dotSize*0.99, angle+angleOffsetA, newx, newy);
}, {
// 5% chance this will happen
Pen.fillOval(Rect(x, y, dotSize, dotSize));
newx= x+cos(angle);
newy= y+sin(angle);
seed1.value(dotSize*0.99, angle+angleOffsetA, newx, newy);
seed2.value(dotSize*0.60, angle+angleOffsetB, newx, newy);
seed1.value(dotSize*0.50, angle-angleOffsetB, newx, newy);
});
});
};
Routine({
inf.do{
usr.refresh;
frameRate.wait;
};
}).play(AppClock);
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
Simulate_DLA.scd
/**
* Simulate: Diffusion-Limited Aggregation
* 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
*/
//ported to SuperCollider by redFrik
(
var win= Window("Simulate: Diffusion-Limited Aggregation", Rect(99, 99, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
var width= 1024, height= 700;
var particle= (
x: 0, y: 0,
stuck: false,
m_reset: {|self|
// keep choosing random spots until an empty one is found
while({
self.x= width.rand.floor;
self.y= height.rand.floor;
field[self.y*width+self.x];
}, nil);
},
m_update: {|self|
var skip= false;
// move around
if(self.stuck.not, {
self.x= self.x+rrand(-1, 1).round;
self.y= self.y+rrand(-1, 1).round;
if(self.x<0 or:{self.y<0 or:{self.x>=width or:{self.y>=height}}}, {
self.m_reset;
skip= true;
});
// test if something is next to us
if(skip.not and:{self.m_alone.not}, {
self.stuck= true;
field[self.y*width+self.x]= true;
});
});
},
// returns true if no neighboring pixels
m_alone: {|self|
var res= true, skip= false;
var cx= self.x;
var cy= self.y;
// get positions
var lx= cx-1;
var rx= cx+1;
var ty= cy-1;
var by= cy+1;
if(cx<=0 or:{cx>=width or:{
lx<=0 or:{lx>=width or:{
rx<=0 or:{rx>=width or:{
cy<=0 or:{cy>=height or:{
ty<=0 or:{ty>=height or:{
by<=0 or:{by>=height}}}}}}}}}}}, {
res= true;
skip= true;
});
// pre multiply the ys
cy= cy*width;
by= by*width;
ty= ty*width;
if(skip.not, {
// N, W, E, S
if(field[cx+ty] or:{
field[lx+cy] or:{
field[rx+cy] or:{
field[cx+by]}}}, {
res= false;
skip= true;
});
if(skip.not, {
// NW, NE, SW, SE
if(field[lx+ty] or:{
field[lx+by] or:{
field[rx+ty] or:{
field[rx+by]}}}, {
res= false;
});
});
});
res;
}
);
// this number might need to be smaller for some computers
var particleCount= 20000;
var particles= Array.newClear(particleCount);
// create an array that stores the position of our particles
var field= Array.fill(width*height, {false});
// add seed in the center
var fcenterX= width.div(2);
var fcenterY= height.div(2);
field[fcenterX+(fcenterY*width)]= true;
// make particles
particleCount.do{|i|
particles[i]= particle.copy;
};
usr.background= Color.white; // White background
usr.drawFunc= {
Pen.smoothing= false;
Pen.fillColor= Color.black;
particleCount.do{|i|
particles[i].m_update;
if(particles[i].stuck, {
Pen.addRect(Rect(particles[i].x, particles[i].y, 1, 1));
});
};
Pen.fill;
};
usr.animate= true;
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
Simulate_Particles.scd
/**
* Simulate: Particles
* 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
*/
//ported to SuperCollider by redFrik
(
var win= Window("Simulate: Particles", Rect(99, 99, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
var width= 1024, height= 768;
var heading2D= {|v|
var angle= (0-v.y).atan2(v.x);
-1*angle;
};
var mag= {|v|
v.x.sumsqr(v.y).sqrt;
};
var particle= (
loc: Point(0, 0),
vel: Point(0, 0),
acc: Point(0, 0),
hist: [],
counter: 0,
// create the particle
m_init: {|self, l|
var randmin= -0.5pi;
var randmax= 0;
var r= rrand(0, 2pi);
var x= cos(r);
var y= sin(r);
var q= 1.0.rand;
self.acc= Point(x/250, y/250);
r= rrand(randmin, randmax);
x= cos(r)*q;
y= sin(r)*q;
self.vel= Point(x, y);
self.loc= l;
self.hist= Array.newClear(1000);
},
// update location
m_update: {|self|
self.vel= self.vel+self.acc;
self.loc= self.loc+self.vel;
// save location every 10 frames
if(usr.frame%10==0 and:{self.counter<self.hist.size}, {
self.hist[self.counter]= self.loc;
self.counter= self.counter+1;
});
},
// draw particle
m_draw: {|self|
self.drawArrowHead(self.vel, self.loc, 10);
// draw history path
Pen.strokeColor= Color.grey(0, 100/255);
self.counter.do{|i|
if(i==0, {
Pen.moveTo(Point(self.hist[i].x, self.hist[i].y));
}, {
Pen.lineTo(Point(self.hist[i].x, self.hist[i].y));
});
};
if(self.counter>0, {
Pen.lineTo(Point(self.loc.x, self.loc.y));
});
Pen.stroke;
},
drawArrowHead: {|self, v, loc, scale|
var arrowsize= 8;
var len;
Pen.push;
// Translate to location to render vector
Pen.translate(loc.x, loc.y);
// rotate to heading
Pen.rotate(heading2D.value(v));
// Calculate length of vector & scale it to be bigger or smaller if necessary
len= mag.value(v)*scale;
arrowsize= len.linlin(0, 10, 0, 1)*arrowsize;
// Draw point
Pen.strokeColor= Color.grey(0, 100/255);
Pen.fillColor= Color.grey(0, 100/255);
Pen.line(Point(0, 0), Point(len-arrowsize, 0));
Pen.stroke;
Pen.moveTo(Point(len, 0));
Pen.lineTo(Point(len-arrowsize, arrowsize/2));
Pen.lineTo(Point(len-arrowsize, 0-arrowsize/2));
Pen.fill;
Pen.pop;
}
);
var particles= Array.newClear(1000);
var saving= false;
// create particles
particles.size.do{|i|
particles[i]= particle.copy.m_init(Point(100, height-100));
};
usr.background= Color.white;
usr.drawFunc= {
Pen.smoothing= true;
// draw the particles
particles.size.do{|i|
particles[i].m_update;
particles[i].m_draw;
};
};
usr.animate= true;
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
Visualize_Superformula.scd
/**
* Visualize: Superformula
* 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
*/
//ported to SuperCollider by redFrik
(
var win= Window("Visualize: Superformula", Rect(99, 99, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
var width= 700, height= 700;
var scaler= 200;
var m= 2;
var n1= 18;
var n2= 1;
var n3= 1;
var superformula= {|m, n1, n2, n3|
var numPoints= 360;
var phi= 2pi/numPoints;
var points= Array.fill(numPoints+1, {|i|
superformulaPoint.value(m, n1, n2, n3, phi*i);
});
points;
};
var superformulaPoint= {|m, n1, n2, n3, phi|
var r;
var t1, t2;
var a= 1, b= 1;
var x= 0;
var y= 0;
t1= cos(m*phi/4)/a;
t1= abs(t1);
t1= pow(t1, n2);
t2= sin(m*phi/4)/b;
t2= abs(t2);
t2= pow(t2, n3);
r= pow(t1+t2, 1/n1);
if(abs(r)==0, {
x= 0;
y= 0;
}, {
r= 1/r;
x= r*cos(phi);
y= r*sin(phi);
});
Point(x, y);
};
usr.background= Color.black;
usr.drawFunc= {
var newscaler= scaler;
Pen.smoothing= true;
Pen.strokeColor= Color.white;
Pen.push;
Pen.translate(width/2, height/2);
16.do{|i|
var s= 16-i;
var mm= m+s;
var nn1= n1+s;
var nn2= n2+s;
var nn3= n3+s;
var sscaler, points;
newscaler= newscaler*0.98;
sscaler= newscaler;
points= superformula.value(mm, nn1, nn2, nn3);
Pen.moveTo(points[points.size-1]*sscaler);
points.size.do{|i|
Pen.lineTo(points[i]*sscaler);
};
Pen.lineTo(points[0]*sscaler);
Pen.stroke;
};
Pen.pop;
};
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
todo:
- Parameterize_Chair.scd
- Transform_Landscape.scd
- Transform_SlitScan.scd
- Visualize_Data.scd