0

所以,作为一个初学者,我想我会做一个非常可怕的曼德布罗布景项目。在这个可怜的例子中,这个集合是用文本(Shreik!)绘制到一个文本文件中的。因为我想要一些数字编码的练习,所以我设计了现有的最糟糕的复数系统。我无法在代码中发现问题 - 绘制带而不是曼德布罗集的问题。在这里(不要看太久,否则你可能会因过度暴露于noob-ioactivity而死):

-- complex numbers, test for mandelbrot set

----------------- Complex Numbers

data C = Complex Float Float -- a + bi
    deriving Show

data Mandelbrot = Possible -- if thought to be in mandelbrot set
                | Not Integer -- this Integer is iterations before |z| > 2 in z=z^2+c
    deriving Show

complexReal :: C -> Float
complexReal (Complex n _) = n

complexImaginary :: C -> Float
complexImaginary (Complex _ n) = n

modulus :: C -> Float
modulus (Complex n m) = sqrt ((n^2) + (m^2))

argument :: C -> Float --returns in radians
argument (Complex m n)  | n < 0 && m < 0 = pi + (argument (Complex (0-m) (0-n)))
                        | m < 0 = (pi / 2) + (argument (Complex (0-m) n))
                        | n < 0 = ((3 * pi) / 2) + (argument (Complex m (0-n)))
                        | otherwise = atan (n / m)

multComplex :: C -> C -> C
multComplex (Complex m n) (Complex x y) = Complex ((m*x)-(n*y)) ((m*y)+(n*x))

addComplex :: C -> C -> C
addComplex (Complex m n) (Complex x y) = Complex (m + x) (m + y)

----------------- End Complex numbers

----------------- Mandelbrot

inMandelbrot :: C -> Mandelbrot
inMandelbrot c = inMandelbrotTest (Complex 0 0) c 0

--(z, c, i terations) with z=z^2+c, c is plotted on set map if z is bound
inMandelbrotTest :: C -> C -> Integer -> Mandelbrot 
inMandelbrotTest z c i  | (modulus z) > 2 = Not i -- too large
                        | i > 100 = Possible -- upper limit iterations
                        | otherwise = inMandelbrotTest (addComplex (multComplex z z) c) c (i+1)

possiblyInMandelbrot :: Mandelbrot -> Bool
possiblyInMandelbrot Possible = True
possiblyInMandelbrot _ = False

mandelbrotLine :: [C] -> String
mandelbrotLine [] = "\n"
mandelbrotLine (n:x) | possiblyInMandelbrot (inMandelbrot n) = "#" ++ mandelbrotLine x
mandelbrotLine (_:x) = " " ++ mandelbrotLine x

mandelbrotFeild :: [[C]] -> String
mandelbrotFeild [[]] = ""
mandelbrotFeild (n:x) = (mandelbrotLine n) ++ (mandelbrotFeild x)

-----------------End Mandelbrot

---------------- textual output

feildLine :: Float -> Float -> Float -> Float -> [C] -- start R, end R, i, increment x
feildLine s e i x   | s > e = []
                    | otherwise = [(Complex s i)] ++ feildLine (s+x) e i x

feildGenerate :: Float -> Float -> Float -> Float -> Float -> [[C]] -- start R, end R, start i, end i, increment x
feildGenerate sr er si ei x | si > ei = [[]]
                            | otherwise = [(feildLine sr er si x)] ++ (feildGenerate sr er (si+x) ei x)

l1 :: String
l1 = mandelbrotFeild (feildGenerate (-3) 3 (-3) 3 0.05)

---------------- End textual output

main = do
    writeFile "./mandelbrot.txt" (l1)

正如您所看到的(或者如果您没有看到),我的复数有一些未使用的函数。医生有希望吗?

摘要
为什么这会画一个乐队而不是曼德布罗集?

4

1 回答 1

4

发现你的错误:

addComplex :: C -> C -> C
addComplex (Complex m n) (Complex x y) = Complex (m + x) (m + y)

真的就是这么简单。你有一个微不足道的错字。


其他一些建议:

  • 使用Double而不是Float. 对于这个例子,它似乎给出了明显更准确的结果。
  • [x] ++ y和 是一样的x : y
  • x : xs写而不是写是传统的x : y。这清楚地表明一个是列表元素,另一个是列表。
  • 您可以导入Data.Complex以获得复数算术 - 但当然,您编写此代码是为了学习,所以这很好。
  • 如果您定义instance Num C where...,那么您将能够编写z*z + c而不是addComplex (mulComplex z z) c. 读起来更漂亮-如果您还知道如何编写实例...
  • 您不能拼写“字段”。;-)
于 2013-07-06T11:01:54.870 回答