feat: replace half-rings by full rings

This commit is contained in:
s3lph 2025-03-30 16:54:46 +02:00
parent bc6c4822eb
commit c010e3fb40
Signed by: s3lph
GPG key ID: 0AA29A52FB33CFB5
6 changed files with 111 additions and 106 deletions

View file

@ -15,10 +15,13 @@ module case(n=5, diameter=50, tolerance=0.2, $fn=60) {
}
// cutouts for e-clips
rotate([0,0,45]) {
for (i = [0:n]) {
translate([0,0,10*i+3]) {
cube([5, diameter, 3], center=true);
cube([diameter, 5, 3], center=true);
for (j = [0:2]) {
rotate([0,0,120*j]) {
for (i = [0:n]) {
translate([0,diameter/4,10*i+3]) {
cube([5, diameter/2, 3], center=true);
}
}
}
}
}
@ -36,6 +39,7 @@ module case(n=5, diameter=50, tolerance=0.2, $fn=60) {
// DEFAULTS FOR COMMAND LINE INVOCATION
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
N = 5;
DIAMETER = 50;
TOLERANCE = 0.2;

View file

@ -1,80 +0,0 @@
module e_ring(alphabet_length=26, dia=48, width=3, thick=2, spoke_depth=4.5, spoke_width=7, key_depth=3, key_length=4, tolerance = 0.2, indicator=false, clicker=false, $fn=60) {
difference() { // halfing
union() {
// outer ring
difference() {
cylinder(d=dia, h=width-4*tolerance, center=true);
cylinder(d=dia-2*thick, h=width+1, center=true);
}
// key spokes
difference() {
union() {
intersection() {
cube([spoke_width, dia, width], center=true);
cylinder(d=dia, h=width-4*tolerance, center=true);
}
intersection() {
cube([dia, spoke_width, width], center=true);
cylinder(d=dia, h=width-4*tolerance, center=true);
}
}
cylinder(d=dia-2*spoke_depth+2*tolerance, h=width+1, center=true);
}
// keys
difference() {
union() {
cube([key_length, dia-spoke_depth, width-4*tolerance], center=true);
cube([dia-spoke_depth, key_length, width-4*tolerance], center=true);
}
cube([dia-spoke_depth*2-key_depth*2, dia-spoke_depth*2-key_depth*2, width+1], center=true);
}
// indicator
if (indicator) {
rotate([0,0,45]) {
translate([-dia/2,0,0]) {
cube([1.5, width/2, width-4*tolerance], center=true);
}
}
}
// clicker
if (clicker) {
rotate([0,0,45+(floor(alphabet_length/4))*360/alphabet_length]) {
translate([-dia/2+3,0,0]) {
cube([3, 4, width-4*tolerance], center=true);
}
translate([-dia/2+3.5,0,width/2-0.5]) {
scale([0.5,1,1]) {
rotate([0,0,45]) {
cylinder($fn=4, h=1, d1=5.6, d2=3);
}
}
}
}
}
}
translate([-dia/2-2, -tolerance, -width]) {
cube([dia+4, dia, 2*width]);
}
}
}
// DEFAULTS FOR COMMAND LINE INVOCATION
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
DIAMETER = 50;
TOLERANCE = 0.2;
FN = 60;
INDICATOR = false;
CLICKER = false;
e_ring(
alphabet_length=len(ALPHABET),
dia=DIAMETER-2,
indicator=INDICATOR,
clicker=CLICKER,
tolerance=TOLERANCE, $fn=FN);

View file

@ -14,14 +14,14 @@ module key_dial(alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ", key="C", width=7, dia=50,
cylinder($fn=$fn, h=width+2, d=dia-thick*2, center=true);
}
// key
rotate([((0.5+key_index)/len(alphabet)) * 360,0,0]) {
rotate([45+((0.5+key_index)/len(alphabet)) * 360,0,0]) {
translate([0,0,dia/2-thick]) {
cube([width+2, key_width, key_height*2], center=true);
}
}
// anti-picking keys
for (i = [1:len(alphabet)]) {
rotate([((i+0.5)/len(alphabet)) * 360,0,0]) {
rotate([45+((i+0.5)/len(alphabet)) * 360,0,0]) {
translate([width/2,0,dia/2-thick]) {
cube([2*antipick, key_width, key_height*2], center=true);
}

View file

@ -1,41 +1,38 @@
use <key_dial.scad>;
use <e_ring.scad>;
use <ring.scad>;
use <case.scad>;
use <plug.scad>;
module lock(alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ", password="CHAOS", diameter=50, tolerance=0.2, $fn= 60) {
module lock(alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ", password="CHAOS", diameter=50, tolerance=0.2, $fn=60) {
n = len(password);
key_indices=search(password, alphabet);
for (i = [0:n-1]) {
rotate([-key_indices[i]/len(alphabet)*360,0,0]) {
translate([i*10,0,0]) key_dial(alphabet, key=password[i], dia=diameter);
translate([i*10,0,0]) {
key_dial(alphabet, key=password[i], dia=diameter);
}
}
}
for (i = [0:n]) {
translate([-5+10*i,0,0]) {
rotate([0,0,180]) {
rotate([-45,0,0]) {
rotate([0,90,0]) {
e_ring(dia=diameter-2, indicator=true, clicker=i>0);
}
}
rotate([135,0,0]) {
rotate([0,90,0]) {
e_ring(dia=diameter-2);
}
rotate([0,90,0]) {
ring(dia=diameter-2, clicker=i>0);
}
}
}
}
case(n, diameter=diameter);
plug(n, diameter=diameter);
rotate([45,0,0]) {
case(n, diameter=diameter);
plug(n, diameter=diameter);
}
}

View file

@ -1,20 +1,19 @@
#!/bin/bash
ALPHABET=ABCDEFGHIJKLMNOPQRSTUVWXYZ
N=5
LENGTH=5
DIAMETER=50
TOLERANCE=0.2
FN=60
ARGS=("-q" "-DALPHABET=\"$ALPHABET\"" "-DN=$N" "-DDIAMETER=$DIAMETER" "-DTOLERANCE=$TOLERANCE" "-DFN=$FN")
ARGS=("--backend=manifold" "-q" "-DALPHABET=\"$ALPHABET\"" "-DN=$LENGTH" "-DDIAMETER=$DIAMETER" "-DTOLERANCE=$TOLERANCE" "-DFN=$FN")
mkdir -p out
openscad "${ARGS[@]}" -o out/plug.stl plug.scad
openscad "${ARGS[@]}" -o out/case.stl case.scad
openscad "${ARGS[@]}" -o out/e_ring.stl e_ring.scad
openscad "${ARGS[@]}" -DINDICATOR=true -o out/e_ring_indicator.stl e_ring.scad
openscad "${ARGS[@]}" -DINDICATOR=true -DCLICK=true -o out/e_ring_indicator_click.stl e_ring.scad
openscad "${ARGS[@]}" -o out/ring.stl ring.scad
openscad "${ARGS[@]}" -DCLICKER=true -o out/ring_click.stl ring.scad
while read -rn1 char; do
openscad "${ARGS[@]}" "-DKEY=\"$char\"" -o "out/key_dial_${char}.stl" key_dial.scad

85
ring.scad Normal file
View file

@ -0,0 +1,85 @@
module ring(alphabet_length=26, dia=48, width=3, thick=2, spoke_depth=4.5, spoke_width=7, key_depth=3, key_length=4, tolerance = 0.2, indicator=false, clicker=false, $fn=60) {
difference() { // halfing
union() {
// outer ring
difference() {
cylinder(d=dia, h=width-4*tolerance, center=true);
cylinder(d=dia-2*thick, h=width+1, center=true);
}
// key spokes
difference() {
union() {
for (i = [0:2]) {
rotate([0,0,120*i]) {
intersection() {
translate([-dia/4,0,0]) {
cube([dia/2, spoke_width, width], center=true);
}
cylinder(d=dia, h=width-4*tolerance, center=true);
}
}
}
}
cylinder(d=dia-2*spoke_depth+2*tolerance, h=width+1, center=true);
}
// keys
for (i = [0:2]) {
rotate([0,0,120*i]) {
translate([-dia/2+spoke_depth+key_depth/2-1,0,0]) {
cube([key_depth+2, key_length, width-4*tolerance], center=true);
}
}
}
// indicator
translate([-dia/2,0,0]) {
cube([1.5, width, width-4*tolerance], center=true);
}
// clicker
if (clicker) {
rotate([0,0,floor(alphabet_length/3)*360/alphabet_length-45]) {
translate([-dia/2+3,0,0]) {
cube([3, 4, width-4*tolerance], center=true);
}
translate([-dia/2+3.5,0,width/2-0.5]) {
scale([0.5,1,1]) {
rotate([0,0,45]) {
cylinder($fn=4, h=1, d1=5.6, d2=3);
}
}
}
}
}
}
// Ring cut
translate([-dia/2+thick-0.5, -0.25, -width/2]) {
cube([spoke_depth+key_depth,0.5, width]);
}
translate([-dia/2, width/2, -width/2]) {
cube([thick,0.5, width]);
}
translate([-dia/2+thick-0.5, 0, -width/2]) {
cube([0.5, width/2, width]);
}
}
}
// DEFAULTS FOR COMMAND LINE INVOCATION
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
DIAMETER = 50;
TOLERANCE = 0.2;
FN = 60;
INDICATOR = false;
CLICKER = false;
ring(
alphabet_length=len(ALPHABET),
dia=DIAMETER-2,
indicator=INDICATOR,
clicker=CLICKER,
tolerance=TOLERANCE, $fn=FN);