RedMRCM multiple reduction copy machine

plotting with Pen. after Flake - "The Computational Beauty of Nature"

see also [RedLTurtle] [RedIFS]

class methods:

*new(drawFunc, matrices, n)

drawFunc - a function that draws something.

matrices - array of arrays defining affine transformations.

inner array should have 6 values. see Pen's matrix_ method.

outer array can be any length.

n - number of iterations (depth). default is 1.

instance methods:

draw

start drawing at current Pen position.

makeWindow(bounds)

creates a window and draws. mainly for testing.

instance variables:

<>drawFunc

<>matrices

<>n

//--f is drawFunc, m is matrices, n is depth

f= {Pen.addRect(Rect.aboutPoint(Point(0, 0), 190, 190))};

m= [[0.5, 0, 0, 0.5, -0.25, 0.25], [0.5, 0, 0, 0.5, 0.25, 0.25], [0.5, 0, 0, 0.5, 0, -0.25]];

a= RedMRCM(f, m, 2);

a.makeWindow

a.n= 5

a.makeWindow

a.n= 7

a.makeWindow

a.n= 5

a.drawFunc= {Pen.addWedge(Point(0, 0), 190, 0.125pi, 1.75pi)};

a.makeWindow

a.matrices= [[0.5, 0, 0, 0.5, -0.25, 0.25], [0.5, 0, 0, 0.5, 0.25, 0.25], [0, -0.5, 0.5, 0, 0.25, -0.25]];

a.makeWindow

a.n= 2

a.makeWindow

a.matrices= [[1/3, 0, 0, 1/3, 0, -1/3], [0, -1, -1/3, 0, 1/3, 0], [0, -1, 1/3, 0, -1/3, 0]];

a.makeWindow

a.n= 6

a.makeWindow

a.matrices= [[0.75, 0, 0, 0.75, 0, 0], [0.5, -0.5, 0.5, 0.5, 0, 0], [0.25, 0, 0, 0.25, -0.375, -0.375], [0.25, 0, 0, 0.25, 0.375, -0.375], [0.25, 0, 0, 0.25, -0.375, 0.375], [0.25, 0, 0, 0.25, 0.375, 0.375]];

a.n= 4

a.makeWindow

a.matrices= a.matrices+0.1;

a.makeWindow

a.matrices= a.matrices-0.15;

a.makeWindow

a.matrices= a.matrices*1.2;

a.makeWindow

a.makeWindow(Rect(100, 200, 800, 600)).view.background_(Color.red)

//--

(

var width= 500, height= 500;

var f= {Pen.addOval(Rect.aboutPoint(Point(0, 0), width*0.45, height*0.45))};

var m= [

[0, 0.578, -0.577, 0, -0.15, -0.2],

[0, 0.577, -0.577, 0, -0.156, 0.2],

[0, 0.575, -0.577, 0, 0.2, 0]

];

var a= RedMRCM(f, m, 7);

var w= Window("mrcm", Rect(100, 200, width, height), false);

var u= UserView(w, Rect(0, 0, width, height));

u.background= Color.white;

u.drawFunc= {

Pen.translate(width*0.5, height*0.5);

a.draw(width, height);

Pen.stroke;

};

w.front;

)

//--animation

(

var width= 400, height= 400, cnt= 0;

var f= {Pen.addOval(Rect.aboutPoint(Point(0, 0), width*0.48, height*0.48))};

var m= [[1/3, 0, 0, 1/3, 0, -1/3], [0, -1, -1/3, 0, 1/3, 0], [0, -1, 1/3, 0, -1/3, 0]];

var a= RedMRCM(f, m, 4);

var w= Window("mrcm", Rect(100, 200, width, height), false);

var u= UserView(w, Rect(0, 0, width, height));

u.background= Color.white;

u.drawFunc= {

Pen.translate(width*0.5, height*0.5);

a.draw(width, height);

a.n= cnt.div(15).fold(2, 7).postln;

a.matrices= m.collect{|x| x*2.0.rand2};

Pen.stroke;

cnt= cnt+1;

};

w.front;

Routine({while({w.isClosed.not}, {u.refresh; (1/2).wait})}).play(AppClock);

)

//--animation #2

(

var width= 400, height= 400, cnt= 0;

var f= {Pen.lineTo(Point(0, 0)); Pen.addOval(Rect.aboutPoint(Point(0, 0), width*0.25, height*0.25))};

var m= [

[0.5, 0, 0, 0.5, -0.25, 0.25],

[0.5, 0, 0, 0.5, 0.25, 0.25],

[0.5, 0, 0, 0.5, 0, -0.25]

];

var a= RedMRCM(f, m, 4);

var w= Window("mrcm", Rect(100, 200, width, height), false);

var u= UserView(w, Rect(0, 0, width, height));

u.background= Color.white;

u.drawFunc= {

var temp, temp2;

Pen.moveTo(Point(0, 0));

Pen.rotate(cnt*0.01, width*0.5, height*0.5);

Pen.translate(width*0.5, height*0.5);

a.draw(width, height);

a.n= cnt.div(250).fold(2, 6);

a.matrices= m+(sin(cnt%400/400*2pi)*0.1);

if(cnt%350==349, {

temp= m.size.rand;

temp2= 6.rand;

m= m.put(temp, m[temp].put(temp2, m[temp][temp2]+0.2.linrand));

"mutate".postln;

m.postln;

});

Pen.stroke;

cnt= cnt+1;

};

w.front;

Routine({while({w.isClosed.not}, {u.refresh; (1/30).wait})}).play(AppClock);

)