;; Logo Turtle Graphics implementation for Impromptu ;; Andrew R. Brown 2006 ;; ;; Users will need to use a hybrid Scheme/Logo syntax. All Impromptu Turtle Graphics ;; commands start with tg: In particular, ;; a) scheme's bracket syntax and basic function structures and style remain ;; (even when using "tg:to" and "tg:make" rather than "define") ;; (functions conclude with closing brackets, rather than with "end") ;; b) keywords with two parts are written with a hyturtle:pen, e.g., tg:pen-up ;; c) the "tg:repeat" syntax uses separate body statements rather than a list of them ;; d) math functions are still done with prefix notation ;; e) color commands, "tg:set-pc" and "tg:set-bg" take a list of r g b a values between 0 and 1 ;; f) you can't use "tg:make" inside proceedures, use set! instead to update a variable's value ;; ;; Other significant differences include: ;; a) there is no visible turtle ;; b) "tg:set-bg" does not change tg:background colour until "tg:clear-screen" or "tg:clear" is called (define canvas-width 600) (define canvas-height 600) (define turtle:canvas (gfx:make-canvas canvas-width canvas-height)) (define turtle:position (cons (/ canvas-width 2) (/ canvas-height 2))) (define turtle:direction 90) (define turtle:pen #t) (define turtle:pen-color '(0 0 0 1)) (define turtle:bg-color '(1 1 1 1)) (gfx:clear-canvas (now) turtle:canvas turtle:bg-color) (define tg:forward (lambda (distance) (let* ((ang (* (/ turtle:direction 360) (acos -1) 2)) (x (+ (car turtle:position) (* (cos ang) distance))) (y (+ (cdr turtle:position) (* (sin ang) distance)))) (if turtle:pen (gfx:draw-path (now) turtle:canvas (gfx:make-line (car turtle:position) (cdr turtle:position) x y) turtle:pen-color '())) (set-car! turtle:position x) (set-cdr! turtle:position y)) turtle:position)) (define tg:back (lambda (distance) (set! turtle:direction (- turtle:direction 180)) (tg:forward distance) (set! turtle:direction (+ turtle:direction 180)) turtle:position)) (define tg:right (lambda (degrees) (set! turtle:direction (- turtle:direction degrees)) turtle:direction)) (define tg:left (lambda (degrees) (set! turtle:direction (+ turtle:direction degrees)) turtle:direction)) (define tg:pen-up (lambda () (set! turtle:pen #f))) (define tg:pen-down (lambda () (set! turtle:pen #t))) (define tg:home (lambda () (if turtle:pen (begin (gfx:draw-path (now) turtle:canvas (gfx:make-line (car turtle:position) (cdr turtle:position) (/ canvas-width 2) (/ canvas-height 2)) turtle:pen-color '()) (set-car! turtle:position (/ canvas-width 2)) (set-cdr! turtle:position (/ canvas-height 2)))))) (define tg:clear (lambda () (gfx:clear-canvas (now) turtle:canvas turtle:bg-color))) (define tg:clear-screen (lambda () (gfx:clear-canvas (now) turtle:canvas turtle:bg-color) (set-car! turtle:position (/ canvas-width 2)) (set-cdr! turtle:position (/ canvas-height 2)) (set! turtle:direction 90))) (define tg:set-pc (lambda (red green blue alpha) (set! turtle:pen-color (list red green blue alpha)))) (define tg:set-bg (lambda (red green blue alpha) (set! turtle:bg-color (list red green blue alpha)))) (define tg:set-x (lambda (distance) (if turtle:pen (gfx:draw-path (now) turtle:canvas (gfx:make-line (car turtle:position) (cdr turtle:position) (+ (car turtle:position) distance) (cdr turtle:position)) turtle:pen-color '())) (set-car! turtle:position (+ (car turtle:position) distance)))) (define tg:get-x (lambda () (car turtle:position))) (define tg:set-y (lambda (distance) (if turtle:pen (gfx:draw-path (now) turtle:canvas (gfx:make-line (car turtle:position) (cdr turtle:position) (car turtle:position) (+ (cdr turtle:position) distance)) turtle:pen-color '())) (set-cdr! turtle:position (+ (cdr turtle:position) distance)))) (define tg:get-y (lambda () (cdr turtle:position))) (define tg:set-pos (lambda (x-distance y-distance) (if turtle:pen (gfx:draw-path (now) turtle:canvas (gfx:make-line (car turtle:position) (cdr turtle:position) (+ (car turtle:position) x-distance) (+ (cdr turtle:position) y-distance)) turtle:pen-color '())) (set-car! turtle:position (+ (car turtle:position) x-distance)) (set-cdr! turtle:position (+ (cdr turtle:position) y-distance)))) (macro (tg:repeat args) `(let loop ((i ,(cadr args))) ,@(cddr args) (if (> i 1) (loop (- i 1))))) (macro (tg:make args) `(define ,@(cdr args))) (macro (tg:to args) `(define ,@(cdr args))) (define tg:first car) (define tg:but-first cdr) (define tg:last (lambda (lst) (car (reverse lst)))) (define tg:but-last (lambda (lst) (reverse (cdr (reverse lst))))) (define tg:count length) (define tg:item (lambda (index lst) (list-ref lst (- index 1)))) (define tg:l-put (lambda (obj lst) (reverse (cons obj (reverse lst)))))