discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Module Disappears In Render

NH
nop head
Sun, Sep 5, 2021 8:40 AM

It breaks topology when points get merged that shouldn't be, for example
two surfaces that are close but not touching collapse and make a
non-manifold that CGAL will barf on.

On Sun, 5 Sept 2021 at 09:40, Gareth Chen garethenator@gmail.com wrote:

I'm pretty sure the imprecision with floating point numbers is irrelevant,
because OpenSCAD merges points that are within ~0.00003 of each other.

On Sat, Sep 4, 2021, 6:57 PM Doug Moen doug@moens.org wrote:

Okay, let's introduce some notation. "~0.1" means the closest binary
approximation of the number 0.1 in IEEE 64 bit floating point. It's not
exactly equal to "0.1", it is actually
0.1000000000000000055511151231257827021181583404541015625

Now suppose we start at 0, and repeatedly add ~0.1 to our total. But we
will do the addition using IEEE floating point arithmetic, which does not
produce exact results.

The first numbers in our sequence are ~0, ~0.1, ~0.2
Because of the binary representation of floating point, x+x is always
exactly the same as 2*x, there is no rounding or floating point imprecision
in the result.

But when we add ~0.1 a third time, we get an imprecise result. ~0.1 +
~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our
total did not increase by ~0.1, it instead increased by a slightly larger
value, ~0.10000000000000003, and this is due to floating point imprecision.

Here is the same numeric sequence printed in a less ambiguous format:
0.00000000000000000000000000000000000000000000000000000000
0.10000000000000000555111512312578270211815834045410156250
0.20000000000000001110223024625156540423631668090820312500
0.30000000000000004440892098500626161694526672363281250000

If the final addition had been performed exactly, the final value would
have instead been:
0.30000000000000001665334536937734810635447502136230468750

This means that the individual cubes in your stack do not all have the
same height.

On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote:

On 9/4/2021 3:33 PM, Doug Moen wrote:

On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote:

Remember that while 0.1 cannot be represented precisely, it can be
represented repeatably.

If you made a stack of 0.1 cubes by successively adding 0.1, I'd expect
all to be well because the top Z values of the cubes would have been
calculated using the same values as the bottom Z values of the next cubes
up.

That's not true because of the representation of geometry in OpenSCAD. In
that stack of cubes, the height of each cube is not represented by the
number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's
64 bit floating point numbers have a fixed number of bits of precision (53
bits), so as the magnitude of a number gets larger, bits of precision are
lost at the low end. There are more floating point numbers between 0.0 and
0.1 than there are between 10.0 and 10.1, so in the latter case, the
difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 ==
0.09999999999999964, which is different from 0.1.

All of that is true, except for the "that's not true" part. :-)

I set up a very special case:  a stack of cubes, stacked by successively
adding 0.1.

Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964.  But
the next cube starts at Z=0.09999999999999964, and continues to
0.09999999999999964 + 0.09999999999999964.  And so on.  The top face of
each cube will precisely match the bottom face of the next cube.  The
binary representation of 0.1 is not equal to 0.1, and the binary
representation of 0.1 plus itself is not equal to 0.2 (and may not be equal
to the binary representation of 0.2), but it is equal to a separately
calculated sum of the binary representation of 0.1 and the binary
representation of 0.1.

That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal to
0.1+0.1.

But see below for the more general answer.

It's a little trickier if you made a stack of cubes by multiplying the
cube number by 0.1, but I think all would still be well, even without grid
snap.  All of the top Z values would have been calculated using the same
numbers, as would all of the bottom Z values.  Those top Z values would
either all be the same as the bottom Z values of the next layer, or would
all be different.  In either case, you're OK.

Multiplication will give you more accurate results than iterative
addition of 0.1.
10*0.1 == 1 while iteratively adding 0.1 ten times gives you a different
number, 0.9999999999999999

Yes.  Say that you stack ten 0.1 unit cubes by successively adding 0.1.
Indeed, the top face of the topmost cube may well be at something like
0.9999999999999999.

Now you place an eleventh cube at Z=1.  That cube extends from Z=1 to
Z=~1.1.  With these numbers, that means that there is a microscopic gap (or
actually an attoscopic gap :-) between the tenth and the eleventh.

But we shouldn't assume that the representation is always a tiny bit less
than the true number.  Perhaps it is sometimes a tiny bit more.

You are still OK, because all of the corner points in the top face of the
tenth cube are at some particular Z value (call it Z1), and all of the
corner points in the bottom face of the eleventh cube are at some
particular Z value (call it Z2).  If Z1 and Z2 are the same, you're OK
because the two faces precisely match.  If they are different, you are OK
because they either do not touch, or they overlap.  Grid snap doesn't
affect that, because (I assume) grid snap will snap all of the points the
same way - again, they will either all match, or not touch, or overlap.

You should be OK with any stack of cuboids (of constant X-Y dimensions,
aligned in X and Y), no matter what the heights of the cuboids are and no
matter how they are spaced, because the top and bottom faces of each cuboid
are perfectly parallel with the XY plane.  You can never get just one edge
shared; either none of the edges are shared or they are all shared.

I'm pretty sure that this behavior is preserved across translation and
scaling - again, the points will either all match, or will all not match,
because the top and bottom faces remain perfectly parallel to the XY
plane.  I'm pretty sure that it is not preserved across rotation or
skewing; while points that match will stay matched, points that are not
matched might become matched, and that result could be different for
different corners of the cubes.


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

