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
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
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:
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
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:
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 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:
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
@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((ypyp)+(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=ridge3);
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
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:
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
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:
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:
_______________________________________________
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
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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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
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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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
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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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
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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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
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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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
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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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
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=skewangle/(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(orrounding)),
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 ? -skewangle
: n%2==0 ? -(angle-skewangle) - skewangle
: -angle*(2-skew)-skewangle;
topinner = down(cone_heightir,[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(factoror,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
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:
_______________________________________________
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
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
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.
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.
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.
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:
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?

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
>