Here are the new fully interlocking Tiles.
Code: Select all
//!OpenSCAD
//main parameters
emptyToothWidth = 0.4;
emptyToothLength = 0.1;
filledToothWidth = 0.5;
rfilled = 0.55;
cutFilled = 0.1;
r1Jig = 0.2;
r2Jig = 0.14;
slopeJig = 0.4;
//3d structural teeth
cubeSizeW = 0.17;
cubeAngle = 30;
toothLocation = 0.07;
//Adding 3d tooths flag
add3dStructure = false;
addScale= true;
//Height
H = 1;
r = 10;
d = r * cos(45 / 2);
side = 2 * r * sin(45 / 2);
eps = 0.001;
dFactor = 0.1;
scalefactor1 = 0.935;
scalefactor2 = 0.95;
scaleEmpty = 1.03;
cutSlice = 0.09;
cutAngle = 70;
module Tooth()
{
translate([0, 0, -H / 2])rotate([90, 0, 0])linear_extrude(height = cubeSizeW * r) polygon([[-eps,-eps], [-eps ,H / 2],[H / 2 * sin(cubeAngle), -eps]]);
}
module Slice(use3D = false, r1 = r, applyDiff = true)
{
factor = cutSlice;
if(use3D && add3dStructure)
{
difference()
{
union()
{
linear_extrude(height = H) rotate([0,0,-45/2])polygon([[0,0],[r1, 0],[r1 * cos(360/8), r1* sin(360/8)]] );
translate([d, - side * toothLocation, H / 2]) Tooth();
translate([d, side * toothLocation, H / 2]) rotate([180, 0, 0]) Tooth();
}
translate([d, - side * toothLocation, H / 2]) rotate([0, 180, 0]) Tooth();
translate([d, side * toothLocation, H / 2]) rotate([180, 180, 0]) Tooth();
}
}
else
{
difference()
{
linear_extrude(height = H) rotate([0,0,-45/2])polygon([[0,0],[r, 0],[r * cos(360/8), r* sin(360/8)]] );
if(applyDiff)
{
translate([d, side/2])rotate([0,0,cutAngle])translate([-r*factor, -r*factor])cube([r*2*factor, r*2*factor, H]);
translate([d, -side/2])rotate([0,0,-cutAngle])translate([-r*factor, -r*factor])cube([r*2*factor, r*2*factor, H]);
}
}
}
};
module SliceWithTooth()
{
union()
{
Slice(false, r, true);
linear_extrude(height = H) translate([d, -r * emptyToothWidth / 2]) square([r * emptyToothLength,r * emptyToothWidth]);
}
};
//Tiles from slices
module SquareTilePiece()
{
difference()
{
union()
{
linear_extrude(height = H) polygon([[0,0], [side/2,side/2], [side/2,-side/2]]);
if(add3dStructure)
{
translate([side / 2, - side * toothLocation, H / 2]) Tooth();
translate([side / 2, side * toothLocation, H / 2]) rotate([180, 0, 0]) Tooth();
}
}
if(add3dStructure)
{
translate([side / 2, - side * toothLocation, H / 2]) rotate([0, 180, 0]) Tooth();
translate([side / 2, side * toothLocation, H / 2]) rotate([180, 180, 0]) Tooth();
}
}
}
module SquareTile()
{
rotate([0,0,45/2])union()
{
SquareTilePiece();
rotate([0,0,90]) SquareTilePiece();
rotate([0,0,180]) SquareTilePiece();
rotate([0,0,-90]) SquareTilePiece();
}
};
//Simple Living parts
module LiveSlice()
{
r1 = (r * cos(45/2) - emptyToothLength * r) / cos(45/2);
color([0, 0.4, 0.9]) linear_extrude(height = H) rotate([0,0,-45/2])polygon([[0,0],[r1, 0],[r1 * cos(360/8), r1 * sin(360/8)]] );
};
//Simple Living parts
module LiveSlicePartial(dir)
{
r1 = (r * cos(45/2) - emptyToothLength * r) / cos(45/2);
r2 = r1 * rfilled;
r3 = r * cutFilled;
difference()
{
color([0, 0.4, 0.9]) linear_extrude(height = H) rotate([0,0,-45/2])polygon([[0,0],[r1, 0],[r1 * cos(360/8), r1 * sin(360/8)]] );
linear_extrude(height = H) rotate([0,0,-45/2])polygon([[0,0],[r2, 0],[r2 * cos(360/8), r2 * sin(360/8)]]);
linear_extrude(height = H) polygon([[0,0],[r2 * cos(360 / 16) + r3, 0],[r2 * cos(360 / 16) + r3, r * dir]]);
}
};
module LiveSliceWithTooth()
{
size = r/6;
dtooth = r * filledToothWidth;
color([0, 0.4, 0.9]) union()
{
LiveSlice();
linear_extrude(height = H)translate([r * cos(45/2) - size, -dtooth /2])square([size,dtooth ]);
}
};
module LiveSliceWithToothPartial(dir)
{
size = r/6;
dtooth = r * filledToothWidth;
color([0, 0.4, 0.9]) union()
{
LiveSlicePartial(dir);
linear_extrude(height = H)translate([r * cos(45/2) - size, -dtooth /2])square([size,dtooth ]);
}
};
module HelperLife_InternalTooth()
{
rotate([0,0,45])
union()
{
LiveSliceWithTooth();
rotate([0,0,45]) LiveSliceWithTooth();
rotate([0,0,-45]) LiveSliceWithTooth();
}
};
module Helper_InternalTooth()
{
rotate([0,0,45])
union()
{
Slice();
rotate([0,0,45]) Slice();
rotate([0,0,-45]) Slice();
}
};
module TileLife_InternalTooth()
{
rotate([0,0,45/2])
color([0, 0.4, 0.9])
difference()
{
linear_extrude(height = H)polygon([[-d, d], [-d, -d], [d, -d], [d, d]]);
translate([-d, -d]) HelperLife_InternalTooth();
translate([d, -d]) rotate([0,0,90]) HelperLife_InternalTooth();
translate([-d, d]) rotate([0,0,-90]) HelperLife_InternalTooth();
translate([d, d]) rotate([0,0,180]) HelperLife_InternalTooth();
translate([d - filledToothWidth * r / 2, -d/2])cube([side, side, H]);
translate([-side -d + filledToothWidth * r / 2, -d/2])cube([side, side, H]);
translate([-d/2, -side -d + filledToothWidth * r / 2 ])cube([side, side, H]);
translate([-d/2, d - filledToothWidth * r / 2 ])cube([side, side, H]);
}
};
module Tile_Internal()
{
rotate([0,0,45/2])
color([0.8, 0.8, 0.2])
difference()
{
linear_extrude(height = H)polygon([[-d, d], [-d, -d], [d, -d], [d, d]]);
translate([-d, -d]) Helper_InternalTooth();
translate([d, -d]) rotate([0,0,90]) Helper_InternalTooth();
translate([-d, d]) rotate([0,0,-90]) Helper_InternalTooth();
translate([d, d]) rotate([0,0,180]) Helper_InternalTooth();
}
}
module TileSpaceFiller_Type4()
{
rotate([0,0,-45/2])
color([0, 0.4, 0.9])
difference()
{
linear_extrude(height = H) polygon([[-side, side], [-side, -side], [side, -side], [side, side]]);
translate([d, -d]) rotate([0,0,45 + 135]) SliceWithTooth() ;
translate([d, -d]) rotate([0,0,45 + 90]) Slice() ;
translate([d, -d]) rotate([0,0,45 + 45]) SliceWithTooth() ;
translate([d, d]) rotate([0,0,45 + 180])LiveSliceWithTooth() ;
translate([d, d]) rotate([0,0,45 + 135 ])LiveSlice() ;
translate([d, d]) rotate([0,0,45 + -135])LiveSlice() ;
translate([-d, d]) rotate([0,0,45 + -45]) SliceWithTooth() ;
translate([-d, d]) rotate([0,0,45 + -90]) Slice() ;
translate([-d, d]) rotate([0,0,45 + -135]) SliceWithTooth();
translate([-d, -d])rotate([0,0,45]) LiveSliceWithTooth() ;
translate([-d,-d]) rotate([0,0,45 + 45])LiveSlice() ;
translate([-d, -d]) rotate([0,0,45 + -45])LiveSlice() ;
}
};
module TileSpaceFiller_Type3()
{
rotate([0,0,-45/2])
color([0, 0.4, 0.9])
difference()
{
linear_extrude(height = H) polygon([[-side, side], [-side, -side], [side, -side], [side, side]]);
translate([d, -d]) rotate([0,0,45 + 135]) LiveSlice() ;
scale(1 + eps)translate([d, -d]) rotate([0,0,45 + 90]) LiveSlice() ;
translate([d, -d]) rotate([0,0,45 + 45]) LiveSlice() ;
translate([d, d]) rotate([0,0,90 + 180])SliceWithTooth() ;
scale(1 + eps)translate([d, d]) rotate([0,0,45 + 180])Slice() ;
translate([d, d]) rotate([0,0,45 + 135])Slice() ;
translate([-d, d]) rotate([0,0,45 + -45]) Slice() ;
scale(1 + eps)translate([-d, d]) rotate([0,0,45 + -90]) SliceWithTooth() ;
translate([-d, d]) rotate([0,0,45 + -135]) Slice();
translate([-d,-d]) rotate([0,0,45 + 45])Slice() ;
scale(1 + eps)translate([-d, -d])rotate([0,0,45]) Slice() ;
translate([-d, -d]) rotate([0,0,45 + -45])SliceWithTooth() ;
}
};
module TileSpaceFiller_Type2()
{
rotate([0,0,-45/2])
color([0, 0.4, 0.9])
difference()
{
linear_extrude(height = H) polygon([[-side, side], [-side, -side], [side, -side], [side, side]]);
translate([d, -d]) rotate([0,0,45 + 135]) LiveSliceWithTooth() ;
scale(1 + eps)translate([d, -d]) rotate([0,0,45 + 90]) LiveSlice() ;
translate([d, -d]) rotate([0,0,45 + 45]) LiveSlice() ;
translate([d, d]) rotate([0,0,90 + 180])SliceWithTooth() ;
scale(1 + eps)translate([d, d]) rotate([0,0,45 + 180])SliceWithTooth() ;
translate([d, d]) rotate([0,0,45 + 135])Slice() ;
translate([-d, d]) rotate([0,0,45 + -45]) Slice() ;
scale(1 + eps)translate([-d, d]) rotate([0,0,45 + -90]) SliceWithTooth() ;
translate([-d, d]) rotate([0,0,45 + -135]) SliceWithTooth();
translate([-d,-d]) rotate([0,0,45 + 45])LiveSlice() ;
scale(1 + eps)translate([-d, -d])rotate([0,0,45]) LiveSlice() ;
translate([-d, -d]) rotate([0,0,45 + -45])LiveSliceWithTooth() ;
}
};
module TileSpaceFiller_Type1()
{
rotate([0,0,-45/2])
color([0, 0.4, 0.9])
difference()
{
linear_extrude(height = H) polygon([[-side, side], [-side, -side], [side, -side], [side, side]]);
translate([d, -d]) rotate([0,0,45 + 135]) SliceWithTooth() ;
scale(1 + eps)translate([d, -d]) rotate([0,0,45 + 90]) SliceWithTooth() ;
translate([d, -d]) rotate([0,0,45 + 45]) SliceWithTooth() ;
translate([d, d]) rotate([0,0,90 + 180])LiveSlice() ;
scale(1 + eps)translate([d, d]) rotate([0,0,45 + 180])LiveSliceWithTooth() ;
translate([d, d]) rotate([0,0,45 + 135])LiveSliceWithTooth() ;
translate([-d, d]) rotate([0,0,45 + -45]) LiveSliceWithTooth() ;
scale(1 + eps)translate([-d, d]) rotate([0,0,45 + -90]) LiveSlice() ;
translate([-d, d]) rotate([0,0,45 + -135]) LiveSliceWithTooth();
translate([-d,-d]) rotate([0,0,45 + 45])LiveSliceWithTooth() ;
scale(1 + eps)translate([-d, -d])rotate([0,0,45]) LiveSliceWithTooth() ;
translate([-d, -d]) rotate([0,0,45 + -45])LiveSlice() ;
}
};
module TileLife_TwoSlicePartial()
{
color([0, 0.4, 0.9]) union()
{
LiveSliceWithToothPartial(1);
rotate([0, 0, 45])LiveSlicePartial(-1);
}
}
module TileLife_FourSlicePartial()
{
r1j = r * r1Jig;
r2j = r * r2Jig;
color([0, 0.4, 0.9]) rotate([0,0,-45/2])difference()
{
rotate([0,0,45/2])difference()
{
union()
{
LiveSlice();
rotate([0, 0, 45])LiveSlice();
rotate([0, 0, 90])LiveSlice();
rotate([0, 0, 135])LiveSliceWithTooth();
}
rotate([0, 0, 45])TileLife_TwoSlicePartial();
}
linear_extrude(height = H) polygon([[-r1j, 0], [r1j, 0], [r1j + slopeJig * r2j, r2j], [-r1j - slopeJig * r2j, r2j]]);
}
}
module TileLife_FourSlice()
{
r1j = r * r1Jig;
r2j = r * r2Jig;
color([0, 0.4, 0.9]) rotate([0,0,-45/2])difference()
{
rotate([0,0,45/2])
{
union()
{
LiveSlice();
rotate([0, 0, 45])LiveSlice();
rotate([0, 0, 90])LiveSlice();
rotate([0, 0, 135])LiveSliceWithTooth();
}
}
linear_extrude(height = H) polygon([[-r1j, 0], [r1j, 0], [r1j + slopeJig * r2j, r2j], [-r1j - slopeJig * r2j, r2j]]);
}
}
module TileLife_StaticPart()
{
color([0, 0.4, 0.9]) difference()
{
union()
{
for (i = [0 : 7])
rotate([0,0,45 * i]) LiveSlice();
}
rotate([0,0,45])TileLife_TwoSlicePartial();
rotate([0,0,180])TileLife_TwoSlicePartial();
TileLife_FourSlicePartial();
}
}
module EmptyTile4_2teeth_90()
{
difference()
{
union()
{
SliceWithTooth();
rotate([0,0,45]) SliceWithTooth();
}
TileLife_InternalTooth();
}
};
module EmptyTile4_1teeth_90()
{
difference()
{
union()
{
Slice();
rotate([0,0,45]) SliceWithTooth();
}
TileLife_InternalTooth();
}
};
module EmptyTile4_2teeth_180()
{
difference()
{
union()
{
Slice();
rotate([0,0,45]) Slice();
rotate([0,0,90]) SliceWithTooth();
rotate([0,0,135]) SliceWithTooth();
}
TileLife_InternalTooth();
}
};
module PlaceFilled(x, y, type, rot)
{
dx = dFactor * cos(45/2 - 45 * rot);
dy = dFactor * sin(45/2 - 45 * rot);
if(type == 0)
translate([2 * d * x + dx, 2 * d * y + dy]) scale(scaleEmpty * scalefactor1) rotate([0,0,-45 - 45 * rot])TileLife_EmptyInternalEdgeTooth();
if(type == 1)
translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scaleEmpty * scalefactor1) rotate([0,180, -90 - 45 * rot])TileLife_EmptyInternalEdgeTooth();
if(type == 2)
translate([2 * d * x + dx, 2 * d * y + dy]) scale(scaleEmpty * scalefactor1) rotate([0,0,-45 - 45 * rot])TileLife_EmptyInternalTooth();
if(type == 3)
translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scaleEmpty * scalefactor1) rotate([0,180, -90 - 45 * rot])TileLife_EmptyInternalTooth();
if(type == 4)
translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,-45 - 45 * rot]) TileLife_FilledInternalEdgeTooth();
if(type == 5)
translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scalefactor2) rotate([0,180, -90 - 45 * rot])TileLife_FilledInternalEdgeTooth();
if(type == 6)
translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,-45 - 45 * rot]) TileLife_FilledInternalTooth();
if(type == 7)
translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scalefactor2) rotate([0,180, -90 - 45 * rot])TileLife_FilledInternalTooth();
};
module PlaceInternalConnector(x, y, type, rot)
{
dx = 0;
dy = 0;
if(type == 0)
translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,- 45 * rot])TileSpaceFiller_Type4();
if(type == 12)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,45 - 45 * rot])SquareTile();
if(type == 4)
{
if(abs(rot - floor(rot)) < 0.1)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,45 - 45 * rot])TileLife_InternalTooth();
else
color([0, 0.4, 0.9]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor1) rotate([0,0, 45 /2 - 45 * rot])TileLife_InternalTooth();
}
}
module PlaceExternalConnector(x, y, type, rot)
{
dx = 0;
dy = 0;
if(type == 0)
translate([d + 2 * d * x + dx, d + 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,45/2 - 90 * rot])TileSpaceFiller_Type4();
if(type == 1)
color([0.8, 0.8, 0.2]) translate([d + 2 * d * x + dx, d + 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,45/2 - 90 - 90 * rot])TileSpaceFiller_Type3();
if(type == 2)
color([0.8, 0.8, 0.2]) translate([d + 2 * d * x + dx, d + 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,45/2 - 90 - 90 * rot])TileSpaceFiller_Type1();
if(type == 3)
color([0.8, 0.8, 0.2]) translate([d + 2 * d * x + dx, d + 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,45/2 - 90 - 90 * rot])TileSpaceFiller_Type2();
if(type == 12)
color([0.8, 0.8, 0.2]) translate([d + 2 * d * x + dx, d + 2 * d * y + dy]) scale(scalefactor1) rotate([0,0,45/2 - 45 * rot])SquareTile();
if(type == 4)
color([0, 0.4, 0.9]) translate([d +2 * d * x + dx, d +2 * d * y + dy]) scale(scalefactor1) rotate([0,0,-45/2 ])TileLife_InternalTooth();
}
module PlaceEmpty0(x, y, type, rot)
{
dx = dFactor * cos(45/2 - 45 * rot);
dy = dFactor * sin(45/2 - 45 * rot);
if(type == 0)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,-45 - 45 * rot])EmptyTile0_NoTeeth();
if(type == 1)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,-45 - 45 * rot])EmptyTile0_InternalTeeth();
if(type == 2)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scalefactor2) rotate([0,180, -90 - 45 * rot])EmptyTile0_InternalTeeth();
if(type == 3)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,-45 - 45 * rot])EmptyTile0_EdgeTeeth();
if(type == 4)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scalefactor2) rotate([0,180, -90 - 45 * rot])EmptyTile0_EdgeTeeth();
}
module PlaceEmpty4(x, y, type, rot)
{
dx = dFactor * cos(45/2 - 45 * rot);
dy = dFactor * sin(45/2 - 45 * rot);
if(type == 0)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,-45 - 45 * rot])EmptyTile4_2teeth_180();
if(type == 1)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scalefactor2) rotate([0,180, -90 - 45 * rot])EmptyTile4_2teeth_180();
if(type == 2)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,45 - 45 * rot])EmptyTile4_1teeth_90();
if(type == 3)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy, H]) scale(scalefactor2) rotate([0,180, -90 - 45 * rot])EmptyTile4_1teeth_90();
if(type == 4)
color([0.8, 0.8, 0.2]) translate([2 * d * x + dx, 2 * d * y + dy]) scale(scalefactor2) rotate([0,0,45 - 45 * rot])EmptyTile4_2teeth_90();
}
module EmptyTile0_NoTeeth()
{
difference()
{
union()
{
Slice();
rotate([0,0,45]) Slice();
rotate([0,0,90]) Slice();
rotate([0,0,135]) Slice();
}
rotate([0,0,45]) TileLife_InternalTooth();
}
};
module EmptyTile0_EdgeTeeth()
{
difference()
{
union()
{
SliceWithTooth();
rotate([0,0,45]) Slice();
rotate([0,0,90]) Slice();
rotate([0,0,135]) Slice();
}
rotate([0,0,45]) TileLife_InternalTooth();
}
};
module EmptyTile0_InternalTeeth()
{
difference()
{
union()
{
Slice();
rotate([0,0,45]) SliceWithTooth();
rotate([0,0,90]) Slice();
rotate([0,0,135]) Slice();
}
rotate([0,0,45]) TileLife_InternalTooth();
}
};
/*
translate([r * 3, 0])TileLife_FourSlicePartial();
translate([r * 6, 0])TileLife_TwoSlicePartial();
TileLife_StaticPart();
translate([r * 9, 0])TileLife_FourSlice();
*/
d1 = 2.4 * d;
translate([-2 * d1, 2 * d1]) TileSpaceFiller_Type4();
translate([- d1, 2 * d1])TileSpaceFiller_Type3();
translate([0, 2 * d1])TileSpaceFiller_Type1();
translate([d1, 2 * d1])TileSpaceFiller_Type2();
color([0.8, 0.8, 0.2])translate([- 2 * d1, d1])TileLife_InternalTooth();
translate([- d1, d1])TileLife_FourSlicePartial();
translate([0, d1])TileLife_TwoSlicePartial();
translate([d1, d1])TileLife_StaticPart();
translate([- 2 * d1, 0])TileLife_FourSlice();
color([0.8, 0.8, 0.2])translate([- d1, 0])EmptyTile4_2teeth_180();
color([0.8, 0.8, 0.2])translate([0, 0])EmptyTile4_1teeth_90();
color([0.8, 0.8, 0.2])translate([d1, 0])EmptyTile4_2teeth_90();
color([0.8, 0.8, 0.2])translate([- 2 * d1, -d1])Tile_Internal();
color([0.8, 0.8, 0.2])translate([- d1, -d1])EmptyTile0_NoTeeth();
color([0.8, 0.8, 0.2])translate([0, -d1])EmptyTile0_InternalTeeth();
color([0.8, 0.8, 0.2])translate([d1, -d1])EmptyTile0_EdgeTeeth();