It breaks topology when points get merged that shouldn't be, for example two surfaces that are close but not touching collapse and make a non-manifold that CGAL will barf on. On Sun, 5 Sept 2021 at 09:40, Gareth Chen <garethenator@gmail.com> wrote: > I'm pretty sure the imprecision with floating point numbers is irrelevant, > because OpenSCAD merges points that are within ~0.00003 of each other. > > On Sat, Sep 4, 2021, 6:57 PM Doug Moen <doug@moens.org> wrote: > >> Okay, let's introduce some notation. "~0.1" means the closest binary >> approximation of the number 0.1 in IEEE 64 bit floating point. It's not >> exactly equal to "0.1", it is actually >> 0.1000000000000000055511151231257827021181583404541015625 >> >> Now suppose we start at 0, and repeatedly add ~0.1 to our total. But we >> will do the addition using IEEE floating point arithmetic, which does not >> produce exact results. >> >> The first numbers in our sequence are ~0, ~0.1, ~0.2 >> Because of the binary representation of floating point, x+x is always >> exactly the same as 2*x, there is no rounding or floating point imprecision >> in the result. >> >> But when we add ~0.1 a third time, we get an imprecise result. ~0.1 + >> ~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our >> total did not increase by ~0.1, it instead increased by a slightly larger >> value, ~0.10000000000000003, and this is due to floating point imprecision. >> >> Here is the same numeric sequence printed in a less ambiguous format: >> 0.00000000000000000000000000000000000000000000000000000000 >> 0.10000000000000000555111512312578270211815834045410156250 >> 0.20000000000000001110223024625156540423631668090820312500 >> 0.30000000000000004440892098500626161694526672363281250000 >> >> If the final addition had been performed exactly, the final value would >> have instead been: >> 0.30000000000000001665334536937734810635447502136230468750 >> >> This means that the individual cubes in your stack do not all have the >> same height. >> >> On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote: >> >> On 9/4/2021 3:33 PM, Doug Moen wrote: >> >> On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote: >> >> Remember that while 0.1 cannot be represented *precisely*, it can be >> represented *repeatably*. >> >> If you made a stack of 0.1 cubes by successively adding 0.1, I'd expect >> all to be well because the top Z values of the cubes would have been >> calculated using the same values as the bottom Z values of the next cubes >> up. >> >> >> That's not true because of the representation of geometry in OpenSCAD. In >> that stack of cubes, the height of each cube is not represented by the >> number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's >> 64 bit floating point numbers have a fixed number of bits of precision (53 >> bits), so as the magnitude of a number gets larger, bits of precision are >> lost at the low end. There are more floating point numbers between 0.0 and >> 0.1 than there are between 10.0 and 10.1, so in the latter case, the >> difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 == >> 0.09999999999999964, which is different from 0.1. >> >> >> All of that is true, except for the "that's not true" part. :-) >> >> I set up a very special case: a stack of cubes, stacked by successively >> adding 0.1. >> >> Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964. But >> the next cube starts at Z=0.09999999999999964, and continues to >> 0.09999999999999964 + 0.09999999999999964. And so on. The top face of >> each cube will precisely match the bottom face of the next cube. The >> binary representation of 0.1 is not equal to 0.1, and the binary >> representation of 0.1 plus itself is not equal to 0.2 (and may not be equal >> to the binary representation of 0.2), but it *is* equal to a separately >> calculated sum of the binary representation of 0.1 and the binary >> representation of 0.1. >> >> That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal to >> 0.1+0.1. >> >> But see below for the more general answer. >> >> >> It's a little trickier if you made a stack of cubes by multiplying the >> cube number by 0.1, but I think all would still be well, even without grid >> snap. All of the top Z values would have been calculated using the same >> numbers, as would all of the bottom Z values. Those top Z values would >> either all be the same as the bottom Z values of the next layer, or would >> all be different. In either case, you're OK. >> >> >> Multiplication will give you more accurate results than iterative >> addition of 0.1. >> 10*0.1 == 1 while iteratively adding 0.1 ten times gives you a different >> number, 0.9999999999999999 >> >> >> Yes. Say that you stack ten 0.1 unit cubes by successively adding 0.1. >> Indeed, the top face of the topmost cube may well be at something like >> 0.9999999999999999. >> >> Now you place an eleventh cube at Z=1. That cube extends from Z=1 to >> Z=~1.1. With these numbers, that means that there is a microscopic gap (or >> actually an attoscopic gap :-) between the tenth and the eleventh. >> >> But we shouldn't assume that the representation is always a tiny bit less >> than the true number. Perhaps it is sometimes a tiny bit more. >> >> You are still OK, because all of the corner points in the top face of the >> tenth cube are at some particular Z value (call it Z1), and all of the >> corner points in the bottom face of the eleventh cube are at some >> particular Z value (call it Z2). If Z1 and Z2 are the same, you're OK >> because the two faces precisely match. If they are different, you are OK >> because they either do not touch, or they overlap. Grid snap doesn't >> affect that, because (I assume) grid snap will snap all of the points the >> same way - again, they will either all match, or not touch, or overlap. >> >> You should be OK with any stack of cuboids (of constant X-Y dimensions, >> aligned in X and Y), no matter what the heights of the cuboids are and no >> matter how they are spaced, because the top and bottom faces of each cuboid >> are perfectly parallel with the XY plane. You can never get just one edge >> shared; either none of the edges are shared or they are all shared. >> >> I'm pretty sure that this behavior is preserved across translation and >> scaling - again, the points will either all match, or will all not match, >> because the top and bottom faces remain perfectly parallel to the XY >> plane. I'm pretty sure that it is *not* preserved across rotation or >> skewing; while points that match will stay matched, points that are *not* >> matched might *become* matched, and that result could be different for >> different corners of the cubes. >> >> >> _______________________________________________ >> 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 >
GC
Gareth Chen
Sun, Sep 5, 2021 9:10 AM

Yeah that makes sense, it just doesn't have anything to do with floating
point precision

On Sun, Sep 5, 2021, 1:43 AM nop head nop.head@gmail.com wrote:

It breaks topology when points get merged that shouldn't be, for example
two surfaces that are close but not touching collapse and make a
non-manifold that CGAL will barf on.

On Sun, 5 Sept 2021 at 09:40, Gareth Chen garethenator@gmail.com wrote:

I'm pretty sure the imprecision with floating point numbers is
irrelevant, because OpenSCAD merges points that are within ~0.00003 of each
other.

On Sat, Sep 4, 2021, 6:57 PM Doug Moen doug@moens.org wrote:

Okay, let's introduce some notation. "~0.1" means the closest binary
approximation of the number 0.1 in IEEE 64 bit floating point. It's not
exactly equal to "0.1", it is actually
0.1000000000000000055511151231257827021181583404541015625

Now suppose we start at 0, and repeatedly add ~0.1 to our total. But we
will do the addition using IEEE floating point arithmetic, which does not
produce exact results.

The first numbers in our sequence are ~0, ~0.1, ~0.2
Because of the binary representation of floating point, x+x is always
exactly the same as 2*x, there is no rounding or floating point imprecision
in the result.

But when we add ~0.1 a third time, we get an imprecise result. ~0.1 +
~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our
total did not increase by ~0.1, it instead increased by a slightly larger
value, ~0.10000000000000003, and this is due to floating point imprecision.

Here is the same numeric sequence printed in a less ambiguous format:
0.00000000000000000000000000000000000000000000000000000000
0.10000000000000000555111512312578270211815834045410156250
0.20000000000000001110223024625156540423631668090820312500
0.30000000000000004440892098500626161694526672363281250000

If the final addition had been performed exactly, the final value would
have instead been:
0.30000000000000001665334536937734810635447502136230468750

This means that the individual cubes in your stack do not all have the
same height.

On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote:

On 9/4/2021 3:33 PM, Doug Moen wrote:

On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote:

Remember that while 0.1 cannot be represented precisely, it can be
represented repeatably.

