Почему был бы изображение (Mandelbrot) быть скошенным и повториться?

Таким образом, я просто записал немного отрывка, чтобы генерировать фрактал Mandelbrot и вообразить мое удивление, когда это вышло все ужасные и скошенные (как Вы видите внизу). Я ценил бы точку в направлении того, почему это даже произойдет. Это - полезный опыт, и я не ищу никого, чтобы сделать это для меня, но я отчасти в тупике, отлаживающем его. Незаконный код поколения:

module Mandelbrot where
import Complex
import Image

main = writeFile "mb.ppm" $ imageMB 1000

mandelbrotPixel x y = mb (x:+y) (0:+0) 0

mb c x iter | magnitude x > 2 = iter
            | iter >= 255     = 255
            | otherwise       = mb c (c+q^2) (iter+1)
    where q = x -- Mandelbrot
          -- q = (abs.realPart $ x) :+ (abs.imagPart $ x) --Burning Ship

argandPlane x0 x1 y0 y1 width height = [ (x,y) | 
        y <- [y1, y1 - dy .. y0], --traverse from
        x <- [x0, x0 + dx .. x1] ] --top-left to bottom-right
    where dx = (x1 - x0) / width
          dy = (y1 - y0) / height

drawPicture :: (a -> b -> c) -> (c -> Colour) -> [(a, b)] -> Image
drawPicture function colourFunction = map (colourFunction . uncurry function)

imageMB s = createPPM s s
        $ drawPicture mandelbrotPixel (replicate 3)
        $ argandPlane (-1.8) (-1.7) (0.02) 0.055 s' s'
    where s' = fromIntegral s

И код изображения (в котором я довольно уверен):

module Image where

type Colour = [Int]
type Image = [Colour]

createPPM :: Int -> Int -> Image -> String
createPPM w h i = concat ["P3 ", show w, " ", show h, " 255\n",
    unlines.map (unwords.map show) $ i]

Ugly Mandelskew thing

7
задан C. A. McCann 2 June 2010 в 14:01
поделиться

2 ответа

Ну, изображение перекошено, потому что размеры неправильные, но это очевидно. Вы указываете размер изображения, а затем выплевываете список пикселей, но с неправильным количеством пикселей в строке.

Более конкретно, обратите внимание, что изображение оборачивается почти точно один раз: другими словами, перекос на строку * высота изображения = ширина изображения. Поскольку изображение квадратное, это означает, что вы генерируете дополнительный пиксель на строку - старая добрая ошибка off-by-one.

Очевидное место, где это может произойти, это когда вы генерируете координаты для итерации. Давайте попробуем небольшой набор и посмотрим, что он нам даст:

> length $ argandPlane (-2.5) (-2) 1.5 2 10 10
121
> 10 ^ 2
100
> 11 ^ 2
121

И так. Я подозреваю, что ошибка связана с тем, что вы рассчитываете приращение как реальное расстояние, деленное на размер пикселя, что дает правильное количество интервалов, но лишнюю точку. Рассмотрим интервал от 0,0 до 1,0. Используя ваш расчет с шириной 4, мы получаем:

> let x0 = 0.0
> let x1 = 1.0
> let width = 4.0
> let dx = (x1 - x0) / width
> dx
0.25
> let xs = [x0, x0 + dx .. x1]
> xs
[0.0, 0.25, 0.5, 0.75, 1.0]
> length xs
5

Итак, чтобы получить правильное количество точек, просто уменьшите размер на 1 при генерации координат.

15
ответ дан 6 December 2019 в 09:58
поделиться

Это учебный опыт, и я не ищу никого, кто бы сделал это за меня, но я в тупике, отлаживая это

Я знаю, что camccann уже решил вашу проблему, но он как бы "дал вам рыбу", в то время как "научить вас ловить рыбу" могло бы быть более полезным.

Поэтому я поделюсь тем, что, по моему мнению, может быть полезным способом достижения решения.

Итак, ваше изображение Мандельброта перекошено. Некоторые возможные причины:

  • У вас ошибка в формуле Мандельброта
  • У вас ошибка в представлении/сохранении изображения

Вы можете провести эксперимент, чтобы узнать, релевантны ли какие-либо из вышеперечисленных объяснений или нет. Таким экспериментом может быть, например, рисование тривиальных изображений, скажем, горизонтальных и вертикальных линий.

Проделав этот эксперимент, вы увидите, что ваши вертикальные линии не такие уж вертикальные. Возвращаясь к вероятным возможным причинам, ясно, что у вас ошибка в представлении/сохранении изображения, и это все объясняет. Возможно, у вас все еще есть ошибка в формуле Мандельброта, но, скорее всего, нет, и это не имеет отношения к рассматриваемому вопросу.

Теперь вы должны подумать, какая ошибка сохранения изображения может привести к тому, что вертикальные линии будут диагональными. Если никакой идеи не возникнет, вы можете делать ваш простой пример все меньше и меньше, пока результат PPM не станет настолько мал, что вы сможете рассмотреть его вручную. Тогда вы наверняка поймаете ошибку.

4
ответ дан 6 December 2019 в 09:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: