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