If you made a stack of 0.1 cubes by successively adding 0.1, I'd expect
all to be well because the top Z values of the cubes would have been
calculated using the same values as the bottom Z values of the next cubes
up.

That's not true because of the representation of geometry in OpenSCAD.
In that stack of cubes, the height of each cube is not represented by the
number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's
64 bit floating point numbers have a fixed number of bits of precision (53
bits), so as the magnitude of a number gets larger, bits of precision are
lost at the low end. There are more floating point numbers between 0.0 and
0.1 than there are between 10.0 and 10.1, so in the latter case, the
difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 ==
0.09999999999999964, which is different from 0.1.

All of that is true, except for the "that's not true" part. :-)

I set up a very special case:  a stack of cubes, stacked by successively
adding 0.1.

Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964.
But the next cube starts at Z=0.09999999999999964, and continues to
0.09999999999999964 + 0.09999999999999964.  And so on.  The top face of
each cube will precisely match the bottom face of the next cube.  The
binary representation of 0.1 is not equal to 0.1, and the binary
representation of 0.1 plus itself is not equal to 0.2 (and may not be equal
to the binary representation of 0.2), but it is equal to a separately
calculated sum of the binary representation of 0.1 and the binary
representation of 0.1.

That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal to
0.1+0.1.

But see below for the more general answer.

It's a little trickier if you made a stack of cubes by multiplying the
cube number by 0.1, but I think all would still be well, even without grid
snap.  All of the top Z values would have been calculated using the same
numbers, as would all of the bottom Z values.  Those top Z values would
either all be the same as the bottom Z values of the next layer, or would
all be different.  In either case, you're OK.

Multiplication will give you more accurate results than iterative
addition of 0.1.
10*0.1 == 1 while iteratively adding 0.1 ten times gives you a different
number, 0.9999999999999999

Yes.  Say that you stack ten 0.1 unit cubes by successively adding 0.1.
Indeed, the top face of the topmost cube may well be at something like
0.9999999999999999.

Now you place an eleventh cube at Z=1.  That cube extends from Z=1 to
Z=~1.1.  With these numbers, that means that there is a microscopic gap (or
actually an attoscopic gap :-) between the tenth and the eleventh.

But we shouldn't assume that the representation is always a tiny bit
less than the true number.  Perhaps it is sometimes a tiny bit more.

You are still OK, because all of the corner points in the top face of
the tenth cube are at some particular Z value (call it Z1), and all of the
corner points in the bottom face of the eleventh cube are at some
particular Z value (call it Z2).  If Z1 and Z2 are the same, you're OK
because the two faces precisely match.  If they are different, you are OK
because they either do not touch, or they overlap.  Grid snap doesn't
affect that, because (I assume) grid snap will snap all of the points the
same way - again, they will either all match, or not touch, or overlap.

You should be OK with any stack of cuboids (of constant X-Y dimensions,
aligned in X and Y), no matter what the heights of the cuboids are and no
matter how they are spaced, because the top and bottom faces of each cuboid
are perfectly parallel with the XY plane.  You can never get just one edge
shared; either none of the edges are shared or they are all shared.

I'm pretty sure that this behavior is preserved across translation and
scaling - again, the points will either all match, or will all not match,
because the top and bottom faces remain perfectly parallel to the XY
plane.  I'm pretty sure that it is not preserved across rotation or
skewing; while points that match will stay matched, points that are not
matched might become matched, and that result could be different for
different corners of the cubes.


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

Yeah that makes sense, it just doesn't have anything to do with floating point precision On Sun, Sep 5, 2021, 1:43 AM nop head <nop.head@gmail.com> wrote: > It breaks topology when points get merged that shouldn't be, for example > two surfaces that are close but not touching collapse and make a > non-manifold that CGAL will barf on. > > On Sun, 5 Sept 2021 at 09:40, Gareth Chen <garethenator@gmail.com> wrote: > >> I'm pretty sure the imprecision with floating point numbers is >> irrelevant, because OpenSCAD merges points that are within ~0.00003 of each >> other. >> >> On Sat, Sep 4, 2021, 6:57 PM Doug Moen <doug@moens.org> wrote: >> >>> Okay, let's introduce some notation. "~0.1" means the closest binary >>> approximation of the number 0.1 in IEEE 64 bit floating point. It's not >>> exactly equal to "0.1", it is actually >>> 0.1000000000000000055511151231257827021181583404541015625 >>> >>> Now suppose we start at 0, and repeatedly add ~0.1 to our total. But we >>> will do the addition using IEEE floating point arithmetic, which does not >>> produce exact results. >>> >>> The first numbers in our sequence are ~0, ~0.1, ~0.2 >>> Because of the binary representation of floating point, x+x is always >>> exactly the same as 2*x, there is no rounding or floating point imprecision >>> in the result. >>> >>> But when we add ~0.1 a third time, we get an imprecise result. ~0.1 + >>> ~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our >>> total did not increase by ~0.1, it instead increased by a slightly larger >>> value, ~0.10000000000000003, and this is due to floating point imprecision. >>> >>> Here is the same numeric sequence printed in a less ambiguous format: >>> 0.00000000000000000000000000000000000000000000000000000000 >>> 0.10000000000000000555111512312578270211815834045410156250 >>> 0.20000000000000001110223024625156540423631668090820312500 >>> 0.30000000000000004440892098500626161694526672363281250000 >>> >>> If the final addition had been performed exactly, the final value would >>> have instead been: >>> 0.30000000000000001665334536937734810635447502136230468750 >>> >>> This means that the individual cubes in your stack do not all have the >>> same height. >>> >>> On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote: >>> >>> On 9/4/2021 3:33 PM, Doug Moen wrote: >>> >>> On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote: >>> >>> Remember that while 0.1 cannot be represented *precisely*, it can be >>> represented *repeatably*. >>> >>> If you made a stack of 0.1 cubes by successively adding 0.1, I'd expect >>> all to be well because the top Z values of the cubes would have been >>> calculated using the same values as the bottom Z values of the next cubes >>> up. >>> >>> >>> That's not true because of the representation of geometry in OpenSCAD. >>> In that stack of cubes, the height of each cube is not represented by the >>> number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's >>> 64 bit floating point numbers have a fixed number of bits of precision (53 >>> bits), so as the magnitude of a number gets larger, bits of precision are >>> lost at the low end. There are more floating point numbers between 0.0 and >>> 0.1 than there are between 10.0 and 10.1, so in the latter case, the >>> difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 == >>> 0.09999999999999964, which is different from 0.1. >>> >>> >>> All of that is true, except for the "that's not true" part. :-) >>> >>> I set up a very special case: a stack of cubes, stacked by successively >>> adding 0.1. >>> >>> Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964. >>> But the next cube starts at Z=0.09999999999999964, and continues to >>> 0.09999999999999964 + 0.09999999999999964. And so on. The top face of >>> each cube will precisely match the bottom face of the next cube. The >>> binary representation of 0.1 is not equal to 0.1, and the binary >>> representation of 0.1 plus itself is not equal to 0.2 (and may not be equal >>> to the binary representation of 0.2), but it *is* equal to a separately >>> calculated sum of the binary representation of 0.1 and the binary >>> representation of 0.1. >>> >>> That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal to >>> 0.1+0.1. >>> >>> But see below for the more general answer. >>> >>> >>> It's a little trickier if you made a stack of cubes by multiplying the >>> cube number by 0.1, but I think all would still be well, even without grid >>> snap. All of the top Z values would have been calculated using the same >>> numbers, as would all of the bottom Z values. Those top Z values would >>> either all be the same as the bottom Z values of the next layer, or would >>> all be different. In either case, you're OK. >>> >>> >>> Multiplication will give you more accurate results than iterative >>> addition of 0.1. >>> 10*0.1 == 1 while iteratively adding 0.1 ten times gives you a different >>> number, 0.9999999999999999 >>> >>> >>> Yes. Say that you stack ten 0.1 unit cubes by successively adding 0.1. >>> Indeed, the top face of the topmost cube may well be at something like >>> 0.9999999999999999. >>> >>> Now you place an eleventh cube at Z=1. That cube extends from Z=1 to >>> Z=~1.1. With these numbers, that means that there is a microscopic gap (or >>> actually an attoscopic gap :-) between the tenth and the eleventh. >>> >>> But we shouldn't assume that the representation is always a tiny bit >>> less than the true number. Perhaps it is sometimes a tiny bit more. >>> >>> You are still OK, because all of the corner points in the top face of >>> the tenth cube are at some particular Z value (call it Z1), and all of the >>> corner points in the bottom face of the eleventh cube are at some >>> particular Z value (call it Z2). If Z1 and Z2 are the same, you're OK >>> because the two faces precisely match. If they are different, you are OK >>> because they either do not touch, or they overlap. Grid snap doesn't >>> affect that, because (I assume) grid snap will snap all of the points the >>> same way - again, they will either all match, or not touch, or overlap. >>> >>> You should be OK with any stack of cuboids (of constant X-Y dimensions, >>> aligned in X and Y), no matter what the heights of the cuboids are and no >>> matter how they are spaced, because the top and bottom faces of each cuboid >>> are perfectly parallel with the XY plane. You can never get just one edge >>> shared; either none of the edges are shared or they are all shared. >>> >>> I'm pretty sure that this behavior is preserved across translation and >>> scaling - again, the points will either all match, or will all not match, >>> because the top and bottom faces remain perfectly parallel to the XY >>> plane. I'm pretty sure that it is *not* preserved across rotation or >>> skewing; while points that match will stay matched, points that are *not* >>> matched might *become* matched, and that result could be different for >>> different corners of the cubes. >>> >>> >>> _______________________________________________ >>> 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 >
NH
nop head
Sun, Sep 5, 2021 9:12 AM

