discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

hirth joint

AM
Adrian Mariano
Mon, Nov 4, 2024 2:07 AM

Since a new thread was requested, I'm starting a new thread.  I completed
an implementation based on the principles I previously described of tilting
the triangle.  One thing that I didn't make clear is that even though the
errors are small at high tooth counts, those errors can make the polyhedron
invalid.  Part of the intention of my approach was to construct the hirth
joint as a single polyhedron.  If you're willing to accept that a 30 tooth
joint is a 60 sided polyhedron then you don't need the extra complications
of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the tilt of
the triangle causes a rounding profile to stick out and create a funny
ridge along the valley.  Perhaps the approach can be adapted to use
projection instead of tilt?

Here's a 16 tooth example:

[image: image.png]
Here's 8 teeth:
[image: image.png]

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case where
you crop the part with a cylinder.  Code attached.

Since a new thread was requested, I'm starting a new thread. I completed an implementation based on the principles I previously described of tilting the triangle. One thing that I didn't make clear is that even though the errors are small at high tooth counts, those errors can make the polyhedron invalid. Part of the intention of my approach was to construct the hirth joint as a single polyhedron. If you're willing to accept that a 30 tooth joint is a 60 sided polyhedron then you don't need the extra complications of intersecting with a tube. I thought it would be a simple matter to round the valleys, but I was wrong. I can round the tooth tips, but not the valleys because the tilt of the triangle causes a rounding profile to stick out and create a funny ridge along the valley. Perhaps the approach can be adapted to use projection instead of tilt? Here's a 16 tooth example: [image: image.png] Here's 8 teeth: [image: image.png] Code is attached. A significant amount of complication arose from calculating the location of the bottoms of the valleys in the case where you crop the part with a cylinder. Code attached.
SP
Sanjeev Prabhakar
Mon, Nov 4, 2024 2:40 AM

I have posted my explanation here:
https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf

because the file size became 1.5 mb

On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

Since a new thread was requested, I'm starting a new thread.  I completed
an implementation based on the principles I previously described of tilting
the triangle.  One thing that I didn't make clear is that even though the
errors are small at high tooth counts, those errors can make the polyhedron
invalid.  Part of the intention of my approach was to construct the hirth
joint as a single polyhedron.  If you're willing to accept that a 30 tooth
joint is a 60 sided polyhedron then you don't need the extra complications
of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the tilt of
the triangle causes a rounding profile to stick out and create a funny
ridge along the valley.  Perhaps the approach can be adapted to use
projection instead of tilt?

Here's a 16 tooth example:

[image: image.png]
Here's 8 teeth:
[image: image.png]

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case where
you crop the part with a cylinder.  Code attached.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I have posted my explanation here: https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf because the file size became 1.5 mb On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss < discuss@lists.openscad.org> wrote: > Since a new thread was requested, I'm starting a new thread. I completed > an implementation based on the principles I previously described of tilting > the triangle. One thing that I didn't make clear is that even though the > errors are small at high tooth counts, those errors can make the polyhedron > invalid. Part of the intention of my approach was to construct the hirth > joint as a single polyhedron. If you're willing to accept that a 30 tooth > joint is a 60 sided polyhedron then you don't need the extra complications > of intersecting with a tube. > > I thought it would be a simple matter to round the valleys, but I was > wrong. I can round the tooth tips, but not the valleys because the tilt of > the triangle causes a rounding profile to stick out and create a funny > ridge along the valley. Perhaps the approach can be adapted to use > projection instead of tilt? > > Here's a 16 tooth example: > > [image: image.png] > Here's 8 teeth: > [image: image.png] > > > Code is attached. A significant amount of complication arose from > calculating the location of the bottoms of the valleys in the case where > you crop the part with a cylinder. Code attached. > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Mon, Nov 4, 2024 2:47 AM

And the YouTube video is here in case anyone is interested :
https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7

On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, sprabhakar2006@gmail.com
wrote:

I have posted my explanation here:

https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf

because the file size became 1.5 mb

On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

Since a new thread was requested, I'm starting a new thread.  I completed
an implementation based on the principles I previously described of tilting
the triangle.  One thing that I didn't make clear is that even though the
errors are small at high tooth counts, those errors can make the polyhedron
invalid.  Part of the intention of my approach was to construct the hirth
joint as a single polyhedron.  If you're willing to accept that a 30 tooth
joint is a 60 sided polyhedron then you don't need the extra complications
of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the tilt of
the triangle causes a rounding profile to stick out and create a funny
ridge along the valley.  Perhaps the approach can be adapted to use
projection instead of tilt?

Here's a 16 tooth example:

[image: image.png]
Here's 8 teeth:
[image: image.png]

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case where
you crop the part with a cylinder.  Code attached.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

And the YouTube video is here in case anyone is interested : https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7 On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, <sprabhakar2006@gmail.com> wrote: > I have posted my explanation here: > > https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf > > because the file size became 1.5 mb > > On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss < > discuss@lists.openscad.org> wrote: > >> Since a new thread was requested, I'm starting a new thread. I completed >> an implementation based on the principles I previously described of tilting >> the triangle. One thing that I didn't make clear is that even though the >> errors are small at high tooth counts, those errors can make the polyhedron >> invalid. Part of the intention of my approach was to construct the hirth >> joint as a single polyhedron. If you're willing to accept that a 30 tooth >> joint is a 60 sided polyhedron then you don't need the extra complications >> of intersecting with a tube. >> >> I thought it would be a simple matter to round the valleys, but I was >> wrong. I can round the tooth tips, but not the valleys because the tilt of >> the triangle causes a rounding profile to stick out and create a funny >> ridge along the valley. Perhaps the approach can be adapted to use >> projection instead of tilt? >> >> Here's a 16 tooth example: >> >> [image: image.png] >> Here's 8 teeth: >> [image: image.png] >> >> >> Code is attached. A significant amount of complication arose from >> calculating the location of the bottoms of the valleys in the case where >> you crop the part with a cylinder. Code attached. >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >
NH
nop head
Mon, Nov 4, 2024 9:48 AM

A lot of discussion but it doesn't look like a useful coupling to me as it
will always try to force itself apart. Wouldn't straight sided teeth with a
chamfer to aid initial engagement be better.

On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss <
discuss@lists.openscad.org> wrote:

And the YouTube video is here in case anyone is interested :
https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7

On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, sprabhakar2006@gmail.com
wrote:

I have posted my explanation here:

https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf

because the file size became 1.5 mb

On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

Since a new thread was requested, I'm starting a new thread.  I
completed an implementation based on the principles I previously described
of tilting the triangle.  One thing that I didn't make clear is that even
though the errors are small at high tooth counts, those errors can make the
polyhedron invalid.  Part of the intention of my approach was to construct
the hirth joint as a single polyhedron.  If you're willing to accept that a
30 tooth joint is a 60 sided polyhedron then you don't need the extra
complications of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the tilt of
the triangle causes a rounding profile to stick out and create a funny
ridge along the valley.  Perhaps the approach can be adapted to use
projection instead of tilt?

Here's a 16 tooth example:

[image: image.png]
Here's 8 teeth:
[image: image.png]

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case where
you crop the part with a cylinder.  Code attached.


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

A lot of discussion but it doesn't look like a useful coupling to me as it will always try to force itself apart. Wouldn't straight sided teeth with a chamfer to aid initial engagement be better. On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss < discuss@lists.openscad.org> wrote: > And the YouTube video is here in case anyone is interested : > https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7 > > On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, <sprabhakar2006@gmail.com> > wrote: > >> I have posted my explanation here: >> >> https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf >> >> because the file size became 1.5 mb >> >> On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> Since a new thread was requested, I'm starting a new thread. I >>> completed an implementation based on the principles I previously described >>> of tilting the triangle. One thing that I didn't make clear is that even >>> though the errors are small at high tooth counts, those errors can make the >>> polyhedron invalid. Part of the intention of my approach was to construct >>> the hirth joint as a single polyhedron. If you're willing to accept that a >>> 30 tooth joint is a 60 sided polyhedron then you don't need the extra >>> complications of intersecting with a tube. >>> >>> I thought it would be a simple matter to round the valleys, but I was >>> wrong. I can round the tooth tips, but not the valleys because the tilt of >>> the triangle causes a rounding profile to stick out and create a funny >>> ridge along the valley. Perhaps the approach can be adapted to use >>> projection instead of tilt? >>> >>> Here's a 16 tooth example: >>> >>> [image: image.png] >>> Here's 8 teeth: >>> [image: image.png] >>> >>> >>> Code is attached. A significant amount of complication arose from >>> calculating the location of the bottoms of the valleys in the case where >>> you crop the part with a cylinder. Code attached. >>> >>> _______________________________________________ >>> 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 >
AM
Adrian Mariano
Mon, Nov 4, 2024 1:23 PM

I think the point is that it wedges together with good alignment and no
slop. Square teeth would need a clearance gap and then there would be
backlash.

On Mon, Nov 4, 2024 at 04:49 nop head via Discuss <
discuss@lists.openscad.org> wrote:

A lot of discussion but it doesn't look like a useful coupling to me as it
will always try to force itself apart. Wouldn't straight sided teeth with a
chamfer to aid initial engagement be better.

On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss <
discuss@lists.openscad.org> wrote:

And the YouTube video is here in case anyone is interested :
https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7

On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, sprabhakar2006@gmail.com
wrote:

I have posted my explanation here:

https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf

because the file size became 1.5 mb

On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

Since a new thread was requested, I'm starting a new thread.  I
completed an implementation based on the principles I previously described
of tilting the triangle.  One thing that I didn't make clear is that even
though the errors are small at high tooth counts, those errors can make the
polyhedron invalid.  Part of the intention of my approach was to construct
the hirth joint as a single polyhedron.  If you're willing to accept that a
30 tooth joint is a 60 sided polyhedron then you don't need the extra
complications of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the tilt of
the triangle causes a rounding profile to stick out and create a funny
ridge along the valley.  Perhaps the approach can be adapted to use
projection instead of tilt?

Here's a 16 tooth example:

[image: image.png]
Here's 8 teeth:
[image: image.png]

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case where
you crop the part with a cylinder.  Code attached.


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


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I think the point is that it wedges together with good alignment and no slop. Square teeth would need a clearance gap and then there would be backlash. On Mon, Nov 4, 2024 at 04:49 nop head via Discuss < discuss@lists.openscad.org> wrote: > A lot of discussion but it doesn't look like a useful coupling to me as it > will always try to force itself apart. Wouldn't straight sided teeth with a > chamfer to aid initial engagement be better. > > On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss < > discuss@lists.openscad.org> wrote: > >> And the YouTube video is here in case anyone is interested : >> https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7 >> >> On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, <sprabhakar2006@gmail.com> >> wrote: >> >>> I have posted my explanation here: >>> >>> https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf >>> >>> because the file size became 1.5 mb >>> >>> On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>>> Since a new thread was requested, I'm starting a new thread. I >>>> completed an implementation based on the principles I previously described >>>> of tilting the triangle. One thing that I didn't make clear is that even >>>> though the errors are small at high tooth counts, those errors can make the >>>> polyhedron invalid. Part of the intention of my approach was to construct >>>> the hirth joint as a single polyhedron. If you're willing to accept that a >>>> 30 tooth joint is a 60 sided polyhedron then you don't need the extra >>>> complications of intersecting with a tube. >>>> >>>> I thought it would be a simple matter to round the valleys, but I was >>>> wrong. I can round the tooth tips, but not the valleys because the tilt of >>>> the triangle causes a rounding profile to stick out and create a funny >>>> ridge along the valley. Perhaps the approach can be adapted to use >>>> projection instead of tilt? >>>> >>>> Here's a 16 tooth example: >>>> >>>> [image: image.png] >>>> Here's 8 teeth: >>>> [image: image.png] >>>> >>>> >>>> Code is attached. A significant amount of complication arose from >>>> calculating the location of the bottoms of the valleys in the case where >>>> you crop the part with a cylinder. Code attached. >>>> >>>> _______________________________________________ >>>> 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 >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JD
John David
Mon, Nov 4, 2024 4:15 PM

@nop head nop.head@gmail.com
, these type of joints are typically loaded, so they cannot just pop off.

Another take on the theme, if someone develops a profile they like on one
side, they should be able to use a geometrical diff operation to form the
mating surface without slop. That said, the profile has to be symmetric to
accommodate the adjustment.

Hope this helps.

On Mon, Nov 4, 2024 at 8:24 AM Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

I think the point is that it wedges together with good alignment and no
slop. Square teeth would need a clearance gap and then there would be
backlash.

On Mon, Nov 4, 2024 at 04:49 nop head via Discuss <
discuss@lists.openscad.org> wrote:

A lot of discussion but it doesn't look like a useful coupling to me as
it will always try to force itself apart. Wouldn't straight sided teeth
with a chamfer to aid initial engagement be better.

On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss <
discuss@lists.openscad.org> wrote:

And the YouTube video is here in case anyone is interested :
https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7

On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, sprabhakar2006@gmail.com
wrote:

I have posted my explanation here:

https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf

because the file size became 1.5 mb

On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

Since a new thread was requested, I'm starting a new thread.  I
completed an implementation based on the principles I previously described
of tilting the triangle.  One thing that I didn't make clear is that even
though the errors are small at high tooth counts, those errors can make the
polyhedron invalid.  Part of the intention of my approach was to construct
the hirth joint as a single polyhedron.  If you're willing to accept that a
30 tooth joint is a 60 sided polyhedron then you don't need the extra
complications of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the tilt of
the triangle causes a rounding profile to stick out and create a funny
ridge along the valley.  Perhaps the approach can be adapted to use
projection instead of tilt?

Here's a 16 tooth example:

[image: image.png]
Here's 8 teeth:
[image: image.png]

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case where
you crop the part with a cylinder.  Code attached.


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


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

@nop head <nop.head@gmail.com> , these type of joints are typically loaded, so they cannot just pop off. Another take on the theme, if someone develops a profile they like on one side, they should be able to use a geometrical diff operation to form the mating surface without slop. That said, the profile has to be symmetric to accommodate the adjustment. Hope this helps. On Mon, Nov 4, 2024 at 8:24 AM Adrian Mariano via Discuss < discuss@lists.openscad.org> wrote: > I think the point is that it wedges together with good alignment and no > slop. Square teeth would need a clearance gap and then there would be > backlash. > > On Mon, Nov 4, 2024 at 04:49 nop head via Discuss < > discuss@lists.openscad.org> wrote: > >> A lot of discussion but it doesn't look like a useful coupling to me as >> it will always try to force itself apart. Wouldn't straight sided teeth >> with a chamfer to aid initial engagement be better. >> >> On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> And the YouTube video is here in case anyone is interested : >>> https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7 >>> >>> On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, <sprabhakar2006@gmail.com> >>> wrote: >>> >>>> I have posted my explanation here: >>>> >>>> https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf >>>> >>>> because the file size became 1.5 mb >>>> >>>> On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss < >>>> discuss@lists.openscad.org> wrote: >>>> >>>>> Since a new thread was requested, I'm starting a new thread. I >>>>> completed an implementation based on the principles I previously described >>>>> of tilting the triangle. One thing that I didn't make clear is that even >>>>> though the errors are small at high tooth counts, those errors can make the >>>>> polyhedron invalid. Part of the intention of my approach was to construct >>>>> the hirth joint as a single polyhedron. If you're willing to accept that a >>>>> 30 tooth joint is a 60 sided polyhedron then you don't need the extra >>>>> complications of intersecting with a tube. >>>>> >>>>> I thought it would be a simple matter to round the valleys, but I was >>>>> wrong. I can round the tooth tips, but not the valleys because the tilt of >>>>> the triangle causes a rounding profile to stick out and create a funny >>>>> ridge along the valley. Perhaps the approach can be adapted to use >>>>> projection instead of tilt? >>>>> >>>>> Here's a 16 tooth example: >>>>> >>>>> [image: image.png] >>>>> Here's 8 teeth: >>>>> [image: image.png] >>>>> >>>>> >>>>> Code is attached. A significant amount of complication arose from >>>>> calculating the location of the bottoms of the valleys in the case where >>>>> you crop the part with a cylinder. Code attached. >>>>> >>>>> _______________________________________________ >>>>> 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 >>> >> _______________________________________________ >> 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
Mon, Nov 4, 2024 4:41 PM

Hi Adrian,

the rounding of the valleys is a manufacturing requirement, (couldn't
get long lasting grinding disks with sharp corners) the flat tops to the
crests, is so they don't bottom out.

The initial code I submitted worked fine with the parameters I gave, but
no others.

My second, version, which I used to generate the images, worked fine as
parametric, but I have not been on line for a day or so, and I am
reconstructing that code, having not saved it, and it seems file history
is not working.

If you can generate bevel gears, then you should be able to make Curvic
couplings.

On 04/11/2024 02:07, Adrian Mariano via Discuss wrote:

Since a new thread was requested, I'm starting a new thread.  I
completed an implementation based on the principles I previously
described of tilting the triangle.  One thing that I didn't make clear
is that even though the errors are small at high tooth counts, those
errors can make the polyhedron invalid.  Part of the intention of my
approach was to construct the hirth joint as a single polyhedron.  If
you're willing to accept that a 30 tooth joint is a 60 sided
polyhedron then you don't need the extra complications of intersecting
with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the
tilt of the triangle causes a rounding profile to stick out and create
a funny ridge along the valley.  Perhaps the approach can be adapted
to use projection instead of tilt?

Here's a 16 tooth example:

image.png
Here's 8 teeth:
image.png

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case
where you crop the part with a cylinder. Code attached.


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

Hi Adrian, the rounding of the valleys is a manufacturing requirement, (couldn't get long lasting grinding disks with sharp corners) the flat tops to the crests, is so they don't bottom out. The initial code I submitted worked fine with the parameters I gave, but no others. My second, version, which I used to generate the images, worked fine as parametric, but I have not been on line for a day or so, and I am reconstructing that code, having not saved it, and it seems file history is not working. If you can generate bevel gears, then you should be able to make Curvic couplings. On 04/11/2024 02:07, Adrian Mariano via Discuss wrote: > Since a new thread was requested, I'm starting a new thread.  I > completed an implementation based on the principles I previously > described of tilting the triangle.  One thing that I didn't make clear > is that even though the errors are small at high tooth counts, those > errors can make the polyhedron invalid.  Part of the intention of my > approach was to construct the hirth joint as a single polyhedron.  If > you're willing to accept that a 30 tooth joint is a 60 sided > polyhedron then you don't need the extra complications of intersecting > with a tube. > > I thought it would be a simple matter to round the valleys, but I was > wrong.  I can round the tooth tips, but not the valleys because the > tilt of the triangle causes a rounding profile to stick out and create > a funny ridge along the valley.  Perhaps the approach can be adapted > to use projection instead of tilt? > > Here's a 16 tooth example: > > image.png > Here's 8 teeth: > image.png > > > Code is attached.  A significant amount of complication arose from > calculating the location of the bottoms of the valleys in the case > where you crop the part with a cylinder. Code attached. > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
JD
John David
Mon, Nov 4, 2024 4:51 PM

@Raymond West raywest@raywest.com, actually, I think the rounded corners
is generally an engineering requirement.  Sharp edges are stress-risers,
causing cracks and breaks.  That said, not having to grinding into a
sharp corner makes things a LOT easier ;-)

On Mon, Nov 4, 2024 at 11:41 AM Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

Hi Adrian,

the rounding of the valleys is a manufacturing requirement, (couldn't get
long lasting grinding disks with sharp corners) the flat tops to the
crests, is so they don't bottom out.

The initial code I submitted worked fine with the parameters I gave, but
no others.

My second, version, which I used to generate the images, worked fine as
parametric, but I have not been on line for a day or so, and I am
reconstructing that code, having not saved it, and it seems file history is
not working.

If you can generate bevel gears, then you should be able to make Curvic
couplings.
On 04/11/2024 02:07, Adrian Mariano via Discuss wrote:

Since a new thread was requested, I'm starting a new thread.  I completed
an implementation based on the principles I previously described of tilting
the triangle.  One thing that I didn't make clear is that even though the
errors are small at high tooth counts, those errors can make the polyhedron
invalid.  Part of the intention of my approach was to construct the hirth
joint as a single polyhedron.  If you're willing to accept that a 30 tooth
joint is a 60 sided polyhedron then you don't need the extra complications
of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the tilt of
the triangle causes a rounding profile to stick out and create a funny
ridge along the valley.  Perhaps the approach can be adapted to use
projection instead of tilt?

Here's a 16 tooth example:

[image: image.png]
Here's 8 teeth:
[image: image.png]

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case where
you crop the part with a cylinder.  Code attached.


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

@Raymond West <raywest@raywest.com>, actually, I think the rounded corners is generally an engineering requirement. Sharp edges are stress-risers, causing cracks and breaks. That said, *not* having to grinding into a sharp corner makes things a LOT easier ;-) On Mon, Nov 4, 2024 at 11:41 AM Raymond West via Discuss < discuss@lists.openscad.org> wrote: > Hi Adrian, > > the rounding of the valleys is a manufacturing requirement, (couldn't get > long lasting grinding disks with sharp corners) the flat tops to the > crests, is so they don't bottom out. > > The initial code I submitted worked fine with the parameters I gave, but > no others. > > My second, version, which I used to generate the images, worked fine as > parametric, but I have not been on line for a day or so, and I am > reconstructing that code, having not saved it, and it seems file history is > not working. > > If you can generate bevel gears, then you should be able to make Curvic > couplings. > On 04/11/2024 02:07, Adrian Mariano via Discuss wrote: > > Since a new thread was requested, I'm starting a new thread. I completed > an implementation based on the principles I previously described of tilting > the triangle. One thing that I didn't make clear is that even though the > errors are small at high tooth counts, those errors can make the polyhedron > invalid. Part of the intention of my approach was to construct the hirth > joint as a single polyhedron. If you're willing to accept that a 30 tooth > joint is a 60 sided polyhedron then you don't need the extra complications > of intersecting with a tube. > > I thought it would be a simple matter to round the valleys, but I was > wrong. I can round the tooth tips, but not the valleys because the tilt of > the triangle causes a rounding profile to stick out and create a funny > ridge along the valley. Perhaps the approach can be adapted to use > projection instead of tilt? > > Here's a 16 tooth example: > > [image: image.png] > Here's 8 teeth: > [image: image.png] > > > Code is attached. A significant amount of complication arose from > calculating the location of the bottoms of the valleys in the case where > you crop the part with a cylinder. Code attached. > > > _______________________________________________ > 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
Mon, Nov 4, 2024 5:05 PM

found it-

// clutch.scad

ind = 50;  // overall diameter
num = 46;  // number of teeth
back = 5; //thickness of back
bore = 8.3; // diameter of hole
recess = 30;// diameter of recess in centre
////////////////////////////////////////////

diam  = ind/cos (180/num);
chord = diam*sin(180/num);

ridge= chord sqrt(3)/4;  // or set to whatever
// Basic parameters
radius = diam / 2;
angle_per_tooth = 360 / num;
yp =radius * tan(angle_per_tooth / 2);
rp = sqrt((yp
yp)+(radius*radius)); //radius to point

points = [
    [0, 0, ridge / 2],    // Center
    [radius, -yp, 0],     // Left base
    [radius, yp, 0],      // Right base
    [radius , 0, ridge]   // Peak of the ridge
];

 faces=[
 [0,1,2],
 [0,1,3],
 [0,2,3],
 [1,2,3]
 ];

 module wedge(){
   polyhedron(points,faces,convexity=10);
 }

 //rotate wedge
 module clutch(){

 difference(){
 intersection(){
     translate([0,0,-back])
       cylinder(d=ind,h=200,$fn=100);
        union(){
             for (j=[0:1:num-1])
              rotate([0,0,j360/num]) wedge();
                      rotate([0,0,180/num])
                    cylinder(r1=rp,r2=0,h=ridge/2,$fn=num);
                    translate([0,0,-back])
                     cylinder(d=diam,h=back,$fn=num);
     }
 }
   cylinder(d=recess,h=ridge
3);
   translate([0,0,-back-ridge])
   cylinder (d=bore,h=(back+ridge)*3);

 }
 }
 $fn=100;
 clutch();

 /*
 translate([50,0,0])
// rotate([0,180,360/(num*2)])
 import("P:/Docs/openscad/clutch.stl");

cube(ind,true);

 */

On 04/11/2024 16:41, Raymond West via Discuss wrote:

Hi Adrian,

the rounding of the valleys is a manufacturing requirement, (couldn't
get long lasting grinding disks with sharp corners) the flat tops to
the crests, is so they don't bottom out.

The initial code I submitted worked fine with the parameters I gave,
but no others.

My second, version, which I used to generate the images, worked fine
as parametric, but I have not been on line for a day or so, and I am
reconstructing that code, having not saved it, and it seems file
history is not working.

If you can generate bevel gears, then you should be able to make
Curvic couplings.

On 04/11/2024 02:07, Adrian Mariano via Discuss wrote:

Since a new thread was requested, I'm starting a new thread.  I
completed an implementation based on the principles I previously
described of tilting the triangle. One thing that I didn't make clear
is that even though the errors are small at high tooth counts, those
errors can make the polyhedron invalid.  Part of the intention of my
approach was to construct the hirth joint as a single polyhedron.  If
you're willing to accept that a 30 tooth joint is a 60 sided
polyhedron then you don't need the extra complications of
intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was
wrong.  I can round the tooth tips, but not the valleys because the
tilt of the triangle causes a rounding profile to stick out and
create a funny ridge along the valley.  Perhaps the approach can be
adapted to use projection instead of tilt?

Here's a 16 tooth example:

image.png
Here's 8 teeth:
image.png

Code is attached.  A significant amount of complication arose from
calculating the location of the bottoms of the valleys in the case
where you crop the part with a cylinder.   Code attached.


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

found it- // clutch.scad ind = 50;  // overall diameter num = 46;  // number of teeth back = 5; //thickness of back bore = 8.3; // diameter of hole recess = 30;// diameter of recess in centre //////////////////////////////////////////// diam  = ind/cos (180/num); chord = diam*sin(180/num); ridge= chord *sqrt(3)/4;  // or set to whatever // Basic parameters radius = diam / 2; angle_per_tooth = 360 / num; yp =radius * tan(angle_per_tooth / 2); rp = sqrt((yp*yp)+(radius*radius)); //radius to point points = [     [0, 0, ridge / 2],    // Center     [radius, -yp, 0],     // Left base     [radius, yp, 0],      // Right base     [radius , 0, ridge]   // Peak of the ridge ];  faces=[  [0,1,2],  [0,1,3],  [0,2,3],  [1,2,3]  ];  module wedge(){    polyhedron(points,faces,convexity=10);  }  //rotate wedge  module clutch(){  difference(){  intersection(){      translate([0,0,-back])        cylinder(d=ind,h=200,$fn=100);         union(){              for (j=[0:1:num-1])               rotate([0,0,j*360/num]) wedge();                       rotate([0,0,180/num])                     cylinder(r1=rp,r2=0,h=ridge/2,$fn=num);                     translate([0,0,-back])                      cylinder(d=diam,h=back,$fn=num);      }  }    cylinder(d=recess,h=ridge*3);    translate([0,0,-back-ridge])    cylinder (d=bore,h=(back+ridge)*3);  }  }  $fn=100;  clutch();  /*  translate([50,0,0]) // rotate([0,180,360/(num*2)])  import("P:/Docs/openscad/clutch.stl"); # cube(ind,true);  */ On 04/11/2024 16:41, Raymond West via Discuss wrote: > > Hi Adrian, > > the rounding of the valleys is a manufacturing requirement, (couldn't > get long lasting grinding disks with sharp corners) the flat tops to > the crests, is so they don't bottom out. > > The initial code I submitted worked fine with the parameters I gave, > but no others. > > My second, version, which I used to generate the images, worked fine > as parametric, but I have not been on line for a day or so, and I am > reconstructing that code, having not saved it, and it seems file > history is not working. > > If you can generate bevel gears, then you should be able to make > Curvic couplings. > > On 04/11/2024 02:07, Adrian Mariano via Discuss wrote: >> Since a new thread was requested, I'm starting a new thread.  I >> completed an implementation based on the principles I previously >> described of tilting the triangle. One thing that I didn't make clear >> is that even though the errors are small at high tooth counts, those >> errors can make the polyhedron invalid.  Part of the intention of my >> approach was to construct the hirth joint as a single polyhedron.  If >> you're willing to accept that a 30 tooth joint is a 60 sided >> polyhedron then you don't need the extra complications of >> intersecting with a tube. >> >> I thought it would be a simple matter to round the valleys, but I was >> wrong.  I can round the tooth tips, but not the valleys because the >> tilt of the triangle causes a rounding profile to stick out and >> create a funny ridge along the valley.  Perhaps the approach can be >> adapted to use projection instead of tilt? >> >> Here's a 16 tooth example: >> >> image.png >> Here's 8 teeth: >> image.png >> >> >> Code is attached.  A significant amount of complication arose from >> calculating the location of the bottoms of the valleys in the case >> where you crop the part with a cylinder.   Code attached. >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
RW
Raymond West
Mon, Nov 4, 2024 5:33 PM

You have a steeper angle, and higher tension on the centre fixing to
improve grip, I guess. The idea of the tapered sides is for ease of
manufacturing. To get vertical sides, then it would involve more passes
of the grinding wheel/mill. With a 'V' shape, you get more strength at
the root, compared to square, (acme thread is stronger than square, plus
can use a split nut - not relevant in this case).

On 04/11/2024 09:48, nop head via Discuss wrote:

A lot of discussion but it doesn't look like a useful coupling to me
as it will always try to force itself apart. Wouldn't straight sided
teeth with a chamfer to aid initial engagement be better.

On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss
discuss@lists.openscad.org wrote:

 And the YouTube video is here in case anyone is interested :
 https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7

 On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar,
 <sprabhakar2006@gmail.com> wrote:

     I have posted my explanation here:
     https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf

     because the file size became 1.5 mb

     On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss
     <discuss@lists.openscad.org> wrote:

         Since a new thread was requested, I'm starting a new
         thread.  I completed an implementation based on the
         principles I previously described of tilting the
         triangle.  One thing that I didn't make clear is that even
         though the errors are small at high tooth counts, those
         errors can make the polyhedron invalid.  Part of the
         intention of my approach was to construct the hirth joint
         as a single polyhedron.  If you're willing to accept that
         a 30 tooth joint is a 60 sided polyhedron then you don't
         need the extra complications of intersecting with a tube.

         I thought it would be a simple matter to round the
         valleys, but I was wrong.  I can round the tooth tips, but
         not the valleys because the tilt of the triangle causes a
         rounding profile to stick out and create a funny ridge
         along the valley. Perhaps the approach can be adapted to
         use projection instead of tilt?

         Here's a 16 tooth example:

         image.png
         Here's 8 teeth:
         image.png


         Code is attached.  A significant amount of complication
         arose from calculating the location of the bottoms of the
         valleys in the case where you crop the part with a
         cylinder.   Code attached.

         _______________________________________________
         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

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

You have a steeper angle, and higher tension on the centre fixing to improve grip, I guess. The idea of the tapered sides is for ease of manufacturing. To get vertical sides, then it would involve more passes of the grinding wheel/mill. With a 'V' shape, you get more strength at the root, compared to square, (acme thread is stronger than square, plus can use a split nut - not relevant in this case). On 04/11/2024 09:48, nop head via Discuss wrote: > A lot of discussion but it doesn't look like a useful coupling to me > as it will always try to force itself apart. Wouldn't straight sided > teeth with a chamfer to aid initial engagement be better. > > On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss > <discuss@lists.openscad.org> wrote: > > And the YouTube video is here in case anyone is interested : > https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7 > > On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, > <sprabhakar2006@gmail.com> wrote: > > I have posted my explanation here: > https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf > > because the file size became 1.5 mb > > On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss > <discuss@lists.openscad.org> wrote: > > Since a new thread was requested, I'm starting a new > thread.  I completed an implementation based on the > principles I previously described of tilting the > triangle.  One thing that I didn't make clear is that even > though the errors are small at high tooth counts, those > errors can make the polyhedron invalid.  Part of the > intention of my approach was to construct the hirth joint > as a single polyhedron.  If you're willing to accept that > a 30 tooth joint is a 60 sided polyhedron then you don't > need the extra complications of intersecting with a tube. > > I thought it would be a simple matter to round the > valleys, but I was wrong.  I can round the tooth tips, but > not the valleys because the tilt of the triangle causes a > rounding profile to stick out and create a funny ridge > along the valley. Perhaps the approach can be adapted to > use projection instead of tilt? > > Here's a 16 tooth example: > > image.png > Here's 8 teeth: > image.png > > > Code is attached.  A significant amount of complication > arose from calculating the location of the bottoms of the > valleys in the case where you crop the part with a > cylinder.   Code attached. > > _______________________________________________ > 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 > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
BC
Bob Carlson
Tue, Nov 5, 2024 5:29 PM

I had been using spherical coordinates and that made it very easy to construct the part using only the 3 angles, groove angle, ridge angle and tooth angle (radial between teeth). Since I have been specifying the chamfer as a percentage of the tooth height, I realized that finding the angles for the chamfers was easy too since everything is proportional including the angles.

The final realization I had though is that normal spherical coordinates did not produce quite the right result as the radii I know are the inner and outer ones. These lie on a cylinder not a sphere. I looked into cylinder_to_xyz in BOSL2 and found that it uses (r, theta, z), spherical uses (r, theta, phi). I needed something else. I created sperical2_to_xyz(r, theta, phi). This is the same as spherical but r is the radius in the XY plane, not in XYZ. It was quite easy to alter the spherical_to_xyz code to get what I wanted.

Here is just a code fragment but it gets the point across.

IR = _ir(hs);
OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the circumscribing polygon of N

// Ridge Chamfer
thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

function profileToooth(r) =
     [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) + phiCA),
      spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
      spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
      spherical2_to_xyz(r, - thetaCA2,         _ridgeAngle(hs) + phiCA)
      ];

