M
mikeonenine@web.de
Thu, Oct 31, 2024 8:58 PM
I looked up Hirth joints online and found no indication at all that a
conical hirth joint exists. No pictures. Nobody selling them. Nobody
describing them. So that did make me wonder what the advantage is. Is it
in fact easier to connect conical joints? The joint is said to self-center
normally and it could be made so the parts are identical, which is a
simplification compared to a conical design where you need two different
parts.
Personally I think the simplest way to chamfer the teeth of this joint is
as in the code I posted: in 2d on the profile. No cone required.
On Thu, Oct 31, 2024 at 4:27 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:
I have encountered exactly one hirth spline IRL and it was conical. I made
some attachments for my golf cart (carries just my bag). The spot where
options are attached has a hirth spline to prevent rotation of the things
attached. It is conical, 60 teeth and 35 mm in D. I made a matching part
without understanding anything about the hirth spline or knowing the name.
It seems obvious that the cone shape makes it easier to center the parts
by hand as you put new attachments on.
On Oct 31, 2024, at 12:36, Caddiy via Discuss discuss@lists.openscad.org
wrote:
Jordan Brown wrote:
To cut a long story short, a polygon can give you the filler-cone plus a
bit more in one piece, which a primitive cone can’t.
Sort of. It depends on what your requirements are for the "plus a bit
more".
If your cone is anchored at the top, scaling it up will expand it at the
base without changing the shape of the top.
This is easy to demonstrate with BOSL2, because you can natively anchor at
the top:
include <BOSL2/std.scad>
s = 1;
scale(s) zcyl(r1=10, r2=0, h=10, anchor=TOP);
as you change s, observe that the top portion of the cone stays the same.
It's a tiny bit more complex in base OpenSCAD because base OpenSCAD
cylinders are anchored at their bottoms or centers.
s = 1;
h = 10;
scale(s) translate([0,0,-h]) cylinder(r1=10, r2=0, h=h);
(Though you can demonstrate it with an upside-down cone without needing a
translate().)
It even retains the same number of sides as it grows, because cylinder()
decides on the number of sides when it creates the object, and scale()
doesn't affect that choice.
In the particular case that this came from, the user was already using
BOSL2, and it happened that the top of the cone was easy to know, and that
since it was cutting away past the bottom of the object the shape of the
"extra" didn't matter. Net, that negative object could be a
straightforward cone anchored at its top.
A conical face spline joint will need two different cones as fillers to
get a flat face at the back of each piece. One piece, with luck or by
design, may already have a flat face, or it may even be conical, requiring
a negative/hollow cone, that I’m calling an anticone, to get a flat face.
But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
A polygon can. (The polygon is then rotate-extruded to form the desired
anticone.)
I wonder, though, how many Hirth joints are conical and why. A conical
joint seems like an unnecessary complication, as a plain joint already
self-centres very precisely.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
I tried the code in your post of Tue, Oct 29, 2024 12:35 AM at the time, but it didn’t work. I got a big fat red spot against line 22 [0,(-1+chamfer_bot)width,chamfer_bot],
and the opening round bracket was marked, but i couldn’t find anything wrong. I am still using Version 2021.01**.**
Adrian Mariano wrote:
> I looked up Hirth joints online and found no indication at all that a
> conical hirth joint exists. No pictures. Nobody selling them. Nobody
> describing them. So that did make me wonder what the advantage is. Is it
> in fact easier to connect conical joints? The joint is said to self-center
> normally and it could be made so the parts are identical, which is a
> simplification compared to a conical design where you need two different
> parts.
>
> Personally I think the simplest way to chamfer the teeth of this joint is
> as in the code I posted: in 2d on the profile. No cone required.
>
> On Thu, Oct 31, 2024 at 4:27 PM Bob Carlson via Discuss <
> discuss@lists.openscad.org> wrote:
>
> > I have encountered exactly one hirth spline IRL and it was conical. I made
> > some attachments for my golf cart (carries just my bag). The spot where
> > options are attached has a hirth spline to prevent rotation of the things
> > attached. It is conical, 60 teeth and 35 mm in D. I made a matching part
> > without understanding anything about the hirth spline or knowing the name.
> >
> > It seems obvious that the cone shape makes it easier to center the parts
> > by hand as you put new attachments on.
> >
> > * Bob
> >
> > On Oct 31, 2024, at 12:36, Caddiy via Discuss [discuss@lists.openscad.org](mailto:discuss@lists.openscad.org)
> > wrote:
> >
> > Jordan Brown wrote:
> >
> > To cut a long story short, a polygon can give you the filler-cone plus a
> > bit more in one piece, which a primitive cone can’t.
> >
> > Sort of. It depends on what your requirements are for the "plus a bit
> > more".
> >
> > If your cone is anchored at the top, scaling it up will expand it at the
> > base without changing the shape of the top.
> >
> > This is easy to demonstrate with BOSL2, because you can natively anchor at
> > the top:
> >
> > include <BOSL2/std.scad>
> >
> > s = 1;
> > scale(s) zcyl(r1=10, r2=0, h=10, anchor=TOP);
> >
> > as you change s, observe that the top portion of the cone stays the same.
> >
> > It's a tiny bit more complex in base OpenSCAD because base OpenSCAD
> > cylinders are anchored at their bottoms or centers.
> >
> > s = 1;
> > h = 10;
> > scale(s) translate(\[0,0,-h\]) cylinder(r1=10, r2=0, h=h);
> >
> > (Though you can demonstrate it with an upside-down cone without needing a
> > translate().)
> >
> > It even retains the same number of sides as it grows, because cylinder()
> > decides on the number of sides when it creates the object, and scale()
> > doesn't affect that choice.
> >
> > In the particular case that this came from, the user was already using
> > BOSL2, and it happened that the top of the cone was easy to know, and that
> > since it was cutting away past the bottom of the object the shape of the
> > "extra" didn't matter. Net, that negative object could be a
> > straightforward cone anchored at its top.
> >
> > A conical face spline joint will need two different cones as fillers to
> > get a flat face at the back of each piece. One piece, with luck or by
> > design, may already have a flat face, or it may even be conical, requiring
> > a negative/hollow cone, that I’m calling an anticone, to get a flat face.
> > But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
> >
> > A polygon can. (The polygon is then rotate-extruded to form the desired
> > anticone.)
> >
> > I wonder, though, how many Hirth joints are conical and why. A conical
> > joint seems like an unnecessary complication, as a plain joint already
> > self-centres very precisely.
> >
> > ---
> >
> > OpenSCAD mailing list
> > To unsubscribe send an email to discuss-leave@lists.openscad.org
> >
> > ---
> >
> > OpenSCAD mailing list
> > To unsubscribe send an email to discuss-leave@lists.openscad.org
I tried the code in your post of Tue, Oct 29, 2024 12:35 AM at the time, but it didn’t work. I got a big fat red spot against line 22 `[0,(-1+chamfer_bot)width,chamfer_bot],` and the opening round bracket was marked, but i couldn’t find anything wrong. I am still using Version 2021.01**.**
BC
Bob Carlson
Thu, Oct 31, 2024 9:06 PM
Unfortunately, you cannot raise the cone by _conic + _chamferHeight. The chamfer must (should?) radiate from the “origin” just like the ridge and grooves. I believe your code as written takes a constant chamfer off the teeth, but at the inner radius, that’s too much.
This code appears to be correct. I ran a lot of quick tests using this cone and my rotated cone. There’s a lot of noise in the results, but the rotate_extrude seems slightly faster. They are close enough, however, that I think the difference is not significant. F6 is around .35-.4 s and F5 is about .25 s. Oddly the time increased as _conic became larger. The number of facets and vertices did not change markedly so I don’t know how to explain that.
module _chamferF() {
up(_conic)
scale(1.5)
zcyl(h = _conic + _toothHeight/2 - _chamferHeight,
r1 = _or,
r2 = 0,
anchor = TOP);
}
The cone is easier to read and understand so I will keep it, but leave the other code as a comment.
On Oct 31, 2024, at 13:19, Jordan Brown via Discuss discuss@lists.openscad.org wrote:
On 10/31/2024 12:36 PM, Caddiy via Discuss wrote:
A conical face spline joint will need two different cones as fillers to get a flat face at the back of each piece. One piece, with luck or by design, may already have a flat face, or it may even be conical, requiring a negative/hollow cone, that I’m calling an anticone, to get a flat face. But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
I don't know beans about a conical face spline joint, and am having a hard time following your description.
I just know that the OP's model had teeth with bottoms that touched a cone, that needed to have the bottom little bit differenced off. The OP did this using a rotate-extruded triangle, when a plain old cone would work fine and be simpler.
OP's solution:
module _chamferF() {
A = -_toothHeight/2 - .1;
B = -_toothHeight/2 + _chamferHeight;
pts = [[0, _conic],
[_or+tiny, A],
[_or+tiny, B]];
#rotate_extrude(angle = 360)
polygon(pts);
}
<0xCTkrdavMv8rZkH.png>
Note: that's a "hollow" cone.
Simpler solution:
module _chamferF() {
#up(_conic + _chamferHeight)
scale(1.5)
zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
}
<dhtMIIdEBLBwh0VG.png>
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Unfortunately, you cannot raise the cone by _conic + _chamferHeight. The chamfer must (should?) radiate from the “origin” just like the ridge and grooves. I believe your code as written takes a constant chamfer off the teeth, but at the inner radius, that’s too much.
This code appears to be correct. I ran a lot of quick tests using this cone and my rotated cone. There’s a lot of noise in the results, but the rotate_extrude seems slightly faster. They are close enough, however, that I think the difference is not significant. F6 is around .35-.4 s and F5 is about .25 s. Oddly the time increased as _conic became larger. The number of facets and vertices did not change markedly so I don’t know how to explain that.
module _chamferF() {
up(_conic)
scale(1.5)
zcyl(h = _conic + _toothHeight/2 - _chamferHeight,
r1 = _or,
r2 = 0,
anchor = TOP);
}
The cone is easier to read and understand so I will keep it, but leave the other code as a comment.
- Bob
> On Oct 31, 2024, at 13:19, Jordan Brown via Discuss <discuss@lists.openscad.org> wrote:
>
> On 10/31/2024 12:36 PM, Caddiy via Discuss wrote:
>> A conical face spline joint will need two different cones as fillers to get a flat face at the back of each piece. One piece, with luck or by design, may already have a flat face, or it may even be conical, requiring a negative/hollow cone, that I’m calling an anticone, to get a flat face. But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
>>
>
> I don't know beans about a conical face spline joint, and am having a hard time following your description.
>
> I just know that the OP's model had teeth with bottoms that touched a cone, that needed to have the bottom little bit differenced off. The OP did this using a rotate-extruded triangle, when a plain old cone would work fine and be simpler.
>
> OP's solution:
>
> module _chamferF() {
> A = -_toothHeight/2 - .1;
> B = -_toothHeight/2 + _chamferHeight;
>
> pts = [[0, _conic],
> [_or+tiny, A],
> [_or+tiny, B]];
> #rotate_extrude(angle = 360)
> polygon(pts);
> }
> <0xCTkrdavMv8rZkH.png>
> Note: that's a "hollow" cone.
>
> Simpler solution:
> module _chamferF() {
> #up(_conic + _chamferHeight)
> scale(1.5)
> zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
> }
>
> <dhtMIIdEBLBwh0VG.png>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
M
mikeonenine@web.de
Thu, Oct 31, 2024 10:33 PM
I don't know beans about a conical face spline joint, and am having a
hard time following your description.
A conical face spline joint or conical Hirth joint is what Bob wants. A US patent https://patents.google.com/patent/US20080175526A1/en belonging to the German Schaeffler Group is very interesting in that it shows such a joint in great detail and in that “Hirth” does not appear anywhere in the text. The ridges of the splines appear to be rounded with the same radius along the whole length, as do the grooves. GKN https://web.eoltas.lv/en/trade/trade-news/gkn-face-spline-the-downsizing-does-stop-at-the-driveshaft/ also produces the joints in Germany and calls them face splines. Both companies supply the automotive industry, where “face spline” is evidently the official term - even in Germany. I first encountered it in a description of a US aero-engine (Pratt&Whitney or Curtis-Wright, i can’t remember).
I just know that the OP's model had teeth with bottoms that touched a
cone, that needed to have the bottom little bit differenced off. The OP
did this using a rotate-extruded triangle, when a plain old cone would
work fine and be simpler.
OP's solution:
module _chamferF() {
A = -_toothHeight/2 - .1;
B = -_toothHeight/2 + _chamferHeight;
pts = [[0, _conic],
[_or+tiny, A],
[_or+tiny, B]];
#rotate_extrude(angle = 360)
polygon(pts);
}
Note: that's a "hollow" cone.
Simpler solution:
module _chamferF() {
#up(_conic + _chamferHeight)
scale(1.5)
zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
}
I can’t get OP’s solution to work.
OP’s solution . . . simpler solution . . . simplest solution: Translate([]) cylinder(r1, r2, h); ?
Jordan Brown wrote:
> I don't know beans about a conical face spline joint, and am having a
> hard time following your description.
A conical face spline joint or conical Hirth joint is what Bob wants. A US patent *https://patents.google.com/patent/US20080175526A1/en* belonging to the German Schaeffler Group is very interesting in that it shows such a joint in great detail and in that “Hirth” does not appear anywhere in the text. The ridges of the splines appear to be rounded with the same radius along the whole length, as do the grooves. GKN *https://web.eoltas.lv/en/trade/trade-news/gkn-face-spline-the-downsizing-does-stop-at-the-driveshaft/* also produces the joints in Germany and calls them face splines. Both companies supply the automotive industry, where “face spline” is evidently the official term - even in Germany. I first encountered it in a description of a US aero-engine (Pratt&Whitney or Curtis-Wright, i can’t remember).
> I just know that the OP's model had teeth with bottoms that touched a
> cone, that needed to have the bottom little bit differenced off. The OP
> did this using a rotate-extruded triangle, when a plain old cone would
> work fine and be simpler.
>
> OP's solution:
>
> ```
> module _chamferF() {
> A = -_toothHeight/2 - .1;
> B = -_toothHeight/2 + _chamferHeight;
>
> pts = [[0, _conic],
> [_or+tiny, A],
> [_or+tiny, B]];
> #rotate_extrude(angle = 360)
> polygon(pts);
> }
> ```
>
> Note: that's a "hollow" cone.
>
> Simpler solution:
>
> module _chamferF() {
> \#up(_conic + _chamferHeight)
> scale(1.5)
> zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
> }
I can’t get OP’s solution to work.
OP’s solution . . . simpler solution . . . simplest solution: Translate(\[\]) cylinder(r1, r2, h); ?
AM
Adrian Mariano
Thu, Oct 31, 2024 10:49 PM
In my code the chamfer is scaled to the height of the tooth, so it gets
smaller as you go towards the center. It's a proportion of the tooth
height. (I wanted to confirm that my code matched yours...but your code
was so slow to preview that I was not able to do that.) I'll post a
revised version of my code at some point. Right now I have an issue that
the parts don't mate properly---or at least I don't think they do. It
looks ok when you have lots of teeth like 36 but with 5 teeth it becomes
apparent that something's not quite right, because the gap isn't even. The
gap should be even, right? There is a great deal of complication created
by the cone angle combined with the circular rather than polygonal
edge---give up either one of those and it gets a lot simpler. And actually
some users might prefer a polygonal edge, so I wrote it to do both.
Another thing I like about my approach is that it allows rounding the
valleys (and tops), which is really the ideal thing to do. (I haven't
implemented this, but it's possible.) You can't create rounded teeth or
valleys by subtracting a cone. And don't forget for BOSL2 inclusion we
have to assume that most users are running the "stable" version, 2021.01,
and cannot use manifold.
For the previously posted code, I think there is a trailing comma after the
definition of pts that is allowed in recent versions but not in 2021.01.
If you delete that it should work.
On Thu, Oct 31, 2024 at 5:07 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:
Unfortunately, you cannot raise the cone by _conic + _chamferHeight. The
chamfer must (should?) radiate from the “origin” just like the ridge and
grooves. I believe your code as written takes a constant chamfer off the
teeth, but at the inner radius, that’s too much.
This code appears to be correct. I ran a lot of quick tests using this
cone and my rotated cone. There’s a lot of noise in the results, but the
rotate_extrude seems slightly faster. They are close enough, however, that
I think the difference is not significant. F6 is around .35-.4 s and F5 is
about .25 s. Oddly the time increased as _conic became larger. The number
of facets and vertices did not change markedly so I don’t know how to
explain that.
module _chamferF() {
up(_conic)
scale(1.5)
zcyl(h = _conic + _toothHeight/2 - _chamferHeight,
r1 = _or,
r2 = 0,
anchor = TOP);
}
The cone is easier to read and understand so I will keep it, but leave the
other code as a comment.
On Oct 31, 2024, at 13:19, Jordan Brown via Discuss <
discuss@lists.openscad.org> wrote:
On 10/31/2024 12:36 PM, Caddiy via Discuss wrote:
A conical face spline joint will need two different cones as fillers to
get a flat face at the back of each piece. One piece, with luck or by
design, may already have a flat face, or it may even be conical, requiring
a negative/hollow cone, that I’m calling an anticone, to get a flat face.
But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
I don't know beans about a conical face spline joint, and am having a hard
time following your description.
I just know that the OP's model had teeth with bottoms that touched a
cone, that needed to have the bottom little bit differenced off. The OP
did this using a rotate-extruded triangle, when a plain old cone would work
fine and be simpler.
OP's solution:
module _chamferF() {
A = -_toothHeight/2 - .1;
B = -_toothHeight/2 + _chamferHeight;
pts = [[0, _conic],
[_or+tiny, A],
[_or+tiny, B]];
#rotate_extrude(angle = 360)
polygon(pts);
}
<0xCTkrdavMv8rZkH.png>
Note: that's a "hollow" cone.
Simpler solution:
module _chamferF() {
#up(_conic + _chamferHeight)
scale(1.5)
zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
}
<dhtMIIdEBLBwh0VG.png>
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
In my code the chamfer is scaled to the height of the tooth, so it gets
smaller as you go towards the center. It's a proportion of the tooth
height. (I wanted to confirm that my code matched yours...but your code
was so slow to preview that I was not able to do that.) I'll post a
revised version of my code at some point. Right now I have an issue that
the parts don't mate properly---or at least I don't think they do. It
looks ok when you have lots of teeth like 36 but with 5 teeth it becomes
apparent that something's not quite right, because the gap isn't even. The
gap should be even, right? There is a great deal of complication created
by the cone angle combined with the circular rather than polygonal
edge---give up either one of those and it gets a lot simpler. And actually
some users might prefer a polygonal edge, so I wrote it to do both.
Another thing I like about my approach is that it allows rounding the
valleys (and tops), which is really the ideal thing to do. (I haven't
implemented this, but it's possible.) You can't create rounded teeth or
valleys by subtracting a cone. And don't forget for BOSL2 inclusion we
have to assume that most users are running the "stable" version, 2021.01,
and cannot use manifold.
For the previously posted code, I think there is a trailing comma after the
definition of pts that is allowed in recent versions but not in 2021.01.
If you delete that it should work.
On Thu, Oct 31, 2024 at 5:07 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:
> Unfortunately, you cannot raise the cone by _conic + _chamferHeight. The
> chamfer must (should?) radiate from the “origin” just like the ridge and
> grooves. I believe your code as written takes a constant chamfer off the
> teeth, but at the inner radius, that’s too much.
>
> This code appears to be correct. I ran a lot of quick tests using this
> cone and my rotated cone. There’s a lot of noise in the results, but the
> rotate_extrude seems slightly faster. They are close enough, however, that
> I think the difference is not significant. F6 is around .35-.4 s and F5 is
> about .25 s. Oddly the time increased as _conic became larger. The number
> of facets and vertices did not change markedly so I don’t know how to
> explain that.
>
> module _chamferF() {
> up(_conic)
> scale(1.5)
> zcyl(h = _conic + _toothHeight/2 - _chamferHeight,
> r1 = _or,
> r2 = 0,
> anchor = TOP);
> }
>
> The cone is easier to read and understand so I will keep it, but leave the
> other code as a comment.
>
> - Bob
>
>
> On Oct 31, 2024, at 13:19, Jordan Brown via Discuss <
> discuss@lists.openscad.org> wrote:
>
> On 10/31/2024 12:36 PM, Caddiy via Discuss wrote:
>
> A conical face spline joint will need two different cones as fillers to
> get a flat face at the back of each piece. One piece, with luck or by
> design, may already have a flat face, or it may even be conical, requiring
> a negative/hollow cone, that I’m calling an anticone, to get a flat face.
> But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
>
>
> I don't know beans about a conical face spline joint, and am having a hard
> time following your description.
>
> I just know that the OP's model had teeth with bottoms that touched a
> cone, that needed to have the bottom little bit differenced off. The OP
> did this using a rotate-extruded triangle, when a plain old cone would work
> fine and be simpler.
>
> OP's solution:
>
> module _chamferF() {
> A = -_toothHeight/2 - .1;
> B = -_toothHeight/2 + _chamferHeight;
>
> pts = [[0, _conic],
> [_or+tiny, A],
> [_or+tiny, B]];
> #rotate_extrude(angle = 360)
> polygon(pts);
> }
>
> <0xCTkrdavMv8rZkH.png>
> Note: that's a "hollow" cone.
>
> Simpler solution:
>
> module _chamferF() {
> #up(_conic + _chamferHeight)
> scale(1.5)
> zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
> }
> <dhtMIIdEBLBwh0VG.png>
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
BC
Bob Carlson
Thu, Oct 31, 2024 11:13 PM
I had the same experience. I found no mention of conical joints. But since my one and only real world example is conical, I know they exist and are used. Someone said early on that hirths are not standardized so maybe it’s not surprising that online sources are incomplete. An interesting problem is that if you have a conical hirth part and need to measure it to determine what the “conic” argument should be I have not figured out any way to do that precisely! The ridge angle is easily measured but a “hirth calculator” would be needed to go from ridge angle to conic.
As I worked with the code over the last month or so, I grew to mistrust the idea of a flat profile being projected away from the origin. I used that idea originally. But he more I thought about the situation at the outer radius, the more I suspected that my powers of visualization were not adequate. The tooth at the outer radius is the intersection of the tooth with a cylinder. In a flat joint that doesn’t seem too terrible, but then move the origin make a conical joint and it really gets hard to keep in my mind. Maybe that all doesn’t matter, but I wasn’t confident it didn't.
Much of the material I found about hirth joints was about how to machine them. It was clear that the groove angle was the critical number, because the groove is the path the cutter follows. I realized that I could trust the groove and ridge angles. Using spherical coordinates it was easy to create a tooth and easy to see why it worked correctly. Someone used to working with trig could probably come up with the angles for chamfer shoulders, but not me.
I may spend some more time understanding your method, but right now I’m concentrating on some other things.
On Oct 31, 2024, at 13:39, Adrian Mariano avm4@cornell.edu wrote:
I looked up Hirth joints online and found no indication at all that a conical hirth joint exists. No pictures. Nobody selling them. Nobody describing them. So that did make me wonder what the advantage is. Is it in fact easier to connect conical joints? The joint is said to self-center normally and it could be made so the parts are identical, which is a simplification compared to a conical design where you need two different parts.
Personally I think the simplest way to chamfer the teeth of this joint is as in the code I posted: in 2d on the profile. No cone required.
On Thu, Oct 31, 2024 at 4:27 PM Bob Carlson via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:
I have encountered exactly one hirth spline IRL and it was conical. I made some attachments for my golf cart (carries just my bag). The spot where options are attached has a hirth spline to prevent rotation of the things attached. It is conical, 60 teeth and 35 mm in D. I made a matching part without understanding anything about the hirth spline or knowing the name.
It seems obvious that the cone shape makes it easier to center the parts by hand as you put new attachments on.
On Oct 31, 2024, at 12:36, Caddiy via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:
Jordan Brown wrote:
To cut a long story short, a polygon can give you the filler-cone plus a bit more in one piece, which a primitive cone can’t.
Sort of. It depends on what your requirements are for the "plus a bit more".
If your cone is anchored at the top, scaling it up will expand it at the base without changing the shape of the top.
This is easy to demonstrate with BOSL2, because you can natively anchor at the top:
include <BOSL2/std.scad>
s = 1;
scale(s) zcyl(r1=10, r2=0, h=10, anchor=TOP);
as you change s, observe that the top portion of the cone stays the same.
It's a tiny bit more complex in base OpenSCAD because base OpenSCAD cylinders are anchored at their bottoms or centers.
s = 1;
h = 10;
scale(s) translate([0,0,-h]) cylinder(r1=10, r2=0, h=h);
(Though you can demonstrate it with an upside-down cone without needing a translate().)
It even retains the same number of sides as it grows, because cylinder() decides on the number of sides when it creates the object, and scale() doesn't affect that choice.
In the particular case that this came from, the user was already using BOSL2, and it happened that the top of the cone was easy to know, and that since it was cutting away past the bottom of the object the shape of the "extra" didn't matter. Net, that negative object could be a straightforward cone anchored at its top.
A conical face spline joint will need two different cones as fillers to get a flat face at the back of each piece. One piece, with luck or by design, may already have a flat face, or it may even be conical, requiring a negative/hollow cone, that I’m calling an anticone, to get a flat face. But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
A polygon can. (The polygon is then rotate-extruded to form the desired anticone.)
I wonder, though, how many Hirth joints are conical and why. A conical joint seems like an unnecessary complication, as a plain joint already self-centres very precisely.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
I had the same experience. I found no mention of conical joints. But since my one and only real world example is conical, I know they exist and are used. Someone said early on that hirths are not standardized so maybe it’s not surprising that online sources are incomplete. An interesting problem is that if you have a conical hirth part and need to measure it to determine what the “conic” argument should be I have not figured out any way to do that precisely! The ridge angle is easily measured but a “hirth calculator” would be needed to go from ridge angle to conic.
As I worked with the code over the last month or so, I grew to mistrust the idea of a flat profile being projected away from the origin. I used that idea originally. But he more I thought about the situation at the outer radius, the more I suspected that my powers of visualization were not adequate. The tooth at the outer radius is the intersection of the tooth with a cylinder. In a flat joint that doesn’t seem too terrible, but then move the origin make a conical joint and it really gets hard to keep in my mind. Maybe that all doesn’t matter, but I wasn’t confident it didn't.
Much of the material I found about hirth joints was about how to machine them. It was clear that the groove angle was the critical number, because the groove is the path the cutter follows. I realized that I could trust the groove and ridge angles. Using spherical coordinates it was easy to create a tooth and easy to see why it worked correctly. Someone used to working with trig could probably come up with the angles for chamfer shoulders, but not me.
I may spend some more time understanding your method, but right now I’m concentrating on some other things.
- Bob
> On Oct 31, 2024, at 13:39, Adrian Mariano <avm4@cornell.edu> wrote:
>
> I looked up Hirth joints online and found no indication at all that a conical hirth joint exists. No pictures. Nobody selling them. Nobody describing them. So that did make me wonder what the advantage is. Is it in fact easier to connect conical joints? The joint is said to self-center normally and it could be made so the parts are identical, which is a simplification compared to a conical design where you need two different parts.
>
> Personally I think the simplest way to chamfer the teeth of this joint is as in the code I posted: in 2d on the profile. No cone required.
>
>
> On Thu, Oct 31, 2024 at 4:27 PM Bob Carlson via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote:
>> I have encountered exactly one hirth spline IRL and it was conical. I made some attachments for my golf cart (carries just my bag). The spot where options are attached has a hirth spline to prevent rotation of the things attached. It is conical, 60 teeth and 35 mm in D. I made a matching part without understanding anything about the hirth spline or knowing the name.
>>
>> It seems obvious that the cone shape makes it easier to center the parts by hand as you put new attachments on.
>>
>> - Bob
>>
>>> On Oct 31, 2024, at 12:36, Caddiy via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote:
>>>
>>> Jordan Brown wrote:
>>>
>>> To cut a long story short, a polygon can give you the filler-cone plus a bit more in one piece, which a primitive cone can’t.
>>>
>>> Sort of. It depends on what your requirements are for the "plus a bit more".
>>>
>>> If your cone is anchored at the top, scaling it up will expand it at the base without changing the shape of the top.
>>>
>>> This is easy to demonstrate with BOSL2, because you can natively anchor at the top:
>>>
>>> include <BOSL2/std.scad>
>>>
>>> s = 1;
>>> scale(s) zcyl(r1=10, r2=0, h=10, anchor=TOP);
>>> as you change s, observe that the top portion of the cone stays the same.
>>>
>>> It's a tiny bit more complex in base OpenSCAD because base OpenSCAD cylinders are anchored at their bottoms or centers.
>>>
>>> s = 1;
>>> h = 10;
>>> scale(s) translate([0,0,-h]) cylinder(r1=10, r2=0, h=h);
>>> (Though you can demonstrate it with an upside-down cone without needing a translate().)
>>>
>>> It even retains the same number of sides as it grows, because cylinder() decides on the number of sides when it creates the object, and scale() doesn't affect that choice.
>>>
>>> In the particular case that this came from, the user was already using BOSL2, and it happened that the top of the cone was easy to know, and that since it was cutting away past the bottom of the object the shape of the "extra" didn't matter. Net, that negative object could be a straightforward cone anchored at its top.
>>>
>>> A conical face spline joint will need two different cones as fillers to get a flat face at the back of each piece. One piece, with luck or by design, may already have a flat face, or it may even be conical, requiring a negative/hollow cone, that I’m calling an anticone, to get a flat face. But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
>>>
>>> A polygon can. (The polygon is then rotate-extruded to form the desired anticone.)
>>>
>>> I wonder, though, how many Hirth joints are conical and why. A conical joint seems like an unnecessary complication, as a plain joint already self-centres very precisely.
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org>
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org>
M
mikeonenine@web.de
Thu, Oct 31, 2024 11:16 PM
It was Pratt & Whitney: http://www.enginehistory.org/NoShortDays/CrankHX.pdf
see pages 5-4 &5-5.
Here too, the photo seems to show rounded splines with constant radius.
There are probably different production methods that give different profiles.
It was Pratt & Whitney: `http://www.enginehistory.org/NoShortDays/CrankHX.pdf `see pages 5-4 &5-5.
Here too, the photo seems to show rounded splines with constant radius.
There are probably different production methods that give different profiles.
BC
Bob Carlson
Thu, Oct 31, 2024 11:28 PM
I feel your pain. I’ve been struggling to wrap my head around these for a while now. I decided to limit the number of teeth to 12 or more. That’s somewhat arbitrary but as you specify fewer teeth, things always get weird. If the radii are larger fewer teeth may work. I didn’t see much advantage in figuring out the limits.
I’m not sure what you mean by gap. My parts fit very snugly.
A rounded chamfer might be prettier but I don’t have a need for it and I suspect it will not print as well. I work exclusively with small things so far, so a rounded chamfer on a 60 tooth part with a radius of 20 mm doesn’t mean anything. I’ve spent time looking at the slices in the PrusaSlicer and they are not great when magnified. The tips of the teeth look kinda glopped on.
It’s purely selfish of me, but I am not willing to spend my time making stuff work on a 3 year old version of OpenSCAD. I see why you feel the need.
I feel pretty strongly about the chamfer being specified as a percentage. Like with gears the user cannot know the tooth height. A percentage is much more intuitive and you can have a default.
-Bob
On Oct 31, 2024, at 15:49, Adrian Mariano avm4@cornell.edu wrote:
In my code the chamfer is scaled to the height of the tooth, so it gets smaller as you go towards the center. It's a proportion of the tooth height. (I wanted to confirm that my code matched yours...but your code was so slow to preview that I was not able to do that.) I'll post a revised version of my code at some point. Right now I have an issue that the parts don't mate properly---or at least I don't think they do. It looks ok when you have lots of teeth like 36 but with 5 teeth it becomes apparent that something's not quite right, because the gap isn't even. The gap should be even, right? There is a great deal of complication created by the cone angle combined with the circular rather than polygonal edge---give up either one of those and it gets a lot simpler. And actually some users might prefer a polygonal edge, so I wrote it to do both. Another thing I like about my approach is that it allows rounding the valleys (and tops), which is really the ideal thing to do. (I haven't implemented this, but it's possible.) You can't create rounded teeth or valleys by subtracting a cone. And don't forget for BOSL2 inclusion we have to assume that most users are running the "stable" version, 2021.01, and cannot use manifold.
For the previously posted code, I think there is a trailing comma after the definition of pts that is allowed in recent versions but not in 2021.01. If you delete that it should work.
On Thu, Oct 31, 2024 at 5:07 PM Bob Carlson via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:
Unfortunately, you cannot raise the cone by _conic + _chamferHeight. The chamfer must (should?) radiate from the “origin” just like the ridge and grooves. I believe your code as written takes a constant chamfer off the teeth, but at the inner radius, that’s too much.
This code appears to be correct. I ran a lot of quick tests using this cone and my rotated cone. There’s a lot of noise in the results, but the rotate_extrude seems slightly faster. They are close enough, however, that I think the difference is not significant. F6 is around .35-.4 s and F5 is about .25 s. Oddly the time increased as _conic became larger. The number of facets and vertices did not change markedly so I don’t know how to explain that.
module _chamferF() {
up(_conic)
scale(1.5)
zcyl(h = _conic + _toothHeight/2 - _chamferHeight,
r1 = _or,
r2 = 0,
anchor = TOP);
}
The cone is easier to read and understand so I will keep it, but leave the other code as a comment.
A conical face spline joint will need two different cones as fillers to get a flat face at the back of each piece. One piece, with luck or by design, may already have a flat face, or it may even be conical, requiring a negative/hollow cone, that I’m calling an anticone, to get a flat face. But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
I don't know beans about a conical face spline joint, and am having a hard time following your description.
I just know that the OP's model had teeth with bottoms that touched a cone, that needed to have the bottom little bit differenced off. The OP did this using a rotate-extruded triangle, when a plain old cone would work fine and be simpler.
OP's solution:
module _chamferF() {
A = -_toothHeight/2 - .1;
B = -_toothHeight/2 + _chamferHeight;
pts = [[0, _conic],
[_or+tiny, A],
[_or+tiny, B]];
#rotate_extrude(angle = 360)
polygon(pts);
}
<0xCTkrdavMv8rZkH.png>
Note: that's a "hollow" cone.
Simpler solution:
module _chamferF() {
#up(_conic + _chamferHeight)
scale(1.5)
zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
}
<dhtMIIdEBLBwh0VG.png>
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
I feel your pain. I’ve been struggling to wrap my head around these for a while now. I decided to limit the number of teeth to 12 or more. That’s somewhat arbitrary but as you specify fewer teeth, things always get weird. If the radii are larger fewer teeth may work. I didn’t see much advantage in figuring out the limits.
I’m not sure what you mean by gap. My parts fit very snugly.
A rounded chamfer might be prettier but I don’t have a need for it and I suspect it will not print as well. I work exclusively with small things so far, so a rounded chamfer on a 60 tooth part with a radius of 20 mm doesn’t mean anything. I’ve spent time looking at the slices in the PrusaSlicer and they are not great when magnified. The tips of the teeth look kinda glopped on.
It’s purely selfish of me, but I am not willing to spend my time making stuff work on a 3 year old version of OpenSCAD. I see why you feel the need.
I feel pretty strongly about the chamfer being specified as a percentage. Like with gears the user cannot know the tooth height. A percentage is much more intuitive and you can have a default.
-Bob
> On Oct 31, 2024, at 15:49, Adrian Mariano <avm4@cornell.edu> wrote:
>
> In my code the chamfer is scaled to the height of the tooth, so it gets smaller as you go towards the center. It's a proportion of the tooth height. (I wanted to confirm that my code matched yours...but your code was so slow to preview that I was not able to do that.) I'll post a revised version of my code at some point. Right now I have an issue that the parts don't mate properly---or at least I don't think they do. It looks ok when you have lots of teeth like 36 but with 5 teeth it becomes apparent that something's not quite right, because the gap isn't even. The gap should be even, right? There is a great deal of complication created by the cone angle combined with the circular rather than polygonal edge---give up either one of those and it gets a lot simpler. And actually some users might prefer a polygonal edge, so I wrote it to do both. Another thing I like about my approach is that it allows rounding the valleys (and tops), which is really the ideal thing to do. (I haven't implemented this, but it's possible.) You can't create rounded teeth or valleys by subtracting a cone. And don't forget for BOSL2 inclusion we have to assume that most users are running the "stable" version, 2021.01, and cannot use manifold.
>
> For the previously posted code, I think there is a trailing comma after the definition of pts that is allowed in recent versions but not in 2021.01. If you delete that it should work.
>
>
> On Thu, Oct 31, 2024 at 5:07 PM Bob Carlson via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote:
>> Unfortunately, you cannot raise the cone by _conic + _chamferHeight. The chamfer must (should?) radiate from the “origin” just like the ridge and grooves. I believe your code as written takes a constant chamfer off the teeth, but at the inner radius, that’s too much.
>>
>> This code appears to be correct. I ran a lot of quick tests using this cone and my rotated cone. There’s a lot of noise in the results, but the rotate_extrude seems slightly faster. They are close enough, however, that I think the difference is not significant. F6 is around .35-.4 s and F5 is about .25 s. Oddly the time increased as _conic became larger. The number of facets and vertices did not change markedly so I don’t know how to explain that.
>>
>> module _chamferF() {
>> up(_conic)
>> scale(1.5)
>> zcyl(h = _conic + _toothHeight/2 - _chamferHeight,
>> r1 = _or,
>> r2 = 0,
>> anchor = TOP);
>> }
>>
>> The cone is easier to read and understand so I will keep it, but leave the other code as a comment.
>>
>> - Bob
>>
>>
>>> On Oct 31, 2024, at 13:19, Jordan Brown via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote:
>>>
>>> On 10/31/2024 12:36 PM, Caddiy via Discuss wrote:
>>>> A conical face spline joint will need two different cones as fillers to get a flat face at the back of each piece. One piece, with luck or by design, may already have a flat face, or it may even be conical, requiring a negative/hollow cone, that I’m calling an anticone, to get a flat face. But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
>>>>
>>>
>>> I don't know beans about a conical face spline joint, and am having a hard time following your description.
>>>
>>> I just know that the OP's model had teeth with bottoms that touched a cone, that needed to have the bottom little bit differenced off. The OP did this using a rotate-extruded triangle, when a plain old cone would work fine and be simpler.
>>>
>>> OP's solution:
>>>
>>> module _chamferF() {
>>> A = -_toothHeight/2 - .1;
>>> B = -_toothHeight/2 + _chamferHeight;
>>>
>>> pts = [[0, _conic],
>>> [_or+tiny, A],
>>> [_or+tiny, B]];
>>> #rotate_extrude(angle = 360)
>>> polygon(pts);
>>> }
>>> <0xCTkrdavMv8rZkH.png>
>>> Note: that's a "hollow" cone.
>>>
>>> Simpler solution:
>>> module _chamferF() {
>>> #up(_conic + _chamferHeight)
>>> scale(1.5)
>>> zcyl(h = _toothHeight/2 + _conic, r1 = _or, r2 = 0, anchor=TOP);
>>> }
>>>
>>> <dhtMIIdEBLBwh0VG.png>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org>
AM
Adrian Mariano
Thu, Oct 31, 2024 11:39 PM
There is a question that I've noted before about what is meant by "tooth
angle". The wikipedia page suggests that it is measured relative to the
cylinder axis. In gears tooth angle is measured relative to the ridge of
the tooth. These two ideas produce a different result, and the steeper the
cone angle gets the bigger the difference. Arguably it doesn't matter if
you're just trying to make parts that mate with each other as opposed to
mating with some manufactured standard part. (You can change your tooth
angle if you don't like what happened when you specified a steep cone.)
Your method of using spherical coordinates is just a way of projecting
(scaling) a triangle. The results should be the same. (I did want to
confirm that.) There is another question about what you consider the
"zero" conical angle. I initially did it so that the base of the teeth was
at zero angle, but later thought this wasn't right: it should be the angle
that produces a part that mates with itself, which should occur if the line
through the center of the teeth is at angle zero. At least, I think that's
right.
Note: it may not matter in practice, but a rounded valley is STRONGER than
a chamfer. Corners concentrate forces and are the places where parts
fail. If the part is small printing will limit this, but what if someone
prints an 8" diameter part with 6 teeth? There is nothing weird about this
joint that should limit the number of teeth to be more than 12. It should
work with 3 teeth. One might in fact want an 8 tooth version to provide
part alignment at 45 degree detents, so a 12 limit is...welll...limiting.
If you're machining a tooth you're surely going to have a constant
roundover at the bottom, not one that varies with tooth size. At the top I
suppose other things are possible, but it does seem like the natural way to
machine it would also be with a constant with chamfer, not one that varies
with tooth size. I didn't do it that way in my code for two reasons: (1)
I was trying to match Bob's code and (2) the varying width chamfer was much
simpler to implement. Of course, we aren't machining and we don't have to
limit ourselves to things that are easy to machine.
It can be a nuisance as a library author to have to write code that works
on the old version. That's definitely the case. Seeking efficiency in
general for library code is also a good goal, though. When someone makes a
model with 45 hirth joints what happens? I wonder if it's better to call
this "hirth" or "face_spline".
I see you just posted your code while I was typing so I'll take a look and
see if I can compare to mine.
On Thu, Oct 31, 2024 at 7:13 PM Bob Carlson bob@rjcarlson.com wrote:
I had the same experience. I found no mention of conical joints. But since
my one and only real world example is conical, I know they exist and are
used. Someone said early on that hirths are not standardized so maybe it’s
not surprising that online sources are incomplete. An interesting problem
is that if you have a conical hirth part and need to measure it to
determine what the “conic” argument should be I have not figured out any
way to do that precisely! The ridge angle is easily measured but a “hirth
calculator” would be needed to go from ridge angle to conic.
As I worked with the code over the last month or so, I grew to mistrust
the idea of a flat profile being projected away from the origin. I used
that idea originally. But he more I thought about the situation at the
outer radius, the more I suspected that my powers of visualization were not
adequate. The tooth at the outer radius is the intersection of the tooth
with a cylinder. In a flat joint that doesn’t seem too terrible, but then
move the origin make a conical joint and it really gets hard to keep in my
mind. Maybe that all doesn’t matter, but I wasn’t confident it didn't.
Much of the material I found about hirth joints was about how to machine
them. It was clear that the groove angle was the critical number, because
the groove is the path the cutter follows. I realized that I could trust
the groove and ridge angles. Using spherical coordinates it was easy to
create a tooth and easy to see why it worked correctly. Someone used to
working with trig could probably come up with the angles for chamfer
shoulders, but not me.
I may spend some more time understanding your method, but right now I’m
concentrating on some other things.
On Oct 31, 2024, at 13:39, Adrian Mariano avm4@cornell.edu wrote:
I looked up Hirth joints online and found no indication at all that a
conical hirth joint exists. No pictures. Nobody selling them. Nobody
describing them. So that did make me wonder what the advantage is. Is it
in fact easier to connect conical joints? The joint is said to self-center
normally and it could be made so the parts are identical, which is a
simplification compared to a conical design where you need two different
parts.
Personally I think the simplest way to chamfer the teeth of this joint is
as in the code I posted: in 2d on the profile. No cone required.
On Thu, Oct 31, 2024 at 4:27 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:
I have encountered exactly one hirth spline IRL and it was conical. I
made some attachments for my golf cart (carries just my bag). The spot
where options are attached has a hirth spline to prevent rotation of the
things attached. It is conical, 60 teeth and 35 mm in D. I made a matching
part without understanding anything about the hirth spline or knowing the
name.
It seems obvious that the cone shape makes it easier to center the parts
by hand as you put new attachments on.
On Oct 31, 2024, at 12:36, Caddiy via Discuss discuss@lists.openscad.org
wrote:
Jordan Brown wrote:
To cut a long story short, a polygon can give you the filler-cone plus a
bit more in one piece, which a primitive cone can’t.
Sort of. It depends on what your requirements are for the "plus a bit
more".
If your cone is anchored at the top, scaling it up will expand it at the
base without changing the shape of the top.
This is easy to demonstrate with BOSL2, because you can natively anchor
at the top:
include <BOSL2/std.scad>
s = 1;
scale(s) zcyl(r1=10, r2=0, h=10, anchor=TOP);
as you change s, observe that the top portion of the cone stays the same.
It's a tiny bit more complex in base OpenSCAD because base OpenSCAD
cylinders are anchored at their bottoms or centers.
s = 1;
h = 10;
scale(s) translate([0,0,-h]) cylinder(r1=10, r2=0, h=h);
(Though you can demonstrate it with an upside-down cone without needing a
translate().)
It even retains the same number of sides as it grows, because cylinder()
decides on the number of sides when it creates the object, and scale()
doesn't affect that choice.
In the particular case that this came from, the user was already using
BOSL2, and it happened that the top of the cone was easy to know, and that
since it was cutting away past the bottom of the object the shape of the
"extra" didn't matter. Net, that negative object could be a
straightforward cone anchored at its top.
A conical face spline joint will need two different cones as fillers to
get a flat face at the back of each piece. One piece, with luck or by
design, may already have a flat face, or it may even be conical, requiring
a negative/hollow cone, that I’m calling an anticone, to get a flat face.
But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
A polygon can. (The polygon is then rotate-extruded to form the desired
anticone.)
I wonder, though, how many Hirth joints are conical and why. A conical
joint seems like an unnecessary complication, as a plain joint already
self-centres very precisely.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
There is a question that I've noted before about what is meant by "tooth
angle". The wikipedia page suggests that it is measured relative to the
cylinder axis. In gears tooth angle is measured relative to the ridge of
the tooth. These two ideas produce a different result, and the steeper the
cone angle gets the bigger the difference. Arguably it doesn't matter if
you're just trying to make parts that mate with each other as opposed to
mating with some manufactured standard part. (You can change your tooth
angle if you don't like what happened when you specified a steep cone.)
Your method of using spherical coordinates is just a way of projecting
(scaling) a triangle. The results should be the same. (I did want to
confirm that.) There is another question about what you consider the
"zero" conical angle. I initially did it so that the base of the teeth was
at zero angle, but later thought this wasn't right: it should be the angle
that produces a part that mates with itself, which should occur if the line
through the center of the teeth is at angle zero. At least, I think that's
right.
Note: it may not matter in practice, but a rounded valley is STRONGER than
a chamfer. Corners concentrate forces and are the places where parts
fail. If the part is small printing will limit this, but what if someone
prints an 8" diameter part with 6 teeth? There is nothing weird about this
joint that should limit the number of teeth to be more than 12. It should
work with 3 teeth. One might in fact want an 8 tooth version to provide
part alignment at 45 degree detents, so a 12 limit is...welll...limiting.
If you're machining a tooth you're surely going to have a constant
roundover at the bottom, not one that varies with tooth size. At the top I
suppose other things are possible, but it does seem like the natural way to
machine it would also be with a constant with chamfer, not one that varies
with tooth size. I didn't do it that way in my code for two reasons: (1)
I was trying to match Bob's code and (2) the varying width chamfer was much
simpler to implement. Of course, we aren't machining and we don't have to
limit ourselves to things that are easy to machine.
It can be a nuisance as a library author to have to write code that works
on the old version. That's definitely the case. Seeking efficiency in
general for library code is also a good goal, though. When someone makes a
model with 45 hirth joints what happens? I wonder if it's better to call
this "hirth" or "face_spline".
I see you just posted your code while I was typing so I'll take a look and
see if I can compare to mine.
On Thu, Oct 31, 2024 at 7:13 PM Bob Carlson <bob@rjcarlson.com> wrote:
> I had the same experience. I found no mention of conical joints. But since
> my one and only real world example is conical, I know they exist and are
> used. Someone said early on that hirths are not standardized so maybe it’s
> not surprising that online sources are incomplete. An interesting problem
> is that if you have a conical hirth part and need to measure it to
> determine what the “conic” argument should be I have not figured out any
> way to do that precisely! The ridge angle is easily measured but a “hirth
> calculator” would be needed to go from ridge angle to conic.
>
> As I worked with the code over the last month or so, I grew to mistrust
> the idea of a flat profile being projected away from the origin. I used
> that idea originally. But he more I thought about the situation at the
> outer radius, the more I suspected that my powers of visualization were not
> adequate. The tooth at the outer radius is the intersection of the tooth
> with a cylinder. In a flat joint that doesn’t seem too terrible, but then
> move the origin make a conical joint and it really gets hard to keep in my
> mind. Maybe that all doesn’t matter, but I wasn’t confident it didn't.
>
> Much of the material I found about hirth joints was about how to machine
> them. It was clear that the groove angle was the critical number, because
> the groove is the path the cutter follows. I realized that I could trust
> the groove and ridge angles. Using spherical coordinates it was easy to
> create a tooth and easy to see why it worked correctly. Someone used to
> working with trig could probably come up with the angles for chamfer
> shoulders, but not me.
>
> I may spend some more time understanding your method, but right now I’m
> concentrating on some other things.
>
> - Bob
>
> On Oct 31, 2024, at 13:39, Adrian Mariano <avm4@cornell.edu> wrote:
>
> I looked up Hirth joints online and found no indication at all that a
> conical hirth joint exists. No pictures. Nobody selling them. Nobody
> describing them. So that did make me wonder what the advantage is. Is it
> in fact easier to connect conical joints? The joint is said to self-center
> normally and it could be made so the parts are identical, which is a
> simplification compared to a conical design where you need two different
> parts.
>
> Personally I think the simplest way to chamfer the teeth of this joint is
> as in the code I posted: in 2d on the profile. No cone required.
>
>
> On Thu, Oct 31, 2024 at 4:27 PM Bob Carlson via Discuss <
> discuss@lists.openscad.org> wrote:
>
>> I have encountered exactly one hirth spline IRL and it was conical. I
>> made some attachments for my golf cart (carries just my bag). The spot
>> where options are attached has a hirth spline to prevent rotation of the
>> things attached. It is conical, 60 teeth and 35 mm in D. I made a matching
>> part without understanding anything about the hirth spline or knowing the
>> name.
>>
>> It seems obvious that the cone shape makes it easier to center the parts
>> by hand as you put new attachments on.
>>
>> - Bob
>>
>> On Oct 31, 2024, at 12:36, Caddiy via Discuss <discuss@lists.openscad.org>
>> wrote:
>>
>> Jordan Brown wrote:
>>
>> To cut a long story short, a polygon can give you the filler-cone plus a
>> bit more in one piece, which a primitive cone can’t.
>>
>> Sort of. It depends on what your requirements are for the "plus a bit
>> more".
>>
>> If your cone is anchored at the top, scaling it up will expand it at the
>> base without changing the shape of the top.
>>
>> This is easy to demonstrate with BOSL2, because you can natively anchor
>> at the top:
>>
>> include <BOSL2/std.scad>
>>
>> s = 1;
>> scale(s) zcyl(r1=10, r2=0, h=10, anchor=TOP);
>>
>> as you change s, observe that the top portion of the cone stays the same.
>>
>> It's a tiny bit more complex in base OpenSCAD because base OpenSCAD
>> cylinders are anchored at their bottoms or centers.
>>
>> s = 1;
>> h = 10;
>> scale(s) translate([0,0,-h]) cylinder(r1=10, r2=0, h=h);
>>
>> (Though you can demonstrate it with an upside-down cone without needing a
>> translate().)
>>
>> It even retains the same number of sides as it grows, because cylinder()
>> decides on the number of sides when it creates the object, and scale()
>> doesn't affect that choice.
>>
>> In the particular case that this came from, the user was already using
>> BOSL2, and it happened that the top of the cone was easy to know, and that
>> since it was cutting away past the bottom of the object the shape of the
>> "extra" didn't matter. Net, that negative object could be a
>> straightforward cone anchored at its top.
>>
>> A conical face spline joint will need two different cones as fillers to
>> get a flat face at the back of each piece. One piece, with luck or by
>> design, may already have a flat face, or it may even be conical, requiring
>> a negative/hollow cone, that I’m calling an anticone, to get a flat face.
>> But neither a primitive cone nor a BOSL2 cone can handle a negative “h”.
>>
>> A polygon can. (The polygon is then rotate-extruded to form the desired
>> anticone.)
>>
>> I wonder, though, how many Hirth joints are conical and why. A conical
>> joint seems like an unnecessary complication, as a plain joint already
>> self-centres very precisely.
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
>
>
RW
Raymond West
Fri, Nov 1, 2024 12:00 AM
Hi Bob,
Here's the basic code for a parametric Hirth Joint. Spring loaded often
use as a slip clutch in torque sensitive situations, e.g screw drivers,
tapping heads, etc. Larger scale high speed turbines for shaft
connections, since easy to balance, no windage, etc. I've tested as
saving as stl, and re-importing, gives no errors. Easy enough to cut out
the centre teeth if you don't want them.
// clutch.scad
ind= 50; // overall diameter
num= 20; // number of teeth
back = 6; //thickness of back
////////////////////////////////////////////
diam= ind/cos (180/num); // bigger to allow for chords
chord = diam*sin(180/num);
ridge= chord *sqrt(3)/3; // or set to whatever (denominator = 2 for 60
degrees.)
points=[
[0,0,ridge/2],
[diam/2,-chord/2,0],
[diam/2,+chord/2,0],
[diam/2,0,ridge]
];
faces=[
[0,1,2],
[0,1,3],
[0,2,3],
[1,2,3]
];
module wedge(){
polyhedron(points,faces,convexity=10);
}
//rotate wedge
intersection(){
translate([0,0,-back])
cylinder(d=ind,h=200,$fn=100);
union(){
for (j=[0:1:+1+360/num])
rotate([0,0,j360/num+0.5360/num]) wedge();
cylinder(d1=diam,d2=0,h=ridge/2,$fn=num);
translate([0,0,-back])
cylinder(d=diam,h=back,$fn=num);
}
}
//save as stl, then import to check for valid stl. (remove comments
below and run again)
/*
translate([0,0,6])
rotate([0,180,360/(num*2)])
import("P:/Docs/openscad/clutch.stl");
*/
On 26/10/2024 00:44, Bob Carlson via Discuss wrote:
I got really intrigued by the Hirth joint and have been working a library entry that would generate them. I have it fully working, apparently, because it renders perfectly as far as I can see. However when I load one of the parts (a concave part) into PrusaSlicer, it reports thousands of errors that it supposedly fixed. The visual rendering is fine, but when you look at the slice it is completely screwed up.
First some explanation. When I looked up hirth joints I only saw flat ones mentioned. The one I have actually encountered though is a conical one. There is a concave part and a convex part. They fit together perfectly. I had to invent some terminology since I did not find terms for some things I found to be important. The outer center line is the plane that passes through the midpoint of the teeth at the outer radius. In a flat hirth joint all the teeth radiate from the center of this circle, call it the origin. If the origin of the teeth is above the outer center line, then joint has a conical shape and the two parts are concave and convex.
Each tooth at every point has the same profile, the top of the tooth profile is either 60 or 90 degrees. The groove angle is the angle that the groove forms from the origin to the outer radius. It will pass below (for a convex part) the outer radius. It’s critical for making hirth joints because it forms the tool path. The ridge angle is the angle formed by the corresponding ridge.
If the joint is conical, then there is an inner center line that passes through the center of the teeth at the inner radius. The tooth height is the critical number to calculate. It is dependent on the number of teeth, the profile angle and the inner and out radii. Something that really complicates the mental gymnastics is that the tooth height is smaller at the inner radius. My code adds a “base” of extra material at the bottom of the convex part and the top of the concave part. What’s tricky is positioning the base of the concave part relative to the inner center line. The concave parts base is relatively easy to place because it depends on the outer radius and center line.
I generate the raw teeth using the groove and ridge angles and spherical coordinates to make two 2d tooth profiles. Then I complete a tooth using skin(). A for loop generates the full set of N teeth. Then intersection or difference is used the trim the teeth at the inner and outer radii. I discovered something at that point, but solved it pretty simply. When diffing a cylinder from the N teeth, each tooth took up a small portion of the cylinder being diffed out. I had to raise the $fn on the cylinder or tube being used so that I got enough points in each tooth that diff or intersection was accurate. I kept raising it until the results stopped improving. I ended up with the 16*360 you see in the code.
After I have the raw teeth, I generate a cone that is diffed away to produce the chamfer at the top of the teeth. Then I add in the base. The base also adds the “chamfer” at the bottom of the groove. It’s half the size of the top chamfer to leave a little gap when the parts are joined.
When I comment out the everything but the raw teeth and import the STL into PrusaSlicer, it reports errors fixed, but appears to slice correctly when supports are added.
When I add the intersection to trim the raw teeth, the number of reported errors goes way up.
When I add the diff to remove the chamfer, the number goes way up again.
When I add in the base, the number goes up again and it starts reporting many open edges.
Throughout, OpenSCAD reports no errors. Using $fn at 16360, manifold renders in 4+ seconds. At 32360, it’s 53+ seconds. I did check CSG and it did not help.
Maybe the biggest hint is that the convex part uses almost identical code, but produces no errors. Very weird.
So, is this an OpenSCAD problem? Or something in my code?
It’s also possible that my math is off somewhere. My formal trig training was 60 years ago. However I doubt a math error is responsible for the slicing problem and STL errors.
-Bob
include <BOSL2/std.scad>
include <BOSL2/structs.scad>
// Number of Teeth
_n = 36; // Number Of Teeth
// Inner Radius
_ir = 30;
// Outer Radius
_or = 50;
// Is the coupling conical?
_conic = 10;
// Tooth Profile Angle
_profile = 60; // [60, 90]
// Percentage of tooth height
_chamfer = 5; // Default 5%
_base = 1;
$fn = 180;
tiny = 1 / 1024;
hirth_concave();
_irRatio = _ir / _or;
_toothAngle = 360/_n;
_toothHeight = (sin(_toothAngle/2) * _or) / tan(_profile/2);
_chamferHeight = _chamfer * _toothHeight / 100;
_grooveAngle = atan(((_toothHeight/2) + _conic) / _or);
_ridgeAngle = -atan(((_toothHeight/2) - _conic) / _or);
_innerCenterLine = (1 - _irRatio) * _conic;
_stackHeight = _innerCenterLine + _toothHeight + 2*_base;
_tubeHeight = 2*_conic + 2*_base + 2*_toothHeight;
module hirth_concave() {
zrot(_toothAngle/2)
union() {
difference() {
intersection() {
union() {
for (i = [0 : 360/_n : 359])
zrot(i)
_profileF();
}
tube(ir = _ir, or = _or, anchor = CENTER, l = _tubeHeight, orient = UP, $fn = 16360);
}
_chamferF();
zcyl(r = _ir, h = _tubeHeight, $fn = 16360, anchor = CENTER);
}
_baseF();
}
} // hirth_concave
module _profileF() {
IR = _ir * .5;
OR = _or * 1.5;
tI = [spherical_to_xyz(IR, 0, _grooveAngle + 90),
spherical_to_xyz(IR, _toothAngle/2, _ridgeAngle + 90),
spherical_to_xyz(IR, -_toothAngle/2, _ridgeAngle + 90)];
tO = [spherical_to_xyz(OR, 0, _grooveAngle + 90),
spherical_to_xyz(OR, _toothAngle/2, _ridgeAngle + 90),
spherical_to_xyz(OR, -_toothAngle/2, _ridgeAngle + 90)];
up(_conic)
skin([tI, tO], slices = 0);
}
module _chamferF() {
A = -_toothHeight/2 - .1;
B = -_toothHeight/2 + _chamferHeight;
pts = [[0, _conic],
[_or+tiny, A],
[_or+tiny, B]];
rotate_extrude(angle = 360, $fn = 16*360)
polygon(pts);
}
module _baseF() {
A = _base + _irRatio*_toothHeight/2 + _innerCenterLine;
B = _irRatio * (_toothHeight/2 - _chamferHeight/2) + _innerCenterLine;
C = _toothHeight/2 - _chamferHeight/2;
pts = [
[_ir, A],
[_ir, B],
[_or, C],
[_or, A]
];
rotate_extrude(angle = 360, $fn = 360*16)
polygon(pts);
}
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Hi Bob,
Here's the basic code for a parametric Hirth Joint. Spring loaded often
use as a slip clutch in torque sensitive situations, e.g screw drivers,
tapping heads, etc. Larger scale high speed turbines for shaft
connections, since easy to balance, no windage, etc. I've tested as
saving as stl, and re-importing, gives no errors. Easy enough to cut out
the centre teeth if you don't want them.
// clutch.scad
ind= 50; // overall diameter
num= 20; // number of teeth
back = 6; //thickness of back
////////////////////////////////////////////
diam= ind/cos (180/num); // bigger to allow for chords
chord = diam*sin(180/num);
ridge= chord *sqrt(3)/3; // or set to whatever (denominator = 2 for 60
degrees.)
points=[
[0,0,ridge/2],
[diam/2,-chord/2,0],
[diam/2,+chord/2,0],
[diam/2,0,ridge]
];
faces=[
[0,1,2],
[0,1,3],
[0,2,3],
[1,2,3]
];
module wedge(){
polyhedron(points,faces,convexity=10);
}
//rotate wedge
intersection(){
translate([0,0,-back])
cylinder(d=ind,h=200,$fn=100);
union(){
for (j=[0:1:+1+360/num])
rotate([0,0,j*360/num+0.5*360/num]) wedge();
cylinder(d1=diam,d2=0,h=ridge/2,$fn=num);
translate([0,0,-back])
cylinder(d=diam,h=back,$fn=num);
}
}
//save as stl, then import to check for valid stl. (remove comments
below and run again)
/*
translate([0,0,6])
rotate([0,180,360/(num*2)])
import("P:/Docs/openscad/clutch.stl");
*/
On 26/10/2024 00:44, Bob Carlson via Discuss wrote:
> I got really intrigued by the Hirth joint and have been working a library entry that would generate them. I have it fully working, apparently, because it renders perfectly as far as I can see. However when I load one of the parts (a concave part) into PrusaSlicer, it reports thousands of errors that it supposedly fixed. The visual rendering is fine, but when you look at the slice it is completely screwed up.
>
> First some explanation. When I looked up hirth joints I only saw flat ones mentioned. The one I have actually encountered though is a conical one. There is a concave part and a convex part. They fit together perfectly. I had to invent some terminology since I did not find terms for some things I found to be important. The outer center line is the plane that passes through the midpoint of the teeth at the outer radius. In a flat hirth joint all the teeth radiate from the center of this circle, call it the origin. If the origin of the teeth is above the outer center line, then joint has a conical shape and the two parts are concave and convex.
>
> Each tooth at every point has the same profile, the top of the tooth profile is either 60 or 90 degrees. The groove angle is the angle that the groove forms from the origin to the outer radius. It will pass below (for a convex part) the outer radius. It’s critical for making hirth joints because it forms the tool path. The ridge angle is the angle formed by the corresponding ridge.
>
> If the joint is conical, then there is an inner center line that passes through the center of the teeth at the inner radius. The tooth height is the critical number to calculate. It is dependent on the number of teeth, the profile angle and the inner and out radii. Something that really complicates the mental gymnastics is that the tooth height is smaller at the inner radius. My code adds a “base” of extra material at the bottom of the convex part and the top of the concave part. What’s tricky is positioning the base of the concave part relative to the inner center line. The concave parts base is relatively easy to place because it depends on the outer radius and center line.
>
> I generate the raw teeth using the groove and ridge angles and spherical coordinates to make two 2d tooth profiles. Then I complete a tooth using skin(). A for loop generates the full set of N teeth. Then intersection or difference is used the trim the teeth at the inner and outer radii. I discovered something at that point, but solved it pretty simply. When diffing a cylinder from the N teeth, each tooth took up a small portion of the cylinder being diffed out. I had to raise the $fn on the cylinder or tube being used so that I got enough points in each tooth that diff or intersection was accurate. I kept raising it until the results stopped improving. I ended up with the 16*360 you see in the code.
>
> After I have the raw teeth, I generate a cone that is diffed away to produce the chamfer at the top of the teeth. Then I add in the base. The base also adds the “chamfer” at the bottom of the groove. It’s half the size of the top chamfer to leave a little gap when the parts are joined.
>
> When I comment out the everything but the raw teeth and import the STL into PrusaSlicer, it reports errors fixed, but appears to slice correctly when supports are added.
>
> When I add the intersection to trim the raw teeth, the number of reported errors goes way up.
>
> When I add the diff to remove the chamfer, the number goes way up again.
>
> When I add in the base, the number goes up again and it starts reporting many open edges.
>
> Throughout, OpenSCAD reports no errors. Using $fn at 16*360, manifold renders in 4+ seconds. At 32*360, it’s 53+ seconds. I did check CSG and it did not help.
>
> Maybe the biggest hint is that the convex part uses almost identical code, but produces no errors. Very weird.
>
> So, is this an OpenSCAD problem? Or something in my code?
>
> It’s also possible that my math is off somewhere. My formal trig training was 60 years ago. However I doubt a math error is responsible for the slicing problem and STL errors.
>
> -Bob
>
>
> include <BOSL2/std.scad>
> include <BOSL2/structs.scad>
>
> // Number of Teeth
> _n = 36; // Number Of Teeth
>
> // Inner Radius
> _ir = 30;
> // Outer Radius
> _or = 50;
> // Is the coupling conical?
> _conic = 10;
> // Tooth Profile Angle
> _profile = 60; // [60, 90]
> // Percentage of tooth height
> _chamfer = 5; // Default 5%
> _base = 1;
>
> $fn = 180;
> tiny = 1 / 1024;
>
> hirth_concave();
>
> _irRatio = _ir / _or;
> _toothAngle = 360/_n;
> _toothHeight = (sin(_toothAngle/2) * _or) / tan(_profile/2);
> _chamferHeight = _chamfer * _toothHeight / 100;
> _grooveAngle = atan(((_toothHeight/2) + _conic) / _or);
> _ridgeAngle = -atan(((_toothHeight/2) - _conic) / _or);
> _innerCenterLine = (1 - _irRatio) * _conic;
> _stackHeight = _innerCenterLine + _toothHeight + 2*_base;
> _tubeHeight = 2*_conic + 2*_base + 2*_toothHeight;
>
> module hirth_concave() {
> zrot(_toothAngle/2)
> union() {
> difference() {
> intersection() {
> union() {
> for (i = [0 : 360/_n : 359])
> zrot(i)
> _profileF();
> }
> tube(ir = _ir, or = _or, anchor = CENTER, l = _tubeHeight, orient = UP, $fn = 16*360);
> }
> _chamferF();
> zcyl(r = _ir, h = _tubeHeight, $fn = 16*360, anchor = CENTER);
> }
> _baseF();
> }
> } // hirth_concave
>
> module _profileF() {
> IR = _ir * .5;
> OR = _or * 1.5;
> tI = [spherical_to_xyz(IR, 0, _grooveAngle + 90),
> spherical_to_xyz(IR, _toothAngle/2, _ridgeAngle + 90),
> spherical_to_xyz(IR, -_toothAngle/2, _ridgeAngle + 90)];
>
> tO = [spherical_to_xyz(OR, 0, _grooveAngle + 90),
> spherical_to_xyz(OR, _toothAngle/2, _ridgeAngle + 90),
> spherical_to_xyz(OR, -_toothAngle/2, _ridgeAngle + 90)];
> up(_conic)
> skin([tI, tO], slices = 0);
> }
>
>
> module _chamferF() {
> A = -_toothHeight/2 - .1;
> B = -_toothHeight/2 + _chamferHeight;
>
> pts = [[0, _conic],
> [_or+tiny, A],
> [_or+tiny, B]];
>
> rotate_extrude(angle = 360, $fn = 16*360)
> polygon(pts);
> }
>
> module _baseF() {
> A = _base + _irRatio*_toothHeight/2 + _innerCenterLine;
> B = _irRatio * (_toothHeight/2 - _chamferHeight/2) + _innerCenterLine;
> C = _toothHeight/2 - _chamferHeight/2;
> pts = [
> [_ir, A],
> [_ir, B],
> [_or, C],
> [_or, A]
> ];
>
> rotate_extrude(angle = 360, $fn = 360*16)
> polygon(pts);
> }
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
SP
Sanjeev Prabhakar
Fri, Nov 1, 2024 2:22 AM
Here is the python code for creating the hirth_coupling with no limitation
of teeth, cone angle,teeth angle, chamfer etc.
from openscad2 import *
hirth coupling
n=36 # number of teeths
ta=60 # teeth angle
ca=20 # for straight 360/42.232 # cone angle
i_r=30 # inner radius
o_r=50 # outer radius
ch=1 # chamfer height
l1=[[i_r,0],[o_r,0]]
l2=[ q_rot([f'z{i}'],l1) for i in linspace(0,360,n+1)[:-1]]
l3=axis_rot_1(l1,ax1=[0,1,0],loc1=[o_r,0],theta=ca)
l3= line2length(flip(line2length(l3,(o_r-i_r)+5)),(o_r-i_r)+10)
cone1=[ q_rot([f'z{i}'],l3) for i in linspace(0,360,n)]
l2=psos(cone1,l2,[0,0,1])
l1=[l2[0][0],l2[1][0]]
d1=l_len(l1)/2/cos(d2r(ta))
l1=axis_rot_1(l1,line_as_axis(l2[0]),l2[0][0],ta)
l1=line2length(l1,d1)
l3=[l2[0][1],l2[1][1]]
d2=l_len(l3)/2/cos(d2r(ta))
l3=axis_rot_1(l3,line_as_axis(l2[0]),l2[0][1],ta)
l3=line2length(l3,d2)
l4=[l1[1],l3[1]]
a,b=l4
l4=line2length(flip(line2length(l4,25)),30)
cone2=[ q_rot([f'z{i}'],l4) for i in linspace(0,360,n)]
l3=psos(cone2,l2,[0,0,1])
l3=q_rot([f'z{360/n/2}'],l3)
s1=l_(a_([l2,l3]).transpose(1,0,2,3).reshape(n*2,2,3))
s1=s1+[s1[0]]
s1=l_(a_(s1).transpose(1,0,2))
sol1=flip(surf_base(s1,s1[0][1][2]+10))
s2=l_(a_(cone1).transpose(1,0,2))
s2=surface_offset(s2,-ch)
sol2=surf_base(s2,s1[1][0][2]-10)
sol2=sol2+[sol2[0]]
sol3=surf_base(flip(s1),s1[1][0][2]-10)
s3=q_rot(['z5'],l_(a_(cone2[:-1]).transpose(1,0,2)))
s3=surface_offset(s3,ch)
sol4=surf_base(s3,s1[0][1][2]+10)
sol4=sol4+[sol4[0]]
with open('trial.scad','w+') as f:
f.write(f'''
translate([0,0,25])
// color([.13,.81,.37])
difference(){{
{swp_c(sol1)}
{swp_c(sol2)}
}}
difference(){{
{swp_c(sol3)}
{swp_c(sol4)}
}}
''')
On Fri, 1 Nov 2024 at 05:31, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:
Hi Bob,
Here's the basic code for a parametric Hirth Joint. Spring loaded often
use as a slip clutch in torque sensitive situations, e.g screw drivers,
tapping heads, etc. Larger scale high speed turbines for shaft
connections, since easy to balance, no windage, etc. I've tested as
saving as stl, and re-importing, gives no errors. Easy enough to cut out
the centre teeth if you don't want them.
// clutch.scad
ind= 50; // overall diameter
num= 20; // number of teeth
back = 6; //thickness of back
////////////////////////////////////////////
diam= ind/cos (180/num); // bigger to allow for chords
chord = diam*sin(180/num);
ridge= chord *sqrt(3)/3; // or set to whatever (denominator = 2 for 60
degrees.)
points=[
[0,0,ridge/2],
[diam/2,-chord/2,0],
[diam/2,+chord/2,0],
[diam/2,0,ridge]
];
faces=[
[0,1,2],
[0,1,3],
[0,2,3],
[1,2,3]
];
module wedge(){
polyhedron(points,faces,convexity=10);
}
//rotate wedge
intersection(){
translate([0,0,-back])
cylinder(d=ind,h=200,$fn=100);
union(){
for (j=[0:1:+1+360/num])
rotate([0,0,j360/num+0.5360/num]) wedge();
cylinder(d1=diam,d2=0,h=ridge/2,$fn=num);
translate([0,0,-back])
cylinder(d=diam,h=back,$fn=num);
}
}
//save as stl, then import to check for valid stl. (remove comments
below and run again)
/*
translate([0,0,6])
rotate([0,180,360/(num*2)])
import("P:/Docs/openscad/clutch.stl");
*/
On 26/10/2024 00:44, Bob Carlson via Discuss wrote:
I got really intrigued by the Hirth joint and have been working a
library entry that would generate them. I have it fully working,
apparently, because it renders perfectly as far as I can see. However when
I load one of the parts (a concave part) into PrusaSlicer, it reports
thousands of errors that it supposedly fixed. The visual rendering is fine,
but when you look at the slice it is completely screwed up.
First some explanation. When I looked up hirth joints I only saw flat
ones mentioned. The one I have actually encountered though is a conical
one. There is a concave part and a convex part. They fit together
perfectly. I had to invent some terminology since I did not find terms for
some things I found to be important. The outer center line is the plane
that passes through the midpoint of the teeth at the outer radius. In a
flat hirth joint all the teeth radiate from the center of this circle, call
it the origin. If the origin of the teeth is above the outer center line,
then joint has a conical shape and the two parts are concave and convex.
Each tooth at every point has the same profile, the top of the tooth
profile is either 60 or 90 degrees. The groove angle is the angle that the
groove forms from the origin to the outer radius. It will pass below (for a
convex part) the outer radius. It’s critical for making hirth joints
because it forms the tool path. The ridge angle is the angle formed by the
corresponding ridge.
If the joint is conical, then there is an inner center line that passes
through the center of the teeth at the inner radius. The tooth height is
the critical number to calculate. It is dependent on the number of teeth,
the profile angle and the inner and out radii. Something that really
complicates the mental gymnastics is that the tooth height is smaller at
the inner radius. My code adds a “base” of extra material at the bottom of
the convex part and the top of the concave part. What’s tricky is
positioning the base of the concave part relative to the inner center line.
The concave parts base is relatively easy to place because it depends on
the outer radius and center line.
I generate the raw teeth using the groove and ridge angles and spherical
coordinates to make two 2d tooth profiles. Then I complete a tooth using
skin(). A for loop generates the full set of N teeth. Then intersection or
difference is used the trim the teeth at the inner and outer radii. I
discovered something at that point, but solved it pretty simply. When
diffing a cylinder from the N teeth, each tooth took up a small portion of
the cylinder being diffed out. I had to raise the $fn on the cylinder or
tube being used so that I got enough points in each tooth that diff or
intersection was accurate. I kept raising it until the results stopped
improving. I ended up with the 16*360 you see in the code.
After I have the raw teeth, I generate a cone that is diffed away to
produce the chamfer at the top of the teeth. Then I add in the base. The
base also adds the “chamfer” at the bottom of the groove. It’s half the
size of the top chamfer to leave a little gap when the parts are joined.
When I comment out the everything but the raw teeth and import the STL
into PrusaSlicer, it reports errors fixed, but appears to slice correctly
when supports are added.
When I add the intersection to trim the raw teeth, the number of
reported errors goes way up.
When I add the diff to remove the chamfer, the number goes way up again.
When I add in the base, the number goes up again and it starts reporting
Throughout, OpenSCAD reports no errors. Using $fn at 16*360, manifold
renders in 4+ seconds. At 32*360, it’s 53+ seconds. I did check CSG and it
did not help.
Maybe the biggest hint is that the convex part uses almost identical
code, but produces no errors. Very weird.
So, is this an OpenSCAD problem? Or something in my code?
It’s also possible that my math is off somewhere. My formal trig
training was 60 years ago. However I doubt a math error is responsible for
the slicing problem and STL errors.
-Bob
include <BOSL2/std.scad>
include <BOSL2/structs.scad>
// Number of Teeth
_n = 36; // Number Of Teeth
// Inner Radius
_ir = 30;
// Outer Radius
_or = 50;
// Is the coupling conical?
_conic = 10;
// Tooth Profile Angle
_profile = 60; // [60, 90]
// Percentage of tooth height
_chamfer = 5; // Default 5%
_base = 1;
$fn = 180;
tiny = 1 / 1024;
hirth_concave();
_irRatio = _ir / _or;
_toothAngle = 360/_n;
_toothHeight = (sin(_toothAngle/2) * _or) / tan(_profile/2);
_chamferHeight = _chamfer * _toothHeight / 100;
_grooveAngle = atan(((_toothHeight/2) + _conic) / _or);
_ridgeAngle = -atan(((_toothHeight/2) - _conic) / _or);
_innerCenterLine = (1 - _irRatio) * _conic;
_stackHeight = _innerCenterLine + _toothHeight + 2*_base;
_tubeHeight = 2*_conic + 2*_base + 2*_toothHeight;
module hirth_concave() {
zrot(_toothAngle/2)
union() {
difference() {
intersection() {
union() {
for (i = [0 : 360/_n : 359])
zrot(i)
_profileF();
}
tube(ir = _ir, or = _or, anchor = CENTER, l =
_tubeHeight, orient = UP, $fn = 16*360);
}
_chamferF();
zcyl(r = _ir, h = _tubeHeight, $fn = 16*360, anchor =
}
_baseF();
}
} // hirth_concave
module _profileF() {
IR = _ir * .5;
OR = _or * 1.5;
tI = [spherical_to_xyz(IR, 0, _grooveAngle + 90),
spherical_to_xyz(IR, _toothAngle/2, _ridgeAngle + 90),
spherical_to_xyz(IR, -_toothAngle/2, _ridgeAngle + 90)];
tO = [spherical_to_xyz(OR, 0, _grooveAngle + 90),
spherical_to_xyz(OR, _toothAngle/2, _ridgeAngle + 90),
spherical_to_xyz(OR, -_toothAngle/2, _ridgeAngle + 90)];
up(_conic)
skin([tI, tO], slices = 0);
}
module _chamferF() {
A = -_toothHeight/2 - .1;
B = -_toothHeight/2 + _chamferHeight;
pts = [[0, _conic],
[_or+tiny, A],
[_or+tiny, B]];
rotate_extrude(angle = 360, $fn = 16*360)
polygon(pts);
}
module _baseF() {
A = _base + _irRatio*_toothHeight/2 + _innerCenterLine;
B = _irRatio * (_toothHeight/2 - _chamferHeight/2) +
C = _toothHeight/2 - _chamferHeight/2;
pts = [
[_ir, A],
[_ir, B],
[_or, C],
[_or, A]
];
rotate_extrude(angle = 360, $fn = 360*16)
polygon(pts);
}
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Here is the python code for creating the hirth_coupling with no limitation
of teeth, cone angle,teeth angle, chamfer etc.
from openscad2 import *
# hirth coupling
n=36 # number of teeths
ta=60 # teeth angle
ca=20 # for straight 360/42.232 # cone angle
i_r=30 # inner radius
o_r=50 # outer radius
ch=1 # chamfer height
l1=[[i_r,0],[o_r,0]]
l2=[ q_rot([f'z{i}'],l1) for i in linspace(0,360,n+1)[:-1]]
l3=axis_rot_1(l1,ax1=[0,1,0],loc1=[o_r,0],theta=ca)
l3= line2length(flip(line2length(l3,(o_r-i_r)+5)),(o_r-i_r)+10)
cone1=[ q_rot([f'z{i}'],l3) for i in linspace(0,360,n)]
l2=psos(cone1,l2,[0,0,1])
l1=[l2[0][0],l2[1][0]]
d1=l_len(l1)/2/cos(d2r(ta))
l1=axis_rot_1(l1,line_as_axis(l2[0]),l2[0][0],ta)
l1=line2length(l1,d1)
l3=[l2[0][1],l2[1][1]]
d2=l_len(l3)/2/cos(d2r(ta))
l3=axis_rot_1(l3,line_as_axis(l2[0]),l2[0][1],ta)
l3=line2length(l3,d2)
l4=[l1[1],l3[1]]
a,b=l4
l4=line2length(flip(line2length(l4,25)),30)
cone2=[ q_rot([f'z{i}'],l4) for i in linspace(0,360,n)]
l3=psos(cone2,l2,[0,0,1])
l3=q_rot([f'z{360/n/2}'],l3)
s1=l_(a_([l2,l3]).transpose(1,0,2,3).reshape(n*2,2,3))
s1=s1+[s1[0]]
s1=l_(a_(s1).transpose(1,0,2))
sol1=flip(surf_base(s1,s1[0][1][2]+10))
s2=l_(a_(cone1).transpose(1,0,2))
s2=surface_offset(s2,-ch)
sol2=surf_base(s2,s1[1][0][2]-10)
sol2=sol2+[sol2[0]]
sol3=surf_base(flip(s1),s1[1][0][2]-10)
s3=q_rot(['z5'],l_(a_(cone2[:-1]).transpose(1,0,2)))
s3=surface_offset(s3,ch)
sol4=surf_base(s3,s1[0][1][2]+10)
sol4=sol4+[sol4[0]]
with open('trial.scad','w+') as f:
f.write(f'''
translate([0,0,25])
// color([.13,.81,.37])
difference(){{
{swp_c(sol1)}
{swp_c(sol2)}
}}
difference(){{
{swp_c(sol3)}
{swp_c(sol4)}
}}
''')
On Fri, 1 Nov 2024 at 05:31, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:
> Hi Bob,
>
> Here's the basic code for a parametric Hirth Joint. Spring loaded often
> use as a slip clutch in torque sensitive situations, e.g screw drivers,
> tapping heads, etc. Larger scale high speed turbines for shaft
> connections, since easy to balance, no windage, etc. I've tested as
> saving as stl, and re-importing, gives no errors. Easy enough to cut out
> the centre teeth if you don't want them.
>
> // clutch.scad
>
> ind= 50; // overall diameter
> num= 20; // number of teeth
> back = 6; //thickness of back
> ////////////////////////////////////////////
>
>
> diam= ind/cos (180/num); // bigger to allow for chords
> chord = diam*sin(180/num);
>
> ridge= chord *sqrt(3)/3; // or set to whatever (denominator = 2 for 60
> degrees.)
>
> points=[
> [0,0,ridge/2],
> [diam/2,-chord/2,0],
> [diam/2,+chord/2,0],
> [diam/2,0,ridge]
> ];
> faces=[
> [0,1,2],
> [0,1,3],
> [0,2,3],
> [1,2,3]
> ];
>
> module wedge(){
> polyhedron(points,faces,convexity=10);
> }
>
> //rotate wedge
>
> intersection(){
> translate([0,0,-back])
> cylinder(d=ind,h=200,$fn=100);
> union(){
> for (j=[0:1:+1+360/num])
> rotate([0,0,j*360/num+0.5*360/num]) wedge();
> cylinder(d1=diam,d2=0,h=ridge/2,$fn=num);
> translate([0,0,-back])
> cylinder(d=diam,h=back,$fn=num);
> }
> }
>
> //save as stl, then import to check for valid stl. (remove comments
> below and run again)
>
> /*
> translate([0,0,6])
> rotate([0,180,360/(num*2)])
> import("P:/Docs/openscad/clutch.stl");
> */
>
>
> On 26/10/2024 00:44, Bob Carlson via Discuss wrote:
> > I got really intrigued by the Hirth joint and have been working a
> library entry that would generate them. I have it fully working,
> apparently, because it renders perfectly as far as I can see. However when
> I load one of the parts (a concave part) into PrusaSlicer, it reports
> thousands of errors that it supposedly fixed. The visual rendering is fine,
> but when you look at the slice it is completely screwed up.
> >
> > First some explanation. When I looked up hirth joints I only saw flat
> ones mentioned. The one I have actually encountered though is a conical
> one. There is a concave part and a convex part. They fit together
> perfectly. I had to invent some terminology since I did not find terms for
> some things I found to be important. The outer center line is the plane
> that passes through the midpoint of the teeth at the outer radius. In a
> flat hirth joint all the teeth radiate from the center of this circle, call
> it the origin. If the origin of the teeth is above the outer center line,
> then joint has a conical shape and the two parts are concave and convex.
> >
> > Each tooth at every point has the same profile, the top of the tooth
> profile is either 60 or 90 degrees. The groove angle is the angle that the
> groove forms from the origin to the outer radius. It will pass below (for a
> convex part) the outer radius. It’s critical for making hirth joints
> because it forms the tool path. The ridge angle is the angle formed by the
> corresponding ridge.
> >
> > If the joint is conical, then there is an inner center line that passes
> through the center of the teeth at the inner radius. The tooth height is
> the critical number to calculate. It is dependent on the number of teeth,
> the profile angle and the inner and out radii. Something that really
> complicates the mental gymnastics is that the tooth height is smaller at
> the inner radius. My code adds a “base” of extra material at the bottom of
> the convex part and the top of the concave part. What’s tricky is
> positioning the base of the concave part relative to the inner center line.
> The concave parts base is relatively easy to place because it depends on
> the outer radius and center line.
> >
> > I generate the raw teeth using the groove and ridge angles and spherical
> coordinates to make two 2d tooth profiles. Then I complete a tooth using
> skin(). A for loop generates the full set of N teeth. Then intersection or
> difference is used the trim the teeth at the inner and outer radii. I
> discovered something at that point, but solved it pretty simply. When
> diffing a cylinder from the N teeth, each tooth took up a small portion of
> the cylinder being diffed out. I had to raise the $fn on the cylinder or
> tube being used so that I got enough points in each tooth that diff or
> intersection was accurate. I kept raising it until the results stopped
> improving. I ended up with the 16*360 you see in the code.
> >
> > After I have the raw teeth, I generate a cone that is diffed away to
> produce the chamfer at the top of the teeth. Then I add in the base. The
> base also adds the “chamfer” at the bottom of the groove. It’s half the
> size of the top chamfer to leave a little gap when the parts are joined.
> >
> > When I comment out the everything but the raw teeth and import the STL
> into PrusaSlicer, it reports errors fixed, but appears to slice correctly
> when supports are added.
> >
> > When I add the intersection to trim the raw teeth, the number of
> reported errors goes way up.
> >
> > When I add the diff to remove the chamfer, the number goes way up again.
> >
> > When I add in the base, the number goes up again and it starts reporting
> many open edges.
> >
> > Throughout, OpenSCAD reports no errors. Using $fn at 16*360, manifold
> renders in 4+ seconds. At 32*360, it’s 53+ seconds. I did check CSG and it
> did not help.
> >
> > Maybe the biggest hint is that the convex part uses almost identical
> code, but produces no errors. Very weird.
> >
> > So, is this an OpenSCAD problem? Or something in my code?
> >
> > It’s also possible that my math is off somewhere. My formal trig
> training was 60 years ago. However I doubt a math error is responsible for
> the slicing problem and STL errors.
> >
> > -Bob
> >
> >
> > include <BOSL2/std.scad>
> > include <BOSL2/structs.scad>
> >
> > // Number of Teeth
> > _n = 36; // Number Of Teeth
> >
> > // Inner Radius
> > _ir = 30;
> > // Outer Radius
> > _or = 50;
> > // Is the coupling conical?
> > _conic = 10;
> > // Tooth Profile Angle
> > _profile = 60; // [60, 90]
> > // Percentage of tooth height
> > _chamfer = 5; // Default 5%
> > _base = 1;
> >
> > $fn = 180;
> > tiny = 1 / 1024;
> >
> > hirth_concave();
> >
> > _irRatio = _ir / _or;
> > _toothAngle = 360/_n;
> > _toothHeight = (sin(_toothAngle/2) * _or) / tan(_profile/2);
> > _chamferHeight = _chamfer * _toothHeight / 100;
> > _grooveAngle = atan(((_toothHeight/2) + _conic) / _or);
> > _ridgeAngle = -atan(((_toothHeight/2) - _conic) / _or);
> > _innerCenterLine = (1 - _irRatio) * _conic;
> > _stackHeight = _innerCenterLine + _toothHeight + 2*_base;
> > _tubeHeight = 2*_conic + 2*_base + 2*_toothHeight;
> >
> > module hirth_concave() {
> > zrot(_toothAngle/2)
> > union() {
> > difference() {
> > intersection() {
> > union() {
> > for (i = [0 : 360/_n : 359])
> > zrot(i)
> > _profileF();
> > }
> > tube(ir = _ir, or = _or, anchor = CENTER, l =
> _tubeHeight, orient = UP, $fn = 16*360);
> > }
> > _chamferF();
> > zcyl(r = _ir, h = _tubeHeight, $fn = 16*360, anchor =
> CENTER);
> > }
> > _baseF();
> > }
> > } // hirth_concave
> >
> > module _profileF() {
> > IR = _ir * .5;
> > OR = _or * 1.5;
> > tI = [spherical_to_xyz(IR, 0, _grooveAngle + 90),
> > spherical_to_xyz(IR, _toothAngle/2, _ridgeAngle + 90),
> > spherical_to_xyz(IR, -_toothAngle/2, _ridgeAngle + 90)];
> >
> > tO = [spherical_to_xyz(OR, 0, _grooveAngle + 90),
> > spherical_to_xyz(OR, _toothAngle/2, _ridgeAngle + 90),
> > spherical_to_xyz(OR, -_toothAngle/2, _ridgeAngle + 90)];
> > up(_conic)
> > skin([tI, tO], slices = 0);
> > }
> >
> >
> > module _chamferF() {
> > A = -_toothHeight/2 - .1;
> > B = -_toothHeight/2 + _chamferHeight;
> >
> > pts = [[0, _conic],
> > [_or+tiny, A],
> > [_or+tiny, B]];
> >
> > rotate_extrude(angle = 360, $fn = 16*360)
> > polygon(pts);
> > }
> >
> > module _baseF() {
> > A = _base + _irRatio*_toothHeight/2 + _innerCenterLine;
> > B = _irRatio * (_toothHeight/2 - _chamferHeight/2) +
> _innerCenterLine;
> > C = _toothHeight/2 - _chamferHeight/2;
> > pts = [
> > [_ir, A],
> > [_ir, B],
> > [_or, C],
> > [_or, A]
> > ];
> >
> > rotate_extrude(angle = 360, $fn = 360*16)
> > polygon(pts);
> > }
> > _______________________________________________
> > OpenSCAD mailing list
> > To unsubscribe send an email to discuss-leave@lists.openscad.org
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>