Skip to content

Instantly share code, notes, and snippets.

@kmcallister
Created March 27, 2021 03:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmcallister/52951e31907b2a68c75e554321717701 to your computer and use it in GitHub Desktop.
Save kmcallister/52951e31907b2a68c75e554321717701 to your computer and use it in GitHub Desktop.
Parametric culture slant rack
// Copyright 2021 Keegan McAllister
// License: CC-BY 4.0
// https://creativecommons.org/licenses/by/4.0/
include <MCAD/units.scad>
/* [Part selection] */
// Part selection
part = "assembly"; // [assembly, plate, grid, rail, base]
/* [Basic] */
// Diameter of culture tube (mm)
tube_size = 25;
// Angle from horizontal (degrees)
angle = 20;
// Number of holes in horizontal direction
num_holes_horiz = 4;
// Number of holes in vertical direction
num_holes_vert = 2;
/* [Advanced] */
// Material thickness (mm)
thickness = 1.5;
// Added to tube diameter to widen holes for easier insertion (mm)
hole_slack = 1.0;
// Space between holes or from hole to edge (mm)
hole_spacing = 8;
// Space between grids / back plate (mm)
grid_spacing = 30;
// Number of grids
num_grids = 2;
// Width of base pieces (mm)
base_width = 20;
// Width of connecting rails (mm)
rail_width = 10;
// Depth of slots in base pieces and connecting rails (mm)
slot_depth = 5;
eff_tube_size = tube_size + hole_slack;
hole_pitch = eff_tube_size + hole_spacing;
plate_width = num_holes_horiz*hole_pitch + hole_spacing;
plate_height = num_holes_vert*hole_pitch + hole_spacing;
hole_offset = eff_tube_size/2 + hole_spacing;
grid_pitch = grid_spacing + thickness;
rail_length = grid_pitch*num_grids + 3*thickness;
module plate() {
cube([plate_width, plate_height, thickness]);
}
module grid() {
difference() {
plate();
for (i=[0:num_holes_vert-1], j=[0:num_holes_horiz-1]) {
translate([hole_offset + j*hole_pitch,
hole_offset + i*hole_pitch,
-epsilon])
cylinder(h=thickness + epsilon*2, r=eff_tube_size/2);
}
}
}
module smooth_rail(width) {
cube([rail_length, width, thickness]);
}
module generic_rail(width) {
smooth_rail(width);
for (i=[0:num_grids], d=[0, 2*thickness]) {
translate([i*grid_pitch + d, 0, thickness])
cube([thickness, width, slot_depth]);
}
}
module rail() {
generic_rail(rail_width);
}
module base() {
rotate(-angle * Y)
generic_rail(base_width);
hull() {
rotate(-angle * Y)
smooth_rail(base_width);
smooth_rail(base_width);
}
}
module assembly() {
module oriented_rail() {
color("Red")
translate([rail_width, thickness, plate_height + thickness])
rotate(180*Y)
rotate(-90*Z)
rail();
}
module oriented_base() {
color("Gold")
rotate(-90*Z)
base();
}
oriented_base();
translate((plate_width - base_width)*X)
oriented_base();
rotate(-angle * X)
translate([0, -thickness, thickness]) {
rotate(90*X) {
color("MediumBlue")
plate();
color("LimeGreen")
for (i=[1:num_grids]) {
translate(i*grid_pitch * Z)
grid();
}
}
oriented_rail();
translate((plate_width - rail_width)*X)
oriented_rail();
}
}
if (part == "assembly") assembly();
else if (part == "plate") plate();
else if (part == "grid") grid();
else if (part == "rail") rail();
else if (part == "base") base();
else assert(false, str("unknown part: ", part));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment