Haskell-Things / Haskell-Things/ImplicitCAD

A bug in RefineSegs.hs

Open
#234 6 comments 0 reactions 1 assignee Claimed by @julialongtin View on GitHub
graphics-engine In-Progress
Dominant language
JavaScript
Stars
1.6k
Forks
148
PR merge metrics
No merged PRs in 30d

Description

Hi devolopers and maintainers of this great project,

I have come across a bug in the `refine` function, which generates broken faces in some models. For now, I don't understand the full idea of the function so I don't come with a fix proposal, so I provide the reproduction code (which creates an internal helic involute gear):

```
module Main where

import Prelude
import Graphics.Implicit
import Graphics.Implicit.Definitions

involute x y = - (x * cos angle + y * sin angle - 1)
where angle = sqrt$ abs$ x**2 + y**2 - 1

circ x y = x**2 + y**2 - 1

invcirc :: SymbolicObj2
invcirc = flip implicit ((-5, -5), (5, 5)) $ \(x, y) -> maximum
[ min (involute x y) (maximum [x - 1, y - 1.5, -x - 3])
, -y
, circ (x/4.9) (y/4.9)
]

double :: a -> (a, a)
double x = (x, x)

involuteGear :: ℝ -> ℕ -> ℝ -> ℝ-> SymbolicObj2
involuteGear pressureAngle toothCount modulus gapExpansion = scale scale_ $
intersect
[ circle (1 + 2/toothCountℝ)
, union$ [circle (1 - 2*5/4/toothCountℝ)] ++
[ rotate ((fromℕtoℝ i)*toothAngle) $
intersect [toothHalf, rotate toothAngle$ scale (1, -1) toothHalf]
| i <- [0..toothCount - 1]
]
]
where
toothCountℝ = fromℕtoℝ toothCount
scale_ = double$ modulus * toothCountℝ / 2

toothHalf = rotate (halfGapAngle)$ scale (double involuteScale) invcirc
involuteScale = cos pressureAngle

toothAngle = 2 * pi / toothCountℝ
halfGapAngle = (toothAngle / 2 - 2 * (tan pressureAngle - pressureAngle)) / 2
+ gapExpansion

main = writeSTL 1 "test.stl" obj
where
pressureAngle = 30*pi/180
modulus = 2
gearProfile toothCount gapExpansion =
involuteGear pressureAngle toothCount modulus gapExpansion

gearLike toothCount profile = extrudeRM
0
(Right$ \z -> abs$ 360/toothCount' - 360/toothCount'/5*2*z)
(Left 1)
(Left (0, 0))
profile
(Left 5)
where toothCount' = fromℕtoℝ toothCount

gear toothCount gapExpansion = gearLike toothCount$
gearProfile toothCount gapExpansion

obj = gearLike 54$ difference [circle$ 54*modulus/2 + 10, gearProfile 54 (-0.003)]
```

The broken faces were no more there when I removed the `refine` function application [here](https://github.com/colah/ImplicitCAD/blob/c54929328ddae304118d8466df8d18708e6979a2/Graphics/Implicit/Export/Render/GetSegs.hs#L80), which can be used as a simple workaround to this bug:
```
- in map (refine res obj) . filter notPointLine $ case (x1y2 <= 0, x2y2 <= 0,
- x1y1 <= 0, x2y1 <= 0) of
+ in filter notPointLine $ case (x1y2 <= 0, x2y2 <= 0, x1y1 <= 0, x2y1 <= 0) of
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.