Haskell-Things / ImplicitCAD

A math-inspired CAD program in haskell. CSG, bevels, and shells; 2D & 3D geometry; 2D gcode generation...
https://implicitcad.org/
GNU Affero General Public License v3.0
1.32k stars 140 forks source link

Small polygons under rotation result in SDF flipping its sign #449

Open sorki opened 9 months ago

sorki commented 9 months ago

These two should be equal, but internally when sampled at (V2 (-1) 0) the sign of the SDF differs yet they both get rendered correctly.

let funPoly = polygon [V2 0 0, V2 0 (-0.1), V2 (-2) 0, V2 0 (-1)]
    rotFunPoly = rotate (2*pi) funPoly
> getImplicit funPoly (V2 (-1) 0)
-4.993761694389224e-2
> getBox funPoly
(V2 (-2.0) (-1.0),V2 0.0 0.0)

vs

> getImplicit rotFunPoly (V2 (-1) 0)) 
4.9937616943891996e-2
> getBox rotFunPoly
(V2 (-2.0000000000000004) (-1.0),V2 0.0 4.898587196589413e-16)

This has something to do with isIn https://github.com/Haskell-Things/ImplicitCAD/blob/874cb7673ef8b81b022249c3604d477519dfe057/Graphics/Implicit/ObjectUtil/GetImplicit2.hs#L60 and https://github.com/Haskell-Things/ImplicitCAD/blob/874cb7673ef8b81b022249c3604d477519dfe057/Graphics/Implicit/ObjectUtil/GetImplicit2.hs#L49-L56

and it only seems to affect small polygons + rotation. If the isIn mechanism is dropped, they don't get rendered at all.

sorki commented 9 months ago

https://github.com/Haskell-Things/ImplicitCAD/pull/445/commits/be1ee7a4d3a79104578b434b2dc486cb5b18a789 adds golden test (since we don't have any 2D ones). The two renders differ in one pixel and 9 bytes..