闭包实践(一)------sicp图形语言--picture

一、问题的定义和作用

1.定义:Peter J. Landin 在1964年将术语 闭包 定义为一种包含 环境成分 和 控制成分的实体,用于在他的SECD 机器上对表达式求值。

2. 作用:通过构造出某种同类的东西,支持任意和无限次的复合。

实践一


上面的图形(P(n))可以通过这种方法构造:首先在右边画一个长方形(Rn),然后左边是由两个上下临界的图形(P(n-1)/P(n-1))组成的,每个图形(P(n-1))是先画一个长方形,然后左边是两个上下临界的图形组成的

可以这样使用数学公式表示

P(n)=(P(n-1)/P(n-1))|Rn   P(n-1)=(1/4)P(n),(/表示上下临界,|表示左右临界

P0为小正方行

下面是产生该图形的代码:

#lang slideshow

(define MinSize 5)

(define (picture-2  n)
  (let ((wid (* (expt 2 n) MinSize)))
    (if (= n 0)
        (rectangle wid wid)
        (hc-append (vc-append (picture-2 (- n 1)) (picture-2 (- n 1))) (rectangle (/ wid 2) wid)))))
(picture-2 4)

drracket中图形库slideshow是闭包的,我们可以将任意两个图形组合成一个新的图形,然后新的图形组合成更复杂的图形。

实践二


上面这个图形更加复杂,首先我们将它分成4份


其中R(n-1)为T(n-1)旋转90度所得

Pn=(P(n-1)/R(n-1))|(T(n-1)/Sn), P(n-1)=1/4(P(n))  P0为正方形

T(n-1)的画法很多,可以将其看作两个长方形区域组成(K(n-1)|K(n-1))

K(n)=(K(n-1)|K(n-1)/S(n-1)   (S表示正方形 S(n-1)=1/4(S(n)),/表示上下临界,|表示左右临界)

这样就可以写出下面的代码

(define (first-splite-second-half  combine splite n f1 f2)
    (let ((wid (* (expt 2 n) MinSize)))
    (if (= n 0)
        (rectangle wid wid)
        (combine (splite (first-splite-second-half  combine splite (- n 1) f1 f2)
                         (first-splite-second-half  combine splite (- n 1) f1 f2))
                   (rectangle (* wid f1) (* wid f2))))))
(define (top-splite-1 n)
   (first-splite-second-half vc-append hc-append n 1 1))
(define (left-splite-1 n)
  (first-splite-second-half hc-append vc-append n 1 1))
(define (corner-splite-left-top n)
  (let ((wid (* (expt 2 n) MinSize)))
    (if (= n 0)
        (rectangle wid wid)
        (let ((up (top-splite-1 (- n 1)))
              (left (left-splite-1 (- n 1))))
          (let ((top-right (hc-append up up))
                (bottom-left (vc-append left left))
                (corner (corner-splite-left-top (- n 1))))
            (vc-append (hc-append corner top-right)
                       (hc-append bottom-left (rectangle wid wid))))))))


可能是slideshow自身的原因(计算旋转会有一些误差,当把left-splite-1改为top-splite-1旋转90度,则画出的图形有一些瑕疵

(define (top-splite-1 n)
   (first-splite-second-half vc-append hc-append n 1 1))
;(top-splite-1 4)
(define (left-splite-1 n)
  ;(first-splite-second-half hc-append vc-append n 1 1))
  (rotate (top-splite-1 n) (/ pi 2)))

实践三

如果将上面得到的图形分别旋转90 180 270, 然后拼成一个大正方形,就是这样的

(define (c2 n) (corner-splite-left-top n))
(define (c3 n) (rotate (c2 n) (/ pi 2)))
(define (c4 n) (rotate (c3 n) (/ pi 2)))
(define (c5 n) (rotate (c4 n) (/ pi 2)))
(define (whole n)
  (hc-append 
   (vc-append (c2 n) (c3 n))
   (vc-append (c5 n) (c4 n))))



(参考SICP)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值