It works down to N = 3 and could work for N = 2 if the profile were changed to a half tooth. I used skin at first but that breaks down at low tooth counts. I also found that using the tooth profile to produce the groove chamfer didn’t work very well with skin or hull, so I now do that as part of adding the base. I’ll post more complete code soon as I can.

-Bob

On Nov 4, 2024, at 10:33, Raymond West via Discuss discuss@lists.openscad.org wrote:

You have a steeper angle, and higher tension on the centre fixing to improve grip, I guess. The idea of the tapered sides is for ease of manufacturing. To get vertical sides, then it would involve more passes of the grinding wheel/mill. With a 'V' shape, you get more strength at the root, compared to square, (acme thread is stronger than square, plus can use a split nut - not relevant in this case).

On 04/11/2024 09:48, nop head via Discuss wrote:

A lot of discussion but it doesn't look like a useful coupling to me as it will always try to force itself apart. Wouldn't straight sided teeth with a chamfer to aid initial engagement be better.

On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:

And the YouTube video is here in case anyone is interested :
https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7

On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, <sprabhakar2006@gmail.com mailto:sprabhakar2006@gmail.com> wrote:

I have posted my explanation here:
https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf

because the file size became 1.5 mb

On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:

Since a new thread was requested, I'm starting a new thread.  I completed an implementation based on the principles I previously described of tilting the triangle.  One thing that I didn't make clear is that even though the errors are small at high tooth counts, those errors can make the polyhedron invalid.  Part of the intention of my approach was to construct the hirth joint as a single polyhedron.  If you're willing to accept that a 30 tooth joint is a 60 sided polyhedron then you don't need the extra complications of intersecting with a tube.

I thought it would be a simple matter to round the valleys, but I was wrong.  I can round the tooth tips, but not the valleys because the tilt of the triangle causes a rounding profile to stick out and create a funny ridge along the valley.  Perhaps the approach can be adapted to use projection instead of tilt?

Here's a 16 tooth example:

<image.png>
Here's 8 teeth:
<image.png>

Code is attached.  A significant amount of complication arose from calculating the location of the bottoms of the valleys in the case where you crop the part with a cylinder.  Code attached.


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


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

I had been using spherical coordinates and that made it very easy to construct the part using only the 3 angles, groove angle, ridge angle and tooth angle (radial between teeth). Since I have been specifying the chamfer as a percentage of the tooth height, I realized that finding the angles for the chamfers was easy too since everything is proportional including the angles. The final realization I had though is that normal spherical coordinates did not produce quite the right result as the radii I know are the inner and outer ones. These lie on a cylinder not a sphere. I looked into cylinder_to_xyz in BOSL2 and found that it uses (r, theta, z), spherical uses (r, theta, phi). I needed something else. I created sperical2_to_xyz(r, theta, phi). This is the same as spherical but r is the radius in the XY plane, not in XYZ. It was quite easy to alter the spherical_to_xyz code to get what I wanted. Here is just a code fragment but it gets the point across. IR = _ir(hs); OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the circumscribing polygon of N // Ridge Chamfer thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; function profileToooth(r) = [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + phiCA), spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + phiCA) ]; It works down to N = 3 and could work for N = 2 if the profile were changed to a half tooth. I used skin at first but that breaks down at low tooth counts. I also found that using the tooth profile to produce the groove chamfer didn’t work very well with skin or hull, so I now do that as part of adding the base. I’ll post more complete code soon as I can. -Bob  > On Nov 4, 2024, at 10:33, Raymond West via Discuss <discuss@lists.openscad.org> wrote: > > You have a steeper angle, and higher tension on the centre fixing to improve grip, I guess. The idea of the tapered sides is for ease of manufacturing. To get vertical sides, then it would involve more passes of the grinding wheel/mill. With a 'V' shape, you get more strength at the root, compared to square, (acme thread is stronger than square, plus can use a split nut - not relevant in this case). > > On 04/11/2024 09:48, nop head via Discuss wrote: >> A lot of discussion but it doesn't look like a useful coupling to me as it will always try to force itself apart. Wouldn't straight sided teeth with a chamfer to aid initial engagement be better. >> >> On Mon, 4 Nov 2024 at 02:47, Sanjeev Prabhakar via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote: >>> And the YouTube video is here in case anyone is interested : >>> https://youtu.be/Wp8q71eMqrE?si=fY1AxbXp8itbZRm7 >>> >>> On Mon, 4 Nov 2024, 08:10 Sanjeev Prabhakar, <sprabhakar2006@gmail.com <mailto:sprabhakar2006@gmail.com>> wrote: >>>> I have posted my explanation here: >>>> https://github.com/sprabhakar2006/openSCAD/blob/main/explanation%20of%20approaches/explanation%20hirth%20coupling.pdf >>>> >>>> because the file size became 1.5 mb >>>> >>>> On Mon, 4 Nov 2024 at 07:38, Adrian Mariano via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote: >>>>> Since a new thread was requested, I'm starting a new thread. I completed an implementation based on the principles I previously described of tilting the triangle. One thing that I didn't make clear is that even though the errors are small at high tooth counts, those errors can make the polyhedron invalid. Part of the intention of my approach was to construct the hirth joint as a single polyhedron. If you're willing to accept that a 30 tooth joint is a 60 sided polyhedron then you don't need the extra complications of intersecting with a tube. >>>>> >>>>> I thought it would be a simple matter to round the valleys, but I was wrong. I can round the tooth tips, but not the valleys because the tilt of the triangle causes a rounding profile to stick out and create a funny ridge along the valley. Perhaps the approach can be adapted to use projection instead of tilt? >>>>> >>>>> Here's a 16 tooth example: >>>>> >>>>> <image.png> >>>>> Here's 8 teeth: >>>>> <image.png> >>>>> >>>>> >>>>> Code is attached. A significant amount of complication arose from calculating the location of the bottoms of the valleys in the case where you crop the part with a cylinder. Code attached. >>>>> >>>>> _______________________________________________ >>>>> 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> >> >> >> _______________________________________________ >> 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
RW
Raymond West
Tue, Nov 5, 2024 5:53 PM

I've modified it slightly, to allow the tooth angle to be set - In
manufacturing, most likely a 60 or 90 degree angle. I've also included
the angle to set the rotary table, and added a method of flattening the
tips. I think this could 3d printed OK, I've yet to test. The stl would
not be used in any other manufacturing process, afaik. For machining, It
could be set up directly from the parameters. I've attached the code
below. The flattening of the peaks give a slight taper. Adding an extra
triangle to the polyhedron, could generate a more tapered width to the
flat top, but for whatever use I may put this too, if any, it is
unlikely to make much difference.

The code will produce a viable stl, for any number of teeth, including
three and upwards, and it f6 renders fast enough.

Here is a link to some curvic coupling design, which is a bit more
involved to generate -
https://www.geartechnology.com/articles/20867-curvic-coupling-design.

On 04/11/2024 17:05, Raymond West via Discuss wrote:

found it- etc.

I've modified it slightly, to allow the tooth angle to be set - In manufacturing, most likely a 60 or 90 degree angle. I've also included the angle to set the rotary table, and added a method of flattening the tips. I think this could 3d printed OK, I've yet to test. The stl would not be used in any other manufacturing process, afaik. For machining, It could be set up directly from the parameters. I've attached the code below. The flattening of the peaks give a slight taper. Adding an extra triangle to the polyhedron, could generate a more tapered width to the flat top, but for whatever use I may put this too, if any, it is unlikely to make much difference. The code will produce a viable stl, for any number of teeth, including three and upwards, and it f6 renders fast enough. Here is a link to some curvic coupling design, which is a bit more involved to generate - https://www.geartechnology.com/articles/20867-curvic-coupling-design. On 04/11/2024 17:05, Raymond West via Discuss wrote: > > found it- etc. >
AM
Adrian Mariano
Tue, Nov 5, 2024 10:27 PM

Ray, I tried your code and (1) preview is very very slow on my machine and
(2) render gives

Rendering Polygon Mesh using CGAL...

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

Geometries in cache: 9903

I'm now convinced that Bob has the right basic approach. The key thing is
the idea of projecting onto a cylinder. Working in spherical coordinates
never made sense to me, but for some reason the idea of just projecting
points onto a cylinder didn't occur to me. (At one point I thought about
doing it, but with equations, not with code, which was a bad idea.) With
this insight I can now make roundings while creating the object as a single
polyhedron:

[image: image.png]

On Tue, Nov 5, 2024 at 12:54 PM Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

I've modified it slightly, to allow the tooth angle to be set - In
manufacturing, most likely a 60 or 90 degree angle. I've also included the
angle to set the rotary table, and added a method of flattening the tips. I
think this could 3d printed OK, I've yet to test. The stl would not be used
in any other manufacturing process, afaik. For machining, It could be set
up directly from the parameters. I've attached the code below. The
flattening of the peaks give a slight taper. Adding an extra triangle to
the polyhedron, could generate a more tapered width to the flat top, but
for whatever use I may put this too, if any, it is unlikely to make much
difference.

The code will produce a viable stl, for any number of teeth,  including
three and upwards, and it f6 renders fast enough.

Here is a link to some curvic coupling design, which is a bit more
involved to generate -
https://www.geartechnology.com/articles/20867-curvic-coupling-design.

On 04/11/2024 17:05, Raymond West via Discuss wrote:

found it- etc.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Ray, I tried your code and (1) preview is very very slow on my machine and (2) render gives Rendering Polygon Mesh using CGAL... ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. Geometries in cache: 9903 I'm now convinced that Bob has the right basic approach. The key thing is the idea of projecting onto a cylinder. Working in spherical coordinates never made sense to me, but for some reason the idea of just projecting points onto a cylinder didn't occur to me. (At one point I thought about doing it, but with equations, not with code, which was a bad idea.) With this insight I can now make roundings while creating the object as a single polyhedron: [image: image.png] On Tue, Nov 5, 2024 at 12:54 PM Raymond West via Discuss < discuss@lists.openscad.org> wrote: > I've modified it slightly, to allow the tooth angle to be set - In > manufacturing, most likely a 60 or 90 degree angle. I've also included the > angle to set the rotary table, and added a method of flattening the tips. I > think this could 3d printed OK, I've yet to test. The stl would not be used > in any other manufacturing process, afaik. For machining, It could be set > up directly from the parameters. I've attached the code below. The > flattening of the peaks give a slight taper. Adding an extra triangle to > the polyhedron, could generate a more tapered width to the flat top, but > for whatever use I may put this too, if any, it is unlikely to make much > difference. > > The code will produce a viable stl, for any number of teeth, including > three and upwards, and it f6 renders fast enough. > > Here is a link to some curvic coupling design, which is a bit more > involved to generate - > https://www.geartechnology.com/articles/20867-curvic-coupling-design. > > > On 04/11/2024 17:05, Raymond West via Discuss wrote: > > found it- etc. > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
K
Ken
Tue, Nov 5, 2024 11:32 PM

I tried it on mine- I'm using version 2024.10.2 git e972ed84e.
F5 takes 0.059 seconds, f6 0.096 seconds.
I get-

"WARNING: PolySet -> Manifold conversion failed: NotManifold
Trying to repair and reconstruct mesh.."

four times, then it continues to render with no further errors. I have just finished printing two of them so I can have a play.

On 2024-11-06 09:27, Adrian Mariano via Discuss wrote:

Ray, I tried your code and (1) preview is very very slow on my machine and (2) render gives

Rendering Polygon Mesh using CGAL...

ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron.

Geometries in cache: 9903

I'm now convinced that Bob has the right basic approach. The key thing is the idea of projecting onto a cylinder. Working in spherical coordinates never made sense to me, but for some reason the idea of just projecting points onto a cylinder didn't occur to me. (At one point I thought about doing it, but with equations, not with code, which was a bad idea.) With this insight I can now make roundings while creating the object as a single polyhedron:

image.png

On Tue, Nov 5, 2024 at 12:54 PM Raymond West via Discuss discuss@lists.openscad.org wrote:

 I've modified it slightly, to allow the tooth angle to be set - In manufacturing, most likely a 60 or 90 degree angle. I've also included the angle to set the rotary table, and added a method of flattening the tips. I think this could 3d printed OK, I've yet to test. The stl would not be used in any other manufacturing process, afaik. For machining, It could be set up directly from the parameters. I've attached the code below. The flattening of the peaks give a slight taper. Adding an extra triangle to the polyhedron, could generate a more tapered width to the flat top, but for whatever use I may put this too, if any, it is unlikely to make much difference.

 The code will produce a viable stl, for any number of teeth,  including three and upwards, and it f6 renders fast enough.

 Here is a link to some curvic coupling design, which is a bit more involved to generate - https://www.geartechnology.com/articles/20867-curvic-coupling-design.


 On 04/11/2024 17:05, Raymond West via Discuss wrote:
 found it- etc.
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

--
Cheers, Ken
bats059@gmail.com
https://vk7krj.com
https://vk7krj.com/running.html

A baby can be defined as an ego with a noise at one end and a smell at the other.
Your job as parents is to teach them to control all three.
My job as a grandad is to tell you how you are doing it all wrong!

I tried it on mine- I'm using version 2024.10.2 git e972ed84e. F5 takes 0.059 seconds, f6 0.096 seconds. I get- "WARNING: PolySet -> Manifold conversion failed: NotManifold Trying to repair and reconstruct mesh.." four times, then it continues to render with no further errors. I have just finished printing two of them so I can have a play. On 2024-11-06 09:27, Adrian Mariano via Discuss wrote: > Ray, I tried your code and (1) preview is very very slow on my machine and (2) render gives > > Rendering Polygon Mesh using CGAL... > > ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. > > ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. > > ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. > > ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. > > ERROR: The given mesh is not closed! Unable to convert to CGAL_Nef_Polyhedron. > > Geometries in cache: 9903 > > > I'm now convinced that Bob has the right basic approach. The key thing is the idea of projecting onto a cylinder. Working in spherical coordinates never made sense to me, but for some reason the idea of just projecting points onto a cylinder didn't occur to me. (At one point I thought about doing it, but with equations, not with code, which was a bad idea.) With this insight I can now make roundings while creating the object as a single polyhedron: > > > image.png > > > > > On Tue, Nov 5, 2024 at 12:54 PM Raymond West via Discuss <discuss@lists.openscad.org> wrote: > > I've modified it slightly, to allow the tooth angle to be set - In manufacturing, most likely a 60 or 90 degree angle. I've also included the angle to set the rotary table, and added a method of flattening the tips. I think this could 3d printed OK, I've yet to test. The stl would not be used in any other manufacturing process, afaik. For machining, It could be set up directly from the parameters. I've attached the code below. The flattening of the peaks give a slight taper. Adding an extra triangle to the polyhedron, could generate a more tapered width to the flat top, but for whatever use I may put this too, if any, it is unlikely to make much difference. > > The code will produce a viable stl, for any number of teeth,  including three and upwards, and it f6 renders fast enough. > > Here is a link to some curvic coupling design, which is a bit more involved to generate - https://www.geartechnology.com/articles/20867-curvic-coupling-design. > > > On 04/11/2024 17:05, Raymond West via Discuss wrote: >> >> found it- etc. >> > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org -- Cheers, Ken bats059@gmail.com https://vk7krj.com https://vk7krj.com/running.html ---------------------------------------- A baby can be defined as an ego with a noise at one end and a smell at the other. Your job as parents is to teach them to control all three. My job as a grandad is to tell you how you are doing it all wrong!
SP
Sanjeev Prabhakar
Wed, Nov 6, 2024 2:21 AM

Hi Ray
I tried your code and it is almost instant render and there are no issues
in the manifold which I use during f6 render. There are some warnings but
that's fine

On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

I've modified it slightly, to allow the tooth angle to be set - In
manufacturing, most likely a 60 or 90 degree angle. I've also included the
angle to set the rotary table, and added a method of flattening the tips. I
think this could 3d printed OK, I've yet to test. The stl would not be used
in any other manufacturing process, afaik. For machining, It could be set
up directly from the parameters. I've attached the code below. The
flattening of the peaks give a slight taper. Adding an extra triangle to
the polyhedron, could generate a more tapered width to the flat top, but
for whatever use I may put this too, if any, it is unlikely to make much
difference.

The code will produce a viable stl, for any number of teeth,  including
three and upwards, and it f6 renders fast enough.

Here is a link to some curvic coupling design, which is a bit more
involved to generate -
https://www.geartechnology.com/articles/20867-curvic-coupling-design.

On 04/11/2024 17:05, Raymond West via Discuss wrote:

found it- etc.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Hi Ray I tried your code and it is almost instant render and there are no issues in the manifold which I use during f6 render. There are some warnings but that's fine On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss < discuss@lists.openscad.org> wrote: > I've modified it slightly, to allow the tooth angle to be set - In > manufacturing, most likely a 60 or 90 degree angle. I've also included the > angle to set the rotary table, and added a method of flattening the tips. I > think this could 3d printed OK, I've yet to test. The stl would not be used > in any other manufacturing process, afaik. For machining, It could be set > up directly from the parameters. I've attached the code below. The > flattening of the peaks give a slight taper. Adding an extra triangle to > the polyhedron, could generate a more tapered width to the flat top, but > for whatever use I may put this too, if any, it is unlikely to make much > difference. > > The code will produce a viable stl, for any number of teeth, including > three and upwards, and it f6 renders fast enough. > > Here is a link to some curvic coupling design, which is a bit more > involved to generate - > https://www.geartechnology.com/articles/20867-curvic-coupling-design. > > > On 04/11/2024 17:05, Raymond West via Discuss wrote: > > found it- etc. > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
BC
Bob Carlson
Thu, Nov 7, 2024 12:54 AM

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the theta for the chamfer “shoulder” point would be proportional to the chamfer but it produces a slight error. It is barely noticeable but gets more blatant at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss discuss@lists.openscad.org wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) + phiCA),
       spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
       spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
       spherical2_to_xyz(r, - thetaCA2,         _ridgeAngle(hs) + phiCA)
       ];
I have established that there is an error in the code fragment. The line > thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; Is where the error lies. What should it be? I was assuming that the theta for the chamfer “shoulder” point would be proportional to the chamfer but it produces a slight error. It is barely noticeable but gets more blatant at low tooth counts and high conic. Anyone see what it should be? I’m guessing there is some trig functions involved,but ... -Bob > On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <discuss@lists.openscad.org> wrote: > > Here is just a code fragment but it gets the point across. > > IR = _ir(hs); > OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the circumscribing polygon of N > > // Ridge Chamfer > thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; > phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; > > function profileToooth(r) = > [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + phiCA), > spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), > spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), > spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + phiCA) > ];
AM
Adrian Mariano
Thu, Nov 7, 2024 2:41 AM

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge (and
slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does rounding
and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a number
between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than outside
radius (or/od)")
assert(all_positive([tooth_angle]) && tooth_angle<360*(n-1)/2/n,
str("tooth angle must be between 0 and ",360*(n-1)/2/n," for spline with
",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define both
chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value") ;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized tooth
height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going around
the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2), valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts, reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true, col_wrap=true,
row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the theta
for the chamfer “shoulder” point would be proportional to the chamfer but
it produces a slight error. It is barely noticeable but gets more blatant
at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) + phiCA)
];


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Bob, I did I think exactly the same thing in my code and didn't notice anything, but now that you mention it, doing chamfers on an angular basis is of course not going to match doing them on a linear basis. So that means the geometry changes a bit if you change the chamfer size. This isn't necessarily catastrophic, but is a little unexpected, I suppose. Generally speaking you can't mate two parts produced with different chamfer size anyway, so I'm not sure this is crucial to get right. But in order to get it right, I think both thetaCA2 and phiCA are going to need to be computed with trig---either that or there's some complicated way of computing just one. The question is whether these two parameters can be computed independently or are they related in some complicated way. Treated as a 2d problem you are trying to get the angle that corresponds to a fraction of a chord of the circle, which is a reasonably straight forward triangle calculation. I got atan(chamfer*tan(angle)) where angle is 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't align with the unchamfered. For example: [image: image.png] Yellow is unchamfered. Blue has huge chamfer applied only at ridge (and slightly larger radius so we can see it clearly). And we see that the angle has changed. I actually got less error with the original calculation, but that might be because I didn't correct the phi angle only the theta angle. (Or maybe I botched the trig.) So I tried computing a correction for phi and got ridge_angle-atan(ridge_angle - chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line up correctly. (And the horizontal correction is still worse than not, which makes me wonder if the horizontal correction needs to take into account the vertical position of the chamfer somehow.) Doing the phi correction alone actually is an improvement over no correction. Here's my current code (without any chamfer corrections). It does rounding and skew teeth. module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) { ir = get_radius(r=ir,d=id); or = get_radius(r=or,d=od); dummy = assert(all_positive([ir]), "ir/id must be a positive value") assert(all_positive([or]), "or/od must be a positive value") assert(is_int(n) && n>1, "n must be an integer larger than 1") assert(is_finite(skew) && abs(skew)<=1, "skew must be a number between -1 and 1") assert(ir<or, "inside radius (ir/id) must be smaller than outside radius (or/od)") assert(all_positive([tooth_angle]) && tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and ",360*(n-1)/2/n," for spline with ",n," teeth.")) assert(num_defined([chamfer,rounding]) <=1, "Cannot define both chamfer and rounding") assert(is_undef(chamfer) || all_nonnegative([chamfer]) && chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") assert(is_undef(rounding) || all_nonnegative([rounding]) && rounding<1/2, "rounding must be a non-negative value smaller than 1/2") assert(all_positive([base]), "base must be a positive value") ; tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized tooth height cone_height = -tan(cone_angle); // Normalized height change corresponding to the cone angle ridge_angle = atan(tooth_height/2 + cone_height); valley_angle = atan(-tooth_height/2 + cone_height); angle = 180/n; // Half the angle occupied by each tooth going around the circle factor = crop ? 3 : 1; // Make it oversized when crop is true profile = is_undef(rounding) || rounding==0 ? let( chamfer=default(chamfer,0), vchamf = chamfer*(ridge_angle-valley_angle), pts = [ [-angle*(1-chamfer/2), valley_angle+vchamf/2], [-angle*chamfer, ridge_angle-vchamf] ], full = deduplicate(concat(pts, reverse(xflip(pts)))) ) back(valley_angle, skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) : let( vround=rounding*(ridge_angle-valley_angle), profpts = [ [ -angle, valley_angle+vround/2], [ -angle*(1-rounding/2), valley_angle+vround/2], [ -angle*rounding, ridge_angle-vround], ], segs = max(16,segs(or*rounding)), full = concat(profpts, reverse(xflip(profpts))), skewed = back(valley_angle, skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), // Using computed values for the joints lead to round-off error issues joints = [(skewed[1]-skewed[0]).x, (skewed[3]-skewed[2]).x/2, (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], roundpts = round_corners(skewed, joint=joints, closed=false,$fn=segs) ) roundpts; // project spherical coordinate point onto cylinder of radius r cyl_proj = function (r,theta_phi) [for(pt=theta_phi) let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) r * xyz / norm(point2d(xyz))]; bottom = min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; safebottom = min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; ang_ofs = !rot ? -skew*angle : n%2==0 ? -(angle-skew*angle) - skew*angle : -angle*(2-skew)-skew*angle; topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) each zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) each zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); botinner = [for(val=topinner) [val.x,val.y,safebottom]]; botouter = [for(val=topouter) [val.x,val.y,safebottom]]; vert = [topouter, topinner, botinner, botouter]; anchors = [ named_anchor("teeth_bot", [0,0,bottom], DOWN) ]; attachable(anchor=anchor,spin=spin,orient=orient, r=or, h=-2*bottom,anchors=anchors){ intersection(){ vnf_polyhedron(vnf_vertex_array(vert, reverse=true, col_wrap=true, row_wrap=true),convexity=min(10,n)); if (crop) zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); } children(); } } On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < discuss@lists.openscad.org> wrote: > I have established that there is an error in the code fragment. The line > > thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; > > Is where the error lies. What should it be? I was assuming that the theta > for the chamfer “shoulder” point would be proportional to the chamfer but > it produces a slight error. It is barely noticeable but gets more blatant > at low tooth counts and high conic. > > Anyone see what it should be? I’m guessing there is some trig > functions involved,but ... > > -Bob > > On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < > discuss@lists.openscad.org> wrote: > > Here is just a code fragment but it gets the point across. > > IR = _ir(hs); > OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the > circumscribing polygon of N > > // Ridge Chamfer > thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; > phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; > > function profileToooth(r) = > [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + > phiCA), > spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), > spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), > spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + phiCA) > ]; > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Thu, Nov 7, 2024 4:24 AM

I don't think the straight projection on cylinder will work.
The only way I think this can work is if you project using vectors
considering outer race and inner race, projecting outwards and inwards
respectively on outer and inner cylinder.
picture below can make this clear.
magenta lines are the vectors
[image: Screenshot 2024-11-07 at 9.49.27 AM.png]
[image: Screenshot 2024-11-07 at 9.53.29 AM.png]

On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, <
discuss@lists.openscad.org> wrote:

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge (and
slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does
rounding and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a number
between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than
outside radius (or/od)")
assert(all_positive([tooth_angle]) && tooth_angle<360*(n-1)/2/n,
str("tooth angle must be between 0 and ",360*(n-1)/2/n," for spline with
",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define both
chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value") ;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized tooth
height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going around
the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2), valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts, reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true, col_wrap=true,
row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the theta
for the chamfer “shoulder” point would be proportional to the chamfer but
it produces a slight error. It is barely noticeable but gets more blatant
at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) +
phiCA)
];


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 don't think the straight projection on cylinder will work. The only way I think this can work is if you project using vectors considering outer race and inner race, projecting outwards and inwards respectively on outer and inner cylinder. picture below can make this clear. magenta lines are the vectors [image: Screenshot 2024-11-07 at 9.49.27 AM.png] [image: Screenshot 2024-11-07 at 9.53.29 AM.png] On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, < discuss@lists.openscad.org> wrote: > Bob, I did I think exactly the same thing in my code and didn't notice > anything, but now that you mention it, doing chamfers on an angular basis > is of course not going to match doing them on a linear basis. So that > means the geometry changes a bit if you change the chamfer size. This > isn't necessarily catastrophic, but is a little unexpected, I suppose. > Generally speaking you can't mate two parts produced with different chamfer > size anyway, so I'm not sure this is crucial to get right. But in order to > get it right, I think both thetaCA2 and phiCA are going to need to be > computed with trig---either that or there's some complicated way of > computing just one. The question is whether these two parameters can be > computed independently or are they related in some complicated way. > Treated as a 2d problem you are trying to get the angle that corresponds to > a fraction of a chord of the circle, which is a reasonably straight forward > triangle calculation. I got atan(chamfer*tan(angle)) where angle is > 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't > align with the unchamfered. For example: > > [image: image.png] > > Yellow is unchamfered. Blue has huge chamfer applied only at ridge (and > slightly larger radius so we can see it clearly). And we see that the > angle has changed. I actually got less error with the original > calculation, but that might be because I didn't correct the phi angle only > the theta angle. (Or maybe I botched the trig.) So I tried computing a > correction for phi and got ridge_angle-atan(ridge_angle - > chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line > up correctly. (And the horizontal correction is still worse than not, > which makes me wonder if the horizontal correction needs to take into > account the vertical position of the chamfer somehow.) Doing the phi > correction alone actually is an improvement over no correction. > > Here's my current code (without any chamfer corrections). It does > rounding and skew teeth. > > module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, > rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) > { > ir = get_radius(r=ir,d=id); > or = get_radius(r=or,d=od); > dummy = assert(all_positive([ir]), "ir/id must be a positive value") > assert(all_positive([or]), "or/od must be a positive value") > assert(is_int(n) && n>1, "n must be an integer larger than 1") > assert(is_finite(skew) && abs(skew)<=1, "skew must be a number > between -1 and 1") > assert(ir<or, "inside radius (ir/id) must be smaller than > outside radius (or/od)") > assert(all_positive([tooth_angle]) && tooth_angle<360*(n-1)/2/n, > str("tooth angle must be between 0 and ",360*(n-1)/2/n," for spline with > ",n," teeth.")) > assert(num_defined([chamfer,rounding]) <=1, "Cannot define both > chamfer and rounding") > assert(is_undef(chamfer) || all_nonnegative([chamfer]) && > chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") > assert(is_undef(rounding) || all_nonnegative([rounding]) && > rounding<1/2, "rounding must be a non-negative value smaller than 1/2") > assert(all_positive([base]), "base must be a positive value") ; > tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized tooth > height > cone_height = -tan(cone_angle); // Normalized > height change corresponding to the cone angle > ridge_angle = atan(tooth_height/2 + cone_height); > valley_angle = atan(-tooth_height/2 + cone_height); > angle = 180/n; // Half the angle occupied by each tooth going around > the circle > > factor = crop ? 3 : 1; // Make it oversized when crop is true > > profile = is_undef(rounding) || rounding==0 ? > let( > chamfer=default(chamfer,0), > vchamf = chamfer*(ridge_angle-valley_angle), > pts = [ > [-angle*(1-chamfer/2), valley_angle+vchamf/2], > [-angle*chamfer, ridge_angle-vchamf] > ], > full = deduplicate(concat(pts, reverse(xflip(pts)))) > ) > back(valley_angle, > skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) > : let( > vround=rounding*(ridge_angle-valley_angle), > profpts = [ > [ -angle, valley_angle+vround/2], > [ -angle*(1-rounding/2), > valley_angle+vround/2], > [ -angle*rounding, ridge_angle-vround], > ], > segs = max(16,segs(or*rounding)), > full = concat(profpts, reverse(xflip(profpts))), > skewed = back(valley_angle, > skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), > // Using computed values for the joints > lead to round-off error issues > joints = [(skewed[1]-skewed[0]).x, > (skewed[3]-skewed[2]).x/2, > (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], > roundpts = round_corners(skewed, joint=joints, > closed=false,$fn=segs) > ) > roundpts; > > // project spherical coordinate point onto cylinder of radius r > cyl_proj = function (r,theta_phi) > [for(pt=theta_phi) > let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) > r * xyz / norm(point2d(xyz))]; > > bottom = > min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; > safebottom = > min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; > ang_ofs = !rot ? -skew*angle > : n%2==0 ? -(angle-skew*angle) - skew*angle > : -angle*(2-skew)-skew*angle; > topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) > each > zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); > topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) > each > zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); > botinner = [for(val=topinner) [val.x,val.y,safebottom]]; > botouter = [for(val=topouter) [val.x,val.y,safebottom]]; > vert = [topouter, topinner, botinner, botouter]; > > anchors = [ > named_anchor("teeth_bot", [0,0,bottom], DOWN) > ]; > attachable(anchor=anchor,spin=spin,orient=orient, r=or, > h=-2*bottom,anchors=anchors){ > intersection(){ > vnf_polyhedron(vnf_vertex_array(vert, reverse=true, col_wrap=true, > row_wrap=true),convexity=min(10,n)); > if (crop) > > zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); > } > children(); > } > } > > > > On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < > discuss@lists.openscad.org> wrote: > >> I have established that there is an error in the code fragment. The line >> >> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >> >> Is where the error lies. What should it be? I was assuming that the theta >> for the chamfer “shoulder” point would be proportional to the chamfer but >> it produces a slight error. It is barely noticeable but gets more blatant >> at low tooth counts and high conic. >> >> Anyone see what it should be? I’m guessing there is some trig >> functions involved,but ... >> >> -Bob >> >> On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < >> discuss@lists.openscad.org> wrote: >> >> Here is just a code fragment but it gets the point across. >> >> IR = _ir(hs); >> OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the >> circumscribing polygon of N >> >> // Ridge Chamfer >> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >> phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; >> >> function profileToooth(r) = >> [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + >> phiCA), >> spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), >> spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), >> spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + >> phiCA) >> ]; >> >> >> _______________________________________________ >> 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 >
SP
Sanjeev Prabhakar
Thu, Nov 7, 2024 4:58 AM

this is the final version (attached is the scad file)
[image: Screenshot 2024-11-07 at 10.26.12 AM.png]

On Thu, 7 Nov 2024 at 09:54, Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I don't think the straight projection on cylinder will work.
The only way I think this can work is if you project using vectors
considering outer race and inner race, projecting outwards and inwards
respectively on outer and inner cylinder.
picture below can make this clear.
magenta lines are the vectors
[image: Screenshot 2024-11-07 at 9.49.27 AM.png]
[image: Screenshot 2024-11-07 at 9.53.29 AM.png]

On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, <
discuss@lists.openscad.org> wrote:

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge (and
slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does
rounding and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a number
between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than
outside radius (or/od)")
assert(all_positive([tooth_angle]) &&
tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and
",360*(n-1)/2/n," for spline with ",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define both
chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value") ;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized tooth
height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going around
the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2),
valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts, reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true,
col_wrap=true, row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the
theta for the chamfer “shoulder” point would be proportional to the chamfer
but it produces a slight error. It is barely noticeable but gets more
blatant at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) +
phiCA)
];


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

