scala-logo.hs
It’s the Scala logo, but it’s designed in Haskell
{- stack script --resolver lts-22.6
--package linear
--package waterfall-cad
--extra-dep waterfall-cad-0.4.0.0
--extra-dep opencascade-hs-0.4.0.0
-}
-- short-description: Scala Logo
--
-- description: It's the Scala logo, but it's designed in Haskell
--
-- image: https://doscienceto.it/blog/photos/scala-logo-01.jpg
import qualified Waterfall
import Linear
-- References:
-- 1. A. Riskus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa"
-- 2. Imre Juhasz, "Approximating the helix with rational cubic Bezier curves"
createHelicalArc :: Double -> Double -> Double -> Waterfall.Path
=
createHelicalArc r pitch incAngle let alpha = incAngle / 2 -- half included angle
= pitch/(2* pi) -- helix height per radian
p = r * cos alpha
ax = r * sin alpha
ay = p * alpha * (r - ax) * (3*r - ax)/(ay * (4*r - ax) * tan alpha)
b = V3 ax (negate ay) (negate alpha*p)
b0 = V3 ((4*r - ax)/3) (negate $ (r - ax)*(3*r - ax)/(3*ay)) (negate b)
b1 = V3 ((4*r - ax)/3) ((r - ax)*(3*r - ax)/(3*ay)) b
b2 = V3 ax ay (alpha*p)
b3 in Waterfall.bezier b0 b1 b2 b3
scalaLogo :: Waterfall.Solid
=
scalaLogo let radius = 8
= 8
pitch = 8
segmentsPerTurn = fromIntegral segmentsPerTurn
segmentsPerTurn' = 2 * pi / segmentsPerTurn'
incAngle = pitch / segmentsPerTurn'
incHeight = createHelicalArc radius pitch incAngle
segment = Waterfall.translate (incHeight *^ unit _z) . Waterfall.rotate (unit _z) incAngle
oneStep = 5 * segmentsPerTurn `div` 2
totalSegments = mconcat . take totalSegments . iterate oneStep $ segment
path = Waterfall.uScale2D 3 Waterfall.unitCircle
profile = Waterfall.scale (V3 radius radius 100) Waterfall.centeredCylinder `Waterfall.difference`
mask V3 (radius-1) (radius-1) 200) Waterfall.centeredCylinder
Waterfall.scale (in Waterfall.rotate (unit _z) pi
`Waterfall.intersection` mask)
(Waterfall.sweep path profile
main :: IO ()
= Waterfall.writeSTL 0.05 "scala-logo.stl" scalaLogo main