diff --git a/03_Mandelbulb/Mandelbulb.lhs b/03_Mandelbulb/Mandelbulb.lhs index 2e6de4e..fc20dc0 100644 --- a/03_Mandelbulb/Mandelbulb.lhs +++ b/03_Mandelbulb/Mandelbulb.lhs @@ -65,7 +65,7 @@ An extension of complex numbers with a third component: > fromInteger n = C (fromIntegral n, 0, 0) > C (x,y,z) + C (x',y',z') = C (x+x', y+y', z+z') > abs (C (x,y,z)) = C (sqrt (x*x + y*y + z*z), 0, 0) -> signum (C (x,y,z)) = C (signum x, 0, 0) +> signum (C (x,y,z)) = C (signum x, signum y, signum z) The most important part is the new multiplication instance. Modifying this formula will change radically the shape of the result. diff --git a/04_Mandelbulb/ExtComplex.hs b/04_Mandelbulb/ExtComplex.hs index 6500028..caba8d0 100644 --- a/04_Mandelbulb/ExtComplex.hs +++ b/04_Mandelbulb/ExtComplex.hs @@ -2,32 +2,36 @@ module ExtComplex where import Graphics.Rendering.OpenGL -data ExtComplex = C (GLfloat,GLfloat,GLfloat) +-- This time I use unpacked strict data type +-- Far faster when compiled. +data ExtComplex = C {-# UNPACK #-} !GLfloat + {-# UNPACK #-} !GLfloat + {-# UNPACK #-} !GLfloat deriving (Show,Eq) instance Num ExtComplex where -- The shape of the 3D mandelbrot -- will depend on this formula - C (x,y,z) * C (x',y',z') = C (x*x' - y*y' - z*z', - x*y' + y*x' + z*z', - x*z' + z*x' ) + (C x y z) * (C x' y' z') = C (x*x' - y*y' - z*z') + (x*y' + y*x' + z*z') + (x*z' + z*x' ) -- The rest is straightforward - fromInteger n = C (fromIntegral n, 0, 0) - C (x,y,z) + C (x',y',z') = C (x+x', y+y', z+z') - abs (C (x,y,z)) = C (sqrt (x*x + y*y + z*z), 0, 0) - signum (C (x,y,z)) = C (signum x, 0, 0) + fromInteger n = C (fromIntegral n) 0 0 + (C x y z) + (C x' y' z') = C (x+x') (y+y') (z+z') + abs (C x y z) = C (sqrt (x*x + y*y + z*z)) 0 0 + signum (C x y z) = C (signum x) (signum y) (signum z) extcomplex :: GLfloat -> GLfloat -> GLfloat -> ExtComplex -extcomplex x y z = C (x,y,z) +extcomplex x y z = C x y z real :: ExtComplex -> GLfloat -real (C (x,y,z)) = x +real (C x _ _) = x im :: ExtComplex -> GLfloat -im (C (x,y,z)) = y +im (C _ y _) = y strange :: ExtComplex -> GLfloat -strange (C (x,y,z)) = z +strange (C _ _ z) = z magnitude :: ExtComplex -> GLfloat magnitude = real.abs diff --git a/05_Mandelbulb/ExtComplex.hs b/05_Mandelbulb/ExtComplex.hs index 6500028..caba8d0 100644 --- a/05_Mandelbulb/ExtComplex.hs +++ b/05_Mandelbulb/ExtComplex.hs @@ -2,32 +2,36 @@ module ExtComplex where import Graphics.Rendering.OpenGL -data ExtComplex = C (GLfloat,GLfloat,GLfloat) +-- This time I use unpacked strict data type +-- Far faster when compiled. +data ExtComplex = C {-# UNPACK #-} !GLfloat + {-# UNPACK #-} !GLfloat + {-# UNPACK #-} !GLfloat deriving (Show,Eq) instance Num ExtComplex where -- The shape of the 3D mandelbrot -- will depend on this formula - C (x,y,z) * C (x',y',z') = C (x*x' - y*y' - z*z', - x*y' + y*x' + z*z', - x*z' + z*x' ) + (C x y z) * (C x' y' z') = C (x*x' - y*y' - z*z') + (x*y' + y*x' + z*z') + (x*z' + z*x' ) -- The rest is straightforward - fromInteger n = C (fromIntegral n, 0, 0) - C (x,y,z) + C (x',y',z') = C (x+x', y+y', z+z') - abs (C (x,y,z)) = C (sqrt (x*x + y*y + z*z), 0, 0) - signum (C (x,y,z)) = C (signum x, 0, 0) + fromInteger n = C (fromIntegral n) 0 0 + (C x y z) + (C x' y' z') = C (x+x') (y+y') (z+z') + abs (C x y z) = C (sqrt (x*x + y*y + z*z)) 0 0 + signum (C x y z) = C (signum x) (signum y) (signum z) extcomplex :: GLfloat -> GLfloat -> GLfloat -> ExtComplex -extcomplex x y z = C (x,y,z) +extcomplex x y z = C x y z real :: ExtComplex -> GLfloat -real (C (x,y,z)) = x +real (C x _ _) = x im :: ExtComplex -> GLfloat -im (C (x,y,z)) = y +im (C _ y _) = y strange :: ExtComplex -> GLfloat -strange (C (x,y,z)) = z +strange (C _ _ z) = z magnitude :: ExtComplex -> GLfloat magnitude = real.abs