nophead / NopSCADlib

Library of parts modelled in OpenSCAD and a framework for making projects
GNU General Public License v3.0
1.17k stars 155 forks source link

Function to rotate the nut so that the thread would align on the screw #263

Closed tpimh closed 8 months ago

tpimh commented 8 months ago

When changing the thickness of material, the nut position on the screw should be adjusted. The problem is that both the nut and the screw have threads that never align when moving it. The solution would be to rotate the nut (or the screw) so that the threads actually align. It would be possible by checking the screw pitch, but I don't think there's an easy way to do it.

The image below shows the correctly aligned threads (I just guessed rotation parameter): image

Generated with this code:

$show_threads = true;

include <NopSCADlib/lib.scad>

module screw_with_nut(screw, length, thickness) {
    nut_type = screw_nut(screw);
    nut_offset = -thickness - nut_thickness(nut_type);

    screw(screw, length);
    difference() {
        translate([0, 0, nut_offset]) rotate([0, 0, 50]) nut(nut_type);
        translate([-25, 0]) cube([50, 50, 50], true);
    }
}

screw_with_nut(M4_cap_screw, 12, 8);
tpimh commented 8 months ago

After thinking about it a bit, I think it's better to rotate the screw, not the nut.

$show_threads = true;

include <NopSCADlib/lib.scad>

module screw_with_nut(screw, length, thickness) {
    nut_type = screw_nut(screw);

    rotate([0, 0, $t * 360 - 45]) screw(screw, length);
    difference() {
        translate([0, 0, -thickness]) rotate([180, 0]) nut(nut_type);
        translate([-25, 0]) cube([50, 50, 50], true);
    }
}

screw_with_nut(M4_cap_screw, 12, $t * 0.7);

0.7 here is M4 screw thread pitch.

nophead commented 8 months ago

Whether you rotate the screw or the nut depends if either of them are captive and if the thing they are captive in rotates. e.g. a printed knob with a hex head screw in it, so isn't a simple rule.

This is my take on your code without an arbitrary -45 that was only correct for M4, I think. The issue is the thread starts at the bottom of the screw and the nut, which becomes its top when flipped so the distance has to be taken from the bottom of the screw to the top of the nut.

$show_threads = true;

include <NopSCADlib/lib.scad>

module screw_with_nut(screw, length, thickness) {
    nut = screw_nut(screw);
    pitch =  metric_coarse_pitch(screw_radius(screw) * 2);

    rotate(-360 * (length - thickness) / pitch) 
        screw(screw, length);

    clip(xmin = 0)
        translate_z(-thickness) vflip() nut(nut);
}

screw_with_nut(M4_cap_screw, 12, $t * 10);

We could have a library function that returns the amount a screw should turn relative to the nut given the distance between them.

tpimh commented 8 months ago

Thanks, this worked perfectly. Would definitely be more convenient if there was a library function that does just that.

nophead commented 8 months ago

I added a screw_angle() function.

$show_threads = true;

include <NopSCADlib/lib.scad>

module screw_with_nut(screw, length, thickness) {
    nut = screw_nut(screw);

    rotate(screw_angle(screw, length, thickness))
        screw(screw, length);

    clip(xmin = 0)
        translate_z(-thickness) vflip() nut(nut);
}

screw_with_nut(M4_cap_screw, 12, $t * 10);