No but it is the consequence of grid snap that is trying to mitigate
floating point imprecision.

On Sun, 5 Sept 2021 at 10:10, Gareth Chen garethenator@gmail.com wrote:

Yeah that makes sense, it just doesn't have anything to do with floating
point precision

On Sun, Sep 5, 2021, 1:43 AM nop head nop.head@gmail.com wrote:

It breaks topology when points get merged that shouldn't be, for example
two surfaces that are close but not touching collapse and make a
non-manifold that CGAL will barf on.

On Sun, 5 Sept 2021 at 09:40, Gareth Chen garethenator@gmail.com wrote:

I'm pretty sure the imprecision with floating point numbers is
irrelevant, because OpenSCAD merges points that are within ~0.00003 of each
other.

On Sat, Sep 4, 2021, 6:57 PM Doug Moen doug@moens.org wrote:

Okay, let's introduce some notation. "~0.1" means the closest binary
approximation of the number 0.1 in IEEE 64 bit floating point. It's not
exactly equal to "0.1", it is actually
0.1000000000000000055511151231257827021181583404541015625

Now suppose we start at 0, and repeatedly add ~0.1 to our total. But we
will do the addition using IEEE floating point arithmetic, which does not
produce exact results.

The first numbers in our sequence are ~0, ~0.1, ~0.2
Because of the binary representation of floating point, x+x is always
exactly the same as 2*x, there is no rounding or floating point imprecision
in the result.

But when we add ~0.1 a third time, we get an imprecise result. ~0.1 +
~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our
total did not increase by ~0.1, it instead increased by a slightly larger
value, ~0.10000000000000003, and this is due to floating point imprecision.

Here is the same numeric sequence printed in a less ambiguous format:
0.00000000000000000000000000000000000000000000000000000000
0.10000000000000000555111512312578270211815834045410156250
0.20000000000000001110223024625156540423631668090820312500
0.30000000000000004440892098500626161694526672363281250000

If the final addition had been performed exactly, the final value would
have instead been:
0.30000000000000001665334536937734810635447502136230468750

This means that the individual cubes in your stack do not all have the
same height.

On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote:

On 9/4/2021 3:33 PM, Doug Moen wrote:

On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote:

Remember that while 0.1 cannot be represented precisely, it can be
represented repeatably.

If you made a stack of 0.1 cubes by successively adding 0.1, I'd expect
all to be well because the top Z values of the cubes would have been
calculated using the same values as the bottom Z values of the next cubes
up.

That's not true because of the representation of geometry in OpenSCAD.
In that stack of cubes, the height of each cube is not represented by the
number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's
64 bit floating point numbers have a fixed number of bits of precision (53
bits), so as the magnitude of a number gets larger, bits of precision are
lost at the low end. There are more floating point numbers between 0.0 and
0.1 than there are between 10.0 and 10.1, so in the latter case, the
difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 ==
0.09999999999999964, which is different from 0.1.

All of that is true, except for the "that's not true" part. :-)

I set up a very special case:  a stack of cubes, stacked by
successively adding 0.1.

Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964.
But the next cube starts at Z=0.09999999999999964, and continues to
0.09999999999999964 + 0.09999999999999964.  And so on.  The top face of
each cube will precisely match the bottom face of the next cube.  The
binary representation of 0.1 is not equal to 0.1, and the binary
representation of 0.1 plus itself is not equal to 0.2 (and may not be equal
to the binary representation of 0.2), but it is equal to a separately
calculated sum of the binary representation of 0.1 and the binary
representation of 0.1.

That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal to
0.1+0.1.

But see below for the more general answer.

