AM
Adrian Mariano
Sun, Aug 24, 2025 11:08 PM
Cory did quote links to the code.
Your analysis assumes you can do regular arithmetic on epsilon, which I
think is suspect if epsilon is machine precision, since every computational
step has the potential to introduce error on the order of epsilon---in
either direction. In fact it appears that only by subtracting epsilon at
the end do you guarantee that you're not subject to subsequent rounding
error that makes the value too large.
In the helix() function in fact angle can be arbitrarily large, as the
helix may have many turns.
On Sun, Aug 24, 2025 at 6:46 PM Cory Cross openscad@corycross.org wrote:
On 8/22/25 3:28 PM, Adrian Mariano via Discuss wrote:
Why would it matter if n>360? I don't see that it makes a difference if
you subtract epsilon from angle or from the whole expression. I did the
latter because it was simpler.
So the error is in angle, and it's multiplied by n/360. We're assuming
the error is as much as epsilon, so subtracting at the end:
n*(angle+epsilon)/360 - epsilon
nangle/360 + epsilonn/360 - epsilon
so if n=720 we're still epsilon too much, and if (n*angle/360) is an
integer, the final result will round up to the next higher integer.
versus subtracting at angle:
n*(angle+epsilon-epsilon)/360
n*angle/360
independent of n when error==epsilon (which we're assuming). If it's
actually less than epsilon:
nangle/360 - epsilonn/360
That will only cause a different result if n*angle/360 was slightly more
than a whole number, which will never (for any sane measurements) be the
case when you are choosing some fraction of $fn arc, and only arose in
freak coincidences in existing code.
On Fri, Aug 22, 2025 at 4:38 PM Cory Cross via Discuss <
discuss@lists.openscad.org> wrote:
Representability as a double is not sufficient. You have to also compute
that representation. Since arccos is involved this is not guaranteed. I
see issues with n of 5, 6 and 8 which have integer angles of 72, 60 and
45. It works for n of 3 and 12.
Oops, I inverted the equation. (n * arc_angle / 360) of course. Okay, so
a trigonometric function is calculating the angle and returning 72+epsilon
(or more!? hope not), so just subtracting epsilon from the whole equation
won't always work when n>360, so it should be taken from the angle.
Subtracting epsilon before the ceil seems ok and of course does fix it.
On Thu, Aug 21, 2025 at 13:30 Cory Cross via Discuss <
discuss@lists.openscad.org> wrote:
I think the cause is when either angle or 360/(n*arc_angle) isn't
perfectly representable by a double.
I think the best solution is to subtract epsilon before calling ceil. I
haven't thought of any situation this is worse, especially given n is
In C++, OpenSCAD converts n to int first before doing the arc angle
calculation. That may introduce a tiny difference, as if you do the
calculation in OpenSCAD, it’s kept as double all the way. Not sure if
that’s the root cause though..
If I'm remembering my numerical methods lessons correctly, I don't
that's the reason, as the code correctly multiplies n*arc_angle first,
which will always be less than the maximum representable integer in a
double (for any reasonable n), so it will exact if the angle is
representable as a double.
On Aug 21, 2025, at 10:22, Adrian Mariano via Discuss <
Thanks. The possibility of rounding error exists in the
Someone observed in BOSL2 that offset behaved irregularly. The
calculation does not match openscad but even with it fixed if I offset
regular n gon with $fn = n I get rounding errors and sometimes the ceil
rounds up giving an extra facet. Openscad seems to avoid this somehow
consistently produces just a single facet.
On Thu, Aug 21, 2025 at 09:43 Cory Cross via Discuss <
At least in DxfData:
n = static_cast<int>(ceil(n * arc_angle / 360));
where n comes from
int n = Calc::get_fragments_from_r(radius, fn, fs, fa);
which returns $fn so long as it's at least 3: <
Sorry for non-permalinks.
On August 21, 2025 8:18:44 AM EDT, Adrian Mariano via Discuss <
Does anybody know the calculation openscad uses for the number of
segments on an arc of angle theta as a function of $fn? Exactly what
Cory did quote links to the code.
Your analysis assumes you can do regular arithmetic on epsilon, which I
think is suspect if epsilon is machine precision, since every computational
step has the potential to introduce error on the order of epsilon---in
either direction. In fact it appears that only by subtracting epsilon at
the end do you guarantee that you're not subject to subsequent rounding
error that makes the value too large.
In the helix() function in fact angle can be arbitrarily large, as the
helix may have many turns.
On Sun, Aug 24, 2025 at 6:46 PM Cory Cross <openscad@corycross.org> wrote:
> On 8/22/25 3:28 PM, Adrian Mariano via Discuss wrote:
>
> Why would it matter if n>360? I don't see that it makes a difference if
> you subtract epsilon from angle or from the whole expression. I did the
> latter because it was simpler.
>
>
> So the error is in `angle`, and it's multiplied by n/360. We're assuming
> the error is as much as epsilon, so subtracting at the end:
>
> n*(angle+epsilon)/360 - epsilon
> n*angle/360 + epsilon*n/360 - epsilon
>
> so if n=720 we're still epsilon too much, and if (n*angle/360) is an
> integer, the final result will round up to the next higher integer.
>
> versus subtracting at angle:
>
> n*(angle+epsilon-epsilon)/360
> n*angle/360
>
> independent of n when error==epsilon (which we're assuming). If it's
> actually less than epsilon:
>
> n*angle/360 - epsilon*n/360
>
> That will only cause a different result if n*angle/360 was slightly more
> than a whole number, which will never (for any sane measurements) be the
> case when you are choosing some fraction of $fn arc, and only arose in
> freak coincidences in existing code.
>
> - Cory Cross
>
>
> On Fri, Aug 22, 2025 at 4:38 PM Cory Cross via Discuss <
> discuss@lists.openscad.org> wrote:
>
>>
>>
>> On August 21, 2025 2:02:00 PM EDT, Adrian Mariano via Discuss <
>> discuss@lists.openscad.org> wrote:
>> >Representability as a double is not sufficient. You have to also compute
>> >that representation. Since arccos is involved this is not guaranteed. I
>> >see issues with n of 5, 6 and 8 which have integer angles of 72, 60 and
>> >45. It works for n of 3 and 12.
>>
>> Oops, I inverted the equation. (n * arc_angle / 360) of course. Okay, so
>> a trigonometric function is calculating the angle and returning 72+epsilon
>> (or more!? hope not), so just subtracting epsilon from the whole equation
>> won't always work when n>360, so it should be taken from the angle.
>>
>> - Cory
>>
>>
>> >
>> >Subtracting epsilon before the ceil seems ok and of course does fix it.
>> >
>> >On Thu, Aug 21, 2025 at 13:30 Cory Cross via Discuss <
>> >discuss@lists.openscad.org> wrote:
>> >
>> >> I think the cause is when either angle or 360/(n*arc_angle) isn't
>> >> perfectly representable by a double.
>> >>
>> >> I think the best solution is to subtract epsilon before calling ceil. I
>> >> haven't thought of any situation this is worse, especially given n is
>> never
>> >> less than 3.
>> >>
>> >>
>> >>
>> >> On August 21, 2025 10:45:52 AM EDT, Marius Kintel via Discuss <
>> >> discuss@lists.openscad.org> wrote:
>> >> >In C++, OpenSCAD converts n to int first before doing the arc angle
>> >> calculation. That may introduce a tiny difference, as if you do the
>> same
>> >> calculation in OpenSCAD, it’s kept as double all the way. Not sure if
>> >> that’s the root cause though..
>> >>
>> >> If I'm remembering my numerical methods lessons correctly, I don't
>> think
>> >> that's the reason, as the code correctly multiplies n*arc_angle first,
>> >> which will always be less than the maximum representable integer in a
>> >> double (for any reasonable n), so it will exact if the angle is
>> >> representable as a double.
>> >>
>> >> - Cory Cross
>> >>
>> >>
>> >>
>> >>
>> >> >
>> >> > -Marius
>> >> >
>> >> >> On Aug 21, 2025, at 10:22, Adrian Mariano via Discuss <
>> >> discuss@lists.openscad.org> wrote:
>> >> >>
>> >> >> Thanks. The possibility of rounding error exists in the
>> computation.
>> >> Someone observed in BOSL2 that offset behaved irregularly. The
>> existing
>> >> calculation does not match openscad but even with it fixed if I offset
>> a
>> >> regular n gon with $fn = n I get rounding errors and sometimes the ceil
>> >> rounds up giving an extra facet. Openscad seems to avoid this somehow
>> and
>> >> consistently produces just a single facet.
>> >> >>
>> >> >> On Thu, Aug 21, 2025 at 09:43 Cory Cross via Discuss <
>> >> discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote:
>> >> >>> At least in DxfData:
>> >> >>>
>> >> >>> n = static_cast<int>(ceil(n * arc_angle / 360));
>> >> >>>
>> >> >>> where n comes from
>> >> >>>
>> >> >>> int n = Calc::get_fragments_from_r(radius, fn, fs, fa);
>> >> >>>
>> >> >>> which returns $fn so long as it's at least 3: <
>> >>
>> https://github.com/openscad/openscad/blob/master/src%2Futils%2Fcalc.cc#L47
>> >> >
>> >> >>>
>> >> >>> <
>> >>
>> https://github.com/openscad/openscad/blob/master/src%2Fio%2FDxfData.cc#L205
>> >> >
>> >> >>>
>> >> >>> Sorry for non-permalinks.
>> >> >>>
>> >> >>>
>> >> >>> On August 21, 2025 8:18:44 AM EDT, Adrian Mariano via Discuss <
>> >> discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote:
>> >> >>>> Does anybody know the calculation openscad uses for the number of
>> >> segments on an arc of angle theta as a function of $fn? Exactly what
>> kind
>> >> of rounding is used?
>> >> >>> _______________________________________________
>> >> >>> 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
>> >> >
>> >> _______________________________________________
>> >> 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
>
>
>
CC
Cory Cross
Mon, Aug 25, 2025 12:03 AM
On 8/24/25 4:08 PM, Adrian Mariano via Discuss wrote:
Cory did quote links to the code.
Your analysis assumes you can do regular arithmetic on epsilon, which
I think is suspect if epsilon is machine precision, since every
computational step has the potential to introduce error on the order
of epsilon---in either direction. In fact it appears that only by
subtracting epsilon at the end do you guarantee that you're not
subject to subsequent rounding error that makes the value too large.
Okay, let's assume we're exactly one epsilon too large, see if my Python
is correct. Some lines truncated
... print("n=%d\t%s", n, format(720+1/2**n,'.17f'))
n=%d %s 43 720.00000000000011369
n=%d %s 44 720.00000000000000000
math.log2(1/math.ulp(720))
... print("n=%d\t%s" % (n, format((720+1/2**43)*n,'.17f')))
...
n=2 1440.00000000000022737
n=3 2160.00000000000045475
...
n=6 4320.00000000000090949
...
n=12 8640.00000000000181899
...
n=23 16560.00000000000363798
n=24 17280.00000000000363798
n=25 18000.00000000000363798
for n in range(2,36000,10000):
... postresult=n*(720+math.ulp(720))/360
... postresult-=math.ulp(postresult)
... angresult=n*(720+math.ulp(720)-math.ulp(720))/360
... print("n=%d\t%s\t%s" % (n, format(postresult,'.17f'),
format(angresult,'.17f')))
...
n=2 4.00000000000000000 4.00000000000000000
n=10002 20004.00000000000000000 20004.00000000000000000
n=20002 40004.00000000000000000 40004.00000000000000000
n=30002 60004.00000000000000000 60004.00000000000000000
Okay, as long as you're calculating epsilon it looks correct either way.
(if you use the "machine epsilon" or epsilon of the angle, it gives
wrong answers)
In the helix() function in fact angle can be arbitrarily large, as the
helix may have many turns.
On Sun, Aug 24, 2025 at 6:46 PM Cory Cross openscad@corycross.org wrote:
On 8/22/25 3:28 PM, Adrian Mariano via Discuss wrote:
Why would it matter if n>360? I don't see that it makes a
difference if you subtract epsilon from angle or from the whole
expression. I did the latter because it was simpler.
So the error is in `angle`, and it's multiplied by n/360. We're
assuming the error is as much as epsilon, so subtracting at the end:
n*(angle+epsilon)/360 - epsilon
n*angle/360 + epsilon*n/360 - epsilon
so if n=720 we're still epsilon too much, and if (n*angle/360) is
an integer, the final result will round up to the next higher integer.
versus subtracting at angle:
n*(angle+epsilon-epsilon)/360
n*angle/360
independent of n when error==epsilon (which we're assuming). If
it's actually less than epsilon:
n*angle/360 - epsilon*n/360
That will only cause a different result if n*angle/360 was
slightly more than a whole number, which will never (for any sane
measurements) be the case when you are choosing some fraction of
$fn arc, and only arose in freak coincidences in existing code.
- Cory Cross
On Fri, Aug 22, 2025 at 4:38 PM Cory Cross via Discuss
<discuss@lists.openscad.org> wrote:
On August 21, 2025 2:02:00 PM EDT, Adrian Mariano via Discuss
<discuss@lists.openscad.org> wrote:
Representability as a double is not sufficient. You have to
that representation. Since arccos is involved this is not
see issues with n of 5, 6 and 8 which have integer angles of
45. It works for n of 3 and 12.
Oops, I inverted the equation. (n * arc_angle / 360) of
course. Okay, so a trigonometric function is calculating the
angle and returning 72+epsilon (or more!? hope not), so just
subtracting epsilon from the whole equation won't always work
when n>360, so it should be taken from the angle.
- Cory
Subtracting epsilon before the ceil seems ok and of course
I think the cause is when either angle or
perfectly representable by a double.
I think the best solution is to subtract epsilon before
haven't thought of any situation this is worse, especially
less than 3.
On August 21, 2025 10:45:52 AM EDT, Marius Kintel via
In C++, OpenSCAD converts n to int first before doing the
calculation. That may introduce a tiny difference, as if
calculation in OpenSCAD, it’s kept as double all the way.
that’s the root cause though..
If I'm remembering my numerical methods lessons correctly,
that's the reason, as the code correctly multiplies
which will always be less than the maximum representable
double (for any reasonable n), so it will exact if the
representable as a double.
On Aug 21, 2025, at 10:22, Adrian Mariano via Discuss <
Thanks. The possibility of rounding error exists in
Someone observed in BOSL2 that offset behaved
irregularly. The existing
calculation does not match openscad but even with it fixed
regular n gon with $fn = n I get rounding errors and
rounds up giving an extra facet. Openscad seems to avoid
consistently produces just a single facet.
On Thu, Aug 21, 2025 at 09:43 Cory Cross via Discuss <
<mailto:discuss@lists.openscad.org>> wrote:
At least in DxfData:
n = static_cast<int>(ceil(n * arc_angle / 360));
where n comes from
int n = Calc::get_fragments_from_r(radius,
which returns $fn so long as it's at least 3: <
https://github.com/openscad/openscad/blob/master/src%2Futils%2Fcalc.cc#L47
https://github.com/openscad/openscad/blob/master/src%2Fio%2FDxfData.cc#L205
Sorry for non-permalinks.
On August 21, 2025 8:18:44 AM EDT, Adrian Mariano via
<mailto:discuss@lists.openscad.org>> wrote:
Does anybody know the calculation openscad uses for
segments on an arc of angle theta as a function of $fn?
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
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org
On 8/24/25 4:08 PM, Adrian Mariano via Discuss wrote:
> Cory did quote links to the code.
>
> Your analysis assumes you can do regular arithmetic on epsilon, which
> I think is suspect if epsilon is machine precision, since every
> computational step has the potential to introduce error on the order
> of epsilon---in either direction. In fact it appears that only by
> subtracting epsilon at the end do you guarantee that you're not
> subject to subsequent rounding error that makes the value too large.
Okay, let's assume we're exactly one epsilon too large, see if my Python
is correct. Some lines truncated
>>> for n in range(40,60):
... print("n=%d\t%s", n, format(720+1/2**n,'.17f'))
n=%d %s 43 720.00000000000011369
n=%d %s 44 720.00000000000000000
>>> math.log2(1/math.ulp(720))
43.0
>>> for n in range(2,30):
... print("n=%d\t%s" % (n, format((720+1/2**43)*n,'.17f')))
...
n=2 1440.00000000000022737
n=3 2160.00000000000045475
...
n=6 4320.00000000000090949
...
n=12 8640.00000000000181899
...
n=23 16560.00000000000363798
n=24 17280.00000000000363798
n=25 18000.00000000000363798
>>> for n in range(2,36000,10000):
... postresult=n*(720+math.ulp(720))/360
... postresult-=math.ulp(postresult)
... angresult=n*(720+math.ulp(720)-math.ulp(720))/360
... print("n=%d\t%s\t%s" % (n, format(postresult,'.17f'),
format(angresult,'.17f')))
...
n=2 4.00000000000000000 4.00000000000000000
n=10002 20004.00000000000000000 20004.00000000000000000
n=20002 40004.00000000000000000 40004.00000000000000000
n=30002 60004.00000000000000000 60004.00000000000000000
Okay, as long as you're calculating epsilon it looks correct either way.
(if you use the "machine epsilon" or epsilon of the angle, it gives
wrong answers)
- Cory
> In the helix() function in fact angle can be arbitrarily large, as the
> helix may have many turns.
>
> On Sun, Aug 24, 2025 at 6:46 PM Cory Cross <openscad@corycross.org> wrote:
>
> On 8/22/25 3:28 PM, Adrian Mariano via Discuss wrote:
>> Why would it matter if n>360? I don't see that it makes a
>> difference if you subtract epsilon from angle or from the whole
>> expression. I did the latter because it was simpler.
>
> So the error is in `angle`, and it's multiplied by n/360. We're
> assuming the error is as much as epsilon, so subtracting at the end:
>
> n*(angle+epsilon)/360 - epsilon
> n*angle/360 + epsilon*n/360 - epsilon
>
> so if n=720 we're still epsilon too much, and if (n*angle/360) is
> an integer, the final result will round up to the next higher integer.
>
> versus subtracting at angle:
>
> n*(angle+epsilon-epsilon)/360
> n*angle/360
>
> independent of n when error==epsilon (which we're assuming). If
> it's actually less than epsilon:
>
> n*angle/360 - epsilon*n/360
>
> That will only cause a different result if n*angle/360 was
> slightly more than a whole number, which will never (for any sane
> measurements) be the case when you are choosing some fraction of
> $fn arc, and only arose in freak coincidences in existing code.
>
> - Cory Cross
>
>>
>> On Fri, Aug 22, 2025 at 4:38 PM Cory Cross via Discuss
>> <discuss@lists.openscad.org> wrote:
>>
>>
>>
>> On August 21, 2025 2:02:00 PM EDT, Adrian Mariano via Discuss
>> <discuss@lists.openscad.org> wrote:
>> >Representability as a double is not sufficient. You have to
>> also compute
>> >that representation. Since arccos is involved this is not
>> guaranteed. I
>> >see issues with n of 5, 6 and 8 which have integer angles of
>> 72, 60 and
>> >45. It works for n of 3 and 12.
>>
>> Oops, I inverted the equation. (n * arc_angle / 360) of
>> course. Okay, so a trigonometric function is calculating the
>> angle and returning 72+epsilon (or more!? hope not), so just
>> subtracting epsilon from the whole equation won't always work
>> when n>360, so it should be taken from the angle.
>>
>> - Cory
>>
>>
>> >
>> >Subtracting epsilon before the ceil seems ok and of course
>> does fix it.
>> >
>> >On Thu, Aug 21, 2025 at 13:30 Cory Cross via Discuss <
>> >discuss@lists.openscad.org> wrote:
>> >
>> >> I think the cause is when either angle or
>> 360/(n*arc_angle) isn't
>> >> perfectly representable by a double.
>> >>
>> >> I think the best solution is to subtract epsilon before
>> calling ceil. I
>> >> haven't thought of any situation this is worse, especially
>> given n is never
>> >> less than 3.
>> >>
>> >>
>> >>
>> >> On August 21, 2025 10:45:52 AM EDT, Marius Kintel via
>> Discuss <
>> >> discuss@lists.openscad.org> wrote:
>> >> >In C++, OpenSCAD converts n to int first before doing the
>> arc angle
>> >> calculation. That may introduce a tiny difference, as if
>> you do the same
>> >> calculation in OpenSCAD, it’s kept as double all the way.
>> Not sure if
>> >> that’s the root cause though..
>> >>
>> >> If I'm remembering my numerical methods lessons correctly,
>> I don't think
>> >> that's the reason, as the code correctly multiplies
>> n*arc_angle first,
>> >> which will always be less than the maximum representable
>> integer in a
>> >> double (for any reasonable n), so it will exact if the
>> angle is
>> >> representable as a double.
>> >>
>> >> - Cory Cross
>> >>
>> >>
>> >>
>> >>
>> >> >
>> >> > -Marius
>> >> >
>> >> >> On Aug 21, 2025, at 10:22, Adrian Mariano via Discuss <
>> >> discuss@lists.openscad.org> wrote:
>> >> >>
>> >> >> Thanks. The possibility of rounding error exists in
>> the computation.
>> >> Someone observed in BOSL2 that offset behaved
>> irregularly. The existing
>> >> calculation does not match openscad but even with it fixed
>> if I offset a
>> >> regular n gon with $fn = n I get rounding errors and
>> sometimes the ceil
>> >> rounds up giving an extra facet. Openscad seems to avoid
>> this somehow and
>> >> consistently produces just a single facet.
>> >> >>
>> >> >> On Thu, Aug 21, 2025 at 09:43 Cory Cross via Discuss <
>> >> discuss@lists.openscad.org
>> <mailto:discuss@lists.openscad.org>> wrote:
>> >> >>> At least in DxfData:
>> >> >>>
>> >> >>> n = static_cast<int>(ceil(n * arc_angle / 360));
>> >> >>>
>> >> >>> where n comes from
>> >> >>>
>> >> >>> int n = Calc::get_fragments_from_r(radius,
>> fn, fs, fa);
>> >> >>>
>> >> >>> which returns $fn so long as it's at least 3: <
>> >>
>> https://github.com/openscad/openscad/blob/master/src%2Futils%2Fcalc.cc#L47
>> >> >
>> >> >>>
>> >> >>> <
>> >>
>> https://github.com/openscad/openscad/blob/master/src%2Fio%2FDxfData.cc#L205
>> >> >
>> >> >>>
>> >> >>> Sorry for non-permalinks.
>> >> >>>
>> >> >>>
>> >> >>> On August 21, 2025 8:18:44 AM EDT, Adrian Mariano via
>> Discuss <
>> >> discuss@lists.openscad.org
>> <mailto:discuss@lists.openscad.org>> wrote:
>> >> >>>> Does anybody know the calculation openscad uses for
>> the number of
>> >> segments on an arc of angle theta as a function of $fn?
>> Exactly what kind
>> >> of rounding is used?
>> >> >>> _______________________________________________
>> >> >>> 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
>> >> >
>> >> _______________________________________________
>> >> 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
>
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email todiscuss-leave@lists.openscad.org
JB
Jordan Brown
Mon, Aug 25, 2025 7:05 AM
On 8/24/2025 11:57 PM, Jordan Brown via Discuss wrote:
On 8/21/2025 2:18 PM, Adrian Mariano via Discuss wrote:
Does anybody know the calculation openscad uses for the number of
segments on an arc of angle theta as a function of $fn? Exactly what
kind of rounding is used?
I don't think anybody ever directly quoted the source:
My apologies. I read more into Adrian's question than was there; the
only case that came to mind that processes arcs was rotate_extrude and
so that's what I thought he was talking about.
Part of the true answer is that there is no true answer. There is a
central function for doing the r/fn/fs/fa calculation for the number of
segments in a circle, but no corresponding central function for
calculating the number of segments in an arc. Each component that needs
it does the calculation on its own.
For the particular case of offset(), which is what Adrian is looking
at, it's here:
https://github.com/openscad/openscad/blob/4c9d585cffd9d1e787366eb3023d9f9d3c5084fa/src/geometry/GeometryEvaluator.cc#L599
... which only partially answers the question:
// ClipperLib documentation: The formula for the number of steps in a full
// circular arc is ... Pi / acos(1 - arc_tolerance / abs(delta))
double n = Calc::get_fragments_from_r(std::abs(node.delta), node.fn, node.fs, node.fa);
double arc_tolerance = std::abs(node.delta) * (1 - cos_degrees(180 / n));
geom = ClipperUtils::applyOffset(*polygon, node.delta, node.join_type, node.miter_limit,
arc_tolerance);
so it's considerably uglier than rotate_extrude.
On 8/24/2025 11:57 PM, Jordan Brown via Discuss wrote:
> On 8/21/2025 2:18 PM, Adrian Mariano via Discuss wrote:
>> Does anybody know the calculation openscad uses for the number of
>> segments on an arc of angle theta as a function of $fn? Exactly what
>> kind of rounding is used?
>
> I don't think anybody ever directly quoted the source:
>
My apologies. I read more into Adrian's question than was there; the
only case that came to mind that processes arcs was rotate_extrude and
so that's what I thought he was talking about.
Part of the true answer is that there is no true answer. There is a
central function for doing the r/fn/fs/fa calculation for the number of
segments in a circle, but no corresponding central function for
calculating the number of segments in an arc. Each component that needs
it does the calculation on its own.
For the particular case of offset(), which *is* what Adrian is looking
at, it's here:
https://github.com/openscad/openscad/blob/4c9d585cffd9d1e787366eb3023d9f9d3c5084fa/src/geometry/GeometryEvaluator.cc#L599
... which only partially answers the question:
// ClipperLib documentation: The formula for the number of steps in a full
// circular arc is ... Pi / acos(1 - arc_tolerance / abs(delta))
double n = Calc::get_fragments_from_r(std::abs(node.delta), node.fn, node.fs, node.fa);
double arc_tolerance = std::abs(node.delta) * (1 - cos_degrees(180 / n));
geom = ClipperUtils::applyOffset(*polygon, node.delta, node.join_type, node.miter_limit,
arc_tolerance);
so it's considerably uglier than rotate_extrude.
AM
Adrian Mariano
Mon, Aug 25, 2025 8:31 PM
I can't tell what's going on in that clipperlib code fragment. Does
node.delta hold the r value for the offset?
On Mon, Aug 25, 2025 at 3:06 AM Jordan Brown via Discuss <
discuss@lists.openscad.org> wrote:
On 8/24/2025 11:57 PM, Jordan Brown via Discuss wrote:
On 8/21/2025 2:18 PM, Adrian Mariano via Discuss wrote:
Does anybody know the calculation openscad uses for the number of segments
on an arc of angle theta as a function of $fn? Exactly what kind of
rounding is used?
I don't think anybody ever directly quoted the source:
My apologies. I read more into Adrian's question than was there; the only
case that came to mind that processes arcs was rotate_extrude and so that's
what I thought he was talking about.
Part of the true answer is that there is no true answer. There is a
central function for doing the r/fn/fs/fa calculation for the number of
segments in a circle, but no corresponding central function for calculating
the number of segments in an arc. Each component that needs it does the
calculation on its own.
For the particular case of offset(), which is what Adrian is looking at,
it's here:
https://github.com/openscad/openscad/blob/4c9d585cffd9d1e787366eb3023d9f9d3c5084fa/src/geometry/GeometryEvaluator.cc#L599
... which only partially answers the question:
// ClipperLib documentation: The formula for the number of steps in a full
// circular arc is ... Pi / acos(1 - arc_tolerance / abs(delta))
double n = Calc::get_fragments_from_r(std::abs(node.delta), node.fn, node.fs, node.fa);
double arc_tolerance = std::abs(node.delta) * (1 - cos_degrees(180 / n));
geom = ClipperUtils::applyOffset(*polygon, node.delta, node.join_type, node.miter_limit,
arc_tolerance);
so it's considerably uglier than rotate_extrude.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
I can't tell what's going on in that clipperlib code fragment. Does
node.delta hold the r value for the offset?
On Mon, Aug 25, 2025 at 3:06 AM Jordan Brown via Discuss <
discuss@lists.openscad.org> wrote:
> On 8/24/2025 11:57 PM, Jordan Brown via Discuss wrote:
>
> On 8/21/2025 2:18 PM, Adrian Mariano via Discuss wrote:
>
> Does anybody know the calculation openscad uses for the number of segments
> on an arc of angle theta as a function of $fn? Exactly what kind of
> rounding is used?
>
> I don't think anybody ever directly quoted the source:
>
> My apologies. I read more into Adrian's question than was there; the only
> case that came to mind that processes arcs was rotate_extrude and so that's
> what I thought he was talking about.
>
> Part of the true answer is that there is no true answer. There is a
> central function for doing the r/fn/fs/fa calculation for the number of
> segments in a circle, but no corresponding central function for calculating
> the number of segments in an arc. Each component that needs it does the
> calculation on its own.
>
> For the particular case of offset(), which *is* what Adrian is looking at,
> it's here:
>
>
> https://github.com/openscad/openscad/blob/4c9d585cffd9d1e787366eb3023d9f9d3c5084fa/src/geometry/GeometryEvaluator.cc#L599
>
> ... which only partially answers the question:
>
> // ClipperLib documentation: The formula for the number of steps in a full
> // circular arc is ... Pi / acos(1 - arc_tolerance / abs(delta))
> double n = Calc::get_fragments_from_r(std::abs(node.delta), node.fn, node.fs, node.fa);
> double arc_tolerance = std::abs(node.delta) * (1 - cos_degrees(180 / n));
> geom = ClipperUtils::applyOffset(*polygon, node.delta, node.join_type, node.miter_limit,
> arc_tolerance);
>
> so it's considerably uglier than rotate_extrude.
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Mon, Aug 25, 2025 9:17 PM
On 8/25/2025 10:31 PM, Adrian Mariano via Discuss wrote:
I can't tell what's going on in that clipperlib code fragment. Does
node.delta hold the r value for the offset?
On Mon, Aug 25, 2025 at 3:06 AM Jordan Brown via Discuss
discuss@lists.openscad.org wrote:
On 8/24/2025 11:57 PM, Jordan Brown via Discuss wrote:
On 8/21/2025 2:18 PM, Adrian Mariano via Discuss wrote:
Does anybody know the calculation openscad uses for the number
of segments on an arc of angle theta as a function of $fn?
Exactly what kind of rounding is used?
I don't think anybody ever directly quoted the source:
My apologies. I read more into Adrian's question than was there;
the only case that came to mind that processes arcs was
rotate_extrude and so that's what I thought he was talking about.
Part of the true answer is that there is no true answer. There is
a central function for doing the r/fn/fs/fa calculation for the
number of segments in a circle, but no corresponding central
function for calculating the number of segments in an arc. Each
component that needs it does the calculation on its own.
For the particular case of offset(), which *is* what Adrian is
looking at, it's here:
https://github.com/openscad/openscad/blob/4c9d585cffd9d1e787366eb3023d9f9d3c5084fa/src/geometry/GeometryEvaluator.cc#L599
... which only partially answers the question:
// ClipperLib documentation: The formula for the number of steps in a full
// circular arc is ... Pi / acos(1 - arc_tolerance / abs(delta))
double n = Calc::get_fragments_from_r(std::abs(node.delta), node.fn, node.fs, node.fa);
double arc_tolerance = std::abs(node.delta) * (1 - cos_degrees(180 / n));
geom = ClipperUtils::applyOffset(*polygon, node.delta, node.join_type, node.miter_limit,
arc_tolerance);
so it's considerably uglier than rotate_extrude.
_______________________________________________
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
On 8/25/2025 10:31 PM, Adrian Mariano via Discuss wrote:
> I can't tell what's going on in that clipperlib code fragment. Does
> node.delta hold the r value for the offset?
node.delta gets "r" if it's set, else gets "delta" if it's set, else is 1.
https://github.com/openscad/openscad/blob/4c9d585cffd9d1e787366eb3023d9f9d3c5084fa/src/core/OffsetNode.cc#L55
>
> On Mon, Aug 25, 2025 at 3:06 AM Jordan Brown via Discuss
> <discuss@lists.openscad.org> wrote:
>
> On 8/24/2025 11:57 PM, Jordan Brown via Discuss wrote:
>> On 8/21/2025 2:18 PM, Adrian Mariano via Discuss wrote:
>>> Does anybody know the calculation openscad uses for the number
>>> of segments on an arc of angle theta as a function of $fn?
>>> Exactly what kind of rounding is used?
>>
>> I don't think anybody ever directly quoted the source:
>>
> My apologies. I read more into Adrian's question than was there;
> the only case that came to mind that processes arcs was
> rotate_extrude and so that's what I thought he was talking about.
>
> Part of the true answer is that there is no true answer. There is
> a central function for doing the r/fn/fs/fa calculation for the
> number of segments in a circle, but no corresponding central
> function for calculating the number of segments in an arc. Each
> component that needs it does the calculation on its own.
>
> For the particular case of offset(), which *is* what Adrian is
> looking at, it's here:
>
> https://github.com/openscad/openscad/blob/4c9d585cffd9d1e787366eb3023d9f9d3c5084fa/src/geometry/GeometryEvaluator.cc#L599
>
> ... which only partially answers the question:
>
> // ClipperLib documentation: The formula for the number of steps in a full
> // circular arc is ... Pi / acos(1 - arc_tolerance / abs(delta))
> double n = Calc::get_fragments_from_r(std::abs(node.delta), node.fn, node.fs, node.fa);
> double arc_tolerance = std::abs(node.delta) * (1 - cos_degrees(180 / n));
> geom = ClipperUtils::applyOffset(*polygon, node.delta, node.join_type, node.miter_limit,
> arc_tolerance);
>
> so it's considerably uglier than rotate_extrude.
>
> _______________________________________________
> 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