毕达哥拉斯树在2级以上更令人惊悚,为什么?

时间:2018-06-14 16:56:27

标签: haskell tree gloss

所以我们正在尝试使用Tree构建一个毕达哥拉斯gloss,它失败了2级和下一个(仅适用于0级和1级)。

以下是代码:

data FTree a b = Unit b | Comp a (FTree a b) (FTree a b) deriving (Eq,Show)
type PTree = FTree Square Square
type Square = Float

generatePTree n = aux n 100 where 
   aux :: Int -> Float -> PTree 
   aux 0 x = Unit x
   aux n x = Comp x (aux (n-1) (x * (sqrt(2)/2))) (aux (n-1) (x * (sqrt(2)/2))) 

drawPTree :: PTree -> [Picture]
drawPTree p = aux p (0,0) 0 where
      aux :: PTree -> (Float, Float) -> Float -> [Picture]
      aux (Unit c) (x,y) ang = [Translate x y (Rotate ang (square c))]
      aux (Comp c l r) (x,y) ang = [Translate x y (Rotate ang (square c))]++(aux l (x - somaX c,y + somaY c) (ang - 45)) ++ (aux r (x + somaX c,y + somaY c) (ang + 45)) 
                  where somaX c = c/2 
                        somaY c = c + sqrt(((c * (sqrt 2))/4)^2 - ((sqrt (c^2 + c^2)) / 4)^2)   

window = (InWindow "CP" (800,800) (0,0))
square s = rectangleSolid s s

main = animate window white draw
    where
    pics = drawPTree (generatePTree 2)
    draw t = Pictures $ pics

1 个答案:

答案 0 :(得分:1)

问题完全在于您的drawPTree功能,我会将我在其中发现的问题解决到工作解决方案中。

我们从您当前的解决方案开始:

drawPTree :: PTree -> [Picture]
drawPTree p = aux p (0,0) 0 where
      aux :: PTree -> (Float, Float) -> Float -> [Picture]
      aux (Unit c) (x,y) ang = [Translate x y (Rotate ang (square c))]
      aux (Comp c l r) (x,y) ang = [Translate x y (Rotate ang (square c))]++(aux l (x - somaX c,y + somaY c) (ang - 45)) ++ (aux r (x + somaX c,y + somaY c) (ang + 45)) 
                  where somaX c = c/2 
                        somaY c = c + sqrt(((c * (sqrt 2))/4)^2 - ((sqrt (c^2 + c^2)) / 4)^2)   

首先,让我们与somaXsomaY进行交易,根据实施情况,我们会根据xy向现任分支。
请注意,您可以将它们定义为变量而不是函数,因为c已经在范围内,sqrt(((c * (sqrt 2))/4)^2 - ((sqrt (c^2 + c^2)) / 4)^2)=0因此somaY = c(这可以从毕达哥拉斯树图中看到):< / p>

drawPTree :: PTree -> [Picture]
drawPTree p = aux p (0,0) 0 where
      aux :: PTree -> (Float, Float) -> Float -> [Picture]
      aux (Unit c) (x,y) ang = [Translate x y (Rotate ang (square c))]
      aux (Comp c l r) (x,y) ang = [Translate x y (Rotate ang (square c))] ++
                                   (aux l (x - somaX,y + somaY) (ang - 45)) ++ 
                                   (aux r (x + somaX,y + somaY) (ang + 45)) 
                  where somaX = c/2 
                        somaY = c

这段代码仍然没有给你正确的结果,只是因为Translate适用于全局坐标系,所以我们需要给它正确的点。幸运的是,我们可以通过简单的三角法轻松获得正确的转换

drawPTree :: PTree -> [Picture]
drawPTree p = aux p (0,0) 0 where
      aux :: PTree -> (Float, Float) -> Float -> [Picture]
      aux (Unit c) (x,y) ang = [Translate x y (Rotate ang (square c))]
      aux (Comp c l r) (x,y) ang = [Translate x y (Rotate ang (square c))] ++
                                    (aux l (x + somaXLeft,y + somaYLeft) (ang - 45)) ++ 
                                    (aux r (x + somaXRight,y + somaYRight) (ang + 45)) 
                  where somaX = c/2
                        somaY = c
                        angRads = ang * pi / 180
                        branchToGlobal angle (dx,dy) = 
                          (dx * cos angle + dy * sin angle, dy * cos angle - dx * sin angle)
                        (somaXLeft, somaYLeft) = branchToGlobal angRads (-somaX, somaY)
                        (somaXRight, somaYRight) = branchToGlobal angRads (somaX, somaY)

这确实会正确地渲染树。