It's a little trickier if you made a stack of cubes by multiplying the
cube number by 0.1, but I think all would still be well, even without grid
snap.  All of the top Z values would have been calculated using the same
numbers, as would all of the bottom Z values.  Those top Z values would
either all be the same as the bottom Z values of the next layer, or would
all be different.  In either case, you're OK.

Multiplication will give you more accurate results than iterative
addition of 0.1.
10*0.1 == 1 while iteratively adding 0.1 ten times gives you a
different number, 0.9999999999999999

Yes.  Say that you stack ten 0.1 unit cubes by successively adding
0.1.  Indeed, the top face of the topmost cube may well be at something
like 0.9999999999999999.

Now you place an eleventh cube at Z=1.  That cube extends from Z=1 to
Z=~1.1.  With these numbers, that means that there is a microscopic gap (or
actually an attoscopic gap :-) between the tenth and the eleventh.

But we shouldn't assume that the representation is always a tiny bit
less than the true number.  Perhaps it is sometimes a tiny bit more.

You are still OK, because all of the corner points in the top face of
the tenth cube are at some particular Z value (call it Z1), and all of the
corner points in the bottom face of the eleventh cube are at some
particular Z value (call it Z2).  If Z1 and Z2 are the same, you're OK
because the two faces precisely match.  If they are different, you are OK
because they either do not touch, or they overlap.  Grid snap doesn't
affect that, because (I assume) grid snap will snap all of the points the
same way - again, they will either all match, or not touch, or overlap.

You should be OK with any stack of cuboids (of constant X-Y dimensions,
aligned in X and Y), no matter what the heights of the cuboids are and no
matter how they are spaced, because the top and bottom faces of each cuboid
are perfectly parallel with the XY plane.  You can never get just one edge
shared; either none of the edges are shared or they are all shared.

I'm pretty sure that this behavior is preserved across translation and
scaling - again, the points will either all match, or will all not match,
because the top and bottom faces remain perfectly parallel to the XY
plane.  I'm pretty sure that it is not preserved across rotation or
skewing; while points that match will stay matched, points that are not
matched might become matched, and that result could be different for
different corners of the cubes.


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

No but it is the consequence of grid snap that is trying to mitigate floating point imprecision. On Sun, 5 Sept 2021 at 10:10, Gareth Chen <garethenator@gmail.com> wrote: > Yeah that makes sense, it just doesn't have anything to do with floating > point precision > > On Sun, Sep 5, 2021, 1:43 AM nop head <nop.head@gmail.com> wrote: > >> It breaks topology when points get merged that shouldn't be, for example >> two surfaces that are close but not touching collapse and make a >> non-manifold that CGAL will barf on. >> >> On Sun, 5 Sept 2021 at 09:40, Gareth Chen <garethenator@gmail.com> wrote: >> >>> I'm pretty sure the imprecision with floating point numbers is >>> irrelevant, because OpenSCAD merges points that are within ~0.00003 of each >>> other. >>> >>> On Sat, Sep 4, 2021, 6:57 PM Doug Moen <doug@moens.org> wrote: >>> >>>> Okay, let's introduce some notation. "~0.1" means the closest binary >>>> approximation of the number 0.1 in IEEE 64 bit floating point. It's not >>>> exactly equal to "0.1", it is actually >>>> 0.1000000000000000055511151231257827021181583404541015625 >>>> >>>> Now suppose we start at 0, and repeatedly add ~0.1 to our total. But we >>>> will do the addition using IEEE floating point arithmetic, which does not >>>> produce exact results. >>>> >>>> The first numbers in our sequence are ~0, ~0.1, ~0.2 >>>> Because of the binary representation of floating point, x+x is always >>>> exactly the same as 2*x, there is no rounding or floating point imprecision >>>> in the result. >>>> >>>> But when we add ~0.1 a third time, we get an imprecise result. ~0.1 + >>>> ~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our >>>> total did not increase by ~0.1, it instead increased by a slightly larger >>>> value, ~0.10000000000000003, and this is due to floating point imprecision. >>>> >>>> Here is the same numeric sequence printed in a less ambiguous format: >>>> 0.00000000000000000000000000000000000000000000000000000000 >>>> 0.10000000000000000555111512312578270211815834045410156250 >>>> 0.20000000000000001110223024625156540423631668090820312500 >>>> 0.30000000000000004440892098500626161694526672363281250000 >>>> >>>> If the final addition had been performed exactly, the final value would >>>> have instead been: >>>> 0.30000000000000001665334536937734810635447502136230468750 >>>> >>>> This means that the individual cubes in your stack do not all have the >>>> same height. >>>> >>>> On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote: >>>> >>>> On 9/4/2021 3:33 PM, Doug Moen wrote: >>>> >>>> On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote: >>>> >>>> Remember that while 0.1 cannot be represented *precisely*, it can be >>>> represented *repeatably*. >>>> >>>> If you made a stack of 0.1 cubes by successively adding 0.1, I'd expect >>>> all to be well because the top Z values of the cubes would have been >>>> calculated using the same values as the bottom Z values of the next cubes >>>> up. >>>> >>>> >>>> That's not true because of the representation of geometry in OpenSCAD. >>>> In that stack of cubes, the height of each cube is not represented by the >>>> number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's >>>> 64 bit floating point numbers have a fixed number of bits of precision (53 >>>> bits), so as the magnitude of a number gets larger, bits of precision are >>>> lost at the low end. There are more floating point numbers between 0.0 and >>>> 0.1 than there are between 10.0 and 10.1, so in the latter case, the >>>> difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 == >>>> 0.09999999999999964, which is different from 0.1. >>>> >>>> >>>> All of that is true, except for the "that's not true" part. :-) >>>> >>>> I set up a very special case: a stack of cubes, stacked by >>>> successively adding 0.1. >>>> >>>> Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964. >>>> But the next cube starts at Z=0.09999999999999964, and continues to >>>> 0.09999999999999964 + 0.09999999999999964. And so on. The top face of >>>> each cube will precisely match the bottom face of the next cube. The >>>> binary representation of 0.1 is not equal to 0.1, and the binary >>>> representation of 0.1 plus itself is not equal to 0.2 (and may not be equal >>>> to the binary representation of 0.2), but it *is* equal to a separately >>>> calculated sum of the binary representation of 0.1 and the binary >>>> representation of 0.1. >>>> >>>> That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal to >>>> 0.1+0.1. >>>> >>>> But see below for the more general answer. >>>> >>>> >>>> It's a little trickier if you made a stack of cubes by multiplying the >>>> cube number by 0.1, but I think all would still be well, even without grid >>>> snap. All of the top Z values would have been calculated using the same >>>> numbers, as would all of the bottom Z values. Those top Z values would >>>> either all be the same as the bottom Z values of the next layer, or would >>>> all be different. In either case, you're OK. >>>> >>>> >>>> Multiplication will give you more accurate results than iterative >>>> addition of 0.1. >>>> 10*0.1 == 1 while iteratively adding 0.1 ten times gives you a >>>> different number, 0.9999999999999999 >>>> >>>> >>>> Yes. Say that you stack ten 0.1 unit cubes by successively adding >>>> 0.1. Indeed, the top face of the topmost cube may well be at something >>>> like 0.9999999999999999. >>>> >>>> Now you place an eleventh cube at Z=1. That cube extends from Z=1 to >>>> Z=~1.1. With these numbers, that means that there is a microscopic gap (or >>>> actually an attoscopic gap :-) between the tenth and the eleventh. >>>> >>>> But we shouldn't assume that the representation is always a tiny bit >>>> less than the true number. Perhaps it is sometimes a tiny bit more. >>>> >>>> You are still OK, because all of the corner points in the top face of >>>> the tenth cube are at some particular Z value (call it Z1), and all of the >>>> corner points in the bottom face of the eleventh cube are at some >>>> particular Z value (call it Z2). If Z1 and Z2 are the same, you're OK >>>> because the two faces precisely match. If they are different, you are OK >>>> because they either do not touch, or they overlap. Grid snap doesn't >>>> affect that, because (I assume) grid snap will snap all of the points the >>>> same way - again, they will either all match, or not touch, or overlap. >>>> >>>> You should be OK with any stack of cuboids (of constant X-Y dimensions, >>>> aligned in X and Y), no matter what the heights of the cuboids are and no >>>> matter how they are spaced, because the top and bottom faces of each cuboid >>>> are perfectly parallel with the XY plane. You can never get just one edge >>>> shared; either none of the edges are shared or they are all shared. >>>> >>>> I'm pretty sure that this behavior is preserved across translation and >>>> scaling - again, the points will either all match, or will all not match, >>>> because the top and bottom faces remain perfectly parallel to the XY >>>> plane. I'm pretty sure that it is *not* preserved across rotation or >>>> skewing; while points that match will stay matched, points that are *not* >>>> matched might *become* matched, and that result could be different for >>>> different corners of the cubes. >>>> >>>> >>>> _______________________________________________ >>>> 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 >
MM
Michael Möller
Sun, Sep 5, 2021 12:11 PM

