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