2. Computer-Aided Design (CAD)#
This week I learned how to create 2D images with Inkscape and how to make 3D models with OpensCAD and FreeCAD.
OpensCAD#
OpensCAD is a very useful tool that allows us to perform parametric modeling. This means that when you want to change the size of your object, you just have to change a variable.
It is very easy to learn how to use it and find a tutorial or explanation of some features.
Small tutorial#
// place a cube of a given size
cube(["X-axis size", "Y-axis size", "Z-axis size"], center = "true or false");
// place a cylinder of a given size
cylinder("height", d = "diameter");
// move the next piece with a defined distance
translate(["X-axis size", "Y-axis size", "Z-axis size"])
// rotate the next piece with a defined degree
rotate(["X-axis degree", "Y-axis degree", "Z-axis degree"])
// merge to piece together
union() {
//piece1
//piece2
}
// cut in the first piece with the shape of the second piece
difference() {
//piece1
//piece2
}
If you want to have more information on how to use OpensCAD, you can check the documentation or check the Cheat Sheet.
Making the Flexlink piece#
This Model is inspired by the FlexLinks: “Airplane” Beam by BYU_CMR. In order to get the correct size for the piece I checked a website to get the LEGO Brick Dimensions and Measurements by Christoph Bartneck.
Step 1 : Add a cube in the middle of the grid.
Step 2 : Add 2 cylinders to smooth the sides.
Step 3 : Use the difference with the cylinders to make a hole in the shape.
Step 4 : Use the difference with the cylinders to add details to the hole.
Step 5 : Repeat the shape twice on the sides.
Step 6 : Add a bar between the 2 new pieces.
Step 7 : Use the difference with the cubes on some parts of the bar.
Code and Render#
LEGO Bricks#
NOfPinX = 4;
NOfPinY = 2;
$fn = 100;
width = 7.8;
height = 9.6;
gap = 0.2;
pinHeight = 1.8;
pinWidth = 4.8;
insideUpWidth = 1;
insideOutWidth1xN = 1.5;
insideInWidth1xN = 3.2;
insideOutWidth = 1.2;
insideInWidth = 6.5;
insideSideWidth = 0.6;
insideSideLength = 0.2;
function WidthSize(nPin) = nPin * width + (nPin - 1) * gap;
module LegoCube1x1(){
union(){
difference(){
cube([width, width, height]);
translate([insideOutWidth1xN, insideOutWidth1xN, -insideUpWidth])
cube([width - insideOutWidth1xN * 2, width - insideOutWidth1xN * 2, height]);
} // Add pin on the bloc
translate([width/2, width/2, height])
cylinder(pinHeight, d = pinWidth);
}
}
module LegoCube1xN(nOfPin){
union(){
difference(){
cube([width, WidthSize(nOfPin), height]);
translate([insideOutWidth1xN, insideOutWidth1xN, -insideUpWidth])
cube([width - insideOutWidth1xN * 2, WidthSize(nOfPin) - insideOutWidth1xN * 2, height]);
}
union(){ // Add pin on the bloc
for(i = [1:nOfPin]){
translate([width/2, WidthSize(i) - width/2, height])
cylinder(pinHeight, d = pinWidth);
}
}
union() {
for(i = [1:nOfPin - 1]){
translate([width/2, WidthSize(i) + gap/2, 0])
cylinder(height, d = insideInWidth1xN);
}
}
}
}
module LegoCubeNxM(nOfPinX, nOfPinY){
union(){
difference(){
cube([WidthSize(nOfPinX), WidthSize(nOfPinY), height]);
translate([insideOutWidth, insideOutWidth, -insideUpWidth])
cube([WidthSize(nOfPinX) - insideOutWidth * 2, WidthSize(nOfPinY) - insideOutWidth * 2, height]);
}
union(){ // Add pin on the bloc
for(i = [1:nOfPinX]){
for(j = [1:nOfPinY]){
translate([WidthSize(i) - width/2, WidthSize(j) - width/2, height])
cylinder(pinHeight, d = pinWidth);
}
}
}
union(){
for(i = [1:nOfPinX - 1]){
for(j = [1:nOfPinY - 1]){
translate([WidthSize(i) + gap/2, WidthSize(j) + gap/2, 0])
difference(){
cylinder(height, d = insideInWidth);
translate([0, 0, -insideUpWidth])
cylinder(height, d = pinWidth);
}
}
}
}
union(){
for(i = [1:nOfPinX]){
translate([WidthSize(i) - width/2 - insideSideWidth/2, 0, 0])
union(){
translate([0, insideOutWidth, 0])
cube([insideSideWidth, insideSideLength, height]);
translate([0, WidthSize(nOfPinY) - insideOutWidth - insideSideLength, 0])
cube([insideSideWidth, insideSideLength, height]);
}
}
for(i = [1:nOfPinY]){
translate([0, WidthSize(i) - width/2 - insideSideWidth/2, 0])
union(){
translate([insideOutWidth, 0, 0])
cube([insideSideLength, insideSideWidth, height]);
translate([WidthSize(nOfPinX) - insideOutWidth - insideSideLength, 0, 0])
cube([insideSideLength, insideSideWidth, height]);
}
}
}
}
}
module LegoCube(nOfPinX, nOfPinY){
translate([-WidthSize(nOfPinX/2), -WidthSize(nOfPinY/2), 0])
if (nOfPinX == 1) {
if (nOfPinY == 1) {
LegoCube1x1();
}
else {
LegoCube1xN(nOfPinY);
}
}
else if (nOfPinY == 1) {
translate([0, width, 0])
rotate([0, 0, -90])
LegoCube1xN(nOfPinX);
}
else {
LegoCubeNxM(nOfPinX, nOfPinY);
}
}
LegoCube(NOfPinX, NOfPinY);
LEGO Flexlink#
nOfPinMiddle = 3;
nOfPinSide = 2;
nOfPinBetweenX = 4;
nOfPinBetweenY = 3;
$fn = 100;
width = 7.8;
height = 7.8;
gap = 0.2;
pinWidth = 4.8;
insideOutWidthBeams = 6.2;
insideSideLengthBeams = 0.8;
linkWidth = 1;
function WidthSizeWithGap(nPin) = nPin * (width + gap);
function Hypotenuse(nPinX, nPinY) = sqrt(WidthSizeWithGap(nPinX) * WidthSizeWithGap(nPinX) + WidthSizeWithGap(nPinY) * WidthSizeWithGap(nPinY));
module LegoBeams(nOfPin){
difference(){
union(){
cube([WidthSizeWithGap(nOfPin-1), width, height], center = true);
translate([WidthSizeWithGap(nOfPin-1)/2, 0, -height/2])
cylinder(h = height, d = width);
translate([-WidthSizeWithGap(nOfPin-1)/2, 0, -height/2])
cylinder(h = height, d = width);
}
union(){
translate([-WidthSizeWithGap(nOfPin-1)/2, 0, 0])
for (i = [1:nOfPin]){
translate([WidthSizeWithGap(i-1), 0, 0])
union(){
translate([0, 0, -height])
cylinder(h = height*2, d = pinWidth);
translate([0, 0, (height/2) - insideSideLengthBeams])
cylinder(h = insideSideLengthBeams*2, d = insideOutWidthBeams);
translate([0, 0, -(height/2) - insideSideLengthBeams])
cylinder(h = insideSideLengthBeams*2, d = insideOutWidthBeams);
}
}
}
}
}
module Flexlink(nOfPinMiddle, nOfPinSide, nOfPinBetweenX, nOfPinBetweenY){
union(){
union(){
translate([Hypotenuse(nOfPinBetweenX, nOfPinBetweenY) - WidthSizeWithGap(nOfPinSide/2 - 1), 0, 0])
LegoBeams(nOfPinSide);
translate([-Hypotenuse(nOfPinBetweenX, nOfPinBetweenY) + WidthSizeWithGap(nOfPinSide/2 - 1), 0, 0])
LegoBeams(nOfPinSide);
rotate([0, 0, 90])
LegoBeams(nOfPinMiddle);
}
union(){
difference(){
cube([Hypotenuse(nOfPinBetweenX, nOfPinBetweenY)*2, linkWidth, height], center = true);
union(){
cube([insideOutWidthBeams, linkWidth * 2, height * 2], center = true);
translate([Hypotenuse(nOfPinBetweenX, nOfPinBetweenY) - WidthSizeWithGap(nOfPinSide/2 - 1), 0, 0])
cube([WidthSizeWithGap(nOfPinSide-1) + insideOutWidthBeams, linkWidth * 2, height * 2], center = true);
translate([-Hypotenuse(nOfPinBetweenX, nOfPinBetweenY) + WidthSizeWithGap(nOfPinSide/2 - 1), 0, 0])
cube([WidthSizeWithGap(nOfPinSide-1) + insideOutWidthBeams, linkWidth * 2, height * 2], center = true);
}
}
}
}
}
Flexlink(nOfPinMiddle, nOfPinSide, nOfPinBetweenX, nOfPinBetweenY);
License#
I Choose to license this work under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0). This allows others to freely share or adapt this work if they credit me.
To find out which license to choose for your work, visit this website.