this is the final version (attached is the scad file) [image: Screenshot 2024-11-07 at 10.26.12 AM.png] On Thu, 7 Nov 2024 at 09:54, Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > I don't think the straight projection on cylinder will work. > The only way I think this can work is if you project using vectors > considering outer race and inner race, projecting outwards and inwards > respectively on outer and inner cylinder. > picture below can make this clear. > magenta lines are the vectors > [image: Screenshot 2024-11-07 at 9.49.27 AM.png] > [image: Screenshot 2024-11-07 at 9.53.29 AM.png] > > On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, < > discuss@lists.openscad.org> wrote: > >> Bob, I did I think exactly the same thing in my code and didn't notice >> anything, but now that you mention it, doing chamfers on an angular basis >> is of course not going to match doing them on a linear basis. So that >> means the geometry changes a bit if you change the chamfer size. This >> isn't necessarily catastrophic, but is a little unexpected, I suppose. >> Generally speaking you can't mate two parts produced with different chamfer >> size anyway, so I'm not sure this is crucial to get right. But in order to >> get it right, I think both thetaCA2 and phiCA are going to need to be >> computed with trig---either that or there's some complicated way of >> computing just one. The question is whether these two parameters can be >> computed independently or are they related in some complicated way. >> Treated as a 2d problem you are trying to get the angle that corresponds to >> a fraction of a chord of the circle, which is a reasonably straight forward >> triangle calculation. I got atan(chamfer*tan(angle)) where angle is >> 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't >> align with the unchamfered. For example: >> >> [image: image.png] >> >> Yellow is unchamfered. Blue has huge chamfer applied only at ridge (and >> slightly larger radius so we can see it clearly). And we see that the >> angle has changed. I actually got less error with the original >> calculation, but that might be because I didn't correct the phi angle only >> the theta angle. (Or maybe I botched the trig.) So I tried computing a >> correction for phi and got ridge_angle-atan(ridge_angle - >> chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line >> up correctly. (And the horizontal correction is still worse than not, >> which makes me wonder if the horizontal correction needs to take into >> account the vertical position of the chamfer somehow.) Doing the phi >> correction alone actually is an improvement over no correction. >> >> Here's my current code (without any chamfer corrections). It does >> rounding and skew teeth. >> >> module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, >> rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) >> { >> ir = get_radius(r=ir,d=id); >> or = get_radius(r=or,d=od); >> dummy = assert(all_positive([ir]), "ir/id must be a positive value") >> assert(all_positive([or]), "or/od must be a positive value") >> assert(is_int(n) && n>1, "n must be an integer larger than 1") >> assert(is_finite(skew) && abs(skew)<=1, "skew must be a number >> between -1 and 1") >> assert(ir<or, "inside radius (ir/id) must be smaller than >> outside radius (or/od)") >> assert(all_positive([tooth_angle]) && >> tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and >> ",360*(n-1)/2/n," for spline with ",n," teeth.")) >> assert(num_defined([chamfer,rounding]) <=1, "Cannot define both >> chamfer and rounding") >> assert(is_undef(chamfer) || all_nonnegative([chamfer]) && >> chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") >> assert(is_undef(rounding) || all_nonnegative([rounding]) && >> rounding<1/2, "rounding must be a non-negative value smaller than 1/2") >> assert(all_positive([base]), "base must be a positive value") ; >> tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized tooth >> height >> cone_height = -tan(cone_angle); // Normalized >> height change corresponding to the cone angle >> ridge_angle = atan(tooth_height/2 + cone_height); >> valley_angle = atan(-tooth_height/2 + cone_height); >> angle = 180/n; // Half the angle occupied by each tooth going around >> the circle >> >> factor = crop ? 3 : 1; // Make it oversized when crop is true >> >> profile = is_undef(rounding) || rounding==0 ? >> let( >> chamfer=default(chamfer,0), >> vchamf = chamfer*(ridge_angle-valley_angle), >> pts = [ >> [-angle*(1-chamfer/2), >> valley_angle+vchamf/2], >> [-angle*chamfer, ridge_angle-vchamf] >> ], >> full = deduplicate(concat(pts, reverse(xflip(pts)))) >> ) >> back(valley_angle, >> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) >> : let( >> vround=rounding*(ridge_angle-valley_angle), >> profpts = [ >> [ -angle, valley_angle+vround/2], >> [ -angle*(1-rounding/2), >> valley_angle+vround/2], >> [ -angle*rounding, ridge_angle-vround], >> ], >> segs = max(16,segs(or*rounding)), >> full = concat(profpts, reverse(xflip(profpts))), >> skewed = back(valley_angle, >> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), >> // Using computed values for the joints >> lead to round-off error issues >> joints = [(skewed[1]-skewed[0]).x, >> (skewed[3]-skewed[2]).x/2, >> (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], >> roundpts = round_corners(skewed, joint=joints, >> closed=false,$fn=segs) >> ) >> roundpts; >> >> // project spherical coordinate point onto cylinder of radius r >> cyl_proj = function (r,theta_phi) >> [for(pt=theta_phi) >> let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) >> r * xyz / norm(point2d(xyz))]; >> >> bottom = >> min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; >> safebottom = >> min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; >> ang_ofs = !rot ? -skew*angle >> : n%2==0 ? -(angle-skew*angle) - skew*angle >> : -angle*(2-skew)-skew*angle; >> topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >> each >> zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); >> topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >> each >> zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); >> botinner = [for(val=topinner) [val.x,val.y,safebottom]]; >> botouter = [for(val=topouter) [val.x,val.y,safebottom]]; >> vert = [topouter, topinner, botinner, botouter]; >> >> anchors = [ >> named_anchor("teeth_bot", [0,0,bottom], DOWN) >> ]; >> attachable(anchor=anchor,spin=spin,orient=orient, r=or, >> h=-2*bottom,anchors=anchors){ >> intersection(){ >> vnf_polyhedron(vnf_vertex_array(vert, reverse=true, >> col_wrap=true, row_wrap=true),convexity=min(10,n)); >> if (crop) >> >> zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); >> } >> children(); >> } >> } >> >> >> >> On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> I have established that there is an error in the code fragment. The line >>> >>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>> >>> Is where the error lies. What should it be? I was assuming that the >>> theta for the chamfer “shoulder” point would be proportional to the chamfer >>> but it produces a slight error. It is barely noticeable but gets more >>> blatant at low tooth counts and high conic. >>> >>> Anyone see what it should be? I’m guessing there is some trig >>> functions involved,but ... >>> >>> -Bob >>> >>> On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>> Here is just a code fragment but it gets the point across. >>> >>> IR = _ir(hs); >>> OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the >>> circumscribing polygon of N >>> >>> // Ridge Chamfer >>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>> phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; >>> >>> function profileToooth(r) = >>> [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + >>> phiCA), >>> spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), >>> spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), >>> spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + >>> phiCA) >>> ]; >>> >>> >>> _______________________________________________ >>> 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 >> >
JD
John David
Thu, Nov 7, 2024 6:23 AM

very nice!  Thank you for sharing ;-)

On Wed, Nov 6, 2024 at 11:59 PM Sanjeev Prabhakar via Discuss <
discuss@lists.openscad.org> wrote:

this is the final version (attached is the scad file)
[image: Screenshot 2024-11-07 at 10.26.12 AM.png]

On Thu, 7 Nov 2024 at 09:54, Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I don't think the straight projection on cylinder will work.
The only way I think this can work is if you project using vectors
considering outer race and inner race, projecting outwards and inwards
respectively on outer and inner cylinder.
picture below can make this clear.
magenta lines are the vectors
[image: Screenshot 2024-11-07 at 9.49.27 AM.png]
[image: Screenshot 2024-11-07 at 9.53.29 AM.png]

On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, <
discuss@lists.openscad.org> wrote:

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge (and
slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does
rounding and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a number
between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than
outside radius (or/od)")
assert(all_positive([tooth_angle]) &&
tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and
",360*(n-1)/2/n," for spline with ",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define
both chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value") ;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized
tooth height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going
around the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2),
valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts, reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true,
col_wrap=true, row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the
theta for the chamfer “shoulder” point would be proportional to the chamfer
but it produces a slight error. It is barely noticeable but gets more
blatant at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) +
phiCA)
];


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


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

very nice! Thank you for sharing ;-) On Wed, Nov 6, 2024 at 11:59 PM Sanjeev Prabhakar via Discuss < discuss@lists.openscad.org> wrote: > this is the final version (attached is the scad file) > [image: Screenshot 2024-11-07 at 10.26.12 AM.png] > > On Thu, 7 Nov 2024 at 09:54, Sanjeev Prabhakar <sprabhakar2006@gmail.com> > wrote: > >> I don't think the straight projection on cylinder will work. >> The only way I think this can work is if you project using vectors >> considering outer race and inner race, projecting outwards and inwards >> respectively on outer and inner cylinder. >> picture below can make this clear. >> magenta lines are the vectors >> [image: Screenshot 2024-11-07 at 9.49.27 AM.png] >> [image: Screenshot 2024-11-07 at 9.53.29 AM.png] >> >> On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, < >> discuss@lists.openscad.org> wrote: >> >>> Bob, I did I think exactly the same thing in my code and didn't notice >>> anything, but now that you mention it, doing chamfers on an angular basis >>> is of course not going to match doing them on a linear basis. So that >>> means the geometry changes a bit if you change the chamfer size. This >>> isn't necessarily catastrophic, but is a little unexpected, I suppose. >>> Generally speaking you can't mate two parts produced with different chamfer >>> size anyway, so I'm not sure this is crucial to get right. But in order to >>> get it right, I think both thetaCA2 and phiCA are going to need to be >>> computed with trig---either that or there's some complicated way of >>> computing just one. The question is whether these two parameters can be >>> computed independently or are they related in some complicated way. >>> Treated as a 2d problem you are trying to get the angle that corresponds to >>> a fraction of a chord of the circle, which is a reasonably straight forward >>> triangle calculation. I got atan(chamfer*tan(angle)) where angle is >>> 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't >>> align with the unchamfered. For example: >>> >>> [image: image.png] >>> >>> Yellow is unchamfered. Blue has huge chamfer applied only at ridge (and >>> slightly larger radius so we can see it clearly). And we see that the >>> angle has changed. I actually got less error with the original >>> calculation, but that might be because I didn't correct the phi angle only >>> the theta angle. (Or maybe I botched the trig.) So I tried computing a >>> correction for phi and got ridge_angle-atan(ridge_angle - >>> chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line >>> up correctly. (And the horizontal correction is still worse than not, >>> which makes me wonder if the horizontal correction needs to take into >>> account the vertical position of the chamfer somehow.) Doing the phi >>> correction alone actually is an improvement over no correction. >>> >>> Here's my current code (without any chamfer corrections). It does >>> rounding and skew teeth. >>> >>> module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, >>> rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) >>> { >>> ir = get_radius(r=ir,d=id); >>> or = get_radius(r=or,d=od); >>> dummy = assert(all_positive([ir]), "ir/id must be a positive value") >>> assert(all_positive([or]), "or/od must be a positive value") >>> assert(is_int(n) && n>1, "n must be an integer larger than 1") >>> assert(is_finite(skew) && abs(skew)<=1, "skew must be a number >>> between -1 and 1") >>> assert(ir<or, "inside radius (ir/id) must be smaller than >>> outside radius (or/od)") >>> assert(all_positive([tooth_angle]) && >>> tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and >>> ",360*(n-1)/2/n," for spline with ",n," teeth.")) >>> assert(num_defined([chamfer,rounding]) <=1, "Cannot define >>> both chamfer and rounding") >>> assert(is_undef(chamfer) || all_nonnegative([chamfer]) && >>> chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") >>> assert(is_undef(rounding) || all_nonnegative([rounding]) && >>> rounding<1/2, "rounding must be a non-negative value smaller than 1/2") >>> assert(all_positive([base]), "base must be a positive value") ; >>> tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized >>> tooth height >>> cone_height = -tan(cone_angle); // Normalized >>> height change corresponding to the cone angle >>> ridge_angle = atan(tooth_height/2 + cone_height); >>> valley_angle = atan(-tooth_height/2 + cone_height); >>> angle = 180/n; // Half the angle occupied by each tooth going >>> around the circle >>> >>> factor = crop ? 3 : 1; // Make it oversized when crop is true >>> >>> profile = is_undef(rounding) || rounding==0 ? >>> let( >>> chamfer=default(chamfer,0), >>> vchamf = chamfer*(ridge_angle-valley_angle), >>> pts = [ >>> [-angle*(1-chamfer/2), >>> valley_angle+vchamf/2], >>> [-angle*chamfer, ridge_angle-vchamf] >>> ], >>> full = deduplicate(concat(pts, reverse(xflip(pts)))) >>> ) >>> back(valley_angle, >>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) >>> : let( >>> vround=rounding*(ridge_angle-valley_angle), >>> profpts = [ >>> [ -angle, valley_angle+vround/2], >>> [ -angle*(1-rounding/2), >>> valley_angle+vround/2], >>> [ -angle*rounding, ridge_angle-vround], >>> ], >>> segs = max(16,segs(or*rounding)), >>> full = concat(profpts, reverse(xflip(profpts))), >>> skewed = back(valley_angle, >>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), >>> // Using computed values for the joints >>> lead to round-off error issues >>> joints = [(skewed[1]-skewed[0]).x, >>> (skewed[3]-skewed[2]).x/2, >>> (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], >>> roundpts = round_corners(skewed, joint=joints, >>> closed=false,$fn=segs) >>> ) >>> roundpts; >>> >>> // project spherical coordinate point onto cylinder of radius r >>> cyl_proj = function (r,theta_phi) >>> [for(pt=theta_phi) >>> let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) >>> r * xyz / norm(point2d(xyz))]; >>> >>> bottom = >>> min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; >>> safebottom = >>> min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; >>> ang_ofs = !rot ? -skew*angle >>> : n%2==0 ? -(angle-skew*angle) - skew*angle >>> : -angle*(2-skew)-skew*angle; >>> topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>> each >>> zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); >>> topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>> each >>> zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); >>> botinner = [for(val=topinner) [val.x,val.y,safebottom]]; >>> botouter = [for(val=topouter) [val.x,val.y,safebottom]]; >>> vert = [topouter, topinner, botinner, botouter]; >>> >>> anchors = [ >>> named_anchor("teeth_bot", [0,0,bottom], DOWN) >>> ]; >>> attachable(anchor=anchor,spin=spin,orient=orient, r=or, >>> h=-2*bottom,anchors=anchors){ >>> intersection(){ >>> vnf_polyhedron(vnf_vertex_array(vert, reverse=true, >>> col_wrap=true, row_wrap=true),convexity=min(10,n)); >>> if (crop) >>> >>> zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); >>> } >>> children(); >>> } >>> } >>> >>> >>> >>> On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>>> I have established that there is an error in the code fragment. The line >>>> >>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>> >>>> Is where the error lies. What should it be? I was assuming that the >>>> theta for the chamfer “shoulder” point would be proportional to the chamfer >>>> but it produces a slight error. It is barely noticeable but gets more >>>> blatant at low tooth counts and high conic. >>>> >>>> Anyone see what it should be? I’m guessing there is some trig >>>> functions involved,but ... >>>> >>>> -Bob >>>> >>>> On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < >>>> discuss@lists.openscad.org> wrote: >>>> >>>> Here is just a code fragment but it gets the point across. >>>> >>>> IR = _ir(hs); >>>> OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the >>>> circumscribing polygon of N >>>> >>>> // Ridge Chamfer >>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>> phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; >>>> >>>> function profileToooth(r) = >>>> [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + >>>> phiCA), >>>> spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), >>>> spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), >>>> spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + >>>> phiCA) >>>> ]; >>>> >>>> >>>> _______________________________________________ >>>> 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 >>> >> _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Thu, Nov 7, 2024 11:09 AM

I do not understand the pictures.  Or at least the top one is mystifying.
The bottom one looks like it could describe the process: the projection is
along vectors that originate at the origin and yes, you have a separate
projection onto the inner and outer cylinder.

On Wed, Nov 6, 2024 at 11:24 PM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I don't think the straight projection on cylinder will work.
The only way I think this can work is if you project using vectors
considering outer race and inner race, projecting outwards and inwards
respectively on outer and inner cylinder.
picture below can make this clear.
magenta lines are the vectors
[image: Screenshot 2024-11-07 at 9.49.27 AM.png]
[image: Screenshot 2024-11-07 at 9.53.29 AM.png]

On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, <
discuss@lists.openscad.org> wrote:

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge (and
slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does
rounding and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a number
between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than
outside radius (or/od)")
assert(all_positive([tooth_angle]) &&
tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and
",360*(n-1)/2/n," for spline with ",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define both
chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value") ;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized tooth
height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going around
the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2),
valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts, reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true,
col_wrap=true, row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the
theta for the chamfer “shoulder” point would be proportional to the chamfer
but it produces a slight error. It is barely noticeable but gets more
blatant at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) +
phiCA)
];


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 do not understand the pictures. Or at least the top one is mystifying. The bottom one looks like it could describe the process: the projection is along vectors that originate at the origin and yes, you have a separate projection onto the inner and outer cylinder. On Wed, Nov 6, 2024 at 11:24 PM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > I don't think the straight projection on cylinder will work. > The only way I think this can work is if you project using vectors > considering outer race and inner race, projecting outwards and inwards > respectively on outer and inner cylinder. > picture below can make this clear. > magenta lines are the vectors > [image: Screenshot 2024-11-07 at 9.49.27 AM.png] > [image: Screenshot 2024-11-07 at 9.53.29 AM.png] > > On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, < > discuss@lists.openscad.org> wrote: > >> Bob, I did I think exactly the same thing in my code and didn't notice >> anything, but now that you mention it, doing chamfers on an angular basis >> is of course not going to match doing them on a linear basis. So that >> means the geometry changes a bit if you change the chamfer size. This >> isn't necessarily catastrophic, but is a little unexpected, I suppose. >> Generally speaking you can't mate two parts produced with different chamfer >> size anyway, so I'm not sure this is crucial to get right. But in order to >> get it right, I think both thetaCA2 and phiCA are going to need to be >> computed with trig---either that or there's some complicated way of >> computing just one. The question is whether these two parameters can be >> computed independently or are they related in some complicated way. >> Treated as a 2d problem you are trying to get the angle that corresponds to >> a fraction of a chord of the circle, which is a reasonably straight forward >> triangle calculation. I got atan(chamfer*tan(angle)) where angle is >> 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't >> align with the unchamfered. For example: >> >> [image: image.png] >> >> Yellow is unchamfered. Blue has huge chamfer applied only at ridge (and >> slightly larger radius so we can see it clearly). And we see that the >> angle has changed. I actually got less error with the original >> calculation, but that might be because I didn't correct the phi angle only >> the theta angle. (Or maybe I botched the trig.) So I tried computing a >> correction for phi and got ridge_angle-atan(ridge_angle - >> chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line >> up correctly. (And the horizontal correction is still worse than not, >> which makes me wonder if the horizontal correction needs to take into >> account the vertical position of the chamfer somehow.) Doing the phi >> correction alone actually is an improvement over no correction. >> >> Here's my current code (without any chamfer corrections). It does >> rounding and skew teeth. >> >> module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, >> rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) >> { >> ir = get_radius(r=ir,d=id); >> or = get_radius(r=or,d=od); >> dummy = assert(all_positive([ir]), "ir/id must be a positive value") >> assert(all_positive([or]), "or/od must be a positive value") >> assert(is_int(n) && n>1, "n must be an integer larger than 1") >> assert(is_finite(skew) && abs(skew)<=1, "skew must be a number >> between -1 and 1") >> assert(ir<or, "inside radius (ir/id) must be smaller than >> outside radius (or/od)") >> assert(all_positive([tooth_angle]) && >> tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and >> ",360*(n-1)/2/n," for spline with ",n," teeth.")) >> assert(num_defined([chamfer,rounding]) <=1, "Cannot define both >> chamfer and rounding") >> assert(is_undef(chamfer) || all_nonnegative([chamfer]) && >> chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") >> assert(is_undef(rounding) || all_nonnegative([rounding]) && >> rounding<1/2, "rounding must be a non-negative value smaller than 1/2") >> assert(all_positive([base]), "base must be a positive value") ; >> tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized tooth >> height >> cone_height = -tan(cone_angle); // Normalized >> height change corresponding to the cone angle >> ridge_angle = atan(tooth_height/2 + cone_height); >> valley_angle = atan(-tooth_height/2 + cone_height); >> angle = 180/n; // Half the angle occupied by each tooth going around >> the circle >> >> factor = crop ? 3 : 1; // Make it oversized when crop is true >> >> profile = is_undef(rounding) || rounding==0 ? >> let( >> chamfer=default(chamfer,0), >> vchamf = chamfer*(ridge_angle-valley_angle), >> pts = [ >> [-angle*(1-chamfer/2), >> valley_angle+vchamf/2], >> [-angle*chamfer, ridge_angle-vchamf] >> ], >> full = deduplicate(concat(pts, reverse(xflip(pts)))) >> ) >> back(valley_angle, >> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) >> : let( >> vround=rounding*(ridge_angle-valley_angle), >> profpts = [ >> [ -angle, valley_angle+vround/2], >> [ -angle*(1-rounding/2), >> valley_angle+vround/2], >> [ -angle*rounding, ridge_angle-vround], >> ], >> segs = max(16,segs(or*rounding)), >> full = concat(profpts, reverse(xflip(profpts))), >> skewed = back(valley_angle, >> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), >> // Using computed values for the joints >> lead to round-off error issues >> joints = [(skewed[1]-skewed[0]).x, >> (skewed[3]-skewed[2]).x/2, >> (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], >> roundpts = round_corners(skewed, joint=joints, >> closed=false,$fn=segs) >> ) >> roundpts; >> >> // project spherical coordinate point onto cylinder of radius r >> cyl_proj = function (r,theta_phi) >> [for(pt=theta_phi) >> let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) >> r * xyz / norm(point2d(xyz))]; >> >> bottom = >> min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; >> safebottom = >> min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; >> ang_ofs = !rot ? -skew*angle >> : n%2==0 ? -(angle-skew*angle) - skew*angle >> : -angle*(2-skew)-skew*angle; >> topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >> each >> zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); >> topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >> each >> zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); >> botinner = [for(val=topinner) [val.x,val.y,safebottom]]; >> botouter = [for(val=topouter) [val.x,val.y,safebottom]]; >> vert = [topouter, topinner, botinner, botouter]; >> >> anchors = [ >> named_anchor("teeth_bot", [0,0,bottom], DOWN) >> ]; >> attachable(anchor=anchor,spin=spin,orient=orient, r=or, >> h=-2*bottom,anchors=anchors){ >> intersection(){ >> vnf_polyhedron(vnf_vertex_array(vert, reverse=true, >> col_wrap=true, row_wrap=true),convexity=min(10,n)); >> if (crop) >> >> zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); >> } >> children(); >> } >> } >> >> >> >> On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> I have established that there is an error in the code fragment. The line >>> >>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>> >>> Is where the error lies. What should it be? I was assuming that the >>> theta for the chamfer “shoulder” point would be proportional to the chamfer >>> but it produces a slight error. It is barely noticeable but gets more >>> blatant at low tooth counts and high conic. >>> >>> Anyone see what it should be? I’m guessing there is some trig >>> functions involved,but ... >>> >>> -Bob >>> >>> On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>> Here is just a code fragment but it gets the point across. >>> >>> IR = _ir(hs); >>> OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the >>> circumscribing polygon of N >>> >>> // Ridge Chamfer >>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>> phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; >>> >>> function profileToooth(r) = >>> [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + >>> phiCA), >>> spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), >>> spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), >>> spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + >>> phiCA) >>> ]; >>> >>> >>> _______________________________________________ >>> 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 >> >
SP
Sanjeev Prabhakar
Thu, Nov 7, 2024 11:23 AM

All the magenta lines are vectors, you can think of them originating from
any side of the line.

Each line intersects a circumscribing cylinder outer or inner and that
forms the circular hirth coupling.

On Thu, 7 Nov, 2024, 4:40 pm Adrian Mariano, avm4@cornell.edu wrote:

I do not understand the pictures.  Or at least the top one is mystifying.
The bottom one looks like it could describe the process: the projection is
along vectors that originate at the origin and yes, you have a separate
projection onto the inner and outer cylinder.

On Wed, Nov 6, 2024 at 11:24 PM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I don't think the straight projection on cylinder will work.
The only way I think this can work is if you project using vectors
considering outer race and inner race, projecting outwards and inwards
respectively on outer and inner cylinder.
picture below can make this clear.
magenta lines are the vectors
[image: Screenshot 2024-11-07 at 9.49.27 AM.png]
[image: Screenshot 2024-11-07 at 9.53.29 AM.png]

On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, <
discuss@lists.openscad.org> wrote:

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge (and
slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does
rounding and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a number
between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than
outside radius (or/od)")
assert(all_positive([tooth_angle]) &&
tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and
",360*(n-1)/2/n," for spline with ",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define
both chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value") ;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized
tooth height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going
around the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2),
valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts, reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true,
col_wrap=true, row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the
theta for the chamfer “shoulder” point would be proportional to the chamfer
but it produces a slight error. It is barely noticeable but gets more
blatant at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) +
phiCA)
];


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

All the magenta lines are vectors, you can think of them originating from any side of the line. Each line intersects a circumscribing cylinder outer or inner and that forms the circular hirth coupling. On Thu, 7 Nov, 2024, 4:40 pm Adrian Mariano, <avm4@cornell.edu> wrote: > I do not understand the pictures. Or at least the top one is mystifying. > The bottom one looks like it could describe the process: the projection is > along vectors that originate at the origin and yes, you have a separate > projection onto the inner and outer cylinder. > > On Wed, Nov 6, 2024 at 11:24 PM Sanjeev Prabhakar < > sprabhakar2006@gmail.com> wrote: > >> I don't think the straight projection on cylinder will work. >> The only way I think this can work is if you project using vectors >> considering outer race and inner race, projecting outwards and inwards >> respectively on outer and inner cylinder. >> picture below can make this clear. >> magenta lines are the vectors >> [image: Screenshot 2024-11-07 at 9.49.27 AM.png] >> [image: Screenshot 2024-11-07 at 9.53.29 AM.png] >> >> On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, < >> discuss@lists.openscad.org> wrote: >> >>> Bob, I did I think exactly the same thing in my code and didn't notice >>> anything, but now that you mention it, doing chamfers on an angular basis >>> is of course not going to match doing them on a linear basis. So that >>> means the geometry changes a bit if you change the chamfer size. This >>> isn't necessarily catastrophic, but is a little unexpected, I suppose. >>> Generally speaking you can't mate two parts produced with different chamfer >>> size anyway, so I'm not sure this is crucial to get right. But in order to >>> get it right, I think both thetaCA2 and phiCA are going to need to be >>> computed with trig---either that or there's some complicated way of >>> computing just one. The question is whether these two parameters can be >>> computed independently or are they related in some complicated way. >>> Treated as a 2d problem you are trying to get the angle that corresponds to >>> a fraction of a chord of the circle, which is a reasonably straight forward >>> triangle calculation. I got atan(chamfer*tan(angle)) where angle is >>> 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't >>> align with the unchamfered. For example: >>> >>> [image: image.png] >>> >>> Yellow is unchamfered. Blue has huge chamfer applied only at ridge (and >>> slightly larger radius so we can see it clearly). And we see that the >>> angle has changed. I actually got less error with the original >>> calculation, but that might be because I didn't correct the phi angle only >>> the theta angle. (Or maybe I botched the trig.) So I tried computing a >>> correction for phi and got ridge_angle-atan(ridge_angle - >>> chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line >>> up correctly. (And the horizontal correction is still worse than not, >>> which makes me wonder if the horizontal correction needs to take into >>> account the vertical position of the chamfer somehow.) Doing the phi >>> correction alone actually is an improvement over no correction. >>> >>> Here's my current code (without any chamfer corrections). It does >>> rounding and skew teeth. >>> >>> module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, >>> rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) >>> { >>> ir = get_radius(r=ir,d=id); >>> or = get_radius(r=or,d=od); >>> dummy = assert(all_positive([ir]), "ir/id must be a positive value") >>> assert(all_positive([or]), "or/od must be a positive value") >>> assert(is_int(n) && n>1, "n must be an integer larger than 1") >>> assert(is_finite(skew) && abs(skew)<=1, "skew must be a number >>> between -1 and 1") >>> assert(ir<or, "inside radius (ir/id) must be smaller than >>> outside radius (or/od)") >>> assert(all_positive([tooth_angle]) && >>> tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and >>> ",360*(n-1)/2/n," for spline with ",n," teeth.")) >>> assert(num_defined([chamfer,rounding]) <=1, "Cannot define >>> both chamfer and rounding") >>> assert(is_undef(chamfer) || all_nonnegative([chamfer]) && >>> chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") >>> assert(is_undef(rounding) || all_nonnegative([rounding]) && >>> rounding<1/2, "rounding must be a non-negative value smaller than 1/2") >>> assert(all_positive([base]), "base must be a positive value") ; >>> tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized >>> tooth height >>> cone_height = -tan(cone_angle); // Normalized >>> height change corresponding to the cone angle >>> ridge_angle = atan(tooth_height/2 + cone_height); >>> valley_angle = atan(-tooth_height/2 + cone_height); >>> angle = 180/n; // Half the angle occupied by each tooth going >>> around the circle >>> >>> factor = crop ? 3 : 1; // Make it oversized when crop is true >>> >>> profile = is_undef(rounding) || rounding==0 ? >>> let( >>> chamfer=default(chamfer,0), >>> vchamf = chamfer*(ridge_angle-valley_angle), >>> pts = [ >>> [-angle*(1-chamfer/2), >>> valley_angle+vchamf/2], >>> [-angle*chamfer, ridge_angle-vchamf] >>> ], >>> full = deduplicate(concat(pts, reverse(xflip(pts)))) >>> ) >>> back(valley_angle, >>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) >>> : let( >>> vround=rounding*(ridge_angle-valley_angle), >>> profpts = [ >>> [ -angle, valley_angle+vround/2], >>> [ -angle*(1-rounding/2), >>> valley_angle+vround/2], >>> [ -angle*rounding, ridge_angle-vround], >>> ], >>> segs = max(16,segs(or*rounding)), >>> full = concat(profpts, reverse(xflip(profpts))), >>> skewed = back(valley_angle, >>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), >>> // Using computed values for the joints >>> lead to round-off error issues >>> joints = [(skewed[1]-skewed[0]).x, >>> (skewed[3]-skewed[2]).x/2, >>> (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], >>> roundpts = round_corners(skewed, joint=joints, >>> closed=false,$fn=segs) >>> ) >>> roundpts; >>> >>> // project spherical coordinate point onto cylinder of radius r >>> cyl_proj = function (r,theta_phi) >>> [for(pt=theta_phi) >>> let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) >>> r * xyz / norm(point2d(xyz))]; >>> >>> bottom = >>> min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; >>> safebottom = >>> min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; >>> ang_ofs = !rot ? -skew*angle >>> : n%2==0 ? -(angle-skew*angle) - skew*angle >>> : -angle*(2-skew)-skew*angle; >>> topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>> each >>> zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); >>> topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>> each >>> zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); >>> botinner = [for(val=topinner) [val.x,val.y,safebottom]]; >>> botouter = [for(val=topouter) [val.x,val.y,safebottom]]; >>> vert = [topouter, topinner, botinner, botouter]; >>> >>> anchors = [ >>> named_anchor("teeth_bot", [0,0,bottom], DOWN) >>> ]; >>> attachable(anchor=anchor,spin=spin,orient=orient, r=or, >>> h=-2*bottom,anchors=anchors){ >>> intersection(){ >>> vnf_polyhedron(vnf_vertex_array(vert, reverse=true, >>> col_wrap=true, row_wrap=true),convexity=min(10,n)); >>> if (crop) >>> >>> zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); >>> } >>> children(); >>> } >>> } >>> >>> >>> >>> On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>>> I have established that there is an error in the code fragment. The line >>>> >>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>> >>>> Is where the error lies. What should it be? I was assuming that the >>>> theta for the chamfer “shoulder” point would be proportional to the chamfer >>>> but it produces a slight error. It is barely noticeable but gets more >>>> blatant at low tooth counts and high conic. >>>> >>>> Anyone see what it should be? I’m guessing there is some trig >>>> functions involved,but ... >>>> >>>> -Bob >>>> >>>> On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < >>>> discuss@lists.openscad.org> wrote: >>>> >>>> Here is just a code fragment but it gets the point across. >>>> >>>> IR = _ir(hs); >>>> OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the >>>> circumscribing polygon of N >>>> >>>> // Ridge Chamfer >>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>> phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; >>>> >>>> function profileToooth(r) = >>>> [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + >>>> phiCA), >>>> spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), >>>> spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), >>>> spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + >>>> phiCA) >>>> ]; >>>> >>>> >>>> _______________________________________________ >>>> 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 >>> >>
SP
Sanjeev Prabhakar
Thu, Nov 7, 2024 11:24 AM

Thanks David
That book you share is good,  but it is taking some time to absorb

On Thu, 7 Nov, 2024, 11:53 am John David, ebo.2112@gmail.com wrote:

very nice!  Thank you for sharing ;-)

On Wed, Nov 6, 2024 at 11:59 PM Sanjeev Prabhakar via Discuss <
discuss@lists.openscad.org> wrote:

this is the final version (attached is the scad file)
[image: Screenshot 2024-11-07 at 10.26.12 AM.png]

On Thu, 7 Nov 2024 at 09:54, Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I don't think the straight projection on cylinder will work.
The only way I think this can work is if you project using vectors
considering outer race and inner race, projecting outwards and inwards
respectively on outer and inner cylinder.
picture below can make this clear.
magenta lines are the vectors
[image: Screenshot 2024-11-07 at 9.49.27 AM.png]
[image: Screenshot 2024-11-07 at 9.53.29 AM.png]

