SOE ex.3.2

SOE ex.3.2

SOE ex.3.2


import GraphicsUtils
import Data.List

angles1, angles2, angles :: [Float]
angles1 = [pi/2, pi/2+pi*2/3, pi/2+pi*4/3]
angles2 = map ((-1)*) angles1
angles  = angles1 ++ angles2

colors :: [Color]
colors = [Blue, Green, Cyan, Red, Magenta, Yellow, White] -- no Black (background color)

nextColor :: Color -> Color
nextColor color =  let Just i = elemIndex color colors
                   in  if (i+1) < (length colors)
                       then colors !! (i+1)
                       else colors !! 0

minSize :: Int
minSize = 8

snowflake :: Window -> Color -> Int -> Int -> Int -> IO ()
snowflake w color x y size =
  if size < minSize
  then return ()
  else do
    drawInWindow w (withColor color (polygon $ map vertexAtAngle angles1))
    drawInWindow w (withColor color (polygon $ map vertexAtAngle angles2))
    --  getKey w    -- uncomment out if like to see each step
    sequence_ (map snowflake' (map nextCenterAtAngle angles))
    return ()
  where
    intToFloat = fromInteger . toInteger
    r = (intToFloat size) / (2 * cos (pi / 6))
    r23 = r * 2 / 3
    vertexAtAngle angle = (x + round(r * cos angle), y + round(r * sin angle))
    nextCenterAtAngle angle = (x + round(r23 * cos angle), y + round(r23 * sin angle))
    snowflake' (x,y) = snowflake w (nextColor color) x y (size `div` 3)

main :: IO ()
main = runGraphics $ do
  w <- openWindow "Snowflake" (300, 300)
  snowflake w Yellow 150 150 250
  getKey w
  closeWindow w

Leave a Reply