;;; adt-turtle.rkt pour Racket v6.6 - Version procedurale (style C) ;;; (jpr, PF2, 2016) ;;; Module avec variables globales et une seule tortue (beurk, a traduire en objet en TP...) ;;; Vous pouvez traduire ce fichier dans tout langage de programmation graphique pour implementer une tortue ! #lang racket (require graphics/graphics) ; le graphisme simplifie de la librairie "graphics" (provide init pen-up pen-down set-heading heading set-position position xcor ycor right left forward back toward repeat) (open-graphics) ; initialisations de la librairie "graphics" (define SIZE 500) (define SIZE/2 (/ SIZE 2)) (define twin (open-viewport "Turtlegraphics" SIZE SIZE)) ; Pour le graphisme de "graphics", l'origine est en haut a gauche, l'axe des y vers le bas. ; D'ou la nessecite d'operer un changement de repere ci-dessous: (define (%turtlepoint->posn x y) (make-posn (+ SIZE/2 x) (- SIZE/2 y))) ; repere au centre, unite 1 pixel (define tr-segment (draw-line twin)) ; notez l'argument optionnel dans la fonction init (define (init pos cap [reset? #t]) ; Exemple : (init '(-100 50) 90) cap vers l'Est (when reset? ((clear-viewport twin))) (pen-up) (set-position pos) (set-heading cap) (pen-down)) (define PENDOWN? #t) ; mode pen down initial (define CAP 0) ; en degres, 0 = Nord, 90 = Est (define XCOR 0) (define YCOR 0) (define PI/180 (/ pi 180)) (define 180/PI (/ 180 pi)) (define (pen-up) (set! PENDOWN? #f)) (define (pen-down) (set! PENDOWN? #t)) (define (real-mod360 x) ; x reel modulo 360 (- x (* 360 (floor (/ x 360.0))))) (define (set-heading angle-en-degres) (set! CAP (real-mod360 angle-en-degres))) (define (heading) CAP) (define (set-position L) ; L == (x y) est un turtlepoint (let ((x (car L)) (y (cadr L))) (when PENDOWN? (tr-segment (%turtlepoint->posn XCOR YCOR) (%turtlepoint->posn x y))) (set! XCOR x) (set! YCOR y))) (define (position) (list XCOR YCOR)) (define (xcor) (car (position))) (define (ycor) (cadr (position))) (define (degrees->radians angle-en-degres) (* angle-en-degres PI/180)) (define (radians->degrees angle-en-radians) (* angle-en-radians 180/PI)) (define (right angle-en-degres) (set-heading (+ CAP angle-en-degres))) (define (left angle-en-degres) (set-heading (- CAP angle-en-degres))) (define (forward dist) (set-position (list (+ XCOR (* dist (sin (degrees->radians CAP)))) (+ YCOR (* dist (cos (degrees->radians CAP))))))) (define (back dist) (forward (- dist))) (define (toward L) ; force la tortue a regarder vers le point L = (x y) (let ((x (car L)) (y (cadr L))) (let ((dx (- XCOR x)) (dy (- YCOR y)) (angle '?)) (if (= dx 0) (set! angle (if (> dy 0) -90 90)) (set! angle (radians->degrees (atan (/ dy dx))))) (set! angle (- angle)) (when (> dx 0) (set! angle (+ angle 180))) ; atant defini entre 0 et 180 (set-heading (+ angle 90))))) (define-syntax repeat ; la boucle (repeat n e1 e2 ...), avec n entier > 0 (syntax-rules () ((repeat n e1 e2 ...) (do ((i 0 (+ i 1))) ((= i n)) e1 e2 ...)))) (printf "Module adt-turtle.rkt loaded : [(init pos cap [reset?]), (pen-up), (pen-down), (set-heading a), (heading), (set-position L), (position), (xcor), (ycor), (right a), (left a), (forward d), (back d), (toward L), and the famous (repeat n e1 e2 ...)\n\n")