Guest User

Untitled

a guest
Apr 19th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.09 KB | None | 0 0
  1. ----------------------------------------------
  2. --
  3. -- Cole Turner
  4. -- Haskell GUI experimentation and Optics program
  5. -- April 9, 2018
  6. --
  7. ----------------------------------------------
  8.  
  9. import Data.Maybe
  10. import Graphics.Gloss
  11. import Graphics.Gloss.Data.Color (makeColor, yellow, white)
  12. import Graphics.Gloss.Data.Vector
  13. import Graphics.Gloss.Geometry.Line
  14. import Graphics.Gloss.Interface.Pure.Game
  15.  
  16. data Lens = MakeLens {pos, rad, foc :: Float}
  17. type Ray = Path
  18.  
  19. main :: IO()
  20. main = play (InWindow "Haskell Optics" (500,500) (10,10))
  21. (makeColor 0.0 0.0 0.0 1)
  22. 10
  23. (0.0,0.0)
  24. getPicture
  25. handleEvent
  26. stepFunction
  27.  
  28. stepFunction :: Float -> (Float, Float) -> (Float, Float)
  29. stepFunction _ p = p
  30.  
  31. sgn :: Float -> Float
  32. sgn num = num / (abs num)
  33.  
  34. handleEvent :: Event -> (Float, Float) -> (Float, Float)
  35. handleEvent (EventKey
  36. (SpecialKey key)
  37. Down
  38. Modifiers{shift = Down}
  39. pos) (a,b) =
  40. case key of
  41. KeyUp -> (a, b+2)
  42. KeyDown -> (a, b-2)
  43. KeyLeft -> (a-2, b)
  44. KeyRight -> (a+2, b)
  45. _ -> (a, b)
  46. handleEvent e p = p
  47.  
  48. getRays :: (Float, Float) -> [Ray]
  49. getRays (a,b) = map (\x -> rayTrace x getLenses)
  50. $ map (\(x,y) -> (x+a,y+b):(a,b):[])
  51. $ map (\x -> (unitVectorAtAngle ((x+0.1)*pi/(2*n)))) [(-n)..(n-1)]
  52. where n = 20
  53.  
  54. getPicture :: (Float, Float) -> Picture
  55. getPicture p = translate (-500) 0 (Pictures [ graphicAxis
  56. , Pictures (map graphicLens getLenses)
  57. , Pictures (map graphicRay $ getRays p)
  58. ])
  59.  
  60. getLenses :: [Lens]
  61. getLenses = [ MakeLens 90 70 50
  62. , MakeLens 200 50 (-50)
  63. , MakeLens 400 100 100
  64. ]
  65.  
  66. rayTrace :: Ray -> [Lens] -> Ray
  67. rayTrace (p:ps) [] = (fst (head ps) + s*(fst p - fst (head ps)), snd (head ps) + s*(snd p - snd (head ps))):ps
  68. where s = 10000
  69. rayTrace (p:ps) (l:ls) = rayTrace i ls
  70. where o = fromMaybe (fst p + 1, snd p) (getImage p l)
  71. i = case getIntersect p (head ps) l of
  72. Nothing -> (p:ps)
  73. Just (a,b) -> ((closestPointOnLine (a,b) o (a+1,b)):(a,b):ps)
  74.  
  75. getIntersect :: Point -> Point -> Lens -> Maybe Point
  76. getIntersect p1 p2 l = intersectSegLine (pos l, -(rad l)) (pos l, rad l) p1 p2
  77.  
  78. getImage :: Point -> Lens -> Maybe Point
  79. getImage p l = intersectLineLine (pos l, snd p) (pos l + foc l, 0) p (pos l, 0)
  80.  
  81. graphicAxis :: Picture
  82. graphicAxis = Color yellow (Line [(-1000,0),(1000,0)])
  83.  
  84. graphicRay :: Ray -> Picture
  85. graphicRay = Color yellow . Line . reverse
  86.  
  87. graphicLens :: Lens -> Picture
  88. graphicLens l = Color white $ Pictures [
  89. Line [(pos l, rad l), (pos l, -(rad l))]
  90. -- , translate (pos l + foc l) 0 $ focalPoint
  91. -- , translate (pos l - foc l) 0 $ focalPoint
  92. , translate (pos l) (rad l * shape) $ upArrow
  93. , translate (pos l) (-rad l * shape) $ downArrow
  94. ]
  95. where upArrow = scale 5 5 $ Line [(-1,-1),(0,0),(1,-1)]
  96. downArrow = scale 5 5 $ Line [(-1,1),(0,0),(1,1)]
  97. shape = sgn $ foc l
  98. -- focalPoint = ThickCircle 1 2
Add Comment
Please, Sign In to add comment