This makes a simple right-triangle sierpinsky gasket using the reduction method. RTRI makes a right triangle, we reuse this with an inverted right triangle to pile on the reductions (in truth, we are dropping white triangles on top of black triangles, but the effect is the theoretically the same):
startshape RTRI2
rule RTRI {
SQUARE {}
RTRI { x -.75 y -.25 s .5 }
RTRI { x .25 y .75 s .5 }
}
rule RTRI2 {
RTRI {}
// actually, this is unnecessary, just use a square and they will accumulate!
// RTRI { r 180 x -1 y 1 b .9 }
SQUARE { x -1 y 1 b .9 }
RTRI2 { x .25 y -.25 s .5 }
RTRI2 { x -.75 y -.25 s .5 }
RTRI2 { x .25 y .75 s .5 }
}
I also have a Menger sponge done the accumulative (i.e. backwards from reductive) way:
startshape MENGER
rule MENGER {
SQUARE { }
MENGER { y -1 x -1 s .3333 }
MENGER { y -1 x 0 s .3333 }
MENGER { y -1 x 1 s .3333 }
MENGER { y 0 x -1 s .3333 }
// you don't want one in the middle!
//MENGER { y 0 x 0 s .3333 }
MENGER { y 0 x 1 s .3333 }
MENGER { y 1 x -1 s .3333 }
MENGER { y 1 x 0 s .3333 }
MENGER { y 1 x 1 s .3333 }
}
startshape sierpinsky
rule sierpinsky {
triangle {}
triangle { s .5 b 1 r 180 }
sierpinsky { s .5 x -.25 y -.144337 }
sierpinsky { s .5 x .25 y -.144337 }
sierpinsky { s .5 y .288675 }
}
rule triangle {
left { y .144337 }
right { y .144337 }
}
rule left {
SQUARE { s .25 x -.125 y -.125 }
SQUARE { s .25 x -.125 y -.308012 }
left { s .5 x -.25 y -.216506 }
left { s .5 y .216506 }
}
rule right {
SQUARE { s .25 x .125 y -.125 }
SQUARE { s .25 x .125 y -.308012 }
right { s .5 x .25 y -.216506 }
right { s .5 y .216506 }
}
startshape sierpinsky
rule sierpinsky {
triangle {}
triangle { s .5 b 1 r 180 }
sierpinsky { s .5 x -.25 y -.144337 }
sierpinsky { s .5 x .25 y -.144337 }
sierpinsky { s .5 y .288675 }
}
rule triangle {
meta_TRIANGLE{ s .288675}
}
rule meta_TRIANGLE{
TRI{}
TRI{r 120}
TRI{r -120}
}
rule TRI{
SQUARE{x -0.183013 y 0.683013 r -30 }
SQUARE{x 0.183013 y 0.683013 r 30 }
TRI{y 1.1547 s 0.42265 }
}
The next version will have a TRIANGLE primitive and you will be able to control the order of transforms. Being able to do a rotate before a translate will eliminate a lot of explicit trig.
Controlling the order of transforms would be nice.
Another thing that would help with the geometry problem would be if you allowed mathmatical expressions instead of just numeric constants. I'm not saying that you should allow variables or anything that breaks the context free principle, but it would be nice to be able to say, for example "sqrt(3) / 3" rather than "0.577350" and having to remember what the hell that number is for later. Using expressions would also make it easier for other people to see how your designs work, and it would help with round off artifacts (since the precision of a double is certainly more than the precision of however many digits I'm willing to copy from calc).
Named constants would also be nice, but I digress.....