(load "2.2.txt") ; height-rect and width-rect return the two side lenght of the rectangle (define (perimeter-rect r) (* 2 (+ (height-rect r) (width-rect r)))) (define (area-rect r) (* (height-rect r) (width-rect r))) (define (square x) (* x x)) ; Distance between points (define (distance p1 p2) (let ((dx (- (x-point p1) (x-point p2))) (dy (- (y-point p1) (y-point p2)))) (sqrt (+ (square dx) (square dy))))) (define (length-segment s) (let ((start (start-segment s)) (end (end-segment s))) (distance start end))) ; Representation 1: ; Store segments for two perpendicular sides ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Input: points p1 p2 p3 defining a right triangle hypotenuse p1 p3 ; (define (make-rect p1 p2 p3) ; (let ((a (make-segment p1 p2)) ; (b (make-segment p2 p3)) ; ; hypotenuse ; (c (make-segment p1 p3))) ; (if (= (+ (square (length-segment a)) ; (square (length-segment b))) ; (square (length-segment c))) ; (cons a b) ; (error "input points do not specify a right triangle with hypotenus from first to last point")))) ; ; (define (height-rect r) (length-segment (car r))) ; (define (width-rect r) (length-segment (cdr r))) ; 1 ]=> (define p1 (make-point -3 7)) ; ; ;Value: p1 ; ; 1 ]=> (define p2 (make-point 1 1)) ; ; ;Value: p2 ; ; 1 ]=> (define p3 (make-point 4 3)) ; ; ;Value: p3 ; ; 1 ]=> (define r (make-rect p1 p2 p3)) ; ; ;Value: r ; ; 1 ]=> (area-rect r) ; ; ;Value: 25.999999999999996 ; ; 1 ]=> (perimeter-rect r) ; ; ;Value: 21.633307652783934 ; ; 1 ]=> (* 6 (sqrt 13)) ; ; ;Value: 21.633307652783934 ; ; 1 ]=> (make-rect p2 p3 p1) ; ; ;input points do not specify a right triangle with hypotenus from first to last point ; Idea: store the diagonal ; Problem: does not work https://en.wikipedia.org/wiki/Thales%27s_theorem ; Representation 2: ; Store three of the verties ; (v1 v2 v3) where v2 - v3 are a diagonal of the rectangle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Input: any three verticies in any order (define (make-rect v1 v2 v3) (let ((d12 (square (distance v1 v2))) (d23 (square (distance v2 v3))) (d13 (square (distance v1 v3)))) ; The three verticies should define a right triangle ; Figure out which segment is a diagonal (the hypotenuse of the right triangle) (cond ((= (+ d12 d23) d13) ; v1 v3 is the diagonal (list v2 v1 v3)) ((= (+ d12 d13) d23) ; v2 v3 is the diagonal (list v1 v2 v3)) ((= (+ d23 d13) d12) ; v1 v2 is the diagonal (list v3 v1 v2)) (else (error "invalid: specified verties do not form a right triangle" v1 v2 v3))))) (define (height-rect r) (distance (car r) (cadr r))) (define (width-rect r) (distance (car r) (caddr r))) (define (permutations elements) ; left and right is a partition of the list of elements into left and right ; suffixes. acc = all permutations starting with elements of left (define (iter left right acc) (if (null? right) acc (let ((element (car right)) (next-right (cdr right))) (iter (append left (list element)) next-right (append acc (map (lambda (p) (cons element p)) (permutations (append left next-right)))))))) (cond ((null? elements) elements) ((null? (cdr elements)) elements) (else (iter '() elements '())))) ; Test (define verticies (list (make-point -3 7) (make-point 1 1) (make-point 4 3) (make-point 0 9))) ; Check that answers are consistent for all combinations of 3 input verticies (display (map (lambda (perm) (let ((r (make-rect (car perm) (cadr perm) (caddr perm)))) (list (area-rect r) (perimeter-rect r)))) (permutations verticies)))