as in "damned if you do, and damned if you don't"

:-}

Msquare

søn. 5. sep. 2021 11.14 skrev nop head nop.head@gmail.com:

No but it is the consequence of grid snap that is trying to mitigate
floating point imprecision.

On Sun, 5 Sept 2021 at 10:10, Gareth Chen garethenator@gmail.com wrote:

Yeah that makes sense, it just doesn't have anything to do with floating
point precision

On Sun, Sep 5, 2021, 1:43 AM nop head nop.head@gmail.com wrote:

It breaks topology when points get merged that shouldn't be, for example
two surfaces that are close but not touching collapse and make a
non-manifold that CGAL will barf on.

On Sun, 5 Sept 2021 at 09:40, Gareth Chen garethenator@gmail.com
wrote:

I'm pretty sure the imprecision with floating point numbers is
irrelevant, because OpenSCAD merges points that are within ~0.00003 of each
other.

On Sat, Sep 4, 2021, 6:57 PM Doug Moen doug@moens.org wrote:

Okay, let's introduce some notation. "~0.1" means the closest binary
approximation of the number 0.1 in IEEE 64 bit floating point. It's not
exactly equal to "0.1", it is actually
0.1000000000000000055511151231257827021181583404541015625

Now suppose we start at 0, and repeatedly add ~0.1 to our total. But
we will do the addition using IEEE floating point arithmetic, which does
not produce exact results.

The first numbers in our sequence are ~0, ~0.1, ~0.2
Because of the binary representation of floating point, x+x is always
exactly the same as 2*x, there is no rounding or floating point imprecision
in the result.

But when we add ~0.1 a third time, we get an imprecise result. ~0.1 +
~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our
total did not increase by ~0.1, it instead increased by a slightly larger
value, ~0.10000000000000003, and this is due to floating point imprecision.

Here is the same numeric sequence printed in a less ambiguous format:
0.00000000000000000000000000000000000000000000000000000000
0.10000000000000000555111512312578270211815834045410156250
0.20000000000000001110223024625156540423631668090820312500
0.30000000000000004440892098500626161694526672363281250000

If the final addition had been performed exactly, the final value
would have instead been:
0.30000000000000001665334536937734810635447502136230468750

This means that the individual cubes in your stack do not all have the
same height.

On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote:

On 9/4/2021 3:33 PM, Doug Moen wrote:

On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote:

Remember that while 0.1 cannot be represented precisely, it can be
represented repeatably.

If you made a stack of 0.1 cubes by successively adding 0.1, I'd
expect all to be well because the top Z values of the cubes would have been
calculated using the same values as the bottom Z values of the next cubes
up.

That's not true because of the representation of geometry in OpenSCAD.
In that stack of cubes, the height of each cube is not represented by the
number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's
64 bit floating point numbers have a fixed number of bits of precision (53
bits), so as the magnitude of a number gets larger, bits of precision are
lost at the low end. There are more floating point numbers between 0.0 and
0.1 than there are between 10.0 and 10.1, so in the latter case, the
difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 ==
0.09999999999999964, which is different from 0.1.

All of that is true, except for the "that's not true" part. :-)

I set up a very special case:  a stack of cubes, stacked by
successively adding 0.1.

Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964.
But the next cube starts at Z=0.09999999999999964, and continues to
0.09999999999999964 + 0.09999999999999964.  And so on.  The top face of
each cube will precisely match the bottom face of the next cube.  The
binary representation of 0.1 is not equal to 0.1, and the binary
representation of 0.1 plus itself is not equal to 0.2 (and may not be equal
to the binary representation of 0.2), but it is equal to a separately
calculated sum of the binary representation of 0.1 and the binary
representation of 0.1.

That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal
to 0.1+0.1.

But see below for the more general answer.

It's a little trickier if you made a stack of cubes by multiplying the
cube number by 0.1, but I think all would still be well, even without grid
snap.  All of the top Z values would have been calculated using the same
numbers, as would all of the bottom Z values.  Those top Z values would
either all be the same as the bottom Z values of the next layer, or would
all be different.  In either case, you're OK.

Multiplication will give you more accurate results than iterative
addition of 0.1.
10*0.1 == 1 while iteratively adding 0.1 ten times gives you a
different number, 0.9999999999999999

Yes.  Say that you stack ten 0.1 unit cubes by successively adding
0.1.  Indeed, the top face of the topmost cube may well be at something
like 0.9999999999999999.

