anim-8.hs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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_ id $ intersperse (raw "\n\\mbox{}\\clearpage{}\n") $ fmap renderd [0.0, pi / 8 .. pi * 15 / 8]
  15. renderd :: Monad m => Double -> LaTeXT_ m
  16. renderd x = do
  17. mapM_ rendere $ polymap (vadd (0.0, 0.0, 3.0)) $ polyrotate sphere (0.0, x, 0.3)
  18. rendere :: LaTeXC l => (Vec3, Vec3) -> l
  19. rendere (a, b) =
  20. if d > 0.001 then textblock' (vw $ fst c) (vw $ snd c) $ rotatebox' ((-t ) * 180 / pi) $ fontsize (vw $ d * 0.222) (vw 0) "collapsing"
  21. else ""
  22. where
  23. c = vadd a' $ vdiv (vsub b' a') 2
  24. d = vdist a' b'
  25. t = atan2 (snd $ vsub b' a') (fst $ vsub b' a')
  26. a' = vadd (0.5, sqrt 2 / 2) $ vmul (vproject a) 1
  27. b' = vadd (0.5, sqrt 2 / 2) $ vmul (vproject b) 1
  28. sphere :: [(Vec3, Vec3)]
  29. sphere = polymap (\x -> vdiv x (vmag x)) $ polyrotate (cubes 0.9) (0.6, 0.9, 0.32)
  30. polymap :: (Vec3 -> Vec3) -> [(Vec3, Vec3)] -> [(Vec3, Vec3)]
  31. polymap f = fmap (\(a, b) -> (f a, f b))
  32. polyrotate :: [(Vec3, Vec3)] -> Vec3 -> [(Vec3, Vec3)]
  33. polyrotate vs t = polymap (flip v3rotate t) vs
  34. cubes :: Double -> [(Vec3, Vec3)]
  35. cubes r = connect dist $ vcubes r
  36. where
  37. connect dist xs = [(x, y) | (x:ys) <- tails xs, y <- ys, vdist x y < dist]
  38. dist = r * 0.251
  39. vcubes :: Double -> [Vec3]
  40. vcubes r = fmap (flip vmul r) vs
  41. where
  42. vs = [(x, y, z) | x <- a, y <- a, z <- b]
  43. a = [-1, -3/4 .. 1]
  44. b = [-1, -3/4 .. 1]
  45. phi :: Double
  46. phi = (1 + sqrt 5) / 2