{-# LANGUAGE FlexibleInstances #-} module Utilities ( cBlack, cLightGray, cBlue, cGreen, cRed, cCyan, cMagenta, cYellow, cWhite, crMat, cCyanMaterial, projection, Num (..), realToReal, doubleToGLfloat, glfloatToDouble, interleave, inGroupsOf, lastAndInit, tailAndHead, showIO ) where import Graphics.Rendering.OpenGL import Graphics.UI.GLUT -- Einige Standard-Farben cBlack = Color4 0 0 0 (1::GLfloat) cLightGray = Color4 0.7 0.7 0.7 (1::GLfloat) cBlue = Color4 0 0 1 (1::GLfloat) cGreen = Color4 0 1 0 (1::GLfloat) cRed = Color4 1 0 0 (1::GLfloat) cCyan = Color4 0 1 1 (1::GLfloat) cMagenta = Color4 1 0 1 (1::GLfloat) cYellow = Color4 1 1 0 (1::GLfloat) cWhite = Color4 1 1 1 (1::GLfloat) -- Lichtundurchlässiges Material erzeugen crMat (rd,gd,bd) (rs,gs,bs) exp = do materialDiffuse Front $= Color4 rd gd bd 1.0 materialAmbient Front $= Color4 rd gd bd 1.0 materialSpecular Front $= Color4 rs gs bs 1.0 materialShininess Front $= exp materialDiffuse Back $= Color4 rd gd bd 1.0 materialSpecular Back $= Color4 rs gs bs 1.0 materialShininess Back $= exp cCyanMaterial :: IO () cCyanMaterial = crMat (0, 0.3, 0.3) (1, 1, 1.0) 5 -- Orthogonale Projektion projection xl xu yl yu zl zu = do matrixMode $= Projection loadIdentity ortho xl xu yl yu zl zu matrixMode $= Modelview 0 -- Vektoraddition, -subtraktion und Kreuzprodukt {-FIXME: It is not right to treat vectors as numbers. Introduce separate operators and then remove the LANGUAGE pragma above. -} instance (Num a, Num a, Num a) => Num (a, a, a) where (x1, y1, z1) + (x2, y2, z2) = (x1 + x2, y1 + y2, z1 + z2) (x1, y1, z1) - (x2, y2, z2) = (x1 - x2, y1 - y2, z1 - z2) (x1, y1, z1) * (x2, y2, z2) = (y1*z2 - z1*y2, z1*x2 - x1*z2, x1*y2 - y1*x2) fromInteger x = (fromInteger x, fromInteger x, fromInteger x) abs (x, y, z) = (abs x, abs y, abs z) signum (x, y, z) = (signum x, signum y, signum z) -- Konvertierung zwischen verschiedenen Real-Typen realToReal :: (Real a, Fractional b) => a -> b realToReal = fromRational . toRational doubleToGLfloat :: Double -> GLfloat doubleToGLfloat = realToReal glfloatToDouble :: GLfloat -> Double glfloatToDouble = realToReal -- Mischt zwei Listen elementweise abwechselnd interleave :: [a] -> [a] -> [a] interleave [] bs = bs interleave as [] = as interleave (a:as) (b:bs) = a : b : interleave as bs -- Teilt Liste in Unterlisten gegebener Länge auf inGroupsOf :: [a] -> Int -> [[a]] inGroupsOf [] _ = [] inGroupsOf cs n = lcs : inGroupsOf rcs n where (lcs, rcs) = splitAt n cs -- Verschiebt das letzte Element einer Liste an den Anfang lastAndInit :: [a] -> [a] lastAndInit [] = [] lastAndInit cs = last cs : init cs -- Verschiebt das erste Element einer Liste ans Ende tailAndHead :: [a] -> [a] tailAndHead [] = [] tailAndHead (c:cs) = cs ++ [c] -- Führt IO-Aktion aus und gibt den Ergebniswert aus showIO :: (Show a) => IO (a) -> IO () showIO ioVal = ioVal >>= putStr . show