5.hs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. {-# LANGUAGE OverloadedStrings #-}
  2. import Data.List
  3. import Text.LaTeX
  4. import Text.LaTeX.Base.Class
  5. import Text.LaTeX.Base.Syntax
  6. import Text.LaTeX.Packages.Graphicx
  7. import Text.LaTeX.Packages.Geometry
  8. import Util
  9. import Vec
  10. main :: IO ()
  11. main = printdoc doc
  12. doc :: Monad m => LaTeXT_ m
  13. doc = do
  14. mapM_ rendere $ polymap (vadd (0.0, 0.0, 1.0)) $ polyrotate (icosahedron 1) (0.0, 0.3, 0.3)
  15. rendere :: LaTeXC l => (Vec3, Vec3) -> l
  16. rendere (a, b) =
  17. if d > 0.001 then textblock' (vw $ fst c) (vw $ snd c) $ rotatebox' (-t * 180 / pi) $ fontsize (vw $ d * 0.092) (vw 0) "Ceci n'est pas un icosaèdre"
  18. else ""
  19. where
  20. c = vadd a' $ vdiv (vsub b' a') 2
  21. d = vdist a' b'
  22. t = atan2 (snd $ vsub b' a') (fst $ vsub b' a')
  23. a' = vadd (0.5, sqrt 2 / 2) $ vproject a
  24. b' = vadd (0.5, sqrt 2 / 2) $ vproject b
  25. polymap :: (Vec3 -> Vec3) -> [(Vec3, Vec3)] -> [(Vec3, Vec3)]
  26. polymap f = fmap (\(a, b) -> (f a, f b))
  27. polyrotate :: [(Vec3, Vec3)] -> Vec3 -> [(Vec3, Vec3)]
  28. polyrotate vs t = polymap (flip v3rotate t) vs
  29. icosahedron :: Double -> [(Vec3, Vec3)]
  30. icosahedron r = connect dist $ vicosahedron r
  31. where
  32. connect dist xs = [(x, y) | (x:ys) <- tails xs, y <- ys, vdist x y < dist]
  33. dist = r * 2.02 / vmag (phi, 1.0 :: Double)
  34. vicosahedron :: Double -> [Vec3]
  35. vicosahedron r = fmap (flip vdiv $ (vmag (phi, 1.0 :: Double)) / r) $ c vs
  36. where
  37. c = (\vs -> vs ++ (fmap (vcycle . vcycle) vs) ++ (fmap vcycle vs))
  38. vs = [(x, y, z) | x <- [-1, 1], y <- [0], z <- [phi, -phi]]
  39. phi :: Double
  40. phi = (1 + sqrt 5) / 2