From 394c1435cde5d0909419e6956589cf20edf155e7 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 12 Jul 2026 11:43:05 -0700 Subject: [PATCH] Initial import --- .gitattributes | 4 ++ box_clamp.scad | 122 +++++++++++++++++++++++++++++++++++++++ cupholder/cupholder.scad | 85 +++++++++++++++++++++++++++ cupholder/cupholder.stl | 3 + 4 files changed, 214 insertions(+) create mode 100644 .gitattributes create mode 100644 box_clamp.scad create mode 100644 cupholder/cupholder.scad create mode 100644 cupholder/cupholder.stl diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8504958 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.stl filter=lfs diff=lfs merge=lfs -text +*.STL filter=lfs diff=lfs merge=lfs -text +*.3mf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/box_clamp.scad b/box_clamp.scad new file mode 100644 index 0000000..39a7df1 --- /dev/null +++ b/box_clamp.scad @@ -0,0 +1,122 @@ +/* [Clamp Dimensions] */ +// Top arm length (mm) +top_arm_length = 55; // [10:1:250] +// Lower arm length (mm) +lower_arm_length = 45; // [10:1:250] +// Clamp height, i.e. distance between arms (mm) +clamp_height = 85; // [5:1:250] +// Width of the clamp (mm) +clamp_width = 20; // [5:1:100] +// Thickness of the clamp, i.e. more increases stability +clamp_thickness = 3.0; // [1:0.5:6] + +/* [Clamp Features] */ +// Increases the grip by adding a pattern to the top arm +with_texture = false; +// Use S‐curve for the lower arm when enabled; otherwise, a straight lower arm is used. +with_s_curve = true; +// Helps to avoid stress fractures by adding a stress relief on the corner of the lower arm +add_stress_relief = true; + +// Increase the back wall height by 1 mm if texture is enabled. +effective_clamp_height = clamp_height + (with_texture ? 1 : 0); + +/* --- Function: S-Curve Center Line --- */ +function s_curve_y(x) = - (clamp_thickness / sqrt(3)) * sin(360 * x / lower_arm_length) + (clamp_thickness / 2); + +/* --- Module: S-Curve Lower Arm --- */ +module lower_arm_s_curve() { + translate([clamp_thickness/2, clamp_thickness/2]) { + num_segments = 100; // Increase for a smoother curve. + union() { + for (i = [0 : num_segments-1]) { + x0 = lower_arm_length * i / num_segments; + x1 = lower_arm_length * (i+1) / num_segments; + y0 = s_curve_y(x0); + y1 = s_curve_y(x1); + hull() { + translate([x0, y0]) + circle(r = clamp_thickness/2, $fn = 50); + translate([x1, y1]) + circle(r = clamp_thickness/2, $fn = 50); + } + } + } + } +} + +/* --- Module: Rounded Lower Arm (if S-curve is disabled) --- */ +module lower_arm_rounded() { + translate([0, 0]) { + union() { + square([lower_arm_length, clamp_thickness]); + intersection() { + translate([lower_arm_length, clamp_thickness/2]) + circle(r = clamp_thickness/2, $fn = 50); + translate([lower_arm_length, 0]) + square([clamp_thickness, clamp_thickness]); + } + } + } +} + +/* --- Module: Rounded Top Arm --- */ +module top_arm_rounded() { + union() { + square([top_arm_length, clamp_thickness]); + intersection() { + translate([top_arm_length, clamp_thickness/2]) + circle(r = clamp_thickness/2, $fn = 50); + translate([top_arm_length, 0]) + square([clamp_thickness, clamp_thickness]); + } + } +} + +difference() { + $fn = 100; + linear_extrude(height = clamp_width) { + union() { + // Lower Arm + if (with_s_curve) + lower_arm_s_curve(); + else + lower_arm_rounded(); + + // Back Wall + translate([0, clamp_thickness]) + square([clamp_thickness, effective_clamp_height]); + + // Top Arm + translate([0, clamp_thickness + effective_clamp_height]) + top_arm_rounded(); + + // Optional Texture on the Top Arm's Inner Side + if (with_texture) { + texture_length = top_arm_length - clamp_thickness; + for (i = [0 : texture_length - 1]) { + translate([clamp_thickness + i, clamp_thickness + effective_clamp_height]) { + hull() { + polygon(points = [[0, 0], [1, 0], [0.5, -1]]); + translate([0.01, 0]) + polygon(points = [[0, 0], [1, 0], [0.5, -1]]); + } + } + } + } + } + } + + // Subtractive Stress Relief + if (add_stress_relief) { + if (with_s_curve) { + translate([clamp_thickness*1.1, clamp_thickness*1.5]) + linear_extrude(height = clamp_width + 1) + circle(r = clamp_thickness * 0.3); + } else { + translate([clamp_thickness*1.1, clamp_thickness*1]) + linear_extrude(height = clamp_width + 1) + circle(r = clamp_thickness * 0.3); + } + } +} diff --git a/cupholder/cupholder.scad b/cupholder/cupholder.scad new file mode 100644 index 0000000..fa0740c --- /dev/null +++ b/cupholder/cupholder.scad @@ -0,0 +1,85 @@ +poses = [ + [-20, -20, -15], + [-20, 20, 15], + [20, -20, -45], + [20, 20, 45], +]; + +for (pos = poses) +translate([pos[0], pos[1], 0]) +rotate([0, 0, pos[2]]) { + difference() { + union() { + difference() { + cylinder(h=15, d1=25, d2=27, $fn=100); + + translate([0, 0, 2]) + cylinder(h=13.01, d1=21, d2=23.5, $fn=100); + + translate([0, 0, -0.01]) + difference() { + cylinder(h=1.01, d=26, $fn=100); + + translate([0, 0, -0.01]) + cylinder(h=1.01, d=23, $fn=100); + } + } + + translate([0, 0, 1.0]) + torus(r_major=11.5, r_minor=1.0, xs=1.06, $fn=100); + } + + for (a = [0, 120, 240]) + rotate([0, 0, a]) { + translate([10, 0, 5]) + cube([8, 4, 10.01], center=true); + + translate([11, 0, 10]) + rotate([0, 90, 0]) + cylinder(h=6, d=4, center=true, $fn=100); + } + } + + translate([0, 0, 15]) + torus(r_major=12.625, r_minor=0.875, $fn=100); +} + +difference() { + union() { + cylinder(h=10, d1=42, d2=44, $fn=100); + + translate([0, 0, 10.1]) + torus(r_major=18.5, r_minor=2, xs=1.75, $fn=100); + } + + translate([0, 0, 5]) + cylinder(h=5.01, d=24, $fn=100); + + translate([0, 0, 10]) + torus(r_major=12, r_minor=3, ys=1.66, $fn=100); + + for (pos = poses) + translate([pos[0], pos[1], 0]) + rotate([0, 0, pos[2]]) { + translate([0, 0, 2]) + cylinder(h=13.01, d1=21, d2=23.5, $fn=100); + } + + translate([0, 0, -0.01]) + difference() { + cylinder(h=1.01, d=43, $fn=100); + + translate([0, 0, -0.01]) + cylinder(h=1.01, d=40, $fn=100); + } +} + +translate([0, 0, 1.0]) +torus(r_major=20, r_minor=1.0, xs=1.1, $fn=100); + +module torus(r_major, r_minor, xs=1.0, ys=1.0) { + rotate_extrude() + translate([r_major, 0, 0]) + scale([xs, ys, 1.0]) + circle(r=r_minor); +} \ No newline at end of file diff --git a/cupholder/cupholder.stl b/cupholder/cupholder.stl new file mode 100644 index 0000000..37fbff2 --- /dev/null +++ b/cupholder/cupholder.stl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c468a0cafc6ade14c04f58098d6c3e12cceefd148b3b463fb6c724a6fb015b6 +size 4494484