Now you place an eleventh cube at Z=1.  That cube extends from Z=1 to
Z=~1.1.  With these numbers, that means that there is a microscopic gap (or
actually an attoscopic gap :-) between the tenth and the eleventh.

But we shouldn't assume that the representation is always a tiny bit
less than the true number.  Perhaps it is sometimes a tiny bit more.

You are still OK, because all of the corner points in the top face of
the tenth cube are at some particular Z value (call it Z1), and all of the
corner points in the bottom face of the eleventh cube are at some
particular Z value (call it Z2).  If Z1 and Z2 are the same, you're OK
because the two faces precisely match.  If they are different, you are OK
because they either do not touch, or they overlap.  Grid snap doesn't
affect that, because (I assume) grid snap will snap all of the points the
same way - again, they will either all match, or not touch, or overlap.

You should be OK with any stack of cuboids (of constant X-Y
dimensions, aligned in X and Y), no matter what the heights of the cuboids
are and no matter how they are spaced, because the top and bottom faces of
each cuboid are perfectly parallel with the XY plane.  You can never get
just one edge shared; either none of the edges are shared or they are all
shared.

I'm pretty sure that this behavior is preserved across translation and
scaling - again, the points will either all match, or will all not match,
because the top and bottom faces remain perfectly parallel to the XY
plane.  I'm pretty sure that it is not preserved across rotation or
skewing; while points that match will stay matched, points that are not
matched might become matched, and that result could be different for
different corners of the cubes.


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 to discuss-leave@lists.openscad.org

as in "damned if you do, and damned if you don't" :-} Msquare søn. 5. sep. 2021 11.14 skrev nop head <nop.head@gmail.com>: > No but it is the consequence of grid snap that is trying to mitigate > floating point imprecision. > > On Sun, 5 Sept 2021 at 10:10, Gareth Chen <garethenator@gmail.com> wrote: > >> Yeah that makes sense, it just doesn't have anything to do with floating >> point precision >> >> On Sun, Sep 5, 2021, 1:43 AM nop head <nop.head@gmail.com> wrote: >> >>> It breaks topology when points get merged that shouldn't be, for example >>> two surfaces that are close but not touching collapse and make a >>> non-manifold that CGAL will barf on. >>> >>> On Sun, 5 Sept 2021 at 09:40, Gareth Chen <garethenator@gmail.com> >>> wrote: >>> >>>> I'm pretty sure the imprecision with floating point numbers is >>>> irrelevant, because OpenSCAD merges points that are within ~0.00003 of each >>>> other. >>>> >>>> On Sat, Sep 4, 2021, 6:57 PM Doug Moen <doug@moens.org> wrote: >>>> >>>>> Okay, let's introduce some notation. "~0.1" means the closest binary >>>>> approximation of the number 0.1 in IEEE 64 bit floating point. It's not >>>>> exactly equal to "0.1", it is actually >>>>> 0.1000000000000000055511151231257827021181583404541015625 >>>>> >>>>> Now suppose we start at 0, and repeatedly add ~0.1 to our total. But >>>>> we will do the addition using IEEE floating point arithmetic, which does >>>>> not produce exact results. >>>>> >>>>> The first numbers in our sequence are ~0, ~0.1, ~0.2 >>>>> Because of the binary representation of floating point, x+x is always >>>>> exactly the same as 2*x, there is no rounding or floating point imprecision >>>>> in the result. >>>>> >>>>> But when we add ~0.1 a third time, we get an imprecise result. ~0.1 + >>>>> ~0.2 == ~0.30000000000000004. When we added ~0.1 to our running total, our >>>>> total did not increase by ~0.1, it instead increased by a slightly larger >>>>> value, ~0.10000000000000003, and this is due to floating point imprecision. >>>>> >>>>> Here is the same numeric sequence printed in a less ambiguous format: >>>>> 0.00000000000000000000000000000000000000000000000000000000 >>>>> 0.10000000000000000555111512312578270211815834045410156250 >>>>> 0.20000000000000001110223024625156540423631668090820312500 >>>>> 0.30000000000000004440892098500626161694526672363281250000 >>>>> >>>>> If the final addition had been performed exactly, the final value >>>>> would have instead been: >>>>> 0.30000000000000001665334536937734810635447502136230468750 >>>>> >>>>> This means that the individual cubes in your stack do not all have the >>>>> same height. >>>>> >>>>> On Sat, Sep 4, 2021, at 8:48 PM, Jordan Brown wrote: >>>>> >>>>> On 9/4/2021 3:33 PM, Doug Moen wrote: >>>>> >>>>> On Fri, Sep 3, 2021, at 2:00 PM, Jordan Brown wrote: >>>>> >>>>> Remember that while 0.1 cannot be represented *precisely*, it can be >>>>> represented *repeatably*. >>>>> >>>>> If you made a stack of 0.1 cubes by successively adding 0.1, I'd >>>>> expect all to be well because the top Z values of the cubes would have been >>>>> calculated using the same values as the bottom Z values of the next cubes >>>>> up. >>>>> >>>>> >>>>> That's not true because of the representation of geometry in OpenSCAD. >>>>> In that stack of cubes, the height of each cube is not represented by the >>>>> number 0.1, it is represented by a difference in Z coordinates. OpenSCAD's >>>>> 64 bit floating point numbers have a fixed number of bits of precision (53 >>>>> bits), so as the magnitude of a number gets larger, bits of precision are >>>>> lost at the low end. There are more floating point numbers between 0.0 and >>>>> 0.1 than there are between 10.0 and 10.1, so in the latter case, the >>>>> difference of 0.1 is represented by fewer bits of precision. 10.1 - 10.0 == >>>>> 0.09999999999999964, which is different from 0.1. >>>>> >>>>> >>>>> All of that is true, except for the "that's not true" part. :-) >>>>> >>>>> I set up a very special case: a stack of cubes, stacked by >>>>> successively adding 0.1. >>>>> >>>>> Yes, the first cube starts at Z=0 and ends at Z=0.09999999999999964. >>>>> But the next cube starts at Z=0.09999999999999964, and continues to >>>>> 0.09999999999999964 + 0.09999999999999964. And so on. The top face of >>>>> each cube will precisely match the bottom face of the next cube. The >>>>> binary representation of 0.1 is not equal to 0.1, and the binary >>>>> representation of 0.1 plus itself is not equal to 0.2 (and may not be equal >>>>> to the binary representation of 0.2), but it *is* equal to a separately >>>>> calculated sum of the binary representation of 0.1 and the binary >>>>> representation of 0.1. >>>>> >>>>> That is, 0.1+0.1 may or may not be equal to 0.2, but is always equal >>>>> to 0.1+0.1. >>>>> >>>>> But see below for the more general answer. >>>>> >>>>> >>>>> It's a little trickier if you made a stack of cubes by multiplying the >>>>> cube number by 0.1, but I think all would still be well, even without grid >>>>> snap. All of the top Z values would have been calculated using the same >>>>> numbers, as would all of the bottom Z values. Those top Z values would >>>>> either all be the same as the bottom Z values of the next layer, or would >>>>> all be different. In either case, you're OK. >>>>> >>>>> >>>>> Multiplication will give you more accurate results than iterative >>>>> addition of 0.1. >>>>> 10*0.1 == 1 while iteratively adding 0.1 ten times gives you a >>>>> different number, 0.9999999999999999 >>>>> >>>>> >>>>> Yes. Say that you stack ten 0.1 unit cubes by successively adding >>>>> 0.1. Indeed, the top face of the topmost cube may well be at something >>>>> like 0.9999999999999999. >>>>> >>>>> Now you place an eleventh cube at Z=1. That cube extends from Z=1 to >>>>> Z=~1.1. With these numbers, that means that there is a microscopic gap (or >>>>> actually an attoscopic gap :-) between the tenth and the eleventh. >>>>> >>>>> But we shouldn't assume that the representation is always a tiny bit >>>>> less than the true number. Perhaps it is sometimes a tiny bit more. >>>>> >>>>> You are still OK, because all of the corner points in the top face of >>>>> the tenth cube are at some particular Z value (call it Z1), and all of the >>>>> corner points in the bottom face of the eleventh cube are at some >>>>> particular Z value (call it Z2). If Z1 and Z2 are the same, you're OK >>>>> because the two faces precisely match. If they are different, you are OK >>>>> because they either do not touch, or they overlap. Grid snap doesn't >>>>> affect that, because (I assume) grid snap will snap all of the points the >>>>> same way - again, they will either all match, or not touch, or overlap. >>>>> >>>>> You should be OK with any stack of cuboids (of constant X-Y >>>>> dimensions, aligned in X and Y), no matter what the heights of the cuboids >>>>> are and no matter how they are spaced, because the top and bottom faces of >>>>> each cuboid are perfectly parallel with the XY plane. You can never get >>>>> just one edge shared; either none of the edges are shared or they are all >>>>> shared. >>>>> >>>>> I'm pretty sure that this behavior is preserved across translation and >>>>> scaling - again, the points will either all match, or will all not match, >>>>> because the top and bottom faces remain perfectly parallel to the XY >>>>> plane. I'm pretty sure that it is *not* preserved across rotation or >>>>> skewing; while points that match will stay matched, points that are *not* >>>>> matched might *become* matched, and that result could be different for >>>>> different corners of the cubes. >>>>> >>>>> >>>>> _______________________________________________ >>>>> 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 to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Sun, Sep 5, 2021 5:28 PM

