Andrew Sweet

22 Jan 2014

Interesting, Beautiful, Useful

Parametric Lego Brick by @HeySweet is a scalable, dimension-pickable open-source #OpenSCAD Lego model file that can support all sizes

lego_0

Growing up, Legos were one of my creative outlets. I could build complex structures out of really simple pieces, and I always liked that. I remember one time picking up Lego’s younger’s child friendly Duplo block somewhere and trying to fit a Lego into. It fit perfectly, and it shocked me because they were totally different sizes. There’s now reason somebody couldn’t scale down Legos up or down 2, 4, 8 times and still get the same effect I had experienced. Additionally if 3D printed, you could have an endless supply of the exact Lego you were missing to complete your structure.

In the design process, dealing with the 1 by x case and other edge cases was clearly something I had to iterate toward in order to support. All of the dimensions I’ve grabbed are from online hobbyists, so I can’t be sure that they will snap together with other Legos unless I try. From what I can tell visually, I made a decent parametric replica of a Lego. If I wanted to continue with the project, there’s now a much wider variety of Legos that I could attempt to support.
lego_3

lego_2

 

lego4 lego3

lego_1

Here’s a list of LEGO dimensions broken down.

brick_dim_1

/* Parameters */
 
//Non-Zero integer values for rows and cols, or number of pegs
numRows = 2;
numCols = 3;
 
// 1/3 and 1 are the two standard heights, 
// all non-negative heights technically supported
height = 1;
 
// Multiples of 2 of each other can fit into each other
brickScale = 1.0; 
 
// The higher the number, the smoother the curves
curveFidelity = 50;
 
/* End Parameters */
 
/* Lego Dimensions courtesy of:
 
http://www.robertcailliau.eu/Lego/Dimensions/zMeasurements-en.xhtml
 
and
 
http://static2.wikia.nocookie.net/__cb20130331204917/legomessageboards/images/3/3c/Lego_brick_2x4.png
 
*/
 
// Brick Dimensions
brickHeightDim = 9.6; // toBeScaled
 
brickUnit = 8.0;
 
dWidth = 0.2;
brickWidth = ((brickUnit * numRows) - dWidth) * brickScale;
brickDepth = ((brickUnit * numCols)  - dWidth) * brickScale;
 
brickHeight = (height * brickHeightDim) * brickScale;
 
shellThicknessTop = 1.0 * brickScale;
shellThicknessSides = 1.2 * brickScale;
 
// UnderPeg
uPegMaxRadius = 6.51 * brickScale/2;
uPegMinRadius = 4.8 * brickScale/2;
uPegOffset    = (8 - 0.1) * brickScale;
uPegHeight    = (brickHeight - shellThicknessTop) * brickScale;
 
// Pegs
tempDistance = 2.4 + 1.6; // To be scaled
pegOffset    = (tempDistance - 0.1) * brickScale;
tempRadius   = 4.8 / 2.0;
pegDistance  = brickUnit * brickScale;
 
pegRadius   = tempRadius * brickScale;
pegHeight   = 1.8 * brickScale;
 
// KnobHolders (small rectangular protrusions underneath)
khWidth  = 0.6 * brickScale;
khDepth  = 0.3 * brickScale;
khOffset = shellThicknessSides + khDepth + pegRadius+ (0.1 * brickScale);
 
// Create the Brick
difference()
{
cube([brickWidth, brickDepth, brickHeight]);
 
translate([shellThicknessSides, 
			shellThicknessSides,
			-1])
cube([brickWidth - (shellThicknessSides * 2), 
		brickDepth - (shellThicknessSides * 2), 
		brickHeight - shellThicknessTop + 1]);
}
 
if (numRows > 1 && numCols > 1){
/* Add Interior */
for (row = [1:(numRows - 1)]){
	for (col = [1:(numCols - 1)]){
 
		// Cylinders
		translate([uPegOffset + (pegDistance * (row - 1)),
				   uPegOffset + (pegDistance * (col-1)),
				   0])	
		difference()
		{
		cylinder(h=uPegHeight, 
				 r1=uPegMaxRadius, 
				 r2=uPegMaxRadius, $fn=curveFidelity);
		translate([0,0,-1])	
		cylinder(h=uPegHeight+0.999, 
				 r1=uPegMinRadius, 
				 r2=uPegMinRadius, $fn=curveFidelity);
		}
	}
}
} else {
	assign (rad = (pegDistance - (pegRadius * 2))/2 - (0.1 * brickScale))
    {
		if (numRows > 1){
 
			for (row = [1:(numRows - 1)]){
				translate(
					[uPegOffset + (pegDistance * (row - 1)),
				  	brickUnit/2,
				  	0])	
				cylinder(h=uPegHeight, 
					 	r1=rad, 
					 	r2=rad, $fn=curveFidelity);
			}
 
		} else if (numCols > 1){
			for (col = [1:(numCols - 1)]){
				translate(
					[brickUnit/2,
				uPegOffset + (pegDistance * (col - 1)),
				  	0])	
				cylinder(h=uPegHeight, 
					 	r1=rad, 
					 	r2=rad, $fn=curveFidelity);
			}
		}
	}
}
 
// KnobHolders (underneath)
if (numRows > 1 && numCols > 1){
for (row = [0:(numRows - 1)]){
		translate([khOffset + (pegDistance * row),
				   shellThicknessSides,
				   0])	
		cube([khWidth, khDepth, uPegHeight]);
 
		translate([khOffset + (pegDistance * row),
			(numCols * brickUnit) - shellThicknessSides - khDepth - (0.2 * brickScale),
				   0])	
		cube([khWidth, khDepth, uPegHeight]);
}
 
for (col = [0:(numCols - 1)]){
		translate([shellThicknessSides,
				   khOffset + (pegDistance * col),
				   0])	
		cube([khDepth, khWidth, uPegHeight]);
 
		translate([(numRows * brickUnit) - shellThicknessSides - khDepth - (0.2 * brickScale),
khOffset + (pegDistance * col),
				   0])	
		cube([khDepth, khWidth, uPegHeight]);
}
}
 
// Create the Pegs
for (row = [0:(numRows - 1)]){
	for (col = [0:(numCols - 1)]){
		translate([pegOffset + (pegDistance * row),
				   pegOffset + (pegDistance * col),
				   brickHeight])	
		cylinder(h=pegHeight, 
				 r1=pegRadius, 
				 r2=pegRadius, $fn=curveFidelity);
	}
}