On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, <
discuss@lists.openscad.org> wrote:

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge
(and slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does
rounding and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a
number between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than
outside radius (or/od)")
assert(all_positive([tooth_angle]) &&
tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and
",360*(n-1)/2/n," for spline with ",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define
both chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value")
;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized
tooth height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going
around the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2),
valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts,
reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true,
col_wrap=true, row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The
line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the
theta for the chamfer “shoulder” point would be proportional to the chamfer
but it produces a slight error. It is barely noticeable but gets more
blatant at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) +
phiCA)
];


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


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Thanks David That book you share is good, but it is taking some time to absorb On Thu, 7 Nov, 2024, 11:53 am John David, <ebo.2112@gmail.com> wrote: > very nice! Thank you for sharing ;-) > > On Wed, Nov 6, 2024 at 11:59 PM Sanjeev Prabhakar via Discuss < > discuss@lists.openscad.org> wrote: > >> this is the final version (attached is the scad file) >> [image: Screenshot 2024-11-07 at 10.26.12 AM.png] >> >> On Thu, 7 Nov 2024 at 09:54, Sanjeev Prabhakar <sprabhakar2006@gmail.com> >> wrote: >> >>> I don't think the straight projection on cylinder will work. >>> The only way I think this can work is if you project using vectors >>> considering outer race and inner race, projecting outwards and inwards >>> respectively on outer and inner cylinder. >>> picture below can make this clear. >>> magenta lines are the vectors >>> [image: Screenshot 2024-11-07 at 9.49.27 AM.png] >>> [image: Screenshot 2024-11-07 at 9.53.29 AM.png] >>> >>> On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, < >>> discuss@lists.openscad.org> wrote: >>> >>>> Bob, I did I think exactly the same thing in my code and didn't notice >>>> anything, but now that you mention it, doing chamfers on an angular basis >>>> is of course not going to match doing them on a linear basis. So that >>>> means the geometry changes a bit if you change the chamfer size. This >>>> isn't necessarily catastrophic, but is a little unexpected, I suppose. >>>> Generally speaking you can't mate two parts produced with different chamfer >>>> size anyway, so I'm not sure this is crucial to get right. But in order to >>>> get it right, I think both thetaCA2 and phiCA are going to need to be >>>> computed with trig---either that or there's some complicated way of >>>> computing just one. The question is whether these two parameters can be >>>> computed independently or are they related in some complicated way. >>>> Treated as a 2d problem you are trying to get the angle that corresponds to >>>> a fraction of a chord of the circle, which is a reasonably straight forward >>>> triangle calculation. I got atan(chamfer*tan(angle)) where angle is >>>> 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't >>>> align with the unchamfered. For example: >>>> >>>> [image: image.png] >>>> >>>> Yellow is unchamfered. Blue has huge chamfer applied only at ridge >>>> (and slightly larger radius so we can see it clearly). And we see that the >>>> angle has changed. I actually got less error with the original >>>> calculation, but that might be because I didn't correct the phi angle only >>>> the theta angle. (Or maybe I botched the trig.) So I tried computing a >>>> correction for phi and got ridge_angle-atan(ridge_angle - >>>> chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line >>>> up correctly. (And the horizontal correction is still worse than not, >>>> which makes me wonder if the horizontal correction needs to take into >>>> account the vertical position of the chamfer somehow.) Doing the phi >>>> correction alone actually is an improvement over no correction. >>>> >>>> Here's my current code (without any chamfer corrections). It does >>>> rounding and skew teeth. >>>> >>>> module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, >>>> rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) >>>> { >>>> ir = get_radius(r=ir,d=id); >>>> or = get_radius(r=or,d=od); >>>> dummy = assert(all_positive([ir]), "ir/id must be a positive value") >>>> assert(all_positive([or]), "or/od must be a positive value") >>>> assert(is_int(n) && n>1, "n must be an integer larger than 1") >>>> assert(is_finite(skew) && abs(skew)<=1, "skew must be a >>>> number between -1 and 1") >>>> assert(ir<or, "inside radius (ir/id) must be smaller than >>>> outside radius (or/od)") >>>> assert(all_positive([tooth_angle]) && >>>> tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and >>>> ",360*(n-1)/2/n," for spline with ",n," teeth.")) >>>> assert(num_defined([chamfer,rounding]) <=1, "Cannot define >>>> both chamfer and rounding") >>>> assert(is_undef(chamfer) || all_nonnegative([chamfer]) && >>>> chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") >>>> assert(is_undef(rounding) || all_nonnegative([rounding]) && >>>> rounding<1/2, "rounding must be a non-negative value smaller than 1/2") >>>> assert(all_positive([base]), "base must be a positive value") >>>> ; >>>> tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized >>>> tooth height >>>> cone_height = -tan(cone_angle); // Normalized >>>> height change corresponding to the cone angle >>>> ridge_angle = atan(tooth_height/2 + cone_height); >>>> valley_angle = atan(-tooth_height/2 + cone_height); >>>> angle = 180/n; // Half the angle occupied by each tooth going >>>> around the circle >>>> >>>> factor = crop ? 3 : 1; // Make it oversized when crop is true >>>> >>>> profile = is_undef(rounding) || rounding==0 ? >>>> let( >>>> chamfer=default(chamfer,0), >>>> vchamf = chamfer*(ridge_angle-valley_angle), >>>> pts = [ >>>> [-angle*(1-chamfer/2), >>>> valley_angle+vchamf/2], >>>> [-angle*chamfer, ridge_angle-vchamf] >>>> ], >>>> full = deduplicate(concat(pts, >>>> reverse(xflip(pts)))) >>>> ) >>>> back(valley_angle, >>>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) >>>> : let( >>>> vround=rounding*(ridge_angle-valley_angle), >>>> profpts = [ >>>> [ -angle, valley_angle+vround/2], >>>> [ -angle*(1-rounding/2), >>>> valley_angle+vround/2], >>>> [ -angle*rounding, ridge_angle-vround], >>>> ], >>>> segs = max(16,segs(or*rounding)), >>>> full = concat(profpts, reverse(xflip(profpts))), >>>> skewed = back(valley_angle, >>>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), >>>> // Using computed values for the joints >>>> lead to round-off error issues >>>> joints = [(skewed[1]-skewed[0]).x, >>>> (skewed[3]-skewed[2]).x/2, >>>> (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], >>>> roundpts = round_corners(skewed, joint=joints, >>>> closed=false,$fn=segs) >>>> ) >>>> roundpts; >>>> >>>> // project spherical coordinate point onto cylinder of radius r >>>> cyl_proj = function (r,theta_phi) >>>> [for(pt=theta_phi) >>>> let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) >>>> r * xyz / norm(point2d(xyz))]; >>>> >>>> bottom = >>>> min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; >>>> safebottom = >>>> min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; >>>> ang_ofs = !rot ? -skew*angle >>>> : n%2==0 ? -(angle-skew*angle) - skew*angle >>>> : -angle*(2-skew)-skew*angle; >>>> topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>>> each >>>> zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); >>>> topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>>> each >>>> zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); >>>> botinner = [for(val=topinner) [val.x,val.y,safebottom]]; >>>> botouter = [for(val=topouter) [val.x,val.y,safebottom]]; >>>> vert = [topouter, topinner, botinner, botouter]; >>>> >>>> anchors = [ >>>> named_anchor("teeth_bot", [0,0,bottom], DOWN) >>>> ]; >>>> attachable(anchor=anchor,spin=spin,orient=orient, r=or, >>>> h=-2*bottom,anchors=anchors){ >>>> intersection(){ >>>> vnf_polyhedron(vnf_vertex_array(vert, reverse=true, >>>> col_wrap=true, row_wrap=true),convexity=min(10,n)); >>>> if (crop) >>>> >>>> zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); >>>> } >>>> children(); >>>> } >>>> } >>>> >>>> >>>> >>>> On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < >>>> discuss@lists.openscad.org> wrote: >>>> >>>>> I have established that there is an error in the code fragment. The >>>>> line >>>>> >>>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>>> >>>>> Is where the error lies. What should it be? I was assuming that the >>>>> theta for the chamfer “shoulder” point would be proportional to the chamfer >>>>> but it produces a slight error. It is barely noticeable but gets more >>>>> blatant at low tooth counts and high conic. >>>>> >>>>> Anyone see what it should be? I’m guessing there is some trig >>>>> functions involved,but ... >>>>> >>>>> -Bob >>>>> >>>>> On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < >>>>> discuss@lists.openscad.org> wrote: >>>>> >>>>> Here is just a code fragment but it gets the point across. >>>>> >>>>> IR = _ir(hs); >>>>> OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the >>>>> circumscribing polygon of N >>>>> >>>>> // Ridge Chamfer >>>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>>> phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; >>>>> >>>>> function profileToooth(r) = >>>>> [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + >>>>> phiCA), >>>>> spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), >>>>> spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), >>>>> spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + >>>>> phiCA) >>>>> ]; >>>>> >>>>> >>>>> _______________________________________________ >>>>> 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 >>>> >>> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >
AM
Adrian Mariano
Thu, Nov 7, 2024 11:29 AM

In the to picture, there is no cylinder pictured, but some complicated
shape with multiple curves, some of which are not even circular arcs.  So I
don't understand that picture.  You can try the code I posted earlier,
which uses the cylinder projection approach.

On Thu, Nov 7, 2024 at 6:23 AM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

All the magenta lines are vectors, you can think of them originating from
any side of the line.

Each line intersects a circumscribing cylinder outer or inner and that
forms the circular hirth coupling.

On Thu, 7 Nov, 2024, 4:40 pm Adrian Mariano, avm4@cornell.edu wrote:

I do not understand the pictures.  Or at least the top one is
mystifying.  The bottom one looks like it could describe the process: the
projection is along vectors that originate at the origin and yes, you have
a separate projection onto the inner and outer cylinder.

On Wed, Nov 6, 2024 at 11:24 PM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I don't think the straight projection on cylinder will work.
The only way I think this can work is if you project using vectors
considering outer race and inner race, projecting outwards and inwards
respectively on outer and inner cylinder.
picture below can make this clear.
magenta lines are the vectors
[image: Screenshot 2024-11-07 at 9.49.27 AM.png]
[image: Screenshot 2024-11-07 at 9.53.29 AM.png]

On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, <
discuss@lists.openscad.org> wrote:

Bob, I did I think exactly the same thing in my code and didn't notice
anything, but now that you mention it, doing chamfers on an angular basis
is of course not going to match doing them on a linear basis.  So that
means the geometry changes a bit if you change the chamfer size.  This
isn't necessarily catastrophic, but is a little unexpected, I suppose.
Generally speaking you can't mate two parts produced with different chamfer
size anyway, so I'm not sure this is crucial to get right.  But in order to
get it right, I think both thetaCA2 and phiCA are going to need to be
computed with trig---either that or there's some complicated way of
computing just one.  The question is whether these two parameters can be
computed independently or are they related in some complicated way.
Treated as a 2d problem you are trying to get the angle that corresponds to
a fraction of a chord of the circle, which is a reasonably straight forward
triangle calculation.  I got atan(chamfer*tan(angle)) where angle is
180/tooth_count for the ridge chamfer.  But the chamfered one still doesn't
align with the unchamfered.  For example:

[image: image.png]

Yellow is unchamfered.  Blue has huge chamfer applied only at ridge
(and slightly larger radius so we can see it clearly).  And we see that the
angle has changed.  I actually got less error with the original
calculation, but that might be because I didn't correct the phi angle only
the theta angle.  (Or maybe I botched the trig.)  So I tried computing a
correction for phi and got ridge_angle-atan(ridge_angle -
chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line
up correctly.  (And the horizontal correction is still worse than not,
which makes me wonder if the horizontal correction needs to take into
account the vertical position of the chamfer somehow.)  Doing the phi
correction alone actually is an improvement over no correction.

Here's my current code (without any chamfer corrections).  It does
rounding and skew teeth.

module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer,
rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin)
{
ir = get_radius(r=ir,d=id);
or = get_radius(r=or,d=od);
dummy = assert(all_positive([ir]), "ir/id must be a positive value")
assert(all_positive([or]), "or/od must be a positive value")
assert(is_int(n) && n>1, "n must be an integer larger than 1")
assert(is_finite(skew) && abs(skew)<=1, "skew must be a
number between -1 and 1")
assert(ir<or, "inside radius (ir/id) must be smaller than
outside radius (or/od)")
assert(all_positive([tooth_angle]) &&
tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and
",360*(n-1)/2/n," for spline with ",n," teeth."))
assert(num_defined([chamfer,rounding]) <=1, "Cannot define
both chamfer and rounding")
assert(is_undef(chamfer) || all_nonnegative([chamfer]) &&
chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2")
assert(is_undef(rounding) || all_nonnegative([rounding]) &&
rounding<1/2, "rounding must be a non-negative value smaller than 1/2")
assert(all_positive([base]), "base must be a positive value")
;
tooth_height = sin(180/n) / tan(tooth_angle/2);    // Normalized
tooth height
cone_height = -tan(cone_angle);                        // Normalized
height change corresponding to the cone angle
ridge_angle = atan(tooth_height/2 + cone_height);
valley_angle = atan(-tooth_height/2 + cone_height);
angle = 180/n;    // Half the angle occupied by each tooth going
around the circle

factor = crop ? 3 : 1;  // Make it oversized when crop is true

profile = is_undef(rounding) || rounding==0 ?
let(
chamfer=default(chamfer,0),
vchamf = chamfer*(ridge_angle-valley_angle),
pts = [
[-angle*(1-chamfer/2),
valley_angle+vchamf/2],
[-anglechamfer, ridge_angle-vchamf]
],
full = deduplicate(concat(pts,
reverse(xflip(pts))))
)
back(valley_angle,
skew(sxy=skew
angle/(ridge_angle-valley_angle),fwd(valley_angle,full)))
: let(
vround=rounding*(ridge_angle-valley_angle),
profpts = [
[  -angle, valley_angle+vround/2],
[  -angle*(1-rounding/2),
valley_angle+vround/2],
[  -anglerounding, ridge_angle-vround],
],
segs = max(16,segs(or
rounding)),
full = concat(profpts, reverse(xflip(profpts))),
skewed = back(valley_angle,
skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))),
// Using computed values for the joints
lead to round-off error issues
joints = [(skewed[1]-skewed[0]).x,
(skewed[3]-skewed[2]).x/2,
(skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ],
roundpts = round_corners(skewed, joint=joints,
closed=false,$fn=segs)
)
roundpts;

// project spherical coordinate point onto cylinder of radius r
cyl_proj = function (r,theta_phi)
[for(pt=theta_phi)
let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1]))
r * xyz / norm(point2d(xyz))];

bottom =
min([tan(valley_angle)ir,tan(valley_angle)or])-base-cone_heightir;
safebottom =
min([tan(valley_angle)ir/factor,tan(valley_angle)orfactor])-base-(crop?1:0)-cone_heightir;
ang_ofs = !rot ? -skew
angle
:  n%2==0 ? -(angle-skewangle)  - skewangle
:  -angle*(2-skew)-skewangle;
topinner = down(cone_height
ir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
topouter = down(cone_heightir,[for(ang=lerpn(0,360,n,endpoint=false))
each
zrot(ang+ang_ofs,cyl_proj(factor
or,profile))]);
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
vert = [topouter, topinner, botinner, botouter];

anchors = [
named_anchor("teeth_bot", [0,0,bottom], DOWN)
];
attachable(anchor=anchor,spin=spin,orient=orient, r=or,
h=-2*bottom,anchors=anchors){
intersection(){
vnf_polyhedron(vnf_vertex_array(vert, reverse=true,
col_wrap=true, row_wrap=true),convexity=min(10,n));
if (crop)

zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1);
}
children();
}
}

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The
line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the
theta for the chamfer “shoulder” point would be proportional to the chamfer
but it produces a slight error. It is barely noticeable but gets more
blatant at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) +
phiCA)
];


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 the to picture, there is no cylinder pictured, but some complicated shape with multiple curves, some of which are not even circular arcs. So I don't understand that picture. You can try the code I posted earlier, which uses the cylinder projection approach. On Thu, Nov 7, 2024 at 6:23 AM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > All the magenta lines are vectors, you can think of them originating from > any side of the line. > > Each line intersects a circumscribing cylinder outer or inner and that > forms the circular hirth coupling. > > > > On Thu, 7 Nov, 2024, 4:40 pm Adrian Mariano, <avm4@cornell.edu> wrote: > >> I do not understand the pictures. Or at least the top one is >> mystifying. The bottom one looks like it could describe the process: the >> projection is along vectors that originate at the origin and yes, you have >> a separate projection onto the inner and outer cylinder. >> >> On Wed, Nov 6, 2024 at 11:24 PM Sanjeev Prabhakar < >> sprabhakar2006@gmail.com> wrote: >> >>> I don't think the straight projection on cylinder will work. >>> The only way I think this can work is if you project using vectors >>> considering outer race and inner race, projecting outwards and inwards >>> respectively on outer and inner cylinder. >>> picture below can make this clear. >>> magenta lines are the vectors >>> [image: Screenshot 2024-11-07 at 9.49.27 AM.png] >>> [image: Screenshot 2024-11-07 at 9.53.29 AM.png] >>> >>> On Thu, 7 Nov, 2024, 8:12 am Adrian Mariano via Discuss, < >>> discuss@lists.openscad.org> wrote: >>> >>>> Bob, I did I think exactly the same thing in my code and didn't notice >>>> anything, but now that you mention it, doing chamfers on an angular basis >>>> is of course not going to match doing them on a linear basis. So that >>>> means the geometry changes a bit if you change the chamfer size. This >>>> isn't necessarily catastrophic, but is a little unexpected, I suppose. >>>> Generally speaking you can't mate two parts produced with different chamfer >>>> size anyway, so I'm not sure this is crucial to get right. But in order to >>>> get it right, I think both thetaCA2 and phiCA are going to need to be >>>> computed with trig---either that or there's some complicated way of >>>> computing just one. The question is whether these two parameters can be >>>> computed independently or are they related in some complicated way. >>>> Treated as a 2d problem you are trying to get the angle that corresponds to >>>> a fraction of a chord of the circle, which is a reasonably straight forward >>>> triangle calculation. I got atan(chamfer*tan(angle)) where angle is >>>> 180/tooth_count for the ridge chamfer. But the chamfered one still doesn't >>>> align with the unchamfered. For example: >>>> >>>> [image: image.png] >>>> >>>> Yellow is unchamfered. Blue has huge chamfer applied only at ridge >>>> (and slightly larger radius so we can see it clearly). And we see that the >>>> angle has changed. I actually got less error with the original >>>> calculation, but that might be because I didn't correct the phi angle only >>>> the theta angle. (Or maybe I botched the trig.) So I tried computing a >>>> correction for phi and got ridge_angle-atan(ridge_angle - >>>> chamfer*(tan(ridge_angle)-tan(valley_angle))), but still things don't line >>>> up correctly. (And the horizontal correction is still worse than not, >>>> which makes me wonder if the horizontal correction needs to take into >>>> account the vertical position of the chamfer somehow.) Doing the phi >>>> correction alone actually is an improvement over no correction. >>>> >>>> Here's my current code (without any chamfer corrections). It does >>>> rounding and skew teeth. >>>> >>>> module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, >>>> rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) >>>> { >>>> ir = get_radius(r=ir,d=id); >>>> or = get_radius(r=or,d=od); >>>> dummy = assert(all_positive([ir]), "ir/id must be a positive value") >>>> assert(all_positive([or]), "or/od must be a positive value") >>>> assert(is_int(n) && n>1, "n must be an integer larger than 1") >>>> assert(is_finite(skew) && abs(skew)<=1, "skew must be a >>>> number between -1 and 1") >>>> assert(ir<or, "inside radius (ir/id) must be smaller than >>>> outside radius (or/od)") >>>> assert(all_positive([tooth_angle]) && >>>> tooth_angle<360*(n-1)/2/n, str("tooth angle must be between 0 and >>>> ",360*(n-1)/2/n," for spline with ",n," teeth.")) >>>> assert(num_defined([chamfer,rounding]) <=1, "Cannot define >>>> both chamfer and rounding") >>>> assert(is_undef(chamfer) || all_nonnegative([chamfer]) && >>>> chamfer<1/2, "chamfer must be a non-negative value smaller than 1/2") >>>> assert(is_undef(rounding) || all_nonnegative([rounding]) && >>>> rounding<1/2, "rounding must be a non-negative value smaller than 1/2") >>>> assert(all_positive([base]), "base must be a positive value") >>>> ; >>>> tooth_height = sin(180/n) / tan(tooth_angle/2); // Normalized >>>> tooth height >>>> cone_height = -tan(cone_angle); // Normalized >>>> height change corresponding to the cone angle >>>> ridge_angle = atan(tooth_height/2 + cone_height); >>>> valley_angle = atan(-tooth_height/2 + cone_height); >>>> angle = 180/n; // Half the angle occupied by each tooth going >>>> around the circle >>>> >>>> factor = crop ? 3 : 1; // Make it oversized when crop is true >>>> >>>> profile = is_undef(rounding) || rounding==0 ? >>>> let( >>>> chamfer=default(chamfer,0), >>>> vchamf = chamfer*(ridge_angle-valley_angle), >>>> pts = [ >>>> [-angle*(1-chamfer/2), >>>> valley_angle+vchamf/2], >>>> [-angle*chamfer, ridge_angle-vchamf] >>>> ], >>>> full = deduplicate(concat(pts, >>>> reverse(xflip(pts)))) >>>> ) >>>> back(valley_angle, >>>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))) >>>> : let( >>>> vround=rounding*(ridge_angle-valley_angle), >>>> profpts = [ >>>> [ -angle, valley_angle+vround/2], >>>> [ -angle*(1-rounding/2), >>>> valley_angle+vround/2], >>>> [ -angle*rounding, ridge_angle-vround], >>>> ], >>>> segs = max(16,segs(or*rounding)), >>>> full = concat(profpts, reverse(xflip(profpts))), >>>> skewed = back(valley_angle, >>>> skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full))), >>>> // Using computed values for the joints >>>> lead to round-off error issues >>>> joints = [(skewed[1]-skewed[0]).x, >>>> (skewed[3]-skewed[2]).x/2, >>>> (skewed[3]-skewed[2]).x/2,(skewed[5]-skewed[4]).x ], >>>> roundpts = round_corners(skewed, joint=joints, >>>> closed=false,$fn=segs) >>>> ) >>>> roundpts; >>>> >>>> // project spherical coordinate point onto cylinder of radius r >>>> cyl_proj = function (r,theta_phi) >>>> [for(pt=theta_phi) >>>> let(xyz = spherical_to_xyz(1,pt[0], 90-pt[1])) >>>> r * xyz / norm(point2d(xyz))]; >>>> >>>> bottom = >>>> min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir; >>>> safebottom = >>>> min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir; >>>> ang_ofs = !rot ? -skew*angle >>>> : n%2==0 ? -(angle-skew*angle) - skew*angle >>>> : -angle*(2-skew)-skew*angle; >>>> topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>>> each >>>> zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]); >>>> topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false)) >>>> each >>>> zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]); >>>> botinner = [for(val=topinner) [val.x,val.y,safebottom]]; >>>> botouter = [for(val=topouter) [val.x,val.y,safebottom]]; >>>> vert = [topouter, topinner, botinner, botouter]; >>>> >>>> anchors = [ >>>> named_anchor("teeth_bot", [0,0,bottom], DOWN) >>>> ]; >>>> attachable(anchor=anchor,spin=spin,orient=orient, r=or, >>>> h=-2*bottom,anchors=anchors){ >>>> intersection(){ >>>> vnf_polyhedron(vnf_vertex_array(vert, reverse=true, >>>> col_wrap=true, row_wrap=true),convexity=min(10,n)); >>>> if (crop) >>>> >>>> zmove(bottom)tube(or=or,ir=ir,height=4*or,anchor=BOT,$fa=1,$fs=1); >>>> } >>>> children(); >>>> } >>>> } >>>> >>>> >>>> >>>> On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < >>>> discuss@lists.openscad.org> wrote: >>>> >>>>> I have established that there is an error in the code fragment. The >>>>> line >>>>> >>>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>>> >>>>> Is where the error lies. What should it be? I was assuming that the >>>>> theta for the chamfer “shoulder” point would be proportional to the chamfer >>>>> but it produces a slight error. It is barely noticeable but gets more >>>>> blatant at low tooth counts and high conic. >>>>> >>>>> Anyone see what it should be? I’m guessing there is some trig >>>>> functions involved,but ... >>>>> >>>>> -Bob >>>>> >>>>> On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < >>>>> discuss@lists.openscad.org> wrote: >>>>> >>>>> Here is just a code fragment but it gets the point across. >>>>> >>>>> IR = _ir(hs); >>>>> OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the >>>>> circumscribing polygon of N >>>>> >>>>> // Ridge Chamfer >>>>> thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; >>>>> phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; >>>>> >>>>> function profileToooth(r) = >>>>> [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + >>>>> phiCA), >>>>> spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), >>>>> spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), >>>>> spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + >>>>> phiCA) >>>>> ]; >>>>> >>>>> >>>>> _______________________________________________ >>>>> 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
Thu, Nov 7, 2024 12:33 PM

Hi Sanjeev,

Thanks for testing it, I get no warnings or errors, unless i use less
than three ridges, or other  inappropriate values. I'm guessing it's an
openscad version difference. I think my geometry is good enough for me,
but probably not bullet proof.

On 06/11/2024 02:21, Sanjeev Prabhakar via Discuss wrote:

Hi Ray
I tried your code and it is almost instant render and there are no
issues in the manifold which I use during f6 render. There are some
warnings but that's fine

On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss
discuss@lists.openscad.org wrote:

Hi Sanjeev, Thanks for testing it, I get no warnings or errors, unless i use less than three ridges, or other  inappropriate values. I'm guessing it's an openscad version difference. I think my geometry is good enough for me, but probably not bullet proof. On 06/11/2024 02:21, Sanjeev Prabhakar via Discuss wrote: > Hi Ray > I tried your code and it is almost instant render and there are no > issues in the manifold which I use during f6 render. There are some > warnings but that's fine > > On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss > <discuss@lists.openscad.org> wrote: >
RW
Raymond West
Thu, Nov 7, 2024 12:49 PM

Hi Ken,

Thanks for testing, I get no errors with  OpenSCAD version 2024.02.19
(git 5cfd4dbe0), but it may be other reasons. I think my geometry is
good enough with reasonable parameters. However, I expect there is the
usual z fighting taking place, since the various parts probably do not
overlap sufficiently in some cases. I expect, using cadquery (which uses
a different rendering engine) the geometry may work with different errors.

On 05/11/2024 23:32, Ken via Discuss wrote:

I tried it on mine- I'm using version 2024.10.2 git e972ed84e.
F5 takes 0.059 seconds, f6 0.096 seconds.
I get-

"WARNING: PolySet -> Manifold conversion failed: NotManifold
Trying to repair and reconstruct mesh.."

four times, then it continues to render with no further errors. I have
just finished printing two of them so I can have a play.

On 2024-11-06 09:27, Adrian Mariano via Discuss wrote:

Ray, I tried your code and (1) preview is very very slow on my
machine and (2) render gives

Rendering Polygon Mesh using CGAL...

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

ERROR: The given mesh is not closed! Unable to convert to
CGAL_Nef_Polyhedron.

Geometries in cache: 9903

I'm now convinced that Bob has the right basic approach. The key
thing is the idea of projecting onto a cylinder. Working in spherical
coordinates never made sense to me, but for some reason the idea of
just projecting points onto a cylinder didn't occur to me. (At one
point I thought about doing it, but with equations, not with code,
which was a bad idea.) With this insight I can now make roundings
while creating the object as a single polyhedron:

image.png

On Tue, Nov 5, 2024 at 12:54 PM Raymond West via Discuss
discuss@lists.openscad.org wrote:

 I've modified it slightly, to allow the tooth angle to be set -
 In manufacturing, most likely a 60 or 90 degree angle. I've also
 included the angle to set the rotary table, and added a method of
 flattening the tips. I think this could 3d printed OK, I've yet
 to test. The stl would not be used in any other manufacturing
 process, afaik. For machining, It could be set up directly from
 the parameters. I've attached the code below. The flattening of
 the peaks give a slight taper. Adding an extra triangle to the
 polyhedron, could generate a more tapered width to the flat top,
 but for whatever use I may put this too, if any, it is unlikely
 to make much difference.

 The code will produce a viable stl, for any number of teeth, 
 including three and upwards, and it f6 renders fast enough.

 Here is a link to some curvic coupling design, which is a bit
 more involved to generate -
 https://www.geartechnology.com/articles/20867-curvic-coupling-design.


 On 04/11/2024 17:05, Raymond West via Discuss wrote:
 found it- etc.
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

--
Cheers, Ken
bats059@gmail.com
https://vk7krj.com
https://vk7krj.com/running.html

A baby can be defined as an ego with a noise at one end and a smell at the other.
Your job as parents is to teach them to control all three.
My job as a grandad is to tell you how you are doing it all wrong!


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

Hi Ken, Thanks for testing, I get no errors with  OpenSCAD version 2024.02.19 (git 5cfd4dbe0), but it may be other reasons. I think my geometry is good enough with reasonable parameters. However, I expect there is the usual z fighting taking place, since the various parts probably do not overlap sufficiently in some cases. I expect, using cadquery (which uses a different rendering engine) the geometry may work with different errors. On 05/11/2024 23:32, Ken via Discuss wrote: > I tried it on mine- I'm using version 2024.10.2 git e972ed84e. > F5 takes 0.059 seconds, f6 0.096 seconds. > I get- > > "WARNING: PolySet -> Manifold conversion failed: NotManifold > Trying to repair and reconstruct mesh.." > > four times, then it continues to render with no further errors. I have > just finished printing two of them so I can have a play. > > > On 2024-11-06 09:27, Adrian Mariano via Discuss wrote: >> Ray, I tried your code and (1) preview is very very slow on my >> machine and (2) render gives >> >> Rendering Polygon Mesh using CGAL... >> >> ERROR: The given mesh is not closed! Unable to convert to >> CGAL_Nef_Polyhedron. >> >> ERROR: The given mesh is not closed! Unable to convert to >> CGAL_Nef_Polyhedron. >> >> ERROR: The given mesh is not closed! Unable to convert to >> CGAL_Nef_Polyhedron. >> >> ERROR: The given mesh is not closed! Unable to convert to >> CGAL_Nef_Polyhedron. >> >> ERROR: The given mesh is not closed! Unable to convert to >> CGAL_Nef_Polyhedron. >> >> Geometries in cache: 9903 >> >> >> I'm now convinced that Bob has the right basic approach. The key >> thing is the idea of projecting onto a cylinder. Working in spherical >> coordinates never made sense to me, but for some reason the idea of >> just projecting points onto a cylinder didn't occur to me. (At one >> point I thought about doing it, but with equations, not with code, >> which was a bad idea.) With this insight I can now make roundings >> while creating the object as a single polyhedron: >> >> >> image.png >> >> >> >> >> On Tue, Nov 5, 2024 at 12:54 PM Raymond West via Discuss >> <discuss@lists.openscad.org> wrote: >> >> I've modified it slightly, to allow the tooth angle to be set - >> In manufacturing, most likely a 60 or 90 degree angle. I've also >> included the angle to set the rotary table, and added a method of >> flattening the tips. I think this could 3d printed OK, I've yet >> to test. The stl would not be used in any other manufacturing >> process, afaik. For machining, It could be set up directly from >> the parameters. I've attached the code below. The flattening of >> the peaks give a slight taper. Adding an extra triangle to the >> polyhedron, could generate a more tapered width to the flat top, >> but for whatever use I may put this too, if any, it is unlikely >> to make much difference. >> >> The code will produce a viable stl, for any number of teeth,  >> including three and upwards, and it f6 renders fast enough. >> >> Here is a link to some curvic coupling design, which is a bit >> more involved to generate - >> https://www.geartechnology.com/articles/20867-curvic-coupling-design. >> >> >> On 04/11/2024 17:05, Raymond West via Discuss wrote: >>> >>> found it- etc. >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > > -- > Cheers, Ken > bats059@gmail.com > https://vk7krj.com > https://vk7krj.com/running.html > ---------------------------------------- > A baby can be defined as an ego with a noise at one end and a smell at the other. > Your job as parents is to teach them to control all three. > My job as a grandad is to tell you how you are doing it all wrong! > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
SP
Sanjeev Prabhakar
Thu, Nov 7, 2024 2:18 PM

I think my geometry is good enough for me

Yes sure It works and that's what matters. anyways it's not a fatal error

On Thu, 7 Nov 2024 at 18:03, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

Hi Sanjeev,

Thanks for testing it, I get no warnings or errors, unless i use less than
three ridges, or other  inappropriate values. I'm guessing it's an openscad
version difference. I think my geometry is good enough for me, but probably
not bullet proof.
On 06/11/2024 02:21, Sanjeev Prabhakar via Discuss wrote:

Hi Ray
I tried your code and it is almost instant render and there are no issues
in the manifold which I use during f6 render. There are some warnings but
that's fine

On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

> I think my geometry is good enough for me Yes sure It works and that's what matters. anyways it's not a fatal error On Thu, 7 Nov 2024 at 18:03, Raymond West via Discuss < discuss@lists.openscad.org> wrote: > Hi Sanjeev, > > Thanks for testing it, I get no warnings or errors, unless i use less than > three ridges, or other inappropriate values. I'm guessing it's an openscad > version difference. I think my geometry is good enough for me, but probably > not bullet proof. > On 06/11/2024 02:21, Sanjeev Prabhakar via Discuss wrote: > > Hi Ray > I tried your code and it is almost instant render and there are no issues > in the manifold which I use during f6 render. There are some warnings but > that's fine > > On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss < > discuss@lists.openscad.org> wrote: > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Thu, Nov 7, 2024 8:15 PM

All errors are fatal when you run with the stop on first warning feature,
which is generally necessary to avoid overwhelming useless cascading error
messages.

Under the stable openscad that I used the model fails to render using the
code exactly as posted. This is because it contains some reversed faces
that can be seen with thrown together. I didn’t know that manifold would
fix those with a warning. I generally prefer to use polyhedron creation
tools to make fully valid face sets.

Even after fixing that problem something else is wrong because I get the
message that the object may not be a valid 2-manifold. I don’t know what
the other problem is. Maybe it’s because wedges touch at their edges?

The problem of sluggish preview also remains.

