Merge pull request #215 from EmperorArthur/update_wall_profile

Auto-Calculate Stacking Lip Fillet
This commit is contained in:
Arthur Moore 2024-10-04 01:45:09 -04:00 committed by GitHub
commit f6ae092962
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 123 additions and 69 deletions

View file

@ -17,7 +17,7 @@ r_hole2| magnet hole radius
d_hole| center-to-center distance between holes d_hole| center-to-center distance between holes
h_hole| magnet hole depth h_hole| magnet hole depth
h_slit| slit depth (printer layer height) 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 r_f2 | internal fillet radius
d_div | width of divider between compartments d_div | width of divider between compartments
d_wall| minimum wall thickness d_wall| minimum wall thickness

View file

@ -161,6 +161,18 @@ function affine_translate(vector) = [
[0, 0, 0, 1] [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. * @brief Create a rectangle with rounded corners by sweeping a 2d object along a path.
* Centered on origin. * Centered on origin.

View file

@ -9,14 +9,18 @@ include <gridfinity-rebuilt-utility.scad>
comments like ' //.5' after variables are intentional and used by the customizer comments like ' //.5' after variables are intentional and used by the customizer
examples at end of file examples at end of file
BIN HEIGHT #BIN HEIGHT
the original gridfinity bins had the overall height defined by 7mm increments The original gridfinity bins had the overall height defined by 7mm increments.
a bin would be 7*u millimeters tall 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 lip at the top of the bin (3.8mm) added onto this height
The stock bins have unit heights of 2, 3, and 6: The stock bins have unit heights of 2, 3, and 6:
Z unit 2 -> 7*2 + 3.8 -> 17.8mm * Z unit 2 -> 7*2 + 4.4 -> 18.4mm
Z unit 3 -> 7*3 + 3.8 -> 24.8mm * Z unit 3 -> 7*3 + 4.4 -> 25.4mm
Z unit 6 -> 7*6 + 3.8 -> 45.8mm * 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 https://github.com/kennetek/gridfinity-rebuilt-openscad

View file

@ -20,7 +20,7 @@ use <gridfinity-rebuilt-holes.scad>
* @returns The final value in mm. * @returns The final value in mm.
*/ */
function fromGridfinityUnits(gridfinityUnit, includeLipHeight = false) = 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. * @Summary Height in mm including fixed heights.
@ -30,7 +30,7 @@ function fromGridfinityUnits(gridfinityUnit, includeLipHeight = false) =
* @returns The final value in mm. * @returns The final value in mm.
*/ */
function includingFixedHeights(mmHeight, includeLipHeight = false) = 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. * @brief Three Functions in One. For height calculations.
@ -42,14 +42,13 @@ function includingFixedHeights(mmHeight, includeLipHeight = false) =
function hf (z, gridz_define, style_lip) = function hf (z, gridz_define, style_lip) =
gridz_define==0 ? fromGridfinityUnits(z, style_lip==2) : gridz_define==0 ? fromGridfinityUnits(z, style_lip==2) :
gridz_define==1 ? includingFixedHeights(z, style_lip==2) : gridz_define==1 ? includingFixedHeights(z, style_lip==2) :
z + ( // Just use z (possibly adding/subtracting lip) gridz_define==2 ? z + (style_lip==2 ? STACKING_LIP_SIZE.y : 0) :
style_lip==1 ? -h_lip : assert(false, "gridz_define must be 0, 1, or 2.")
style_lip==2 ? h_lip : 0
)
; ;
/** /**
* @brief Calculates the proper height for bins. Three Functions in One. * @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 z Height value
* @param d gridz_define as explained in gridfinity-rebuilt-bins.scad * @param d gridz_define as explained in gridfinity-rebuilt-bins.scad
* @param l style_lip 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. * @details Also includes a support base.
*/ */
module stacking_lip() { module stacking_lip() {
// Technique: Descriptive constant names are useful, but can be unweildy. polygon(STACKING_LIP);
// 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.
]);
} }
/** /**
* @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/ * @details Based on https://gridfinity.xyz/specification/
* Also includes a support base. * Also includes a support base.
*/ */
module stacking_lip_chamfered() { module stacking_lip_filleted() {
radius_center_y = h_lip - r_f1; // 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() { union() {
// Create rounded top // Rounded top
intersection() { translate(concat(fillet_center_point, [0]))
translate([0, radius_center_y, 0]) circle(r = STACKING_LIP_FILLET_RADIUS);
square([stacking_lip_depth, stacking_lip_height]);
offset(r = r_f1) // Stacking lip with cutout for circle to fit in
offset(delta = -r_f1)
stacking_lip();
}
// Remove pointed top
difference(){ difference(){
stacking_lip(); polygon(STACKING_LIP);
translate([0, radius_center_y, 0]) translate(concat(to_fillet, [0]))
square([stacking_lip_depth*2, stacking_lip_height*2]); circle(r = intersection_distance);
} }
} }
} }
@ -375,10 +382,10 @@ module stacking_lip_chamfered() {
*/ */
module profile_wall(height_mm) { module profile_wall(height_mm) {
assert(is_num(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]) translate([0, height_mm, 0])
stacking_lip_chamfered(); stacking_lip_filleted();
translate([stacking_lip_depth-d_wall/2, 0, 0]) translate([STACKING_LIP_SIZE.x-d_wall/2, 0, 0])
square([d_wall/2, height_mm]); 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_tab = tab_height;
v_len_lip = d_wall2-d_wall+1.2; 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_cut_lip = d_wall2-d_wall-d_clear;
v_ang_tab = a_tab; v_ang_tab = a_tab;
v_ang_lip = 45; v_ang_lip = 45;

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -56,8 +56,6 @@ BASEPLATE_SCREW_COUNTERBORE_HEIGHT = 3;
// **************************************** // ****************************************
// top edge fillet radius
r_f1 = 0.6;
// internal fillet radius // internal fillet radius
r_f2 = 2.8; r_f2 = 2.8;
@ -74,32 +72,65 @@ d_tabh = 15.85;
d_tabw = 42; d_tabw = 42;
// angle of tab // angle of tab
a_tab = 36; a_tab = 36;
// lip height
h_lip = 3.548;
d_wall2 = r_base-r_c1-d_clear*sqrt(2); d_wall2 = r_base-r_c1-d_clear*sqrt(2);
d_magic = -2*d_clear-2*d_wall+d_div; d_magic = -2*d_clear-2*d_wall+d_div;
// **************************************** // ****************************************
// Stacking Lip Constants // Stacking Lip Constants
// Based on https://gridfinity.xyz/specification/ // 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; * @Summary Fillet so the stacking lip does not come to a sharp point.
stacking_lip_support_height_mm = */
stacking_lip_support_wall_height_mm + d_wall2; 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 // Base constants