mirror of
https://github.com/kennetek/gridfinity-rebuilt-openscad.git
synced 2024-11-17 22:10:50 +00:00
Merge pull request #215 from EmperorArthur/update_wall_profile
Auto-Calculate Stacking Lip Fillet
This commit is contained in:
commit
f6ae092962
6 changed files with 123 additions and 69 deletions
|
@ -17,7 +17,7 @@ r_hole2| magnet hole radius
|
|||
d_hole| center-to-center distance between holes
|
||||
h_hole| magnet hole depth
|
||||
h_slit| slit depth (printer layer height)
|
||||
r_f1| top edge fillet radius
|
||||
STACKING_LIP_FILLET_RADIUS| top edge fillet radius
|
||||
r_f2 | internal fillet radius
|
||||
d_div | width of divider between compartments
|
||||
d_wall| minimum wall thickness
|
||||
|
|
|
@ -161,6 +161,18 @@ function affine_translate(vector) = [
|
|||
[0, 0, 0, 1]
|
||||
];
|
||||
|
||||
/**
|
||||
* @brief Affine transformation matrix equivalent of `scale`
|
||||
* @param vector @see `scale`
|
||||
* @returns An affine transformation matrix for use with `multmatrix()`
|
||||
*/
|
||||
function affine_scale(vector) = [
|
||||
[vector.x, 0, 0, 0],
|
||||
[0, vector.y, 0, 0],
|
||||
[0, 0, vector.z, 0],
|
||||
[0, 0, 0, 1]
|
||||
];
|
||||
|
||||
/**
|
||||
* @brief Create a rectangle with rounded corners by sweeping a 2d object along a path.
|
||||
* Centered on origin.
|
||||
|
|
|
@ -9,14 +9,18 @@ include <gridfinity-rebuilt-utility.scad>
|
|||
comments like ' //.5' after variables are intentional and used by the customizer
|
||||
examples at end of file
|
||||
|
||||
BIN HEIGHT
|
||||
the original gridfinity bins had the overall height defined by 7mm increments
|
||||
a bin would be 7*u millimeters tall
|
||||
the lip at the top of the bin (3.8mm) added onto this height
|
||||
#BIN HEIGHT
|
||||
The original gridfinity bins had the overall height defined by 7mm increments.
|
||||
A bin would be 7*u millimeters tall with a stacking lip at the top of the bin (4.4mm) added onto this height.
|
||||
The stock bins have unit heights of 2, 3, and 6:
|
||||
Z unit 2 -> 7*2 + 3.8 -> 17.8mm
|
||||
Z unit 3 -> 7*3 + 3.8 -> 24.8mm
|
||||
Z unit 6 -> 7*6 + 3.8 -> 45.8mm
|
||||
* Z unit 2 -> 7*2 + 4.4 -> 18.4mm
|
||||
* Z unit 3 -> 7*3 + 4.4 -> 25.4mm
|
||||
* Z unit 6 -> 7*6 + 4.4 -> 46.4mm
|
||||
|
||||
## Note:
|
||||
The stacking lip provided here has a 0.6mm fillet instead of coming to a sharp point.
|
||||
Which has a height of 3.55147mm instead of the specified 4.4mm.
|
||||
This **has no impact on stacking height, and can be ignored.**
|
||||
|
||||
https://github.com/kennetek/gridfinity-rebuilt-openscad
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ use <gridfinity-rebuilt-holes.scad>
|
|||
* @returns The final value in mm.
|
||||
*/
|
||||
function fromGridfinityUnits(gridfinityUnit, includeLipHeight = false) =
|
||||
gridfinityUnit*7 + (includeLipHeight ? h_lip : 0);
|
||||
gridfinityUnit*7 + (includeLipHeight ? STACKING_LIP_SIZE.y : 0);
|
||||
|
||||
/**
|
||||
* @Summary Height in mm including fixed heights.
|
||||
|
@ -30,7 +30,7 @@ function fromGridfinityUnits(gridfinityUnit, includeLipHeight = false) =
|
|||
* @returns The final value in mm.
|
||||
*/
|
||||
function includingFixedHeights(mmHeight, includeLipHeight = false) =
|
||||
mmHeight + h_bot + h_base + (includeLipHeight ? h_lip : 0);
|
||||
mmHeight + h_bot + h_base + (includeLipHeight ? STACKING_LIP_SIZE.y : 0);
|
||||
|
||||
/**
|
||||
* @brief Three Functions in One. For height calculations.
|
||||
|
@ -42,14 +42,13 @@ function includingFixedHeights(mmHeight, includeLipHeight = false) =
|
|||
function hf (z, gridz_define, style_lip) =
|
||||
gridz_define==0 ? fromGridfinityUnits(z, style_lip==2) :
|
||||
gridz_define==1 ? includingFixedHeights(z, style_lip==2) :
|
||||
z + ( // Just use z (possibly adding/subtracting lip)
|
||||
style_lip==1 ? -h_lip :
|
||||
style_lip==2 ? h_lip : 0
|
||||
)
|
||||
gridz_define==2 ? z + (style_lip==2 ? STACKING_LIP_SIZE.y : 0) :
|
||||
assert(false, "gridz_define must be 0, 1, or 2.")
|
||||
;
|
||||
|
||||
/**
|
||||
* @brief Calculates the proper height for bins. Three Functions in One.
|
||||
* @Details Critically, this does not include the baseplate height.
|
||||
* @param z Height value
|
||||
* @param d gridz_define as explained in gridfinity-rebuilt-bins.scad
|
||||
* @param l style_lip as explained in gridfinity-rebuilt-bins.scad
|
||||
|
@ -324,47 +323,55 @@ module block_base(hole_options, off=0, size=[BASE_SIZE, BASE_SIZE]) {
|
|||
* @details Also includes a support base.
|
||||
*/
|
||||
module stacking_lip() {
|
||||
// Technique: Descriptive constant names are useful, but can be unweildy.
|
||||
// Use abbreviations if they are going to be re-used repeatedly in a small piece of code.
|
||||
inner_slope = stacking_lip_inner_slope_height_mm;
|
||||
wall_height = stacking_lip_wall_height_mm;
|
||||
|
||||
support_wall = stacking_lip_support_wall_height_mm;
|
||||
s_total = stacking_lip_support_height_mm;
|
||||
|
||||
polygon([
|
||||
[0, 0], // Inner tip
|
||||
[inner_slope, inner_slope], // Go out 45 degrees
|
||||
[inner_slope, inner_slope+wall_height], // Vertical increase
|
||||
[stacking_lip_depth, stacking_lip_height], // Go out 45 degrees
|
||||
[stacking_lip_depth, -s_total], // Down to support bottom
|
||||
[0, -support_wall], // Up and in
|
||||
[0, 0] // Close the shape. Tehcnically not needed.
|
||||
]);
|
||||
polygon(STACKING_LIP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stacking lip with a with a chamfered (rounded) top.
|
||||
* @brief Stacking lip with a with a filleted (rounded) top.
|
||||
* @details Based on https://gridfinity.xyz/specification/
|
||||
* Also includes a support base.
|
||||
*/
|
||||
module stacking_lip_chamfered() {
|
||||
radius_center_y = h_lip - r_f1;
|
||||
module stacking_lip_filleted() {
|
||||
// Replace 2D edge with a radius.
|
||||
// Method used: tangent, tangent, radius algorithm
|
||||
// See: https://math.stackexchange.com/questions/797828/calculate-center-of-circle-tangent-to-two-lines-in-space
|
||||
before_fillet = STACKING_LIP[2];
|
||||
to_fillet = STACKING_LIP[3]; // tip, Point to Chamfer
|
||||
after_fillet = STACKING_LIP[4];
|
||||
|
||||
fillet_vectors = [
|
||||
to_fillet - before_fillet,
|
||||
after_fillet - to_fillet,
|
||||
];
|
||||
|
||||
to_fillet_angle = 180 + atan2(
|
||||
cross(fillet_vectors[0], fillet_vectors[1]),
|
||||
fillet_vectors[0] * fillet_vectors[1]
|
||||
);
|
||||
half_angle = to_fillet_angle / 2;
|
||||
|
||||
// Distance from tip to the center point of the circle.
|
||||
distance_from_edge = STACKING_LIP_FILLET_RADIUS / sin(half_angle);
|
||||
|
||||
// Circle's center point
|
||||
fillet_center_vector = distance_from_edge * [sin(half_angle), cos(half_angle)];
|
||||
fillet_center_point = to_fillet - fillet_center_vector;
|
||||
|
||||
// Exact point edges intersect the circle
|
||||
intersection_distance = fillet_center_vector.y;
|
||||
|
||||
// echo(final_lip_height=fillet_center_point.y + STACKING_LIP_FILLET_RADIUS);
|
||||
|
||||
union() {
|
||||
// Create rounded top
|
||||
intersection() {
|
||||
translate([0, radius_center_y, 0])
|
||||
square([stacking_lip_depth, stacking_lip_height]);
|
||||
offset(r = r_f1)
|
||||
offset(delta = -r_f1)
|
||||
stacking_lip();
|
||||
}
|
||||
// Remove pointed top
|
||||
// Rounded top
|
||||
translate(concat(fillet_center_point, [0]))
|
||||
circle(r = STACKING_LIP_FILLET_RADIUS);
|
||||
|
||||
// Stacking lip with cutout for circle to fit in
|
||||
difference(){
|
||||
stacking_lip();
|
||||
translate([0, radius_center_y, 0])
|
||||
square([stacking_lip_depth*2, stacking_lip_height*2]);
|
||||
polygon(STACKING_LIP);
|
||||
translate(concat(to_fillet, [0]))
|
||||
circle(r = intersection_distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,10 +382,10 @@ module stacking_lip_chamfered() {
|
|||
*/
|
||||
module profile_wall(height_mm) {
|
||||
assert(is_num(height_mm))
|
||||
translate([r_base - stacking_lip_depth, 0, 0]){
|
||||
translate([r_base - STACKING_LIP_SIZE.x, 0, 0]){
|
||||
translate([0, height_mm, 0])
|
||||
stacking_lip_chamfered();
|
||||
translate([stacking_lip_depth-d_wall/2, 0, 0])
|
||||
stacking_lip_filleted();
|
||||
translate([STACKING_LIP_SIZE.x-d_wall/2, 0, 0])
|
||||
square([d_wall/2, height_mm]);
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +422,7 @@ module block_cutter(x,y,w,h,t,s,tab_width=d_tabw,tab_height=d_tabh) {
|
|||
|
||||
v_len_tab = tab_height;
|
||||
v_len_lip = d_wall2-d_wall+1.2;
|
||||
v_cut_tab = tab_height - (2*r_f1)/tan(a_tab);
|
||||
v_cut_tab = tab_height - (2*STACKING_LIP_FILLET_RADIUS)/tan(a_tab);
|
||||
v_cut_lip = d_wall2-d_wall-d_clear;
|
||||
v_ang_tab = a_tab;
|
||||
v_ang_lip = 45;
|
||||
|
|
BIN
images/stacking_lip_variables.jpg
Normal file
BIN
images/stacking_lip_variables.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
|
@ -56,8 +56,6 @@ BASEPLATE_SCREW_COUNTERBORE_HEIGHT = 3;
|
|||
|
||||
// ****************************************
|
||||
|
||||
// top edge fillet radius
|
||||
r_f1 = 0.6;
|
||||
// internal fillet radius
|
||||
r_f2 = 2.8;
|
||||
|
||||
|
@ -74,32 +72,65 @@ d_tabh = 15.85;
|
|||
d_tabw = 42;
|
||||
// angle of tab
|
||||
a_tab = 36;
|
||||
// lip height
|
||||
h_lip = 3.548;
|
||||
|
||||
d_wall2 = r_base-r_c1-d_clear*sqrt(2);
|
||||
d_magic = -2*d_clear-2*d_wall+d_div;
|
||||
|
||||
|
||||
// ****************************************
|
||||
// Stacking Lip Constants
|
||||
// Based on https://gridfinity.xyz/specification/
|
||||
// Also includes a support base.
|
||||
// ****************************************
|
||||
stacking_lip_inner_slope_height_mm = 0.7;
|
||||
stacking_lip_wall_height_mm = 1.8;
|
||||
stacking_lip_outer_slope_height_mm = 1.9;
|
||||
stacking_lip_depth =
|
||||
stacking_lip_inner_slope_height_mm +
|
||||
stacking_lip_outer_slope_height_mm;
|
||||
stacking_lip_height =
|
||||
stacking_lip_inner_slope_height_mm +
|
||||
stacking_lip_wall_height_mm +
|
||||
stacking_lip_outer_slope_height_mm;
|
||||
|
||||
// Extracted from `profile_wall_sub_sub`.
|
||||
stacking_lip_support_wall_height_mm = 1.2;
|
||||
stacking_lip_support_height_mm =
|
||||
stacking_lip_support_wall_height_mm + d_wall2;
|
||||
/**
|
||||
* @Summary Fillet so the stacking lip does not come to a sharp point.
|
||||
*/
|
||||
STACKING_LIP_FILLET_RADIUS = 0.6;
|
||||
|
||||
/**
|
||||
* @Summary Height of the innermost section. In mm.
|
||||
* @Details Used to keep the innermost lip from just being a triangle.
|
||||
* Spec implicitly expects wall width to equal stacking lip depth, so does not define this.
|
||||
*/
|
||||
STACKING_LIP_SUPPORT_HEIGHT = 1.2;
|
||||
|
||||
/**
|
||||
* @Summary Stacking lip as defined in the spec. No support.
|
||||
*/
|
||||
RAW_STACKING_LIP = [
|
||||
[0, 0], // Inner tip
|
||||
[0.7, 0.7], // Go out 45 degrees
|
||||
[0.7, (0.7+1.8)], // Vertical increase
|
||||
[(0.7+1.9), (0.7+1.8+1.9)], // Go out 45 degrees
|
||||
];
|
||||
|
||||
/**
|
||||
* @Summary Size of the stacking lip.
|
||||
* @Details "x": How deep the stacking lip protrudes into the bin.
|
||||
* Including wall thickness.
|
||||
* "y": The height of the stacking lip.
|
||||
*/
|
||||
STACKING_LIP_SIZE = RAW_STACKING_LIP[3];
|
||||
|
||||
_stacking_lip_support_angle = 45;
|
||||
|
||||
/**
|
||||
* @Summary Calculated value for the overall height of the stacking lip.
|
||||
* Including support.
|
||||
*/
|
||||
_stacking_lip_support_height_mm =
|
||||
STACKING_LIP_SUPPORT_HEIGHT
|
||||
+ tan(90 - _stacking_lip_support_angle) * STACKING_LIP_SIZE.x;
|
||||
|
||||
/**
|
||||
* @Summary Stacking lip with a support.
|
||||
* @Details Support is so the stacking lip is not floating in mid air when wall width is less than stacking lip depth.
|
||||
*/
|
||||
STACKING_LIP = concat(RAW_STACKING_LIP, [
|
||||
[STACKING_LIP_SIZE.x, -_stacking_lip_support_height_mm], // Down to support bottom
|
||||
[0, -STACKING_LIP_SUPPORT_HEIGHT], // Up and in (to bottom inner support)
|
||||
[0, 0] // Close the shape. Technically not needed.
|
||||
]);
|
||||
|
||||
// ****************************************
|
||||
// Base constants
|
||||
|
|
Loading…
Reference in a new issue