On Thu, Nov 7, 2024 at 09:19 Sanjeev Prabhakar via Discuss <
discuss@lists.openscad.org> wrote:

I think my geometry is good enough for me

Yes sure It works and that's what matters. anyways it's not a fatal error

On Thu, 7 Nov 2024 at 18:03, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

Hi Sanjeev,

Thanks for testing it, I get no warnings or errors, unless i use less
than three ridges, or other  inappropriate values. I'm guessing it's an
openscad version difference. I think my geometry is good enough for me, but
probably not bullet proof.
On 06/11/2024 02:21, Sanjeev Prabhakar via Discuss wrote:

Hi Ray
I tried your code and it is almost instant render and there are no issues
in the manifold which I use during f6 render. There are some warnings but
that's fine

On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:


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

All errors are fatal when you run with the stop on first warning feature, which is generally necessary to avoid overwhelming useless cascading error messages. Under the stable openscad that I used the model fails to render using the code exactly as posted. This is because it contains some reversed faces that can be seen with thrown together. I didn’t know that manifold would fix those with a warning. I generally prefer to use polyhedron creation tools to make fully valid face sets. Even after fixing that problem something else is wrong because I get the message that the object may not be a valid 2-manifold. I don’t know what the other problem is. Maybe it’s because wedges touch at their edges? The problem of sluggish preview also remains. On Thu, Nov 7, 2024 at 09:19 Sanjeev Prabhakar via Discuss < discuss@lists.openscad.org> wrote: > > I think my geometry is good enough for me > > Yes sure It works and that's what matters. anyways it's not a fatal error > > On Thu, 7 Nov 2024 at 18:03, Raymond West via Discuss < > discuss@lists.openscad.org> wrote: > >> Hi Sanjeev, >> >> Thanks for testing it, I get no warnings or errors, unless i use less >> than three ridges, or other inappropriate values. I'm guessing it's an >> openscad version difference. I think my geometry is good enough for me, but >> probably not bullet proof. >> On 06/11/2024 02:21, Sanjeev Prabhakar via Discuss wrote: >> >> Hi Ray >> I tried your code and it is almost instant render and there are no issues >> in the manifold which I use during f6 render. There are some warnings but >> that's fine >> >> On Tue, 5 Nov 2024 at 23:24, Raymond West via Discuss < >> discuss@lists.openscad.org> wrote: >> >> _______________________________________________ >> 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 >
AM
Adrian Mariano
Thu, Nov 7, 2024 10:13 PM

I think that to get this right you basically need to take the top point of
the triangle and one of the bottom points of the triangle in their position
projected onto the cylinder, represent in cartesian coordinates, then
interpolate appropriately between them by the chamfer fraction, then
convert back to spherical coordinates to extract the angles.  You can work
through those steps to get some complicated formula, but it looked messy.
I couldn't think of any simpler approach.

On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I have established that there is an error in the code fragment. The line

 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;

Is where the error lies. What should it be? I was assuming that the theta
for the chamfer “shoulder” point would be proportional to the chamfer but
it produces a slight error. It is barely noticeable but gets more blatant
at low tooth counts and high conic.

Anyone see what it should be? I’m guessing there is some trig
functions involved,but ...

-Bob

On Nov 5, 2024, at 10:29, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

Here is just a code fragment but it gets the point across.

 IR = _ir(hs);
 OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the

circumscribing polygon of N

 // Ridge Chamfer
 thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200;
 phiCA   =  (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100;

 function profileToooth(r) =
      [spherical2_to_xyz(r,  thetaCA2,          _ridgeAngle(hs) +

phiCA),
spherical2_to_xyz(r,  _toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)),
spherical2_to_xyz(r, - thetaCA2,        _ridgeAngle(hs) + phiCA)
];


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I think that to get this right you basically need to take the top point of the triangle and one of the bottom points of the triangle in their position projected onto the cylinder, represent in cartesian coordinates, then interpolate appropriately between them by the chamfer fraction, then convert back to spherical coordinates to extract the angles. You can work through those steps to get some complicated formula, but it looked messy. I couldn't think of any simpler approach. On Wed, Nov 6, 2024 at 7:55 PM Bob Carlson via Discuss < discuss@lists.openscad.org> wrote: > I have established that there is an error in the code fragment. The line > > thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; > > Is where the error lies. What should it be? I was assuming that the theta > for the chamfer “shoulder” point would be proportional to the chamfer but > it produces a slight error. It is barely noticeable but gets more blatant > at low tooth counts and high conic. > > Anyone see what it should be? I’m guessing there is some trig > functions involved,but ... > > -Bob > > On Nov 5, 2024, at 10:29, Bob Carlson via Discuss < > discuss@lists.openscad.org> wrote: > > Here is just a code fragment but it gets the point across. > > IR = _ir(hs); > OR = _or(hs) / cos(180/_n(hs)); // OR is the radius of the > circumscribing polygon of N > > // Ridge Chamfer > thetaCA2 = _toothAngle(hs) * _chamfer(hs)/200; > phiCA = (_grooveAngle(hs) -_ridgeAngle(hs)) * _chamfer(hs)/100; > > function profileToooth(r) = > [spherical2_to_xyz(r, thetaCA2, _ridgeAngle(hs) + > phiCA), > spherical2_to_xyz(r, _toothAngle(hs)/2, _grooveAngle(hs)), > spherical2_to_xyz(r, -_toothAngle(hs)/2, _grooveAngle(hs)), > spherical2_to_xyz(r, - thetaCA2, _ridgeAngle(hs) + phiCA) > ]; > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
BC
Bob Carlson
Fri, Nov 8, 2024 4:39 PM

That sounds promising. I tried a lot of stuff but not that and nothing worked quite right. I’ve tweaked my code now to make the chamfer by subtracting later. It’s quite easy. The other thing I did is make 2 half tooth profiles instead of one whole. Now N = 2 works. I also found that skin() did not work at low tooth counts and had to use a combination of skin and hull. If two profiles are very different sizes and far apart, that seemed to be the problem area. I use skin to make thin wafers then hull the wafers together. I suppose some schemes where I generate many profiles close together would work too.

Maybe after I finish this version I’m make one more trial of your idea.

-Bob

On Nov 7, 2024, at 15:13, Adrian Mariano avm4@cornell.edu wrote:

I think that to get this right you basically need to take the top point of the triangle and one of the bottom points of the triangle in their position projected onto the cylinder, represent in cartesian coordinates, then interpolate appropriately between them by the chamfer fraction, then convert back to spherical coordinates to extract the angles.  You can work through those steps to get some complicated formula, but it looked messy.  I couldn't think of any simpler approach.

That sounds promising. I tried a lot of stuff but not that and nothing worked quite right. I’ve tweaked my code now to make the chamfer by subtracting later. It’s quite easy. The other thing I did is make 2 half tooth profiles instead of one whole. Now N = 2 works. I also found that skin() did not work at low tooth counts and had to use a combination of skin and hull. If two profiles are very different sizes and far apart, that seemed to be the problem area. I use skin to make thin wafers then hull the wafers together. I suppose some schemes where I generate many profiles close together would work too. Maybe after I finish this version I’m make one more trial of your idea. -Bob > On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu> wrote: > > I think that to get this right you basically need to take the top point of the triangle and one of the bottom points of the triangle in their position projected onto the cylinder, represent in cartesian coordinates, then interpolate appropriately between them by the chamfer fraction, then convert back to spherical coordinates to extract the angles. You can work through those steps to get some complicated formula, but it looked messy. I couldn't think of any simpler approach. >
AM
Adrian Mariano
Fri, Nov 8, 2024 5:37 PM

I implemented the method I suggested. It was pretty easy to do and works.
I do not understand your problem with skin.  How does it fail?  I construct
mine using vnf_vertex_array which is like skin without fancy point
alignment, and have no issues.  It shouldn’t matter how far apart the
profiles are or how different the scale. Skin just connects the points you
give it to make the polyhedron.

I do have a problem with rounding. The rounding isn’t at the right angle
which leads to a corner where it joins the

I thought the 2 tooth case was working for me but more thorough
investigation revealed problems in the case of skewed teeth. I’ll have to
ponder that.

On Fri, Nov 8, 2024 at 11:39 Bob Carlson bob@rjcarlson.com wrote:

That sounds promising. I tried a lot of stuff but not that and nothing
worked quite right. I’ve tweaked my code now to make the chamfer by
subtracting later. It’s quite easy. The other thing I did is make 2 half
tooth profiles instead of one whole. Now N = 2 works. I also found that
skin() did not work at low tooth counts and had to use a combination of
skin and hull. If two profiles are very different sizes and far apart, that
seemed to be the problem area. I use skin to make thin wafers then hull the
wafers together. I suppose some schemes where I generate many profiles
close together would work too.

Maybe after I finish this version I’m make one more trial of your idea.

-Bob

On Nov 7, 2024, at 15:13, Adrian Mariano avm4@cornell.edu wrote:

I think that to get this right you basically need to take the top point

of the triangle and one of the bottom points of the triangle in their
position projected onto the cylinder, represent in cartesian coordinates,
then interpolate appropriately between them by the chamfer fraction, then
convert back to spherical coordinates to extract the angles.  You can work
through those steps to get some complicated formula, but it looked messy.
I couldn't think of any simpler approach.

I implemented the method I suggested. It was pretty easy to do and works. I do not understand your problem with skin. How does it fail? I construct mine using vnf_vertex_array which is like skin without fancy point alignment, and have no issues. It shouldn’t matter how far apart the profiles are or how different the scale. Skin just connects the points you give it to make the polyhedron. I do have a problem with rounding. The rounding isn’t at the right angle which leads to a corner where it joins the I thought the 2 tooth case was working for me but more thorough investigation revealed problems in the case of skewed teeth. I’ll have to ponder that. On Fri, Nov 8, 2024 at 11:39 Bob Carlson <bob@rjcarlson.com> wrote: > That sounds promising. I tried a lot of stuff but not that and nothing > worked quite right. I’ve tweaked my code now to make the chamfer by > subtracting later. It’s quite easy. The other thing I did is make 2 half > tooth profiles instead of one whole. Now N = 2 works. I also found that > skin() did not work at low tooth counts and had to use a combination of > skin and hull. If two profiles are very different sizes and far apart, that > seemed to be the problem area. I use skin to make thin wafers then hull the > wafers together. I suppose some schemes where I generate many profiles > close together would work too. > > Maybe after I finish this version I’m make one more trial of your idea. > > -Bob > > > On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu> wrote: > > > > I think that to get this right you basically need to take the top point > of the triangle and one of the bottom points of the triangle in their > position projected onto the cylinder, represent in cartesian coordinates, > then interpolate appropriately between them by the chamfer fraction, then > convert back to spherical coordinates to extract the angles. You can work > through those steps to get some complicated formula, but it looked messy. > I couldn't think of any simpler approach. > > > >
BC
Bob Carlson
Thu, Nov 14, 2024 11:25 PM

I’ve attached my code that I now believe is debugged and working reliably. It supports all the way down to N=2 (teeth). Depending on N it renders in .25 to .5 s. Preview is similar.

When N = 2 or 3 this is an edge condition that required a lot of testing and work. The other area that caused the most problems was when the “coned” argument was at or around half the tooth height (as measured at the outer radius.) Around this point any auxiliary shapes you use to add a base, add or subtract a chamfer etc, switch from concave to convex or vice versa.

One file is Customizer enabled and serves as the test platform for the second file where all the working code is. The test file also includes some visualization aids that I wrote to help see exactly what is going on.

A note about the anchors. They are all relative to the entire joint. This makes it easier to position both parts in a larger assembly in a way that insures the parts mesh exactly.

-Bob



On Nov 8, 2024, at 10:37, Adrian Mariano avm4@cornell.edu wrote:

I implemented the method I suggested. It was pretty easy to do and works.  I do not understand your problem with skin.  How does it fail?  I construct mine using vnf_vertex_array which is like skin without fancy point alignment, and have no issues.  It shouldn’t matter how far apart the profiles are or how different the scale. Skin just connects the points you give it to make the polyhedron.

I do have a problem with rounding. The rounding isn’t at the right angle which leads to a corner where it joins the

I thought the 2 tooth case was working for me but more thorough investigation revealed problems in the case of skewed teeth. I’ll have to ponder that.

On Fri, Nov 8, 2024 at 11:39 Bob Carlson <bob@rjcarlson.com mailto:bob@rjcarlson.com> wrote:

That sounds promising. I tried a lot of stuff but not that and nothing worked quite right. I’ve tweaked my code now to make the chamfer by subtracting later. It’s quite easy. The other thing I did is make 2 half tooth profiles instead of one whole. Now N = 2 works. I also found that skin() did not work at low tooth counts and had to use a combination of skin and hull. If two profiles are very different sizes and far apart, that seemed to be the problem area. I use skin to make thin wafers then hull the wafers together. I suppose some schemes where I generate many profiles close together would work too.

Maybe after I finish this version I’m make one more trial of your idea.

-Bob

On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu mailto:avm4@cornell.edu> wrote:

I think that to get this right you basically need to take the top point of the triangle and one of the bottom points of the triangle in their position projected onto the cylinder, represent in cartesian coordinates, then interpolate appropriately between them by the chamfer fraction, then convert back to spherical coordinates to extract the angles.  You can work through those steps to get some complicated formula, but it looked messy.  I couldn't think of any simpler approach.

I’ve attached my code that I now believe is debugged and working reliably. It supports all the way down to N=2 (teeth). Depending on N it renders in .25 to .5 s. Preview is similar. When N = 2 or 3 this is an edge condition that required a lot of testing and work. The other area that caused the most problems was when the “coned” argument was at or around half the tooth height (as measured at the outer radius.) Around this point any auxiliary shapes you use to add a base, add or subtract a chamfer etc, switch from concave to convex or vice versa. One file is Customizer enabled and serves as the test platform for the second file where all the working code is. The test file also includes some visualization aids that I wrote to help see exactly what is going on. A note about the anchors. They are all relative to the entire joint. This makes it easier to position both parts in a larger assembly in a way that insures the parts mesh exactly. -Bob    > On Nov 8, 2024, at 10:37, Adrian Mariano <avm4@cornell.edu> wrote: > > I implemented the method I suggested. It was pretty easy to do and works. I do not understand your problem with skin. How does it fail? I construct mine using vnf_vertex_array which is like skin without fancy point alignment, and have no issues. It shouldn’t matter how far apart the profiles are or how different the scale. Skin just connects the points you give it to make the polyhedron. > > I do have a problem with rounding. The rounding isn’t at the right angle which leads to a corner where it joins the > > I thought the 2 tooth case was working for me but more thorough investigation revealed problems in the case of skewed teeth. I’ll have to ponder that. > > On Fri, Nov 8, 2024 at 11:39 Bob Carlson <bob@rjcarlson.com <mailto:bob@rjcarlson.com>> wrote: >> That sounds promising. I tried a lot of stuff but not that and nothing worked quite right. I’ve tweaked my code now to make the chamfer by subtracting later. It’s quite easy. The other thing I did is make 2 half tooth profiles instead of one whole. Now N = 2 works. I also found that skin() did not work at low tooth counts and had to use a combination of skin and hull. If two profiles are very different sizes and far apart, that seemed to be the problem area. I use skin to make thin wafers then hull the wafers together. I suppose some schemes where I generate many profiles close together would work too. >> >> Maybe after I finish this version I’m make one more trial of your idea. >> >> -Bob >> >> > On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu <mailto:avm4@cornell.edu>> wrote: >> > >> > I think that to get this right you basically need to take the top point of the triangle and one of the bottom points of the triangle in their position projected onto the cylinder, represent in cartesian coordinates, then interpolate appropriately between them by the chamfer fraction, then convert back to spherical coordinates to extract the angles. You can work through those steps to get some complicated formula, but it looked messy. I couldn't think of any simpler approach. >> > >>
BC
Bob Carlson
Thu, Nov 14, 2024 11:34 PM

I forgot something. In _profileU(hs) there is code documented out that causes problems with skin. They show up in the tricky areas like N = 2 and coned = toothHeight/2.

-Bob

On Nov 14, 2024, at 16:25, Bob Carlson via Discuss discuss@lists.openscad.org wrote:

I’ve attached my code that I now believe is debugged and working reliably. It supports all the way down to N=2 (teeth). Depending on N it renders in .25 to .5 s. Preview is similar.

When N = 2 or 3 this is an edge condition that required a lot of testing and work. The other area that caused the most problems was when the “coned” argument was at or around half the tooth height (as measured at the outer radius.) Around this point any auxiliary shapes you use to add a base, add or subtract a chamfer etc, switch from concave to convex or vice versa.

One file is Customizer enabled and serves as the test platform for the second file where all the working code is. The test file also includes some visualization aids that I wrote to help see exactly what is going on.

A note about the anchors. They are all relative to the entire joint. This makes it easier to position both parts in a larger assembly in a way that insures the parts mesh exactly.

-Bob

<PastedGraphic-1.png>

<PastedGraphic-3.png>

<hirth.5.scad>
<hirth test.5.scad>

On Nov 8, 2024, at 10:37, Adrian Mariano avm4@cornell.edu wrote:

I implemented the method I suggested. It was pretty easy to do and works.  I do not understand your problem with skin.  How does it fail?  I construct mine using vnf_vertex_array which is like skin without fancy point alignment, and have no issues.  It shouldn’t matter how far apart the profiles are or how different the scale. Skin just connects the points you give it to make the polyhedron.

I do have a problem with rounding. The rounding isn’t at the right angle which leads to a corner where it joins the

I thought the 2 tooth case was working for me but more thorough investigation revealed problems in the case of skewed teeth. I’ll have to ponder that.

On Fri, Nov 8, 2024 at 11:39 Bob Carlson <bob@rjcarlson.com mailto:bob@rjcarlson.com> wrote:

That sounds promising. I tried a lot of stuff but not that and nothing worked quite right. I’ve tweaked my code now to make the chamfer by subtracting later. It’s quite easy. The other thing I did is make 2 half tooth profiles instead of one whole. Now N = 2 works. I also found that skin() did not work at low tooth counts and had to use a combination of skin and hull. If two profiles are very different sizes and far apart, that seemed to be the problem area. I use skin to make thin wafers then hull the wafers together. I suppose some schemes where I generate many profiles close together would work too.

Maybe after I finish this version I’m make one more trial of your idea.

-Bob

On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu mailto:avm4@cornell.edu> wrote:

I think that to get this right you basically need to take the top point of the triangle and one of the bottom points of the triangle in their position projected onto the cylinder, represent in cartesian coordinates, then interpolate appropriately between them by the chamfer fraction, then convert back to spherical coordinates to extract the angles.  You can work through those steps to get some complicated formula, but it looked messy.  I couldn't think of any simpler approach.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I forgot something. In _profileU(hs) there is code documented out that causes problems with skin. They show up in the tricky areas like N = 2 and coned = toothHeight/2. -Bob > On Nov 14, 2024, at 16:25, Bob Carlson via Discuss <discuss@lists.openscad.org> wrote: > > I’ve attached my code that I now believe is debugged and working reliably. It supports all the way down to N=2 (teeth). Depending on N it renders in .25 to .5 s. Preview is similar. > > When N = 2 or 3 this is an edge condition that required a lot of testing and work. The other area that caused the most problems was when the “coned” argument was at or around half the tooth height (as measured at the outer radius.) Around this point any auxiliary shapes you use to add a base, add or subtract a chamfer etc, switch from concave to convex or vice versa. > > One file is Customizer enabled and serves as the test platform for the second file where all the working code is. The test file also includes some visualization aids that I wrote to help see exactly what is going on. > > A note about the anchors. They are all relative to the entire joint. This makes it easier to position both parts in a larger assembly in a way that insures the parts mesh exactly. > > -Bob > > <PastedGraphic-1.png> > > <PastedGraphic-3.png> > > > <hirth.5.scad> > <hirth test.5.scad> > > >> On Nov 8, 2024, at 10:37, Adrian Mariano <avm4@cornell.edu> wrote: >> >> I implemented the method I suggested. It was pretty easy to do and works. I do not understand your problem with skin. How does it fail? I construct mine using vnf_vertex_array which is like skin without fancy point alignment, and have no issues. It shouldn’t matter how far apart the profiles are or how different the scale. Skin just connects the points you give it to make the polyhedron. >> >> I do have a problem with rounding. The rounding isn’t at the right angle which leads to a corner where it joins the >> >> I thought the 2 tooth case was working for me but more thorough investigation revealed problems in the case of skewed teeth. I’ll have to ponder that. >> >> On Fri, Nov 8, 2024 at 11:39 Bob Carlson <bob@rjcarlson.com <mailto:bob@rjcarlson.com>> wrote: >>> That sounds promising. I tried a lot of stuff but not that and nothing worked quite right. I’ve tweaked my code now to make the chamfer by subtracting later. It’s quite easy. The other thing I did is make 2 half tooth profiles instead of one whole. Now N = 2 works. I also found that skin() did not work at low tooth counts and had to use a combination of skin and hull. If two profiles are very different sizes and far apart, that seemed to be the problem area. I use skin to make thin wafers then hull the wafers together. I suppose some schemes where I generate many profiles close together would work too. >>> >>> Maybe after I finish this version I’m make one more trial of your idea. >>> >>> -Bob >>> >>> > On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu <mailto:avm4@cornell.edu>> wrote: >>> > >>> > I think that to get this right you basically need to take the top point of the triangle and one of the bottom points of the triangle in their position projected onto the cylinder, represent in cartesian coordinates, then interpolate appropriately between them by the chamfer fraction, then convert back to spherical coordinates to extract the angles. You can work through those steps to get some complicated formula, but it looked messy. I couldn't think of any simpler approach. >>> > >>> > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
AM
Adrian Mariano
Fri, Nov 15, 2024 12:24 AM

If you want to identify a specific case for reproducing a problem with
skin() I can take a look at it, but I couldn't find anything obviously
wrong in a brief bit of fiddling with parameters.

It's interesting how rather different our hirth joints can look for similar
parameters.  For 2 teeth, with no cone angle/distance they are pretty
similar:

[image: image.png]
but with an extreme cone setting (I was trying to set it to the tooth
height to create the problem you described) they are rather different:

[image: image.png]
Note that mine are symmetric in that a single module produces both halves
and you specify conical with an angle, and then use the negative angle to
make the mate.

On Thu, Nov 14, 2024 at 6:35 PM Bob Carlson bob@rjcarlson.com wrote:

I forgot something. In _profileU(hs) there is code documented out that
causes problems with skin. They show up in the tricky areas like N = 2 and
coned = toothHeight/2.

-Bob

On Nov 14, 2024, at 16:25, Bob Carlson via Discuss <
discuss@lists.openscad.org> wrote:

I’ve attached my code that I now believe is debugged and working reliably.
It supports all the way down to N=2 (teeth). Depending on N it renders in
.25 to .5 s. Preview is similar.

When N = 2 or 3 this is an edge condition that required a lot of testing
and work. The other area that caused the most problems was when the “coned”
argument was at or around half the tooth height (as measured at the outer
radius.) Around this point any auxiliary shapes you use to add a base, add
or subtract a chamfer etc, switch from concave to convex or vice versa.

One file is Customizer enabled and serves as the test platform for the
second file where all the working code is. The test file also includes some
visualization aids that I wrote to help see exactly what is going on.

A note about the anchors. They are all relative to the entire joint. This
makes it easier to position both parts in a larger assembly in a way that
insures the parts mesh exactly.

-Bob

<PastedGraphic-1.png>

<PastedGraphic-3.png>

<hirth.5.scad>
<hirth test.5.scad>

On Nov 8, 2024, at 10:37, Adrian Mariano avm4@cornell.edu wrote:

I implemented the method I suggested. It was pretty easy to do and works.
I do not understand your problem with skin.  How does it fail?  I construct
mine using vnf_vertex_array which is like skin without fancy point
alignment, and have no issues.  It shouldn’t matter how far apart the
profiles are or how different the scale. Skin just connects the points you
give it to make the polyhedron.

I do have a problem with rounding. The rounding isn’t at the right angle
which leads to a corner where it joins the

I thought the 2 tooth case was working for me but more thorough
investigation revealed problems in the case of skewed teeth. I’ll have to
ponder that.

On Fri, Nov 8, 2024 at 11:39 Bob Carlson bob@rjcarlson.com wrote:

That sounds promising. I tried a lot of stuff but not that and nothing
worked quite right. I’ve tweaked my code now to make the chamfer by
subtracting later. It’s quite easy. The other thing I did is make 2 half
tooth profiles instead of one whole. Now N = 2 works. I also found that
skin() did not work at low tooth counts and had to use a combination of
skin and hull. If two profiles are very different sizes and far apart, that
seemed to be the problem area. I use skin to make thin wafers then hull the
wafers together. I suppose some schemes where I generate many profiles
close together would work too.

Maybe after I finish this version I’m make one more trial of your idea.

-Bob

On Nov 7, 2024, at 15:13, Adrian Mariano avm4@cornell.edu wrote:

I think that to get this right you basically need to take the top point

of the triangle and one of the bottom points of the triangle in their
position projected onto the cylinder, represent in cartesian coordinates,
then interpolate appropriately between them by the chamfer fraction, then
convert back to spherical coordinates to extract the angles.  You can work
through those steps to get some complicated formula, but it looked messy.
I couldn't think of any simpler approach.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

If you want to identify a specific case for reproducing a problem with skin() I can take a look at it, but I couldn't find anything obviously wrong in a brief bit of fiddling with parameters. It's interesting how rather different our hirth joints can look for similar parameters. For 2 teeth, with no cone angle/distance they are pretty similar: [image: image.png] but with an extreme cone setting (I was trying to set it to the tooth height to create the problem you described) they are rather different: [image: image.png] Note that mine are symmetric in that a single module produces both halves and you specify conical with an angle, and then use the negative angle to make the mate. On Thu, Nov 14, 2024 at 6:35 PM Bob Carlson <bob@rjcarlson.com> wrote: > I forgot something. In _profileU(hs) there is code documented out that > causes problems with skin. They show up in the tricky areas like N = 2 and > coned = toothHeight/2. > > -Bob > > On Nov 14, 2024, at 16:25, Bob Carlson via Discuss < > discuss@lists.openscad.org> wrote: > > I’ve attached my code that I now believe is debugged and working reliably. > It supports all the way down to N=2 (teeth). Depending on N it renders in > .25 to .5 s. Preview is similar. > > When N = 2 or 3 this is an edge condition that required a lot of testing > and work. The other area that caused the most problems was when the “coned” > argument was at or around half the tooth height (as measured at the outer > radius.) Around this point any auxiliary shapes you use to add a base, add > or subtract a chamfer etc, switch from concave to convex or vice versa. > > One file is Customizer enabled and serves as the test platform for the > second file where all the working code is. The test file also includes some > visualization aids that I wrote to help see exactly what is going on. > > A note about the anchors. They are all relative to the entire joint. This > makes it easier to position both parts in a larger assembly in a way that > insures the parts mesh exactly. > > -Bob > > <PastedGraphic-1.png> > > <PastedGraphic-3.png> > > > <hirth.5.scad> > <hirth test.5.scad> > > > On Nov 8, 2024, at 10:37, Adrian Mariano <avm4@cornell.edu> wrote: > > I implemented the method I suggested. It was pretty easy to do and works. > I do not understand your problem with skin. How does it fail? I construct > mine using vnf_vertex_array which is like skin without fancy point > alignment, and have no issues. It shouldn’t matter how far apart the > profiles are or how different the scale. Skin just connects the points you > give it to make the polyhedron. > > I do have a problem with rounding. The rounding isn’t at the right angle > which leads to a corner where it joins the > > I thought the 2 tooth case was working for me but more thorough > investigation revealed problems in the case of skewed teeth. I’ll have to > ponder that. > > On Fri, Nov 8, 2024 at 11:39 Bob Carlson <bob@rjcarlson.com> wrote: > >> That sounds promising. I tried a lot of stuff but not that and nothing >> worked quite right. I’ve tweaked my code now to make the chamfer by >> subtracting later. It’s quite easy. The other thing I did is make 2 half >> tooth profiles instead of one whole. Now N = 2 works. I also found that >> skin() did not work at low tooth counts and had to use a combination of >> skin and hull. If two profiles are very different sizes and far apart, that >> seemed to be the problem area. I use skin to make thin wafers then hull the >> wafers together. I suppose some schemes where I generate many profiles >> close together would work too. >> >> Maybe after I finish this version I’m make one more trial of your idea. >> >> -Bob >> >> > On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu> wrote: >> > >> > I think that to get this right you basically need to take the top point >> of the triangle and one of the bottom points of the triangle in their >> position projected onto the cylinder, represent in cartesian coordinates, >> then interpolate appropriately between them by the chamfer fraction, then >> convert back to spherical coordinates to extract the angles. You can work >> through those steps to get some complicated formula, but it looked messy. >> I couldn't think of any simpler approach. >> > >> >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > >
SP
Sanjeev Prabhakar
Fri, Nov 15, 2024 1:43 AM

Hi Bob
At the trough it should be a fillet rather than chamfer. On the crest it
should be chamfer.

On Fri, 15 Nov, 2024, 4:56 am Bob Carlson via Discuss, <
discuss@lists.openscad.org> wrote:

I’ve attached my code that I now believe is debugged and working reliably.
It supports all the way down to N=2 (teeth). Depending on N it renders in
.25 to .5 s. Preview is similar.

When N = 2 or 3 this is an edge condition that required a lot of testing
and work. The other area that caused the most problems was when the “coned”
argument was at or around half the tooth height (as measured at the outer
radius.) Around this point any auxiliary shapes you use to add a base, add
or subtract a chamfer etc, switch from concave to convex or vice versa.

One file is Customizer enabled and serves as the test platform for the
second file where all the working code is. The test file also includes some
visualization aids that I wrote to help see exactly what is going on.

A note about the anchors. They are all relative to the entire joint. This
makes it easier to position both parts in a larger assembly in a way that
insures the parts mesh exactly.

-Bob

On Nov 8, 2024, at 10:37, Adrian Mariano avm4@cornell.edu wrote:

I implemented the method I suggested. It was pretty easy to do and works.
I do not understand your problem with skin.  How does it fail?  I construct
mine using vnf_vertex_array which is like skin without fancy point
alignment, and have no issues.  It shouldn’t matter how far apart the
profiles are or how different the scale. Skin just connects the points you
give it to make the polyhedron.

I do have a problem with rounding. The rounding isn’t at the right angle
which leads to a corner where it joins the

I thought the 2 tooth case was working for me but more thorough
investigation revealed problems in the case of skewed teeth. I’ll have to
ponder that.

On Fri, Nov 8, 2024 at 11:39 Bob Carlson bob@rjcarlson.com wrote:

That sounds promising. I tried a lot of stuff but not that and nothing
worked quite right. I’ve tweaked my code now to make the chamfer by
subtracting later. It’s quite easy. The other thing I did is make 2 half
tooth profiles instead of one whole. Now N = 2 works. I also found that
skin() did not work at low tooth counts and had to use a combination of
skin and hull. If two profiles are very different sizes and far apart, that
seemed to be the problem area. I use skin to make thin wafers then hull the
wafers together. I suppose some schemes where I generate many profiles
close together would work too.

Maybe after I finish this version I’m make one more trial of your idea.

-Bob

On Nov 7, 2024, at 15:13, Adrian Mariano avm4@cornell.edu wrote:

I think that to get this right you basically need to take the top point

of the triangle and one of the bottom points of the triangle in their
position projected onto the cylinder, represent in cartesian coordinates,
then interpolate appropriately between them by the chamfer fraction, then
convert back to spherical coordinates to extract the angles.  You can work
through those steps to get some complicated formula, but it looked messy.
I couldn't think of any simpler approach.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Hi Bob At the trough it should be a fillet rather than chamfer. On the crest it should be chamfer. On Fri, 15 Nov, 2024, 4:56 am Bob Carlson via Discuss, < discuss@lists.openscad.org> wrote: > I’ve attached my code that I now believe is debugged and working reliably. > It supports all the way down to N=2 (teeth). Depending on N it renders in > .25 to .5 s. Preview is similar. > > When N = 2 or 3 this is an edge condition that required a lot of testing > and work. The other area that caused the most problems was when the “coned” > argument was at or around half the tooth height (as measured at the outer > radius.) Around this point any auxiliary shapes you use to add a base, add > or subtract a chamfer etc, switch from concave to convex or vice versa. > > One file is Customizer enabled and serves as the test platform for the > second file where all the working code is. The test file also includes some > visualization aids that I wrote to help see exactly what is going on. > > A note about the anchors. They are all relative to the entire joint. This > makes it easier to position both parts in a larger assembly in a way that > insures the parts mesh exactly. > > -Bob > > > > > > > On Nov 8, 2024, at 10:37, Adrian Mariano <avm4@cornell.edu> wrote: > > I implemented the method I suggested. It was pretty easy to do and works. > I do not understand your problem with skin. How does it fail? I construct > mine using vnf_vertex_array which is like skin without fancy point > alignment, and have no issues. It shouldn’t matter how far apart the > profiles are or how different the scale. Skin just connects the points you > give it to make the polyhedron. > > I do have a problem with rounding. The rounding isn’t at the right angle > which leads to a corner where it joins the > > I thought the 2 tooth case was working for me but more thorough > investigation revealed problems in the case of skewed teeth. I’ll have to > ponder that. > > On Fri, Nov 8, 2024 at 11:39 Bob Carlson <bob@rjcarlson.com> wrote: > >> That sounds promising. I tried a lot of stuff but not that and nothing >> worked quite right. I’ve tweaked my code now to make the chamfer by >> subtracting later. It’s quite easy. The other thing I did is make 2 half >> tooth profiles instead of one whole. Now N = 2 works. I also found that >> skin() did not work at low tooth counts and had to use a combination of >> skin and hull. If two profiles are very different sizes and far apart, that >> seemed to be the problem area. I use skin to make thin wafers then hull the >> wafers together. I suppose some schemes where I generate many profiles >> close together would work too. >> >> Maybe after I finish this version I’m make one more trial of your idea. >> >> -Bob >> >> > On Nov 7, 2024, at 15:13, Adrian Mariano <avm4@cornell.edu> wrote: >> > >> > I think that to get this right you basically need to take the top point >> of the triangle and one of the bottom points of the triangle in their >> position projected onto the cylinder, represent in cartesian coordinates, >> then interpolate appropriately between them by the chamfer fraction, then >> convert back to spherical coordinates to extract the angles. You can work >> through those steps to get some complicated formula, but it looked messy. >> I couldn't think of any simpler approach. >> > >> >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
BC
Bob Carlson
Fri, Nov 15, 2024 4:29 PM