On 9/5/2021 1:40 AM, Gareth Chen wrote:

I'm pretty sure the imprecision with floating point numbers is
irrelevant, because OpenSCAD merges points that are within ~0.00003 of
each other.

I don't know the details of the grid snap algorithm, but it doesn't seem
like it can solve all of the problems.

Say that you have two points that are close enough that they would snap
together.  Now add a third, along the same line, at the same distance. 
Do all three snap together?  Add a fourth, et cetera.  Eventually it
needs to break the chain, snapping one set one way and another set the
other way.  If the algorithm is an obvious rounding algorithm, even the
original pair might snap apart if they span a rounding boundary.  (Using
conventional rounding as an analogy, 1.49 and 1.51 are very close
together, but one rounds to 1 and the other to 2.)  Grid snap will hide
floating point inaccuracy, until the floating point inaccuracy causes
two points that really should match up to snap to different grid points.

On 9/5/2021 1:40 AM, Gareth Chen wrote: > I'm pretty sure the imprecision with floating point numbers is > irrelevant, because OpenSCAD merges points that are within ~0.00003 of > each other. > I don't know the details of the grid snap algorithm, but it doesn't seem like it can solve all of the problems. Say that you have two points that are close enough that they would snap together.  Now add a third, along the same line, at the same distance.  Do all three snap together?  Add a fourth, et cetera.  Eventually it needs to break the chain, snapping one set one way and another set the other way.  If the algorithm is an obvious rounding algorithm, even the original pair might snap apart if they span a rounding boundary.  (Using conventional rounding as an analogy, 1.49 and 1.51 are very close together, but one rounds to 1 and the other to 2.)  Grid snap will hide floating point inaccuracy, until the floating point inaccuracy causes two points that really should match up to snap to different grid points.
DM
Doug Moen
Sun, Sep 5, 2021 5:31 PM

Grid snap is not a perfect solution. One of the problems is that it can perturb the mesh and introduce self-intersections, which can cause CGAL (union, etc) to fail.

On Sun, Sep 5, 2021, at 1:28 PM, Jordan Brown wrote:

On 9/5/2021 1:40 AM, Gareth Chen wrote:

I'm pretty sure the imprecision with floating point numbers is irrelevant, because OpenSCAD merges points that are within ~0.00003 of each other.

I don't know the details of the grid snap algorithm, but it doesn't seem like it can solve all of the problems.

Say that you have two points that are close enough that they would snap together.  Now add a third, along the same line, at the same distance.  Do all three snap together?  Add a fourth, et cetera.  Eventually it needs to break the chain, snapping one set one way and another set the other way.  If the algorithm is an obvious rounding algorithm, even the original pair might snap apart if they span a rounding boundary.  (Using conventional rounding as an analogy, 1.49 and 1.51 are very close together, but one rounds to 1 and the other to 2.)  Grid snap will hide floating point inaccuracy, until the floating point inaccuracy causes two points that really should match up to snap to different grid points.


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

Grid snap is not a perfect solution. One of the problems is that it can perturb the mesh and introduce self-intersections, which can cause CGAL (union, etc) to fail. On Sun, Sep 5, 2021, at 1:28 PM, Jordan Brown wrote: > On 9/5/2021 1:40 AM, Gareth Chen wrote: >> I'm pretty sure the imprecision with floating point numbers is irrelevant, because OpenSCAD merges points that are within ~0.00003 of each other. >> > > I don't know the details of the grid snap algorithm, but it doesn't seem like it can solve all of the problems. > > Say that you have two points that are close enough that they would snap together. Now add a third, along the same line, at the same distance. Do all three snap together? Add a fourth, et cetera. Eventually it needs to break the chain, snapping one set one way and another set the other way. If the algorithm is an obvious rounding algorithm, even the original pair might snap apart if they span a rounding boundary. (Using conventional rounding as an analogy, 1.49 and 1.51 are very close together, but one rounds to 1 and the other to 2.) Grid snap will hide floating point inaccuracy, until the floating point inaccuracy causes two points that really should match up to snap to different grid points. > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >