Code: Select all

```
// The width of the largest shell
maxWidth = 7; // [0:10]
// The side length of the longest shell
maxSideLength = 4; // [0:0.5:5]
// Angle described by each shell
shellAngle = 37; // [30:40]
// How far from the origin of the shells to the pivot point
pivotOffset = 2; // [0:0.5:4]
module ShellShape(width, straightlen, angle){
rotate([90,90+angle/2,0])
rotate_extrude(angle=angle)
translate([-straightlen,-0,0])
union(){
translate([0,-width/2,0])
square([straightlen,width]);
difference(){
circle(d=width);
translate([0,-width/2,0])
square([width/2,width]);
}
}
};
baseThickness = 0.5;
shellOverlap = 1/3; //proportion of each shell to overlap
widthStepDown = 0.25; // how much to reduce the width by for each successive shell
sideLengthStepDown = 0.1; // how much to reduce the side length by for each successive shell
translate([0,0,pivotOffset/2+baseThickness])
for(i=[0:1])
mirror( [i, 0, 0] )
difference() {
union() {
for (i=[0:3]) {
rotate([0,i*(1-shellOverlap)*shellAngle,0])
translate([0,0,-pivotOffset])
ShellShape(maxWidth-i*widthStepDown,maxSideLength-i*sideLengthStepDown,shellAngle);
}
translate([0,0,-pivotOffset])
cylinder(h=pivotOffset+2,d=maxWidth-4*widthStepDown);
translate([0,0,-pivotOffset])
cylinder(h=1,d=maxWidth+3);
}
translate([-(maxWidth+maxSideLength+1),-(maxWidth+maxSideLength+1)/2,-(maxWidth+maxSideLength+1)/2])
cube(maxWidth+maxSideLength+1);
translate([-0.5,-(maxWidth+maxSideLength+1)/2,-(maxWidth+maxSideLength+1)-pivotOffset/2-baseThickness])
cube(maxWidth+maxSideLength+1);
}
$fn=100;
```