2010-06-02 1 views
7

그래서 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

+0

이미지 파일에 링크를 추가 하시겠습니까? – jchl

+0

만델 브로트 (Mandelbrot) : http://gist.github.com/291074 – jrockway

답변

15

음, 이미지 크기이기 때문에 비뚤어 틀린, 그러나 그것은 명백하다. 이미지 크기를 지정하고 픽셀 목록을 뱉어 내고 있지만 어딘가에 한 줄에 잘못된 픽셀 수가 표시됩니다.

더 구체적으로 말하자면 이미지가 거의 정확히 한 번 감싸는 것에 유의하십시오. 즉, skew per line * height of the image = width of the image. 이미지가 정사각형이기 때문에 라인 당 여분의 픽셀을 생성한다는 것을 의미합니다. 이것은 이전의 좋지 않은 오류입니다.

이 문제가 발생하기 쉬운 위치는 반복 할 좌표를 생성 할 때입니다. 작은 세트를 사용해보고 무엇이 우리에게 제공되는지 확인해 봅시다.

> 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 크기를 줄일 수 있습니다. ,

+1

더 나은 답변을 요청할 수 없습니다. 대단히 감사합니다. –

+1

@Sean : 그렇다면 대답을 승인 된 것으로 표시하는 것이 적절하다고 생각합니다. :) –

+0

물론 (너비 -1)을 사용하는 것이 처음에는 답을 읽은 후 처음에는 꼬리를 사용했습니다. –

4

그것은 학습 경험이 있고 난 나를 위해 그것을 할 사람 찾는 게 아니에요,하지만 난 그것을 내가 camccann 이미 문제를 해결 알고

디버깅 막 다른 골목에서 좀 합니다만 그는 "물고기를 줄 수있는 방법"을 가르치는 동안 "물고기를 주었다"는 것이 더 유용 할 수 있습니다.

그래서 나는 해결책에 도달하는 유용한 방법이 될 수 있다고 생각하는 것을 나눌 것입니다.

이렇게 만델 브로 이미지는 비뚤어집니다. 일부 가능성 가능한 원인 :

  • 당신은
  • 당신은 당신은 더의 경우 어떤 내용을 실험을 할 수

사진 저장/제시의 버그가 귀하의 만델 브로 식의 버그가 위의 설명은 관련성이 있거나 없습니다. 그러한 실험은 예를 들어 수평선과 수직선의 사소한 이미지를 그릴 수 있습니다.

그런 경험을 한 후에는 수직선이 그렇게 수직이 아닌 것을 볼 수 있습니다. 가능성이 높은 원인으로 돌아가서 이미지를 표시/저장하는 데 버그가 있다는 것은 분명합니다.Mandelbrot 공식에 여전히 버그가있을 수 있지만 아마 그렇지 않을 것입니다. 현재이 문제와 관련이 없습니다.

이제 이미지 저장 버그로 인해 수직선이 대각선이 될 수 있습니다. PPM 결과가 작아 져 손으로 검토 할 수있을 때까지 간단한 예를 더 작게 만들 수 있습니다. 그럼 분명히 그 버그를 잡을거야.

+1

나는 적어도 나 자신에게 그것을 얻기 위해 뒤따라 거친 순서로 해결책을 이야기하려고 노력했지만, 서둘러서 그렇게했던 것처럼 자세히 설명하지는 않았다. 특히, "한 줄에 한 개의 여분의 픽셀"이라는 사실을 지적하면서이를 좌표 생성에 사용하는 방법을 좁히고 GHCi 스 니펫은 가설을 테스트하는 실험이었습니다. –

+0

대단히 고맙습니다. 다음 번에 내가 붙어있을 때 염두에 두어야 할 것들이 있습니다. 당신의 대답과 캠컨 사이에 내가 원했을 수있는 모든 것이 있다고 생각합니다. –