That’s an interesting exercise. I am playing with another strategy to produce the chamfers that will produce a flat chamfer. My current algorithm produces one that is follows the surface of a cone. Unnoticeable at normal tooth counts, but you can see it with very low tooth counts. I’ll generate some pics of the skin issue, but it won’t be till late today.

Sanjay, you are no doubt correct that the groove should be a fillet, I have no ME background at all. But it seems very difficult to produce. I played around with the math to inscribe a circle into an angle at a specific tangent point, but got tired of the exercise before I solved it. I suspect you can do that off the top of your head. Somewhat arbitrarily I chose to make the groove chamfer 50% of the ridge chamfer. Is there another ratio that is accepted or preferred?

-Bob

On Nov 14, 2024, at 17:24, Adrian Mariano avm4@cornell.edu wrote:

It's interesting how rather different our hirth joints can look for similar parameters.  For 2 teeth, with no cone angle/distance they are pretty similar:

That’s an interesting exercise. I am playing with another strategy to produce the chamfers that will produce a flat chamfer. My current algorithm produces one that is follows the surface of a cone. Unnoticeable at normal tooth counts, but you can see it with very low tooth counts. I’ll generate some pics of the skin issue, but it won’t be till late today. Sanjay, you are no doubt correct that the groove should be a fillet, I have no ME background at all. But it seems very difficult to produce. I played around with the math to inscribe a circle into an angle at a specific tangent point, but got tired of the exercise before I solved it. I suspect you can do that off the top of your head. Somewhat arbitrarily I chose to make the groove chamfer 50% of the ridge chamfer. Is there another ratio that is accepted or preferred? -Bob > On Nov 14, 2024, at 17:24, Adrian Mariano <avm4@cornell.edu> wrote: > > It's interesting how rather different our hirth joints can look for similar parameters. For 2 teeth, with no cone angle/distance they are pretty similar:
SP
Sanjeev Prabhakar
Fri, Nov 15, 2024 11:07 PM

I am not sure how you have modeled this but the main point here is that the
teeth should not foul while meshing, if that is not the case in your design
then it should be fine.

On Fri, 15 Nov, 2024, 10:00 pm Bob Carlson via Discuss, <
discuss@lists.openscad.org> wrote:

That’s an interesting exercise. I am playing with another strategy to
produce the chamfers that will produce a flat chamfer. My current algorithm
produces one that is follows the surface of a cone. Unnoticeable at normal
tooth counts, but you can see it with very low tooth counts. I’ll generate
some pics of the skin issue, but it won’t be till late today.

Sanjay, you are no doubt correct that the groove should be a fillet, I
have no ME background at all. But it seems very difficult to produce. I
played around with the math to inscribe a circle into an angle at a
specific tangent point, but got tired of the exercise before I solved it. I
suspect you can do that off the top of your head. Somewhat arbitrarily I
chose to make the groove chamfer 50% of the ridge chamfer. Is there another
ratio that is accepted or preferred?

-Bob

On Nov 14, 2024, at 17:24, Adrian Mariano avm4@cornell.edu wrote:

It's interesting how rather different our hirth joints can look for
similar parameters.  For 2 teeth, with no cone angle/distance they are
pretty similar:


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I am not sure how you have modeled this but the main point here is that the teeth should not foul while meshing, if that is not the case in your design then it should be fine. On Fri, 15 Nov, 2024, 10:00 pm Bob Carlson via Discuss, < discuss@lists.openscad.org> wrote: > That’s an interesting exercise. I am playing with another strategy to > produce the chamfers that will produce a flat chamfer. My current algorithm > produces one that is follows the surface of a cone. Unnoticeable at normal > tooth counts, but you can see it with very low tooth counts. I’ll generate > some pics of the skin issue, but it won’t be till late today. > > Sanjay, you are no doubt correct that the groove should be a fillet, I > have no ME background at all. But it seems very difficult to produce. I > played around with the math to inscribe a circle into an angle at a > specific tangent point, but got tired of the exercise before I solved it. I > suspect you can do that off the top of your head. Somewhat arbitrarily I > chose to make the groove chamfer 50% of the ridge chamfer. Is there another > ratio that is accepted or preferred? > > -Bob > > On Nov 14, 2024, at 17:24, Adrian Mariano <avm4@cornell.edu> wrote: > > It's interesting how rather different our hirth joints can look for > similar parameters. For 2 teeth, with no cone angle/distance they are > pretty similar: > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
BC
Bob Carlson
Sat, Nov 16, 2024 1:54 AM

It turns out that in the previous version I was calculating the phi angle for the chamfers incorrectly, another place where my math intuition failed me. This code gets it right I think. Look for phiCA in hirth.6.. Phi in spherical coordinates is from vertical and I am sometimes using phiCA from the XY plane instead, so -90. So watch out.

-Bob



On Nov 15, 2024, at 09:29, Bob Carlson via Discuss discuss@lists.openscad.org wrote:

That’s an interesting exercise. I am playing with another strategy to produce the chamfers that will produce a flat chamfer. My current algorithm produces one that is follows the surface of a cone. Unnoticeable at normal tooth counts, but you can see it with very low tooth counts. I’ll generate some pics of the skin issue, but it won’t be till late today.

Sanjay, you are no doubt correct that the groove should be a fillet, I have no ME background at all. But it seems very difficult to produce. I played around with the math to inscribe a circle into an angle at a specific tangent point, but got tired of the exercise before I solved it. I suspect you can do that off the top of your head. Somewhat arbitrarily I chose to make the groove chamfer 50% of the ridge chamfer. Is there another ratio that is accepted or preferred?

-Bob

On Nov 14, 2024, at 17:24, Adrian Mariano avm4@cornell.edu wrote:

It's interesting how rather different our hirth joints can look for similar parameters.  For 2 teeth, with no cone angle/distance they are pretty similar:


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

It turns out that in the previous version I was calculating the phi angle for the chamfers incorrectly, another place where my math intuition failed me. This code gets it right I think. Look for phiCA in hirth.6.. Phi in spherical coordinates is from vertical and I am sometimes using phiCA from the XY plane instead, so -90. So watch out. -Bob  > On Nov 15, 2024, at 09:29, Bob Carlson via Discuss <discuss@lists.openscad.org> wrote: > > That’s an interesting exercise. I am playing with another strategy to produce the chamfers that will produce a flat chamfer. My current algorithm produces one that is follows the surface of a cone. Unnoticeable at normal tooth counts, but you can see it with very low tooth counts. I’ll generate some pics of the skin issue, but it won’t be till late today. > > Sanjay, you are no doubt correct that the groove should be a fillet, I have no ME background at all. But it seems very difficult to produce. I played around with the math to inscribe a circle into an angle at a specific tangent point, but got tired of the exercise before I solved it. I suspect you can do that off the top of your head. Somewhat arbitrarily I chose to make the groove chamfer 50% of the ridge chamfer. Is there another ratio that is accepted or preferred? > > -Bob > >> On Nov 14, 2024, at 17:24, Adrian Mariano <avm4@cornell.edu> wrote: >> >> It's interesting how rather different our hirth joints can look for similar parameters. For 2 teeth, with no cone angle/distance they are pretty similar: > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
M
mikeonenine@web.de
Sun, Nov 17, 2024 5:15 AM

I’ve had a look at some of the codes posted above and actually got one to work. But the question remains:

In the image below, 60° triangles parallel to the z-axis linear_extruded to the origin give an angle of 90° between the flanks of a spline, which can be seen when one looks along a ridge towards the origin.

Are these then 60° splines or 90° splines?

I’ve had a look at some of the codes posted above and actually got one to work. But the question remains: In the image below, 60° triangles parallel to the z-axis linear_extruded to the origin give an angle of 90° between the flanks of a spline, which can be seen when one looks along a ridge towards the origin. Are these then 60° splines or 90° splines? ![](data:image/png;base64,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)
AM
Adrian Mariano
Sun, Nov 17, 2024 5:30 AM

I think it's tough to tell what the angles are in the fixed view like that
due to the distortion from perspective.  In my code the triangles that form
the teeth are constructed with the specified angle, but then they end up
getting projected at a different angle depending on the cone angle you
pick.  Furthermore, there's the question of where the angle is measured.  I
think the wikipedia page suggested it is measured relative to the cylinder
axis, but I'd normally expect tooth angle to be measured on the tooth,
which means the slope of the tooth will also lead to a change in the
effective angle.  (Maybe this factor is what you're talking about?)  I
decided for my implementation to treat the requested angle as "nominal" and
not worry about these various deviations.  As long as you pick the same
angle (and other parameters) for both sides of the joint, the parts will
mate.  And if you don't like the angle you get---change it.

On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

I’ve had a look at some of the codes posted above and actually got one to
work. But the question remains:

In the image below, 60° triangles parallel to the z-axis linear_extruded
to the origin give an angle of 90° between the flanks of a spline, which
can be seen when one looks along a ridge towards the origin.

Are these then 60° splines or 90° splines?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I think it's tough to tell what the angles are in the fixed view like that due to the distortion from perspective. In my code the triangles that form the teeth are constructed with the specified angle, but then they end up getting projected at a different angle depending on the cone angle you pick. Furthermore, there's the question of where the angle is measured. I think the wikipedia page suggested it is measured relative to the cylinder axis, but I'd normally expect tooth angle to be measured on the tooth, which means the slope of the tooth will also lead to a change in the effective angle. (Maybe this factor is what you're talking about?) I decided for my implementation to treat the requested angle as "nominal" and not worry about these various deviations. As long as you pick the same angle (and other parameters) for both sides of the joint, the parts will mate. And if you don't like the angle you get---change it. On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss < discuss@lists.openscad.org> wrote: > I’ve had a look at some of the codes posted above and actually got one to > work. But the question remains: > > In the image below, 60° triangles parallel to the z-axis linear_extruded > to the origin give an angle of 90° between the flanks of a spline, which > can be seen when one looks along a ridge towards the origin. > > Are these then 60° splines or 90° splines? > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
M
mikeonenine@web.de
Sun, Nov 17, 2024 7:37 AM

Adrian Mariano wrote:

I think it's tough to tell what the angles are in the fixed view like that
due to the distortion from perspective.  In my code the triangles that form
the teeth are constructed with the specified angle, but then they end up
getting projected at a different angle depending on the cone angle you
pick.  Furthermore, there's the question of where the angle is measured.  I
think the wikipedia page suggested it is measured relative to the cylinder
axis, but I'd normally expect tooth angle to be measured on the tooth,
which means the slope of the tooth will also lead to a change in the
effective angle.  (Maybe this factor is what you're talking about?)  I
decided for my implementation to treat the requested angle as "nominal" and
not worry about these various deviations.  As long as you pick the same
angle (and other parameters) for both sides of the joint, the parts will
mate.  And if you don't like the angle you get---change it.

On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

I’ve had a look at some of the codes posted above and actually got one to
work. But the question remains:

In the image below, 60° triangles parallel to the z-axis linear_extruded
to the origin give an angle of 90° between the flanks of a spline, which
can be seen when one looks along a ridge towards the origin.

Are these then 60° splines or 90° splines?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Immediately after posting, I thought I should have simply said that the angle between the flanks of a spline viewed perpendicular to the axis of the ring of splines is not the same as the angle around the ridge of the spline = on the tooth. So your guess was right. I too would think that the angle on the tooth would be what counts in practise. Unfortunately, Wikipedia is not very clear on that. I wonder what our resident engineer/machinist would say. Or maybe it’s actually the angle of the cutting tool - that would be the angle between the flanks of adjacent splines? Then only one tool would be needed.

Could be of interest for BOSL, as 60° and 90° seem to be the standard angles, so it would be good to know how/where they are measured. With increasing numbers of splines, the discrepancy between the two frames of reference rapidly decreases.

I have a concept that seems promising, but doing the trigonometry is like trying to swing from tree to tree in a dense jungle in a fog, so I have given up for the time being.

Adrian Mariano wrote: > I think it's tough to tell what the angles are in the fixed view like that > due to the distortion from perspective. In my code the triangles that form > the teeth are constructed with the specified angle, but then they end up > getting projected at a different angle depending on the cone angle you > pick. Furthermore, there's the question of where the angle is measured. I > think the wikipedia page suggested it is measured relative to the cylinder > axis, but I'd normally expect tooth angle to be measured on the tooth, > which means the slope of the tooth will also lead to a change in the > effective angle. (Maybe this factor is what you're talking about?) I > decided for my implementation to treat the requested angle as "nominal" and > not worry about these various deviations. As long as you pick the same > angle (and other parameters) for both sides of the joint, the parts will > mate. And if you don't like the angle you get---change it. > > On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss < > discuss@lists.openscad.org> wrote: > > > I’ve had a look at some of the codes posted above and actually got one to > > work. But the question remains: > > > > In the image below, 60° triangles parallel to the z-axis linear_extruded > > to the origin give an angle of 90° between the flanks of a spline, which > > can be seen when one looks along a ridge towards the origin. > > > > Are these then 60° splines or 90° splines? > > > > --- > > > > OpenSCAD mailing list > > To unsubscribe send an email to discuss-leave@lists.openscad.org Immediately after posting, I thought I should have simply said that the angle between the flanks of a spline viewed perpendicular to the axis of the ring of splines is not the same as the angle around the ridge of the spline = on the tooth. So your guess was right. I too would think that the angle on the tooth would be what counts in practise. Unfortunately, Wikipedia is not very clear on that. I wonder what our resident engineer/machinist would say. Or maybe it’s actually the angle of the cutting tool - that would be the angle between the flanks of adjacent splines? Then only one tool would be needed. Could be of interest for BOSL, as 60° and 90° seem to be the standard angles, so it would be good to know how/where they are measured. With increasing numbers of splines, the discrepancy between the two frames of reference rapidly decreases. I have a concept that seems promising, but doing the trigonometry is like trying to swing from tree to tree in a dense jungle in a fog, so I have given up for the time being.
AM
Adrian Mariano
Sun, Nov 17, 2024 1:16 PM

I did ponder the idea of trying to compute a correction factor to the tooth
angle, but given the uncertainty about what the right angle actually is,
and also uncertainty on my part about how to actually compute that
correction factor, I didn't pursue this idea.  Wouldn't angle between
adjacent flanks be equivalent to angle on the tooth, which is basically the
other angle between flanks?  In the case of no cone angle these angles
must be the same because the part mates with itself.

Another thing is that my code supports skewing the teeth so you can make
teeth with one face vertical, for example.  This distorts the angle.  I
didn't see a compelling reason the angle needs to be "correct".  Here an
example of what you get if you ask for 60 degrees with maximal skew:

[image: image.png]
If I change the tooth angle to try to achieve actual 60 deg at the tops I
get something like this

[image: image.png]
Note that the tooth height has radically changed.  From a design
perspective, I think it's maybe nicer for a user to be able to skew the
teeth while keeping the tooth height fixed, rather than having these
parameters coupled.

In the case of very high cone angle (here 75 deg), weird stuff happens and
I get shapes like this:

[image: image.png]
where the adjacent teeth flanks become coplanar, and then if I push cone
angle higher (85 deg here) the "valley" between the teeth becomes a second
ridge

[image: image.png]
It's not clear if forms like this are useful for anything.  The
construction still works, producing a mating shape that looks like this:

[image: image.png]
But clearly the tooth angle measured at the tooth ridge or the complement
of the angle between the flanks is wildly different from the requested 60
deg.  I'll note also that the very high cone angles look less weird when
the tooth count is high, though the tooth angle is still wildly different
from what was requested.  This is 75 deg angle with lots of teeth:

[image: image.png]
I'm not going to show another image, but if I line it up along a ridge by
eye the tooth ridge angle looks like around 120 deg.  But note how the
triangles running around the baes actually look like 60 deg triangles.

On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

Adrian Mariano wrote:

