0

所以我们正在尝试使用 构建一个毕达哥拉斯Treegloss它失败了 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
4

1 回答 1

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)   

首先,让我们处理somaXand somaY,它基于实现是当前分支方向的x平移。 请注意,您可以将它们定义为变量而不是函数,因为它们已经在范围内,因此(这可以从毕达哥拉斯树的图表中看出): y
csqrt(((c * (sqrt 2))/4)^2 - ((sqrt (c^2 + c^2)) / 4)^2)=0somaY = c

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)

这确实会正确渲染树。

于 2018-06-14T22:15:43.903 回答