(load "ch2support.scm") (define pi (* 4 (atan 1))) ;;; POINT (define (make-point x y) (define (dispatch op) (cond ((eq? op 'x) x) ((eq? op 'y) y) ((eq? op 'distance) (lambda (p) (sqrt (+ (square (- (p 'x) x)) (square (- (p 'y) y)))))) ((eq? op 'print) (display "(")(display x)(display ",")(display y)(display ")") #t) (else (error "Unknown op --- MAKE-POINT" op) nil))) dispatch) ;;; POINT EXAMPLES (define p1 (make-point 0 0)) (define p1.5 (make-point 0 1)) (define p2 (make-point 1 1)) (define p3 (make-point 1 0)) ((p2 'distance) p1) (p3 'print) ;;;; POLYGON (define (make-polygon attributes) ; attributes are the # vertices, followed by that many points (define (dispatch op) (let ((other-vertices (cddr attributes)); list of second point onwards (first-vertex (cadr attributes)) ; first point, save to close the perimeter (sides (car attributes)) ; number of sides (vertices (cdr attributes))) (define (add-perimeter result rest-vertices counter) (if (= counter sides)(+ result ((first-vertex 'distance) (car rest-vertices))) (add-perimeter (+ result (((car rest-vertices) 'distance) (cadr rest-vertices))) (cdr rest-vertices) (1+ counter)))) ; end of add-perimeter (cond ((eq? op 'perimeter) (add-perimeter 0 vertices 1)) ((eq? op 'print) (newline) (for-each (lambda (x) (newline) (x 'print)) vertices) #t) (else (error "Unknown op --- MAKE-POLYGON" op))))) dispatch) ;; POLYGON EXAMPLES (define pol1 (make-polygon (list 3 p1 p2 p3))) ;; a triangle (pol1 'perimeter) (pol1 'print) (define pol2 (make-polygon (list 4 p1 p1.5 p2 p3))) ; a square (pol2 'perimeter) (pol2 'print) ;;;; CIRCLE (define (make-circle attributes) ; attributes are the center and radius (define (dispatch op) (let ((center (car attributes)) (radius (cadr attributes))) (cond ((eq? op 'perimeter) (* 2 pi radius)) ((eq? op 'print) (newline)(display "center: ")(center 'print) (newline)(display "radius: ")(display radius) #t) ((eq? op 'radius) radius) ((eq? op 'center) center) (else (error "Unknown op --- MAKE-CIRCLE" op))))) dispatch) (define cir1 (make-circle (list p1 2))) (cir1 'print) (cir1 'perimeter) ;;;; GENERIC FIGURE HANDLER (define (generic-figure-handler figure op) (figure op)) (generic-figure-handler pol1 'print) (generic-figure-handler cir1 'perimeter) (generic-figure-handler pol1 'perimeter)