I think it's tough to tell what the angles are in the fixed view like that
due to the distortion from perspective. In my code the triangles that form
the teeth are constructed with the specified angle, but then they end up
getting projected at a different angle depending on the cone angle you
pick. Furthermore, there's the question of where the angle is measured. I
think the wikipedia page suggested it is measured relative to the cylinder
axis, but I'd normally expect tooth angle to be measured on the tooth,
which means the slope of the tooth will also lead to a change in the
effective angle. (Maybe this factor is what you're talking about?) I
decided for my implementation to treat the requested angle as "nominal" and
not worry about these various deviations. As long as you pick the same
angle (and other parameters) for both sides of the joint, the parts will
mate. And if you don't like the angle you get---change it.

On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

I’ve had a look at some of the codes posted above and actually got one to
work. But the question remains:

In the image below, 60° triangles parallel to the z-axis linear_extruded
to the origin give an angle of 90° between the flanks of a spline, which
can be seen when one looks along a ridge towards the origin.

Are these then 60° splines or 90° splines?

OpenSCAD mailing list To unsubscribe send an email to
discuss-leave@lists.openscad.org

Immediately after posting, I thought I should have simply said that the
angle between the flanks of a spline viewed perpendicular to the axis of
the ring of splines is not the same as the angle around the ridge of the
spline = on the tooth. So your guess was right. I too would think that the
angle on the tooth would be what counts in practise. Unfortunately,
Wikipedia is not very clear on that. I wonder what our resident
engineer/machinist would say. Or maybe it’s actually the angle of the
cutting tool - that would be the angle between the flanks of adjacent
splines? Then only one tool would be needed.

Could be of interest for BOSL, as 60° and 90° seem to be the standard
angles, so it would be good to know how/where they are measured. With
increasing numbers of splines, the discrepancy between the two frames of
reference rapidly decreases.

I have a concept that seems promising, but doing the trigonometry is like
trying to swing from tree to tree in a dense jungle in a fog, so I have
given up for the time being.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I did ponder the idea of trying to compute a correction factor to the tooth angle, but given the uncertainty about what the right angle actually is, and also uncertainty on my part about how to actually compute that correction factor, I didn't pursue this idea. Wouldn't angle between adjacent flanks be equivalent to angle on the tooth, which is basically the other angle between flanks? In the case of no cone angle these angles must be the same because the part mates with itself. Another thing is that my code supports skewing the teeth so you can make teeth with one face vertical, for example. This distorts the angle. I didn't see a compelling reason the angle needs to be "correct". Here an example of what you get if you ask for 60 degrees with maximal skew: [image: image.png] If I change the tooth angle to try to achieve actual 60 deg at the tops I get something like this [image: image.png] Note that the tooth height has radically changed. From a design perspective, I think it's maybe nicer for a user to be able to skew the teeth while keeping the tooth height fixed, rather than having these parameters coupled. In the case of very high cone angle (here 75 deg), weird stuff happens and I get shapes like this: [image: image.png] where the adjacent teeth flanks become coplanar, and then if I push cone angle higher (85 deg here) the "valley" between the teeth becomes a second ridge [image: image.png] It's not clear if forms like this are useful for anything. The construction still works, producing a mating shape that looks like this: [image: image.png] But clearly the tooth angle measured at the tooth ridge or the complement of the angle between the flanks is wildly different from the requested 60 deg. I'll note also that the very high cone angles look less weird when the tooth count is high, though the tooth angle is still wildly different from what was requested. This is 75 deg angle with lots of teeth: [image: image.png] I'm not going to show another image, but if I line it up along a ridge by eye the tooth ridge angle looks like around 120 deg. But note how the triangles running around the baes actually look like 60 deg triangles. On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss < discuss@lists.openscad.org> wrote: > Adrian Mariano wrote: > > I think it's tough to tell what the angles are in the fixed view like that > due to the distortion from perspective. In my code the triangles that form > the teeth are constructed with the specified angle, but then they end up > getting projected at a different angle depending on the cone angle you > pick. Furthermore, there's the question of where the angle is measured. I > think the wikipedia page suggested it is measured relative to the cylinder > axis, but I'd normally expect tooth angle to be measured on the tooth, > which means the slope of the tooth will also lead to a change in the > effective angle. (Maybe this factor is what you're talking about?) I > decided for my implementation to treat the requested angle as "nominal" and > not worry about these various deviations. As long as you pick the same > angle (and other parameters) for both sides of the joint, the parts will > mate. And if you don't like the angle you get---change it. > > On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss < > discuss@lists.openscad.org> wrote: > > I’ve had a look at some of the codes posted above and actually got one to > work. But the question remains: > > In the image below, 60° triangles parallel to the z-axis linear_extruded > to the origin give an angle of 90° between the flanks of a spline, which > can be seen when one looks along a ridge towards the origin. > > Are these then 60° splines or 90° splines? > ------------------------------ > > OpenSCAD mailing list To unsubscribe send an email to > discuss-leave@lists.openscad.org > > Immediately after posting, I thought I should have simply said that the > angle between the flanks of a spline viewed perpendicular to the axis of > the ring of splines is not the same as the angle around the ridge of the > spline = on the tooth. So your guess was right. I too would think that the > angle on the tooth would be what counts in practise. Unfortunately, > Wikipedia is not very clear on that. I wonder what our resident > engineer/machinist would say. Or maybe it’s actually the angle of the > cutting tool - that would be the angle between the flanks of adjacent > splines? Then only one tool would be needed. > > Could be of interest for BOSL, as 60° and 90° seem to be the standard > angles, so it would be good to know how/where they are measured. With > increasing numbers of splines, the discrepancy between the two frames of > reference rapidly decreases. > > I have a concept that seems promising, but doing the trigonometry is like > trying to swing from tree to tree in a dense jungle in a fog, so I have > given up for the time being. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
MM
Michael Möller
Sun, Nov 17, 2024 1:22 PM

søn. 17. nov. 2024 14.17 skrev Adrian Mariano via Discuss <
discuss@lists.openscad.org>:

I did ponder the idea of trying to compute a correction factor to the
tooth angle, but given the uncertainty about what the right angle actually
is, and also uncertainty on my part about how to actually compute that
correction factor, I didn't pursue this idea.  Wouldn't angle between
adjacent flanks be equivalent to angle on the tooth, which is basically the
other angle between flanks?  In the case of no cone angle these angles
must be the same because the part mates with itself.

Another thing is that my code supports skewing the teeth so you can make
teeth with one face vertical, for example.  This distorts the angle.  I
didn't see a compelling reason the angle needs to be "correct".  Here an
example of what you get if you ask for 60 degrees with maximal skew:

[image: image.png]
If I change the tooth angle to try to achieve actual 60 deg at the tops I
get something like this

[image: image.png]
Note that the tooth height has radically changed.  From a design
perspective, I think it's maybe nicer for a user to be able to skew the
teeth while keeping the tooth height fixed, rather than having these
parameters coupled.

In the case of very high cone angle (here 75 deg), weird stuff happens and
I get shapes like this:

[image: image.png]
where the adjacent teeth flanks become coplanar, and then if I push cone
angle higher (85 deg here) the "valley" between the teeth becomes a second
ridge

[image: image.png]
It's not clear if forms like this are useful for anything.  The
construction still works, producing a mating shape that looks like this:

[image: image.png]
But clearly the tooth angle measured at the tooth ridge or the complement
of the angle between the flanks is wildly different from the requested 60
deg.  I'll note also that the very high cone angles look less weird when
the tooth count is high, though the tooth angle is still wildly different
from what was requested.  This is 75 deg angle with lots of teeth:

[image: image.png]
I'm not going to show another image, but if I line it up along a ridge by
eye the tooth ridge angle looks like around 120 deg.  But note how the
triangles running around the baes actually look like 60 deg triangles.

On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

Adrian Mariano wrote:

I think it's tough to tell what the angles are in the fixed view like
that due to the distortion from perspective. In my code the triangles that
form the teeth are constructed with the specified angle, but then they end
up getting projected at a different angle depending on the cone angle you
pick. Furthermore, there's the question of where the angle is measured. I
think the wikipedia page suggested it is measured relative to the cylinder
axis, but I'd normally expect tooth angle to be measured on the tooth,
which means the slope of the tooth will also lead to a change in the
effective angle. (Maybe this factor is what you're talking about?) I
decided for my implementation to treat the requested angle as "nominal" and
not worry about these various deviations. As long as you pick the same
angle (and other parameters) for both sides of the joint, the parts will
mate. And if you don't like the angle you get---change it.

On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

I’ve had a look at some of the codes posted above and actually got one to
work. But the question remains:

In the image below, 60° triangles parallel to the z-axis linear_extruded
to the origin give an angle of 90° between the flanks of a spline, which
can be seen when one looks along a ridge towards the origin.

Are these then 60° splines or 90° splines?

OpenSCAD mailing list To unsubscribe send an email to
discuss-leave@lists.openscad.org

Immediately after posting, I thought I should have simply said that the
angle between the flanks of a spline viewed perpendicular to the axis of
the ring of splines is not the same as the angle around the ridge of the
spline = on the tooth. So your guess was right. I too would think that the
angle on the tooth would be what counts in practise. Unfortunately,
Wikipedia is not very clear on that. I wonder what our resident
engineer/machinist would say. Or maybe it’s actually the angle of the
cutting tool - that would be the angle between the flanks of adjacent
splines? Then only one tool would be needed.

Could be of interest for BOSL, as 60° and 90° seem to be the standard
angles, so it would be good to know how/where they are measured. With
increasing numbers of splines, the discrepancy between the two frames of
reference rapidly decreases.

I have a concept that seems promising, but doing the trigonometry is like
trying to swing from tree to tree in a dense jungle in a fog, so I have
given up for the time being.


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

søn. 17. nov. 2024 14.17 skrev Adrian Mariano via Discuss < discuss@lists.openscad.org>: > I did ponder the idea of trying to compute a correction factor to the > tooth angle, but given the uncertainty about what the right angle actually > is, and also uncertainty on my part about how to actually compute that > correction factor, I didn't pursue this idea. Wouldn't angle between > adjacent flanks be equivalent to angle on the tooth, which is basically the > other angle between flanks? In the case of no cone angle these angles > must be the same because the part mates with itself. > > Another thing is that my code supports skewing the teeth so you can make > teeth with one face vertical, for example. This distorts the angle. I > didn't see a compelling reason the angle needs to be "correct". Here an > example of what you get if you ask for 60 degrees with maximal skew: > > [image: image.png] > If I change the tooth angle to try to achieve actual 60 deg at the tops I > get something like this > > [image: image.png] > Note that the tooth height has radically changed. From a design > perspective, I think it's maybe nicer for a user to be able to skew the > teeth while keeping the tooth height fixed, rather than having these > parameters coupled. > > In the case of very high cone angle (here 75 deg), weird stuff happens and > I get shapes like this: > > [image: image.png] > where the adjacent teeth flanks become coplanar, and then if I push cone > angle higher (85 deg here) the "valley" between the teeth becomes a second > ridge > > [image: image.png] > It's not clear if forms like this are useful for anything. The > construction still works, producing a mating shape that looks like this: > > [image: image.png] > But clearly the tooth angle measured at the tooth ridge or the complement > of the angle between the flanks is wildly different from the requested 60 > deg. I'll note also that the very high cone angles look less weird when > the tooth count is high, though the tooth angle is still wildly different > from what was requested. This is 75 deg angle with lots of teeth: > > [image: image.png] > I'm not going to show another image, but if I line it up along a ridge by > eye the tooth ridge angle looks like around 120 deg. But note how the > triangles running around the baes actually look like 60 deg triangles. > > On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss < > discuss@lists.openscad.org> wrote: > >> Adrian Mariano wrote: >> >> I think it's tough to tell what the angles are in the fixed view like >> that due to the distortion from perspective. In my code the triangles that >> form the teeth are constructed with the specified angle, but then they end >> up getting projected at a different angle depending on the cone angle you >> pick. Furthermore, there's the question of where the angle is measured. I >> think the wikipedia page suggested it is measured relative to the cylinder >> axis, but I'd normally expect tooth angle to be measured on the tooth, >> which means the slope of the tooth will also lead to a change in the >> effective angle. (Maybe this factor is what you're talking about?) I >> decided for my implementation to treat the requested angle as "nominal" and >> not worry about these various deviations. As long as you pick the same >> angle (and other parameters) for both sides of the joint, the parts will >> mate. And if you don't like the angle you get---change it. >> >> On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss < >> discuss@lists.openscad.org> wrote: >> >> I’ve had a look at some of the codes posted above and actually got one to >> work. But the question remains: >> >> In the image below, 60° triangles parallel to the z-axis linear_extruded >> to the origin give an angle of 90° between the flanks of a spline, which >> can be seen when one looks along a ridge towards the origin. >> >> Are these then 60° splines or 90° splines? >> ------------------------------ >> >> OpenSCAD mailing list To unsubscribe send an email to >> discuss-leave@lists.openscad.org >> >> Immediately after posting, I thought I should have simply said that the >> angle between the flanks of a spline viewed perpendicular to the axis of >> the ring of splines is not the same as the angle around the ridge of the >> spline = on the tooth. So your guess was right. I too would think that the >> angle on the tooth would be what counts in practise. Unfortunately, >> Wikipedia is not very clear on that. I wonder what our resident >> engineer/machinist would say. Or maybe it’s actually the angle of the >> cutting tool - that would be the angle between the flanks of adjacent >> splines? Then only one tool would be needed. >> >> Could be of interest for BOSL, as 60° and 90° seem to be the standard >> angles, so it would be good to know how/where they are measured. With >> increasing numbers of splines, the discrepancy between the two frames of >> reference rapidly decreases. >> >> I have a concept that seems promising, but doing the trigonometry is like >> trying to swing from tree to tree in a dense jungle in a fog, so I have >> given up for the time being. >> _______________________________________________ >> 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 >
MM
Michael Möller
Sun, Nov 17, 2024 1:23 PM

søn. 17. nov. 2024 14.22 skrev Michael Möller private2michael@gmail.com:

søn. 17. nov. 2024 14.17 skrev Adrian Mariano via Discuss <
discuss@lists.openscad.org>:

I did ponder the idea of trying to compute a correction factor to the
tooth angle, but given the uncertainty about what the right angle actually
is, and also uncertainty on my part about how to actually compute that
correction factor, I didn't pursue this idea.  Wouldn't angle between
adjacent flanks be equivalent to angle on the tooth, which is basically the
other angle between flanks?  In the case of no cone angle these angles
must be the same because the part mates with itself.

Another thing is that my code supports skewing the teeth so you can make
teeth with one face vertical, for example.  This distorts the angle.  I
didn't see a compelling reason the angle needs to be "correct".  Here an
example of what you get if you ask for 60 degrees with maximal skew:

[image: image.png]
If I change the tooth angle to try to achieve actual 60 deg at the tops I
get something like this

[image: image.png]
Note that the tooth height has radically changed.  From a design
perspective, I think it's maybe nicer for a user to be able to skew the
teeth while keeping the tooth height fixed, rather than having these
parameters coupled.

In the case of very high cone angle (here 75 deg), weird stuff happens
and I get shapes like this:

[image: image.png]
where the adjacent teeth flanks become coplanar, and then if I push cone
angle higher (85 deg here) the "valley" between the teeth becomes a second
ridge

[image: image.png]
It's not clear if forms like this are useful for anything.  The
construction still works, producing a mating shape that looks like this:

[image: image.png]
But clearly the tooth angle measured at the tooth ridge or the complement
of the angle between the flanks is wildly different from the requested 60
deg.  I'll note also that the very high cone angles look less weird when
the tooth count is high, though the tooth angle is still wildly different
from what was requested.  This is 75 deg angle with lots of teeth:

[image: image.png]
I'm not going to show another image, but if I line it up along a ridge by
eye the tooth ridge angle looks like around 120 deg.  But note how the
triangles running around the baes actually look like 60 deg triangles.

On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

Adrian Mariano wrote:

I think it's tough to tell what the angles are in the fixed view like
that due to the distortion from perspective. In my code the triangles that
form the teeth are constructed with the specified angle, but then they end
up getting projected at a different angle depending on the cone angle you
pick. Furthermore, there's the question of where the angle is measured. I
think the wikipedia page suggested it is measured relative to the cylinder
axis, but I'd normally expect tooth angle to be measured on the tooth,
which means the slope of the tooth will also lead to a change in the
effective angle. (Maybe this factor is what you're talking about?) I
decided for my implementation to treat the requested angle as "nominal" and
not worry about these various deviations. As long as you pick the same
angle (and other parameters) for both sides of the joint, the parts will
mate. And if you don't like the angle you get---change it.

On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

I’ve had a look at some of the codes posted above and actually got one
to work. But the question remains:

In the image below, 60° triangles parallel to the z-axis linear_extruded
to the origin give an angle of 90° between the flanks of a spline, which
can be seen when one looks along a ridge towards the origin.

Are these then 60° splines or 90° splines?

OpenSCAD mailing list To unsubscribe send an email to
discuss-leave@lists.openscad.org

Immediately after posting, I thought I should have simply said that the
angle between the flanks of a spline viewed perpendicular to the axis of
the ring of splines is not the same as the angle around the ridge of the
spline = on the tooth. So your guess was right. I too would think that the
angle on the tooth would be what counts in practise. Unfortunately,
Wikipedia is not very clear on that. I wonder what our resident
engineer/machinist would say. Or maybe it’s actually the angle of the
cutting tool - that would be the angle between the flanks of adjacent
splines? Then only one tool would be needed.

Could be of interest for BOSL, as 60° and 90° seem to be the standard
angles, so it would be good to know how/where they are measured. With
increasing numbers of splines, the discrepancy between the two frames of
reference rapidly decreases.

I have a concept that seems promising, but doing the trigonometry is
like trying to swing from tree to tree in a dense jungle in a fog, so I
have given up for the time being.


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

søn. 17. nov. 2024 14.22 skrev Michael Möller <private2michael@gmail.com>: > > > > søn. 17. nov. 2024 14.17 skrev Adrian Mariano via Discuss < > discuss@lists.openscad.org>: > >> I did ponder the idea of trying to compute a correction factor to the >> tooth angle, but given the uncertainty about what the right angle actually >> is, and also uncertainty on my part about how to actually compute that >> correction factor, I didn't pursue this idea. Wouldn't angle between >> adjacent flanks be equivalent to angle on the tooth, which is basically the >> other angle between flanks? In the case of no cone angle these angles >> must be the same because the part mates with itself. >> >> Another thing is that my code supports skewing the teeth so you can make >> teeth with one face vertical, for example. This distorts the angle. I >> didn't see a compelling reason the angle needs to be "correct". Here an >> example of what you get if you ask for 60 degrees with maximal skew: >> >> [image: image.png] >> If I change the tooth angle to try to achieve actual 60 deg at the tops I >> get something like this >> >> [image: image.png] >> Note that the tooth height has radically changed. From a design >> perspective, I think it's maybe nicer for a user to be able to skew the >> teeth while keeping the tooth height fixed, rather than having these >> parameters coupled. >> >> In the case of very high cone angle (here 75 deg), weird stuff happens >> and I get shapes like this: >> >> [image: image.png] >> where the adjacent teeth flanks become coplanar, and then if I push cone >> angle higher (85 deg here) the "valley" between the teeth becomes a second >> ridge >> >> [image: image.png] >> It's not clear if forms like this are useful for anything. The >> construction still works, producing a mating shape that looks like this: >> >> [image: image.png] >> But clearly the tooth angle measured at the tooth ridge or the complement >> of the angle between the flanks is wildly different from the requested 60 >> deg. I'll note also that the very high cone angles look less weird when >> the tooth count is high, though the tooth angle is still wildly different >> from what was requested. This is 75 deg angle with lots of teeth: >> >> [image: image.png] >> I'm not going to show another image, but if I line it up along a ridge by >> eye the tooth ridge angle looks like around 120 deg. But note how the >> triangles running around the baes actually look like 60 deg triangles. >> >> On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> Adrian Mariano wrote: >>> >>> I think it's tough to tell what the angles are in the fixed view like >>> that due to the distortion from perspective. In my code the triangles that >>> form the teeth are constructed with the specified angle, but then they end >>> up getting projected at a different angle depending on the cone angle you >>> pick. Furthermore, there's the question of where the angle is measured. I >>> think the wikipedia page suggested it is measured relative to the cylinder >>> axis, but I'd normally expect tooth angle to be measured on the tooth, >>> which means the slope of the tooth will also lead to a change in the >>> effective angle. (Maybe this factor is what you're talking about?) I >>> decided for my implementation to treat the requested angle as "nominal" and >>> not worry about these various deviations. As long as you pick the same >>> angle (and other parameters) for both sides of the joint, the parts will >>> mate. And if you don't like the angle you get---change it. >>> >>> On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>> I’ve had a look at some of the codes posted above and actually got one >>> to work. But the question remains: >>> >>> In the image below, 60° triangles parallel to the z-axis linear_extruded >>> to the origin give an angle of 90° between the flanks of a spline, which >>> can be seen when one looks along a ridge towards the origin. >>> >>> Are these then 60° splines or 90° splines? >>> ------------------------------ >>> >>> OpenSCAD mailing list To unsubscribe send an email to >>> discuss-leave@lists.openscad.org >>> >>> Immediately after posting, I thought I should have simply said that the >>> angle between the flanks of a spline viewed perpendicular to the axis of >>> the ring of splines is not the same as the angle around the ridge of the >>> spline = on the tooth. So your guess was right. I too would think that the >>> angle on the tooth would be what counts in practise. Unfortunately, >>> Wikipedia is not very clear on that. I wonder what our resident >>> engineer/machinist would say. Or maybe it’s actually the angle of the >>> cutting tool - that would be the angle between the flanks of adjacent >>> splines? Then only one tool would be needed. >>> >>> Could be of interest for BOSL, as 60° and 90° seem to be the standard >>> angles, so it would be good to know how/where they are measured. With >>> increasing numbers of splines, the discrepancy between the two frames of >>> reference rapidly decreases. >>> >>> I have a concept that seems promising, but doing the trigonometry is >>> like trying to swing from tree to tree in a dense jungle in a fog, so I >>> have given up for the time being. >>> _______________________________________________ >>> 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 >> >
SP
Sanjeev Prabhakar
Sun, Nov 17, 2024 1:43 PM

with 75 deg tooth angle 10 deg cone angle
[image: Screenshot 2024-11-17 at 7.03.48 PM.png]

with 80 deg tooth angle and 10 deg cone angle (lot of distortion)

[image: Screenshot 2024-11-17 at 7.11.04 PM.png]

On Sun, 17 Nov 2024 at 18:47, Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

I did ponder the idea of trying to compute a correction factor to the
tooth angle, but given the uncertainty about what the right angle actually
is, and also uncertainty on my part about how to actually compute that
correction factor, I didn't pursue this idea.  Wouldn't angle between
adjacent flanks be equivalent to angle on the tooth, which is basically the
other angle between flanks?  In the case of no cone angle these angles
must be the same because the part mates with itself.

Another thing is that my code supports skewing the teeth so you can make
teeth with one face vertical, for example.  This distorts the angle.  I
didn't see a compelling reason the angle needs to be "correct".  Here an
example of what you get if you ask for 60 degrees with maximal skew:

[image: image.png]
If I change the tooth angle to try to achieve actual 60 deg at the tops I
get something like this

[image: image.png]
Note that the tooth height has radically changed.  From a design
perspective, I think it's maybe nicer for a user to be able to skew the
teeth while keeping the tooth height fixed, rather than having these
parameters coupled.

In the case of very high cone angle (here 75 deg), weird stuff happens and
I get shapes like this:

[image: image.png]
where the adjacent teeth flanks become coplanar, and then if I push cone
angle higher (85 deg here) the "valley" between the teeth becomes a second
ridge

[image: image.png]
It's not clear if forms like this are useful for anything.  The
construction still works, producing a mating shape that looks like this:

[image: image.png]
But clearly the tooth angle measured at the tooth ridge or the complement
of the angle between the flanks is wildly different from the requested 60
deg.  I'll note also that the very high cone angles look less weird when
the tooth count is high, though the tooth angle is still wildly different
from what was requested.  This is 75 deg angle with lots of teeth:

[image: image.png]
I'm not going to show another image, but if I line it up along a ridge by
eye the tooth ridge angle looks like around 120 deg.  But note how the
triangles running around the baes actually look like 60 deg triangles.

On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

Adrian Mariano wrote:

I think it's tough to tell what the angles are in the fixed view like
that due to the distortion from perspective. In my code the triangles that
form the teeth are constructed with the specified angle, but then they end
up getting projected at a different angle depending on the cone angle you
pick. Furthermore, there's the question of where the angle is measured. I
think the wikipedia page suggested it is measured relative to the cylinder
axis, but I'd normally expect tooth angle to be measured on the tooth,
which means the slope of the tooth will also lead to a change in the
effective angle. (Maybe this factor is what you're talking about?) I
decided for my implementation to treat the requested angle as "nominal" and
not worry about these various deviations. As long as you pick the same
angle (and other parameters) for both sides of the joint, the parts will
mate. And if you don't like the angle you get---change it.

On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

I’ve had a look at some of the codes posted above and actually got one to
work. But the question remains:

In the image below, 60° triangles parallel to the z-axis linear_extruded
to the origin give an angle of 90° between the flanks of a spline, which
can be seen when one looks along a ridge towards the origin.

Are these then 60° splines or 90° splines?

OpenSCAD mailing list To unsubscribe send an email to
discuss-leave@lists.openscad.org

Immediately after posting, I thought I should have simply said that the
angle between the flanks of a spline viewed perpendicular to the axis of
the ring of splines is not the same as the angle around the ridge of the
spline = on the tooth. So your guess was right. I too would think that the
angle on the tooth would be what counts in practise. Unfortunately,
Wikipedia is not very clear on that. I wonder what our resident
engineer/machinist would say. Or maybe it’s actually the angle of the
cutting tool - that would be the angle between the flanks of adjacent
splines? Then only one tool would be needed.

Could be of interest for BOSL, as 60° and 90° seem to be the standard
angles, so it would be good to know how/where they are measured. With
increasing numbers of splines, the discrepancy between the two frames of
reference rapidly decreases.

I have a concept that seems promising, but doing the trigonometry is like
trying to swing from tree to tree in a dense jungle in a fog, so I have
given up for the time being.


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

with 75 deg tooth angle 10 deg cone angle [image: Screenshot 2024-11-17 at 7.03.48 PM.png] with 80 deg tooth angle and 10 deg cone angle (lot of distortion) [image: Screenshot 2024-11-17 at 7.11.04 PM.png] On Sun, 17 Nov 2024 at 18:47, Adrian Mariano via Discuss < discuss@lists.openscad.org> wrote: > I did ponder the idea of trying to compute a correction factor to the > tooth angle, but given the uncertainty about what the right angle actually > is, and also uncertainty on my part about how to actually compute that > correction factor, I didn't pursue this idea. Wouldn't angle between > adjacent flanks be equivalent to angle on the tooth, which is basically the > other angle between flanks? In the case of no cone angle these angles > must be the same because the part mates with itself. > > Another thing is that my code supports skewing the teeth so you can make > teeth with one face vertical, for example. This distorts the angle. I > didn't see a compelling reason the angle needs to be "correct". Here an > example of what you get if you ask for 60 degrees with maximal skew: > > [image: image.png] > If I change the tooth angle to try to achieve actual 60 deg at the tops I > get something like this > > [image: image.png] > Note that the tooth height has radically changed. From a design > perspective, I think it's maybe nicer for a user to be able to skew the > teeth while keeping the tooth height fixed, rather than having these > parameters coupled. > > In the case of very high cone angle (here 75 deg), weird stuff happens and > I get shapes like this: > > [image: image.png] > where the adjacent teeth flanks become coplanar, and then if I push cone > angle higher (85 deg here) the "valley" between the teeth becomes a second > ridge > > [image: image.png] > It's not clear if forms like this are useful for anything. The > construction still works, producing a mating shape that looks like this: > > [image: image.png] > But clearly the tooth angle measured at the tooth ridge or the complement > of the angle between the flanks is wildly different from the requested 60 > deg. I'll note also that the very high cone angles look less weird when > the tooth count is high, though the tooth angle is still wildly different > from what was requested. This is 75 deg angle with lots of teeth: > > [image: image.png] > I'm not going to show another image, but if I line it up along a ridge by > eye the tooth ridge angle looks like around 120 deg. But note how the > triangles running around the baes actually look like 60 deg triangles. > > On Sun, Nov 17, 2024 at 2:38 AM Caddiy via Discuss < > discuss@lists.openscad.org> wrote: > >> Adrian Mariano wrote: >> >> I think it's tough to tell what the angles are in the fixed view like >> that due to the distortion from perspective. In my code the triangles that >> form the teeth are constructed with the specified angle, but then they end >> up getting projected at a different angle depending on the cone angle you >> pick. Furthermore, there's the question of where the angle is measured. I >> think the wikipedia page suggested it is measured relative to the cylinder >> axis, but I'd normally expect tooth angle to be measured on the tooth, >> which means the slope of the tooth will also lead to a change in the >> effective angle. (Maybe this factor is what you're talking about?) I >> decided for my implementation to treat the requested angle as "nominal" and >> not worry about these various deviations. As long as you pick the same >> angle (and other parameters) for both sides of the joint, the parts will >> mate. And if you don't like the angle you get---change it. >> >> On Sun, Nov 17, 2024 at 12:15 AM Caddiy via Discuss < >> discuss@lists.openscad.org> wrote: >> >> I’ve had a look at some of the codes posted above and actually got one to >> work. But the question remains: >> >> In the image below, 60° triangles parallel to the z-axis linear_extruded >> to the origin give an angle of 90° between the flanks of a spline, which >> can be seen when one looks along a ridge towards the origin. >> >> Are these then 60° splines or 90° splines? >> ------------------------------ >> >> OpenSCAD mailing list To unsubscribe send an email to >> discuss-leave@lists.openscad.org >> >> Immediately after posting, I thought I should have simply said that the >> angle between the flanks of a spline viewed perpendicular to the axis of >> the ring of splines is not the same as the angle around the ridge of the >> spline = on the tooth. So your guess was right. I too would think that the >> angle on the tooth would be what counts in practise. Unfortunately, >> Wikipedia is not very clear on that. I wonder what our resident >> engineer/machinist would say. Or maybe it’s actually the angle of the >> cutting tool - that would be the angle between the flanks of adjacent >> splines? Then only one tool would be needed. >> >> Could be of interest for BOSL, as 60° and 90° seem to be the standard >> angles, so it would be good to know how/where they are measured. With >> increasing numbers of splines, the discrepancy between the two frames of >> reference rapidly decreases. >> >> I have a concept that seems promising, but doing the trigonometry is like >> trying to swing from tree to tree in a dense jungle in a fog, so I have >> given up for the time being. >> _______________________________________________ >> 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 >
SP
Sanjeev Prabhakar
Sun, Nov 17, 2024 2:01 PM

50 teeth cone angle 40 deg tooth angle 75 deg
[image: Screenshot 2024-11-17 at 7.29.01 PM.png]

50 teeth cone angle 40 deg tooth angle 75 deg [image: Screenshot 2024-11-17 at 7.29.01 PM.png]
SP
Sanjeev Prabhakar
Sun, Nov 17, 2024 2:05 PM

50 teeth cone angle 40 deg tooth angle 80 deg

[image: Screenshot 2024-11-17 at 7.34.19 PM.png]

50 teeth cone angle 40 deg tooth angle 80 deg [image: Screenshot 2024-11-17 at 7.34.19 PM.png]
AM
Adrian Mariano
Sun, Nov 17, 2024 2:21 PM

Sanjeev, your definition of cone angle is not the same as mine, it would
appear.  I measure cone angle by the line through the center of the
triangle so a zero cone angle is when the mating parts are identical, which
I consider to be the standard joint configuration.  Two parts will mate if
their cone angles are the opposite sign with my approach.

So 60 deg tooth angle, 0 deg cone angle:

[image: image.png]

And the case of 50 teeth, 40 deg cone angle, 75 deg tooth angle for me is
this:

[image: image.png]
Are you constructing your model so that the 75 deg angle is achieved as
measured on the tooth ridge?

On Sun, Nov 17, 2024 at 9:06 AM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

50 teeth cone angle 40 deg tooth angle 80 deg

[image: Screenshot 2024-11-17 at 7.34.19 PM.png]

Sanjeev, your definition of cone angle is not the same as mine, it would appear. I measure cone angle by the line through the center of the triangle so a zero cone angle is when the mating parts are identical, which I consider to be the standard joint configuration. Two parts will mate if their cone angles are the opposite sign with my approach. So 60 deg tooth angle, 0 deg cone angle: [image: image.png] And the case of 50 teeth, 40 deg cone angle, 75 deg tooth angle for me is this: [image: image.png] Are you constructing your model so that the 75 deg angle is achieved as measured on the tooth ridge? On Sun, Nov 17, 2024 at 9:06 AM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > 50 teeth cone angle 40 deg tooth angle 80 deg > > [image: Screenshot 2024-11-17 at 7.34.19 PM.png] >
SP
Sanjeev Prabhakar
Sun, Nov 17, 2024 2:34 PM

I think the tooth angle is the angle which one side of the tooth makes with
x-y plane
I will check that once again

On Sun, 17 Nov, 2024, 7:52 pm Adrian Mariano, avm4@cornell.edu wrote:

Sanjeev, your definition of cone angle is not the same as mine, it would
appear.  I measure cone angle by the line through the center of the
triangle so a zero cone angle is when the mating parts are identical, which
I consider to be the standard joint configuration.  Two parts will mate if
their cone angles are the opposite sign with my approach.

So 60 deg tooth angle, 0 deg cone angle:

[image: image.png]

And the case of 50 teeth, 40 deg cone angle, 75 deg tooth angle for me is
this:

[image: image.png]
Are you constructing your model so that the 75 deg angle is achieved as
measured on the tooth ridge?

On Sun, Nov 17, 2024 at 9:06 AM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

50 teeth cone angle 40 deg tooth angle 80 deg

[image: Screenshot 2024-11-17 at 7.34.19 PM.png]

I think the tooth angle is the angle which one side of the tooth makes with x-y plane I will check that once again On Sun, 17 Nov, 2024, 7:52 pm Adrian Mariano, <avm4@cornell.edu> wrote: > Sanjeev, your definition of cone angle is not the same as mine, it would > appear. I measure cone angle by the line through the center of the > triangle so a zero cone angle is when the mating parts are identical, which > I consider to be the standard joint configuration. Two parts will mate if > their cone angles are the opposite sign with my approach. > > So 60 deg tooth angle, 0 deg cone angle: > > [image: image.png] > > And the case of 50 teeth, 40 deg cone angle, 75 deg tooth angle for me is > this: > > [image: image.png] > Are you constructing your model so that the 75 deg angle is achieved as > measured on the tooth ridge? > > On Sun, Nov 17, 2024 at 9:06 AM Sanjeev Prabhakar < > sprabhakar2006@gmail.com> wrote: > >> 50 teeth cone angle 40 deg tooth angle 80 deg >> >> [image: Screenshot 2024-11-17 at 7.34.19 PM.png] >> >
SP
Sanjeev Prabhakar
Sun, Nov 17, 2024 3:23 PM

I have checked the tooth angles and the measured values are 80.65 on the
inner side, 80.59 on the outer side and cone angle is perfect 40 deg.
Maybe this distortion in angle is due to projection on the cylinder

[image: Screenshot 2024-11-17 at 8.39.03 PM.png]

[image: Screenshot 2024-11-17 at 8.42.14 PM.png]
[image: Screenshot 2024-11-17 at 8.46.45 PM.png]

I have checked the tooth angles and the measured values are 80.65 on the inner side, 80.59 on the outer side and cone angle is perfect 40 deg. Maybe this distortion in angle is due to projection on the cylinder [image: Screenshot 2024-11-17 at 8.39.03 PM.png] [image: Screenshot 2024-11-17 at 8.42.14 PM.png] [image: Screenshot 2024-11-17 at 8.46.45 PM.png]
SP
Sanjeev Prabhakar
Sun, Nov 17, 2024 4:12 PM

I have checked again, the tooth angles in both inner side and outer side
are exactly 80.6 and the distortion is not due to the projection on the
cylinder, it is due to the cone angle and compound effect of the 2 angles.
In my case when I keep the cone angle at 32.5 deg all the angles exactly
match the defined numbers.

I have checked again, the tooth angles in both inner side and outer side are exactly 80.6 and the distortion is not due to the projection on the cylinder, it is due to the cone angle and compound effect of the 2 angles. In my case when I keep the cone angle at 32.5 deg all the angles exactly match the defined numbers.
AM
Adrian Mariano
Sun, Nov 17, 2024 4:26 PM

Sanjeev, I didn't see that you stated what your definition of "cone angle"
is.  In my case, it's not an angle you can easily see in the model, since
it is through the CENTER of the tooth.  And yes, the deviation I was
describing with cone angle in my model is due to the effect of compound
angles, that is, if you measure tooth angle as angle between the planes of
the tooth then that changes with rising cone angle because of the compound
angle effect.

Why is 32.5 degrees a magical cone angle for your model?

On Sun, Nov 17, 2024 at 11:13 AM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I have checked again, the tooth angles in both inner side and outer side
are exactly 80.6 and the distortion is not due to the projection on the
cylinder, it is due to the cone angle and compound effect of the 2 angles.
In my case when I keep the cone angle at 32.5 deg all the angles exactly
match the defined numbers.

Sanjeev, I didn't see that you stated what your definition of "cone angle" is. In my case, it's not an angle you can easily see in the model, since it is through the CENTER of the tooth. And yes, the deviation I was describing with cone angle in my model is due to the effect of compound angles, that is, if you measure tooth angle as angle between the planes of the tooth then that changes with rising cone angle because of the compound angle effect. Why is 32.5 degrees a magical cone angle for your model? On Sun, Nov 17, 2024 at 11:13 AM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > I have checked again, the tooth angles in both inner side and outer side > are exactly 80.6 and the distortion is not due to the projection on the > cylinder, it is due to the cone angle and compound effect of the 2 angles. > In my case when I keep the cone angle at 32.5 deg all the angles exactly > match the defined numbers. > >
SP
Sanjeev Prabhakar
Sun, Nov 17, 2024 4:37 PM

Oh I think the explanation I sent earlier had some pictures which exceeded
the acceptable size for mails here and did not reach anyone.

The angle tooth makes with x-y plane is the angle of the tooth.

32.5 is only for the case where tooth angle is 80 degree, number of teeth
are 50 and cone angle if set to 32.5.

For different configurations this might change.

Also I did not try to measure the angle if tooth face is intersected by a
vertical plane perpendicular to tooth line joining the inner and outer
points.

Maybe that would be correct angle. But I am not sure

On Sun, 17 Nov, 2024, 9:57 pm Adrian Mariano, avm4@cornell.edu wrote:

Sanjeev, I didn't see that you stated what your definition of "cone angle"
is.  In my case, it's not an angle you can easily see in the model, since
it is through the CENTER of the tooth.  And yes, the deviation I was
describing with cone angle in my model is due to the effect of compound
angles, that is, if you measure tooth angle as angle between the planes of
the tooth then that changes with rising cone angle because of the compound
angle effect.

Why is 32.5 degrees a magical cone angle for your model?

On Sun, Nov 17, 2024 at 11:13 AM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I have checked again, the tooth angles in both inner side and outer side
are exactly 80.6 and the distortion is not due to the projection on the
cylinder, it is due to the cone angle and compound effect of the 2 angles.
In my case when I keep the cone angle at 32.5 deg all the angles exactly
match the defined numbers.

Oh I think the explanation I sent earlier had some pictures which exceeded the acceptable size for mails here and did not reach anyone. The angle tooth makes with x-y plane is the angle of the tooth. 32.5 is only for the case where tooth angle is 80 degree, number of teeth are 50 and cone angle if set to 32.5. For different configurations this might change. Also I did not try to measure the angle if tooth face is intersected by a vertical plane perpendicular to tooth line joining the inner and outer points. Maybe that would be correct angle. But I am not sure On Sun, 17 Nov, 2024, 9:57 pm Adrian Mariano, <avm4@cornell.edu> wrote: > Sanjeev, I didn't see that you stated what your definition of "cone angle" > is. In my case, it's not an angle you can easily see in the model, since > it is through the CENTER of the tooth. And yes, the deviation I was > describing with cone angle in my model is due to the effect of compound > angles, that is, if you measure tooth angle as angle between the planes of > the tooth then that changes with rising cone angle because of the compound > angle effect. > > Why is 32.5 degrees a magical cone angle for your model? > > On Sun, Nov 17, 2024 at 11:13 AM Sanjeev Prabhakar < > sprabhakar2006@gmail.com> wrote: > >> I have checked again, the tooth angles in both inner side and outer side >> are exactly 80.6 and the distortion is not due to the projection on the >> cylinder, it is due to the cone angle and compound effect of the 2 angles. >> In my case when I keep the cone angle at 32.5 deg all the angles exactly >> match the defined numbers. >> >>
RW
Raymond West
Sun, Nov 17, 2024 5:43 PM

Afaik, The Hirth joint was invented in 1928, and was very simple to
manufacture, with the machinery available at the time. I'm pretty sure,
that none of the detail On Hirth Ring Couplings: Design Principles
Including the Effect of Friction https://www.mdpi.com/2076-0825/7/4/79
for example, was known. I'm not sure why it is being made so complicated
on here.

On 17/11/2024 13:22, Michael Möller via Discuss wrote:

Afaik, The Hirth joint was invented in 1928, and was very simple to manufacture, with the machinery available at the time. I'm pretty sure, that none of the detail On Hirth Ring Couplings: Design Principles Including the Effect of Friction <https://www.mdpi.com/2076-0825/7/4/79> for example, was known. I'm not sure why it is being made so complicated on here. On 17/11/2024 13:22, Michael Möller via Discuss wrote: > > >
FH
Father Horton
Sun, Nov 17, 2024 6:08 PM

If it’s worth doing, it’s worth overdoing.

If it’s worth doing, it’s worth overdoing.
AM
Adrian Mariano
Sun, Nov 17, 2024 6:46 PM

Ray, I have to say that I've found the complexity lurking in this hirth
joint to be kind of baffling.  When I saw Bob's first attempt I
immediately thought Bob was massively overcomplicating things.  But I was
wrong.  It seems like it should be very simple, and yet it seems to be
remarkably subtle and complicated.  We're not "making" it that
way---that's just the way it is. I thought it was trivial and wrote a
straight forward code and then found that it didn't work in various
cases---it was wrong, in other words, and getting it right is hard.  Or at
least I didn't find an easy way to get it right, and neither did Bob.  And
when I say it was wrong, I mean that the joint didn't mate properly.
Clearly something different happens if you approach the design with "I have
a 60 deg milling cutter, how do I cut a 100 tooth hirth joint" than "I want
to construct a mathematical model that makes a generic version of this
joint".  I think another factor is that a lot of the subtlety results in
errors that become small when there are lots of teeth.  I see potential
interesting applications for this joint with small numbers of teeth like
perhaps 8 or 4 to create mechanisms that lock into a small number of
positions, so I don't want to ignore those small tooth count cases.

Regarding tooth angle, I attempted to measure it at the tooth ridge with
nominal tooth angle set to 60 and zero cone angle.  With four teeth I get
76.8 deg instead of 60 deg.  With 44 teeth I get 60.16 deg.  With 144 teeth
it's 60.01 deg.  If I raise the cone angle to 30 deg then I actually get
60.4 in the 4 tooth case, but in the 44 tooth case it's now 65.5 deg and
with 144 teeth it's 66.8 deg.  Why does the 30 deg cone angle make the 4
tooth case so close to the nominal angle?  It's because the tooth ridge in
this case is very close to parallel to the xy plane, which matches the
design angle reference for the construction of the triangle.    Here's a
picture (4 teeth, 30 deg cone angle, 60 deg nominal tooth angle):

[image: image.png]

So it seems like the deviation of tooth angle for small tooth count has to
do with fitting the teeth around a circle.  When you have lots of teeth,
it's approximately like fitting the teeth onto a line and nothing weird
happens, but when you curve just 4 teeth around a circle, the angles no
longer add up as expected for flat geometry, resulting in an alteration of
the actual realized tooth angle.  So to produce teeth that match the
nominal angle there are two corrections needed.  One is a correction for
fitting a linear arrangement of triangles around a circle, with increasing
correction as the number of teeth shrinks.  The other one has to do with
cone angle, and at least for my definition of cone angle, the correction
looks like it gets smaller and then larger again as you increase the cone
angle---at least for the small tooth count case.

On Sun, Nov 17, 2024 at 12:44 PM Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

Afaik, The Hirth joint was invented in 1928, and was very simple to
manufacture, with the machinery available at the time. I'm pretty sure,
that none of the detail On Hirth Ring Couplings: Design Principles
Including the Effect of Friction https://www.mdpi.com/2076-0825/7/4/79
for example, was known. I'm not sure why it is being made so complicated on
here.

On 17/11/2024 13:22, Michael Möller via Discuss wrote:


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Ray, I have to say that I've found the complexity lurking in this hirth joint to be kind of baffling. When I saw Bob's first attempt I immediately thought Bob was massively overcomplicating things. But I was wrong. It seems like it should be very simple, and yet it seems to be remarkably subtle and complicated. We're not "making" it that way---that's just the way it is. I thought it was trivial and wrote a straight forward code and then found that it didn't work in various cases---it was wrong, in other words, and getting it right is hard. Or at least I didn't find an easy way to get it right, and neither did Bob. And when I say it was wrong, I mean that the joint didn't mate properly. Clearly something different happens if you approach the design with "I have a 60 deg milling cutter, how do I cut a 100 tooth hirth joint" than "I want to construct a mathematical model that makes a generic version of this joint". I think another factor is that a lot of the subtlety results in errors that become small when there are lots of teeth. I see potential interesting applications for this joint with small numbers of teeth like perhaps 8 or 4 to create mechanisms that lock into a small number of positions, so I don't want to ignore those small tooth count cases. Regarding tooth angle, I attempted to measure it at the tooth ridge with nominal tooth angle set to 60 and zero cone angle. With four teeth I get 76.8 deg instead of 60 deg. With 44 teeth I get 60.16 deg. With 144 teeth it's 60.01 deg. If I raise the cone angle to 30 deg then I actually get 60.4 in the 4 tooth case, but in the 44 tooth case it's now 65.5 deg and with 144 teeth it's 66.8 deg. Why does the 30 deg cone angle make the 4 tooth case so close to the nominal angle? It's because the tooth ridge in this case is very close to parallel to the xy plane, which matches the design angle reference for the construction of the triangle. Here's a picture (4 teeth, 30 deg cone angle, 60 deg nominal tooth angle): [image: image.png] So it seems like the deviation of tooth angle for small tooth count has to do with fitting the teeth around a circle. When you have lots of teeth, it's approximately like fitting the teeth onto a line and nothing weird happens, but when you curve just 4 teeth around a circle, the angles no longer add up as expected for flat geometry, resulting in an alteration of the actual realized tooth angle. So to produce teeth that match the nominal angle there are two corrections needed. One is a correction for fitting a linear arrangement of triangles around a circle, with increasing correction as the number of teeth shrinks. The other one has to do with cone angle, and at least for my definition of cone angle, the correction looks like it gets smaller and then larger again as you increase the cone angle---at least for the small tooth count case. On Sun, Nov 17, 2024 at 12:44 PM Raymond West via Discuss < discuss@lists.openscad.org> wrote: > Afaik, The Hirth joint was invented in 1928, and was very simple to > manufacture, with the machinery available at the time. I'm pretty sure, > that none of the detail On Hirth Ring Couplings: Design Principles > Including the Effect of Friction <https://www.mdpi.com/2076-0825/7/4/79> > for example, was known. I'm not sure why it is being made so complicated on > here. > > On 17/11/2024 13:22, Michael Möller via Discuss wrote: > > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
RW
Raymond West
Sun, Nov 17, 2024 9:15 PM

Hi Adrian,

The code I sent seemed to be OK for anything more than two teeth. Maybe
if I explain how I think it would have been originally made will let you
see where you are getting odd angles. The first requirement would be a
grinding wheel. (I would guess that it was most likely a milling cutter,
and material brass, but never mind, same principle.) The standard angles
for such discs would either be 90 degree or 60 degree (inclusive angle),
others would most likely be more expensive. This would be a disc, with a
v edge (at 90 or 60 degrees). The edge of the disc would be rounded,
since a pointed edge would not last long. This would be used in a
horizontal grinder,  the disc can be raised or lowered, and the bed
traversed backwards and forwards under the wheel. A piece of steel,
fixed to the bed could thus have a v groove ground into it, and the
profile, if no sideways movement, would be the inverse of the grinding
disk, it would have a rounded bottom (fillet) to the groove.

Now, if you have a rotary table, then you can clamp a round piece of
steel to that, and rotate the table a certain part of a revolution. So,
say, move in 30 degree steps, and you will get 6 v grooves, crossing in
the centre of the stock piece (or 12 meeting at the centre...) as you
traverse the piece at  the fixed angle beneath the grinding disc.

Now, wedge up one end of the rotary table. A new piece of stock will
give you 12 v grooves, say, but shallower towards the centre. If you
make it, such that the grooves are at zero depth at the centre, and full
depth at the edge, and there are the correct number of grooves,  then
two such pieces will mesh together, and tend to self centre. Of course,
the bottom of grooves are filleted due to the shape of the grinding
wheel. The fillet will be a constant width. To get two such pieces to
fit together, the peaks need to be rounded over, but flattening them is
simpler, and in some ways better (else the point of the mating ridge
bottoms out on the fillet). The centres of the round stock pieces can be
machined away, since there is little force transmitted there, and for
other reasons. So,  simple calculations can be made, depending on the
tooling available, size of desired coupling joint and number of teeth, etc.

Say we have a work piece diameter 40, and a grinding disc, say, width 8,
and 90 degree angle. We can calculate the minimum number of teeth from
d=40 and chord = 8. The maximum will depend on the radius of the 90
degree edge of the grinding wheel (which creates the fillet - we don't
want all fillet!), but let's say 50. That means the rotary table
increments must be in steps of 360/50 =7.2 degrees. If we were going
full depth of cut, then the maximum depth would be 4 (angle of 90
degrees), and 8 between peaks (but we can't go full depth at 7.2degrees).

So, given the length of chord, and diameter of work, we can find the
number of chords, n,  from d=(chord/ (sin(180/n))) we can solve that for
chord, and then the height of the ridge will be half of the chord length
(90 degree angle to wheel)- the assumption is that the grinding wheel
edge is pointed, not rounded.

Now, we want the grinding wheel to cut the depth calculated at the edge
of the work piece, but just touch the centre of the workpiece, so we can
calculate that we need to fix it at an angle that is
ASIN(ridge_height/2)/diam).

That will give a self centring matching Hirth joints, which afaik
complies with the 1928 original specification.

For the purposes of calculation ignore the radius at the bottom of the
grooves - that will depend on the wheel profile. As to all intents and
purposes, the bottom of the fillet will be parallel to the bottom of the
estimated groove, so the angle to the horizontal will be the same. The
top of the flattened ridge can be wider than the width of the fillet,
but the edges of the flat will be parallel, too.

Like most things, it starts off simple, then gets overcomplicated, to
the state that it becomes difficult to see what was the fundamental
reason for its existence in the first place. I would guess, that Hirth,
being a practical engineer, just made it in the workshop, then decided
to document it afterwards, most likely quicker than calculating angles,
etc., back then.

I think, as soon as you change the design so that the matching parts are
not identical, or do not have straight and flat flanks to the ridges,
then it is no longer a Hirth coupling.

On 17/11/2024 18:46, Adrian Mariano wrote:

Ray, I have to say that I've found the complexity lurking in this
hirth joint to be kind of baffling.   When I saw Bob's first attempt I
immediately thought Bob was massively overcomplicating things.  But I
was wrong.  It seems like it should be very simple, and yet it seems
to be remarkably subtle and complicated.   We're not "making" it that
way---that's just the way it is. I thought it was trivial and wrote a
straight forward code and then found that it didn't work in various
cases---it was wrong, in other words, and getting it right is hard. 
Or at least I didn't find an easy way to get it right, and neither did
Bob.  And when I say it was wrong, I mean that the joint didn't mate
properly. Clearly something different happens if you approach the
design with "I have a 60 deg milling cutter, how do I cut a 100 tooth
hirth joint" than "I want to construct a mathematical model that makes
a generic version of this joint".   I think another factor is that a
lot of the subtlety results in errors that become small when there are
lots of teeth.  I see potential interesting applications for this
joint with small numbers of teeth like perhaps 8 or 4 to create
mechanisms that lock into a small number of positions, so I don't want
to ignore those small tooth count cases.

Regarding tooth angle, I attempted to measure it at the tooth ridge
with nominal tooth angle set to 60 and zero cone angle.  With four
teeth I get 76.8 deg instead of 60 deg. With 44 teeth I get 60.16
deg.  With 144 teeth it's 60.01 deg.   If I raise the cone angle to 30
deg then I actually get 60.4 in the 4 tooth case, but in the 44 tooth
case it's now 65.5 deg and with 144 teeth it's 66.8 deg.   Why does
the 30 deg cone angle make the 4 tooth case so close to the nominal
angle?  It's because the tooth ridge in this case is very close to
parallel to the xy plane, which matches the design angle reference for
the construction of the triangle. Here's a picture (4 teeth, 30 deg
cone angle, 60 deg nominal tooth angle):

image.png

So it seems like the deviation of tooth angle for small tooth count
has to do with fitting the teeth around a circle. When you have lots
of teeth, it's approximately like fitting the teeth onto a line and
nothing weird happens, but when you curve just 4 teeth around a
circle, the angles no longer add up as expected for flat geometry,
resulting in an alteration of the actual realized tooth angle.  So to
produce teeth that match the nominal angle there are two corrections
needed.  One is a correction for fitting a linear arrangement of
triangles around a circle, with increasing correction as the number of
teeth shrinks.  The other one has to do with cone angle, and at least
for my definition of cone angle, the correction looks like it gets
smaller and then larger again as you increase the cone angle---at
least for the small tooth count case.

On Sun, Nov 17, 2024 at 12:44 PM Raymond West via Discuss
discuss@lists.openscad.org wrote:

 Afaik, The Hirth joint was invented in 1928, and was very simple
 to manufacture, with the machinery available at the time. I'm
 pretty sure, that none of the detail On Hirth Ring Couplings:
 Design Principles Including the Effect of Friction
 <https://www.mdpi.com/2076-0825/7/4/79> for example, was known.
 I'm not sure why it is being made so complicated on here.

 On 17/11/2024 13:22, Michael Möller via Discuss wrote:
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org
Hi Adrian, The code I sent seemed to be OK for anything more than two teeth. Maybe if I explain how I think it would have been originally made will let you see where you are getting odd angles. The first requirement would be a grinding wheel. (I would guess that it was most likely a milling cutter, and material brass, but never mind, same principle.) The standard angles for such discs would either be 90 degree or 60 degree (inclusive angle), others would most likely be more expensive. This would be a disc, with a v edge (at 90 or 60 degrees). The edge of the disc would be rounded, since a pointed edge would not last long. This would be used in a horizontal grinder,  the disc can be raised or lowered, and the bed traversed backwards and forwards under the wheel. A piece of steel, fixed to the bed could thus have a v groove ground into it, and the profile, if no sideways movement, would be the inverse of the grinding disk, it would have a rounded bottom (fillet) to the groove. Now, if you have a rotary table, then you can clamp a round piece of steel to that, and rotate the table a certain part of a revolution. So, say, move in 30 degree steps, and you will get 6 v grooves, crossing in the centre of the stock piece (or 12 meeting at the centre...) as you traverse the piece at  the fixed angle beneath the grinding disc. Now, wedge up one end of the rotary table. A new piece of stock will give you 12 v grooves, say, but shallower towards the centre. If you make it, such that the grooves are at zero depth at the centre, and full depth at the edge, and there are the correct number of grooves,  then two such pieces will mesh together, and tend to self centre. Of course, the bottom of grooves are filleted due to the shape of the grinding wheel. The fillet will be a constant width. To get two such pieces to fit together, the peaks need to be rounded over, but flattening them is simpler, and in some ways better (else the point of the mating ridge bottoms out on the fillet). The centres of the round stock pieces can be machined away, since there is little force transmitted there, and for other reasons. So,  simple calculations can be made, depending on the tooling available, size of desired coupling joint and number of teeth, etc. Say we have a work piece diameter 40, and a grinding disc, say, width 8, and 90 degree angle. We can calculate the minimum number of teeth from d=40 and chord = 8. The maximum will depend on the radius of the 90 degree edge of the grinding wheel (which creates the fillet - we don't want all fillet!), but let's say 50. That means the rotary table increments must be in steps of 360/50 =7.2 degrees. If we were going full depth of cut, then the maximum depth would be 4 (angle of 90 degrees), and 8 between peaks (but we can't go full depth at 7.2degrees). So, given the length of chord, and diameter of work, we can find the number of chords, n,  from d=(chord/ (sin(180/n))) we can solve that for chord, and then the height of the ridge will be half of the chord length (90 degree angle to wheel)- the assumption is that the grinding wheel edge is pointed, not rounded. Now, we want the grinding wheel to cut the depth calculated at the edge of the work piece, but just touch the centre of the workpiece, so we can calculate that we need to fix it at an angle that is ASIN(ridge_height/2)/diam). That will give a self centring matching Hirth joints, which afaik complies with the 1928 original specification. For the purposes of calculation ignore the radius at the bottom of the grooves - that will depend on the wheel profile. As to all intents and purposes, the bottom of the fillet will be parallel to the bottom of the estimated groove, so the angle to the horizontal will be the same. The top of the flattened ridge can be wider than the width of the fillet, but the edges of the flat will be parallel, too. Like most things, it starts off simple, then gets overcomplicated, to the state that it becomes difficult to see what was the fundamental reason for its existence in the first place. I would guess, that Hirth, being a practical engineer, just made it in the workshop, then decided to document it afterwards, most likely quicker than calculating angles, etc., back then. I think, as soon as you change the design so that the matching parts are not identical, or do not have straight and flat flanks to the ridges, then it is no longer a Hirth coupling. On 17/11/2024 18:46, Adrian Mariano wrote: > Ray, I have to say that I've found the complexity lurking in this > hirth joint to be kind of baffling.   When I saw Bob's first attempt I > immediately thought Bob was massively overcomplicating things.  But I > was wrong.  It seems like it should be very simple, and yet it seems > to be remarkably subtle and complicated.   We're not "making" it that > way---that's just the way it is. I thought it was trivial and wrote a > straight forward code and then found that it didn't work in various > cases---it was wrong, in other words, and getting it right is hard.  > Or at least I didn't find an easy way to get it right, and neither did > Bob.  And when I say it was wrong, I mean that the joint didn't mate > properly. Clearly something different happens if you approach the > design with "I have a 60 deg milling cutter, how do I cut a 100 tooth > hirth joint" than "I want to construct a mathematical model that makes > a generic version of this joint".   I think another factor is that a > lot of the subtlety results in errors that become small when there are > lots of teeth.  I see potential interesting applications for this > joint with small numbers of teeth like perhaps 8 or 4 to create > mechanisms that lock into a small number of positions, so I don't want > to ignore those small tooth count cases. > > Regarding tooth angle, I attempted to measure it at the tooth ridge > with nominal tooth angle set to 60 and zero cone angle.  With four > teeth I get 76.8 deg instead of 60 deg. With 44 teeth I get 60.16 > deg.  With 144 teeth it's 60.01 deg.   If I raise the cone angle to 30 > deg then I actually get 60.4 in the 4 tooth case, but in the 44 tooth > case it's now 65.5 deg and with 144 teeth it's 66.8 deg.   Why does > the 30 deg cone angle make the 4 tooth case so close to the nominal > angle?  It's because the tooth ridge in this case is very close to > parallel to the xy plane, which matches the design angle reference for > the construction of the triangle. Here's a picture (4 teeth, 30 deg > cone angle, 60 deg nominal tooth angle): > > image.png > > So it seems like the deviation of tooth angle for small tooth count > has to do with fitting the teeth around a circle. When you have lots > of teeth, it's approximately like fitting the teeth onto a line and > nothing weird happens, but when you curve just 4 teeth around a > circle, the angles no longer add up as expected for flat geometry, > resulting in an alteration of the actual realized tooth angle.  So to > produce teeth that match the nominal angle there are two corrections > needed.  One is a correction for fitting a linear arrangement of > triangles around a circle, with increasing correction as the number of > teeth shrinks.  The other one has to do with cone angle, and at least > for my definition of cone angle, the correction looks like it gets > smaller and then larger again as you increase the cone angle---at > least for the small tooth count case. > > On Sun, Nov 17, 2024 at 12:44 PM Raymond West via Discuss > <discuss@lists.openscad.org> wrote: > > Afaik, The Hirth joint was invented in 1928, and was very simple > to manufacture, with the machinery available at the time. I'm > pretty sure, that none of the detail On Hirth Ring Couplings: > Design Principles Including the Effect of Friction > <https://www.mdpi.com/2076-0825/7/4/79> for example, was known. > I'm not sure why it is being made so complicated on here. > > On 17/11/2024 13:22, Michael Möller via Discuss wrote: >> >> >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Sun, Nov 17, 2024 9:44 PM

Ray, so if I understand your description, you have the blank you're
grinding mounted at an angle and you then use your 60 deg grinding wheel to
grind the groove, which due to the angled mount, tapers from full depth at
the edge to zero depth in the center.  Is that right?  If the answer is
yes, then it appears to me that the result is NOT a 60 deg angle on the
teeth, because the cutter meets the workpiece at an angle, the effective
tooth angle is modified by that angle at which the blank is tilted.

I also found that to get a symmetric self-mating joint I had to "grind" at
half that angle, in effect.  That is, I had to make the centerline of the
teeth intersect each other at the origin, not the teeth tips or the teeth
valleys.  I tried it the other way at first and it didn't work.

On Sun, Nov 17, 2024 at 4:15 PM Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

Hi Adrian,

The code I sent seemed to be OK for anything more than two teeth. Maybe if
I explain how I think it would have been originally made will let you see
where you are getting odd angles. The first requirement would be a grinding
wheel. (I would guess that it was most likely a milling cutter, and
material brass, but never mind, same principle.) The standard angles for
such discs would either be 90 degree or 60 degree (inclusive angle), others
would most likely be more expensive. This would be a disc, with a v edge
(at 90 or 60 degrees). The edge of the disc would be rounded, since a
pointed edge would not last long. This would be used in a horizontal
grinder,  the disc can be raised or lowered, and the bed traversed
backwards and forwards under the wheel. A piece of steel, fixed to the bed
could thus have a v groove ground into it, and the profile, if no sideways
movement, would be the inverse of the grinding disk, it would have a
rounded bottom (fillet) to the groove.

Now, if you have a rotary table, then you can clamp a round piece of steel
to that, and rotate the table a certain part of a revolution. So, say, move
in 30 degree steps, and you will get 6 v grooves, crossing in the centre of
the stock piece (or 12 meeting at the centre...) as you traverse the piece
at  the fixed angle beneath the grinding disc.

Now, wedge up one end of the rotary table. A new piece of stock will give
you 12 v grooves, say, but shallower towards the centre. If you make it,
such that the grooves are at zero depth at the centre, and full depth at
the edge, and there are the correct number of grooves,  then two such
pieces will mesh together, and tend to self centre. Of course, the bottom
of grooves are filleted due to the shape of the grinding wheel. The fillet
will be a constant width. To get two such pieces to fit together, the peaks
need to be rounded over, but flattening them is simpler, and in some ways
better (else the point of the mating ridge bottoms out on the fillet). The
centres of the round stock pieces can be machined away, since there is
little force transmitted there, and for other reasons. So,  simple
calculations can be made, depending on the tooling available, size of
desired coupling joint and number of teeth, etc.

Say we have a work piece diameter 40, and a grinding disc, say, width 8,
and 90 degree angle. We can calculate the minimum number of teeth from d=40
and chord = 8. The maximum will depend on the radius of the 90 degree edge
of the grinding wheel (which creates the fillet - we don't want all
fillet!), but let's say 50. That means the rotary table increments must be
in steps of 360/50 =7.2 degrees. If we were going full depth of cut, then
the maximum depth would be 4 (angle of 90 degrees), and 8 between peaks
(but we can't go full depth at 7.2degrees).

So, given the length of chord, and diameter of work, we can find the
number of chords, n,  from d=(chord/ (sin(180/n))) we can solve that for
chord, and then the height of the ridge will be half of the chord length
(90 degree angle to wheel)- the assumption is that the grinding wheel edge
is pointed, not rounded.

Now, we want the grinding wheel to cut the depth calculated at the edge of
the work piece, but just touch the centre of the workpiece, so we can
calculate that we need to fix it at an angle that is
ASIN(ridge_height/2)/diam).

That will give a self centring matching Hirth joints, which afaik complies
with the 1928 original specification.

For the purposes of calculation ignore the radius at the bottom of the
grooves - that will depend on the wheel profile. As to all intents and
purposes, the bottom of the fillet will be parallel to the bottom of the
estimated groove, so the angle to the horizontal will be the same. The top
of the flattened ridge can be wider than the width of the fillet, but the
edges of the flat will be parallel, too.

Like most things, it starts off simple, then gets overcomplicated, to the
state that it becomes difficult to see what was the fundamental reason for
its existence in the first place. I would guess, that Hirth, being a
practical engineer, just made it in the workshop, then decided to document
it afterwards, most likely quicker than calculating angles, etc., back
then.

I think, as soon as you change the design so that the matching parts are
not identical, or do not have straight and flat flanks to the ridges, then
it is no longer a Hirth coupling.

On 17/11/2024 18:46, Adrian Mariano wrote:

Ray, I have to say that I've found the complexity lurking in this hirth
joint to be kind of baffling.  When I saw Bob's first attempt I
immediately thought Bob was massively overcomplicating things.  But I was
wrong.  It seems like it should be very simple, and yet it seems to be
remarkably subtle and complicated.  We're not "making" it that
way---that's just the way it is. I thought it was trivial and wrote a
straight forward code and then found that it didn't work in various
cases---it was wrong, in other words, and getting it right is hard.  Or at
least I didn't find an easy way to get it right, and neither did Bob.  And
when I say it was wrong, I mean that the joint didn't mate properly.
Clearly something different happens if you approach the design with "I have
a 60 deg milling cutter, how do I cut a 100 tooth hirth joint" than "I want
to construct a mathematical model that makes a generic version of this
joint".  I think another factor is that a lot of the subtlety results in
errors that become small when there are lots of teeth.  I see potential
interesting applications for this joint with small numbers of teeth like
perhaps 8 or 4 to create mechanisms that lock into a small number of
positions, so I don't want to ignore those small tooth count cases.

Regarding tooth angle, I attempted to measure it at the tooth ridge with
nominal tooth angle set to 60 and zero cone angle.  With four teeth I get
76.8 deg instead of 60 deg.  With 44 teeth I get 60.16 deg.  With 144 teeth
it's 60.01 deg.  If I raise the cone angle to 30 deg then I actually get
60.4 in the 4 tooth case, but in the 44 tooth case it's now 65.5 deg and
with 144 teeth it's 66.8 deg.  Why does the 30 deg cone angle make the 4
tooth case so close to the nominal angle?  It's because the tooth ridge in
this case is very close to parallel to the xy plane, which matches the
design angle reference for the construction of the triangle.    Here's a
picture (4 teeth, 30 deg cone angle, 60 deg nominal tooth angle):

[image: image.png]

So it seems like the deviation of tooth angle for small tooth count has to
do with fitting the teeth around a circle.  When you have lots of teeth,
it's approximately like fitting the teeth onto a line and nothing weird
happens, but when you curve just 4 teeth around a circle, the angles no
longer add up as expected for flat geometry, resulting in an alteration of
the actual realized tooth angle.  So to produce teeth that match the
nominal angle there are two corrections needed.  One is a correction for
fitting a linear arrangement of triangles around a circle, with increasing
correction as the number of teeth shrinks.  The other one has to do with
cone angle, and at least for my definition of cone angle, the correction
looks like it gets smaller and then larger again as you increase the cone
angle---at least for the small tooth count case.

On Sun, Nov 17, 2024 at 12:44 PM Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

Afaik, The Hirth joint was invented in 1928, and was very simple to
manufacture, with the machinery available at the time. I'm pretty sure,
that none of the detail On Hirth Ring Couplings: Design Principles
Including the Effect of Friction https://www.mdpi.com/2076-0825/7/4/79
for example, was known. I'm not sure why it is being made so complicated on
here.

On 17/11/2024 13:22, Michael Möller via Discuss wrote:


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

Ray, so if I understand your description, you have the blank you're grinding mounted at an angle and you then use your 60 deg grinding wheel to grind the groove, which due to the angled mount, tapers from full depth at the edge to zero depth in the center. Is that right? If the answer is yes, then it appears to me that the result is NOT a 60 deg angle on the teeth, because the cutter meets the workpiece at an angle, the effective tooth angle is modified by that angle at which the blank is tilted. I also found that to get a symmetric self-mating joint I had to "grind" at half that angle, in effect. That is, I had to make the centerline of the teeth intersect each other at the origin, not the teeth tips or the teeth valleys. I tried it the other way at first and it didn't work. On Sun, Nov 17, 2024 at 4:15 PM Raymond West via Discuss < discuss@lists.openscad.org> wrote: > Hi Adrian, > > The code I sent seemed to be OK for anything more than two teeth. Maybe if > I explain how I think it would have been originally made will let you see > where you are getting odd angles. The first requirement would be a grinding > wheel. (I would guess that it was most likely a milling cutter, and > material brass, but never mind, same principle.) The standard angles for > such discs would either be 90 degree or 60 degree (inclusive angle), others > would most likely be more expensive. This would be a disc, with a v edge > (at 90 or 60 degrees). The edge of the disc would be rounded, since a > pointed edge would not last long. This would be used in a horizontal > grinder, the disc can be raised or lowered, and the bed traversed > backwards and forwards under the wheel. A piece of steel, fixed to the bed > could thus have a v groove ground into it, and the profile, if no sideways > movement, would be the inverse of the grinding disk, it would have a > rounded bottom (fillet) to the groove. > > Now, if you have a rotary table, then you can clamp a round piece of steel > to that, and rotate the table a certain part of a revolution. So, say, move > in 30 degree steps, and you will get 6 v grooves, crossing in the centre of > the stock piece (or 12 meeting at the centre...) as you traverse the piece > at the fixed angle beneath the grinding disc. > > Now, wedge up one end of the rotary table. A new piece of stock will give > you 12 v grooves, say, but shallower towards the centre. If you make it, > such that the grooves are at zero depth at the centre, and full depth at > the edge, and there are the correct number of grooves, then two such > pieces will mesh together, and tend to self centre. Of course, the bottom > of grooves are filleted due to the shape of the grinding wheel. The fillet > will be a constant width. To get two such pieces to fit together, the peaks > need to be rounded over, but flattening them is simpler, and in some ways > better (else the point of the mating ridge bottoms out on the fillet). The > centres of the round stock pieces can be machined away, since there is > little force transmitted there, and for other reasons. So, simple > calculations can be made, depending on the tooling available, size of > desired coupling joint and number of teeth, etc. > > Say we have a work piece diameter 40, and a grinding disc, say, width 8, > and 90 degree angle. We can calculate the minimum number of teeth from d=40 > and chord = 8. The maximum will depend on the radius of the 90 degree edge > of the grinding wheel (which creates the fillet - we don't want all > fillet!), but let's say 50. That means the rotary table increments must be > in steps of 360/50 =7.2 degrees. If we were going full depth of cut, then > the maximum depth would be 4 (angle of 90 degrees), and 8 between peaks > (but we can't go full depth at 7.2degrees). > > So, given the length of chord, and diameter of work, we can find the > number of chords, n, from d=(chord/ (sin(180/n))) we can solve that for > chord, and then the height of the ridge will be half of the chord length > (90 degree angle to wheel)- the assumption is that the grinding wheel edge > is pointed, not rounded. > > Now, we want the grinding wheel to cut the depth calculated at the edge of > the work piece, but just touch the centre of the workpiece, so we can > calculate that we need to fix it at an angle that is > ASIN(ridge_height/2)/diam). > > That will give a self centring matching Hirth joints, which afaik complies > with the 1928 original specification. > > For the purposes of calculation ignore the radius at the bottom of the > grooves - that will depend on the wheel profile. As to all intents and > purposes, the bottom of the fillet will be parallel to the bottom of the > estimated groove, so the angle to the horizontal will be the same. The top > of the flattened ridge can be wider than the width of the fillet, but the > edges of the flat will be parallel, too. > > Like most things, it starts off simple, then gets overcomplicated, to the > state that it becomes difficult to see what was the fundamental reason for > its existence in the first place. I would guess, that Hirth, being a > practical engineer, just made it in the workshop, then decided to document > it afterwards, most likely quicker than calculating angles, etc., back > then. > > I think, as soon as you change the design so that the matching parts are > not identical, or do not have straight and flat flanks to the ridges, then > it is no longer a Hirth coupling. > > > On 17/11/2024 18:46, Adrian Mariano wrote: > > Ray, I have to say that I've found the complexity lurking in this hirth > joint to be kind of baffling. When I saw Bob's first attempt I > immediately thought Bob was massively overcomplicating things. But I was > wrong. It seems like it should be very simple, and yet it seems to be > remarkably subtle and complicated. We're not "making" it that > way---that's just the way it is. I thought it was trivial and wrote a > straight forward code and then found that it didn't work in various > cases---it was wrong, in other words, and getting it right is hard. Or at > least I didn't find an easy way to get it right, and neither did Bob. And > when I say it was wrong, I mean that the joint didn't mate properly. > Clearly something different happens if you approach the design with "I have > a 60 deg milling cutter, how do I cut a 100 tooth hirth joint" than "I want > to construct a mathematical model that makes a generic version of this > joint". I think another factor is that a lot of the subtlety results in > errors that become small when there are lots of teeth. I see potential > interesting applications for this joint with small numbers of teeth like > perhaps 8 or 4 to create mechanisms that lock into a small number of > positions, so I don't want to ignore those small tooth count cases. > > Regarding tooth angle, I attempted to measure it at the tooth ridge with > nominal tooth angle set to 60 and zero cone angle. With four teeth I get > 76.8 deg instead of 60 deg. With 44 teeth I get 60.16 deg. With 144 teeth > it's 60.01 deg. If I raise the cone angle to 30 deg then I actually get > 60.4 in the 4 tooth case, but in the 44 tooth case it's now 65.5 deg and > with 144 teeth it's 66.8 deg. Why does the 30 deg cone angle make the 4 > tooth case so close to the nominal angle? It's because the tooth ridge in > this case is very close to parallel to the xy plane, which matches the > design angle reference for the construction of the triangle. Here's a > picture (4 teeth, 30 deg cone angle, 60 deg nominal tooth angle): > > [image: image.png] > > So it seems like the deviation of tooth angle for small tooth count has to > do with fitting the teeth around a circle. When you have lots of teeth, > it's approximately like fitting the teeth onto a line and nothing weird > happens, but when you curve just 4 teeth around a circle, the angles no > longer add up as expected for flat geometry, resulting in an alteration of > the actual realized tooth angle. So to produce teeth that match the > nominal angle there are two corrections needed. One is a correction for > fitting a linear arrangement of triangles around a circle, with increasing > correction as the number of teeth shrinks. The other one has to do with > cone angle, and at least for my definition of cone angle, the correction > looks like it gets smaller and then larger again as you increase the cone > angle---at least for the small tooth count case. > > On Sun, Nov 17, 2024 at 12:44 PM Raymond West via Discuss < > discuss@lists.openscad.org> wrote: > >> Afaik, The Hirth joint was invented in 1928, and was very simple to >> manufacture, with the machinery available at the time. I'm pretty sure, >> that none of the detail On Hirth Ring Couplings: Design Principles >> Including the Effect of Friction <https://www.mdpi.com/2076-0825/7/4/79> >> for example, was known. I'm not sure why it is being made so complicated on >> here. >> >> On 17/11/2024 13:22, Michael Möller via Discuss wrote: >> >> >> >> >> _______________________________________________ >> 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 >
M
mikeonenine@web.de
Sun, Nov 17, 2024 11:47 PM

Adrian Mariano wrote:

Ray, so if I understand your description, you have the blank you're
grinding mounted at an angle and you then use your 60 deg grinding wheel to
grind the groove, which due to the angled mount, tapers from full depth at
the edge to zero depth in the center.  Is that right?  If the answer is
yes, then it appears to me that the result is NOT a 60 deg angle on the
teeth, because the cutter meets the workpiece at an angle, the effective
tooth angle is modified by that angle at which the blank is tilted.

That seems to confirm my hunch and it makes sense as then only 60° and 90° tools are required instead of a whole range of different custom-made tools. The resulting splines are then only nominally 60° or 90° while the groove is precisely that angle. Can this be expected to give a proper fit?

The problem for us is also that CAD/3D printing and the machining process work on different principles.

For a little extra complication: what does “fit” mean? To me it means that the flanks must be in contact over the whole area. Even 0.01 mm of clearance means no contact, and no transmission of forces, so that these are concentrated on a small area. It can be seen most clearly in joints with a small number of splines whether full contact is achieved, or not.

However, the discrepancy decreases rapidly with increasing numbers of splines, and even further if the ring of splines is narrow, so that at some point it will become negligible.

I also found that to get a symmetric self-mating joint I had to "grind" at
half that angle, in effect.  That is, I had to make the centerline of the
teeth intersect each other at the origin, not the teeth tips or the teeth
valleys.  I tried it the other way at first and it didn't work.

I would confirm that, the centreline being at half spline height. But with 3 splines, they only touch in the middle - see screenshot of joint with 90° splines (included angle around the ridge, flank to flank).

BTW Hirth couplings were not at all simple to manufacture, with the machinery available at the time and were a luxury. A crankshaft with Hirth couplings for a Grand Prix racing car cost as much as a house.

Adrian Mariano wrote: > Ray, so if I understand your description, you have the blank you're > grinding mounted at an angle and you then use your 60 deg grinding wheel to > grind the groove, which due to the angled mount, tapers from full depth at > the edge to zero depth in the center. Is that right? If the answer is > yes, then it appears to me that the result is NOT a 60 deg angle on the > teeth, because the cutter meets the workpiece at an angle, the effective > tooth angle is modified by that angle at which the blank is tilted. That seems to confirm my hunch and it makes sense as then only 60° and 90° tools are required instead of a whole range of different custom-made tools. The resulting splines are then only nominally 60° or 90° while the groove is precisely that angle. Can this be expected to give a proper fit? The problem for us is also that CAD/3D printing and the machining process work on different principles. For a little extra complication: what does “fit” mean? To me it means that the flanks must be in contact over the whole area. Even 0.01 mm of clearance means no contact, and no transmission of forces, so that these are concentrated on a small area. It can be seen most clearly in joints with a small number of splines whether full contact is achieved, or not. However, the discrepancy decreases rapidly with increasing numbers of splines, and even further if the ring of splines is narrow, so that at some point it will become negligible. > I also found that to get a symmetric self-mating joint I had to "grind" at \ > half that angle, in effect.  That is, I had to make the centerline of the \ > teeth intersect each other at the origin, not the teeth tips or the teeth \ > valleys.  I tried it the other way at first and it didn't work. I would confirm that, the centreline being at half spline height. But with 3 splines, they only touch in the middle - see screenshot of joint with 90° splines (included angle around the ridge, flank to flank). BTW Hirth couplings were not at all simple to manufacture, with the machinery available at the time and were a luxury. A crankshaft with Hirth couplings for a Grand Prix racing car cost as much as a house.
AM
Adrian Mariano
Mon, Nov 18, 2024 12:16 AM

I'm not sure what you mean about "with 3 splines they only touch in the
middle".  That's only true if the model is wrong, like so many of my early
attempts.  With a correct model this is not the case, of course.  What
model gave you the behavior in question?  Or do you mean the model
constructed as described by Ray?  It may be the case that an improper fit
was good enough for machinists making these joints with lots of teeth?  For
my current code I get the image below, where I separated the parts by a
tiny amount to show the gap.  I'm pretty sure Bob's model also gives the
same result, namely that parts mate exactly along the entire joint
surface.  Our models are designed mathematically to ensure that they mate
exactly.  I realized that I never really examined Ray's model because I
couldn't get it to render in either OpenSCAD I had (not the stable nor the
dev) and preview was unusably slow on my machine.

[image: image.png]

On Sun, Nov 17, 2024 at 6:47 PM Caddiy via Discuss <
discuss@lists.openscad.org> wrote:

Adrian Mariano wrote:

Ray, so if I understand your description, you have the blank you're
grinding mounted at an angle and you then use your 60 deg grinding wheel to
grind the groove, which due to the angled mount, tapers from full depth at
the edge to zero depth in the center. Is that right? If the answer is yes,
then it appears to me that the result is NOT a 60 deg angle on the teeth,
because the cutter meets the workpiece at an angle, the effective tooth
angle is modified by that angle at which the blank is tilted.

That seems to confirm my hunch and it makes sense as then only 60° and 90°
tools are required instead of a whole range of different custom-made tools.
The resulting splines are then only nominally 60° or 90° while the groove
is precisely that angle. Can this be expected to give a proper fit?

The problem for us is also that CAD/3D printing and the machining process
work on different principles.

For a little extra complication: what does “fit” mean? To me it means that
the flanks must be in contact over the whole area. Even 0.01 mm of
clearance means no contact, and no transmission of forces, so that these
are concentrated on a small area. It can be seen most clearly in joints
with a small number of splines whether full contact is achieved, or not.

However, the discrepancy decreases rapidly with increasing numbers of
splines, and even further if the ring of splines is narrow, so that at some
point it will become negligible.

I also found that to get a symmetric self-mating joint I had to "grind" at
half that angle, in effect.  That is, I had to make the centerline of the
teeth intersect each other at the origin, not the teeth tips or the teeth
valleys.  I tried it the other way at first and it didn't work.

I would confirm that, the centreline being at half spline height. But with
3 splines, they only touch in the middle - see screenshot of joint with 90°
splines (included angle around the ridge, flank to flank).

BTW Hirth couplings were not at all simple to manufacture, with the
machinery available at the time and were a luxury. A crankshaft with Hirth
couplings for a Grand Prix racing car cost as much as a house.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I'm not sure what you mean about "with 3 splines they only touch in the middle". That's only true if the model is wrong, like so many of my early attempts. With a correct model this is not the case, of course. What model gave you the behavior in question? Or do you mean the model constructed as described by Ray? It may be the case that an improper fit was good enough for machinists making these joints with lots of teeth? For my current code I get the image below, where I separated the parts by a tiny amount to show the gap. I'm pretty sure Bob's model also gives the same result, namely that parts mate exactly along the entire joint surface. Our models are designed mathematically to ensure that they mate exactly. I realized that I never really examined Ray's model because I couldn't get it to render in either OpenSCAD I had (not the stable nor the dev) and preview was unusably slow on my machine. [image: image.png] On Sun, Nov 17, 2024 at 6:47 PM Caddiy via Discuss < discuss@lists.openscad.org> wrote: > Adrian Mariano wrote: > > Ray, so if I understand your description, you have the blank you're > grinding mounted at an angle and you then use your 60 deg grinding wheel to > grind the groove, which due to the angled mount, tapers from full depth at > the edge to zero depth in the center. Is that right? If the answer is yes, > then it appears to me that the result is NOT a 60 deg angle on the teeth, > because the cutter meets the workpiece at an angle, the effective tooth > angle is modified by that angle at which the blank is tilted. > > That seems to confirm my hunch and it makes sense as then only 60° and 90° > tools are required instead of a whole range of different custom-made tools. > The resulting splines are then only nominally 60° or 90° while the groove > is precisely that angle. Can this be expected to give a proper fit? > > The problem for us is also that CAD/3D printing and the machining process > work on different principles. > > For a little extra complication: what does “fit” mean? To me it means that > the flanks must be in contact over the whole area. Even 0.01 mm of > clearance means no contact, and no transmission of forces, so that these > are concentrated on a small area. It can be seen most clearly in joints > with a small number of splines whether full contact is achieved, or not. > > However, the discrepancy decreases rapidly with increasing numbers of > splines, and even further if the ring of splines is narrow, so that at some > point it will become negligible. > > I also found that to get a symmetric self-mating joint I had to "grind" at > half that angle, in effect. That is, I had to make the centerline of the > teeth intersect each other at the origin, not the teeth tips or the teeth > valleys. I tried it the other way at first and it didn't work. > > I would confirm that, the centreline being at half spline height. But with > 3 splines, they only touch in the middle - see screenshot of joint with 90° > splines (included angle around the ridge, flank to flank). > > BTW Hirth couplings were not at all simple to manufacture, with the > machinery available at the time and were a luxury. A crankshaft with Hirth > couplings for a Grand Prix racing car cost as much as a house. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >