Exercise2-2 <---> Exercise2-4
Exercise 2.3
Implement a representation for rectangles in a plane. (Hint: You may want to make use of exercise 2.2.) In terms of your constructors and selectors, create procedures that compute the perimeter and the area of a given rectangle. Now implement a different representation for rectangles. Can you design your system with suitable abstraction barriers, so that the same perimeter and area procedures will work using either representation?
Реализуйте представление прямоугольников на плоскости. (Подсказка: Вам могут потребоваться результаты упражнения 2.2.) Определите в терминах своих конструкторов и селекторов процедуры, которые вычисляют периметр и площадь прямоугольника. Теперь реализуйте другое представление для прямоугольников. Можете ли Вы спроектировать свою систему с подходящими барьерами абстракции так, чтобы одни и те же процедуры вычисления периметра и площади работали с любым из Ваших представлений?
Scheme solution:
Lets represent a rectangle as a pair: a side segment [(x0, y0), (x1,y1)] and the width of the side, perpendicular to the segment. The width is a signed value, depending on a direction of the perpendicular (otherwise the rectangle position in a plane is not identified uniquely). Thus, using the results of exercise 2.2) , the procedures for the perimeter and the area of a given rectangle are as follows:
(define (make-segment start end) (cons start end))
(define (start-segment segment) (car segment))
(define (end-segment segment) (cdr segment))
(define (make-point x y) (cons x y))
(define (x-point point) (car point))
(define (y-point point) (cdr point))
(define (square x) (* x x))
(define (length-segment segment)
(sqrt (+ (square (- (x-point (start-segment segment))
(x-point (end-segment segment))))
(square (- (y-point (start-segment segment))
(y-point (end-segment segment))))))
)
(define (make-rectangle segment width) (cons segment width))
(define (segment-rectangle rect) (car rect))
(define (width-rectangle rect) (cdr rect))
(define (area rectangle)
(* (length-segment (segment-rectangle rectangle))
(abs (width-rectangle rectangle))))
(define (perimeter rectangle)
(* (+ (length-segment (segment-rectangle rectangle))
(abs (width-rectangle rectangle)))
2))
Also we have used a length-segment procedure here.
A different representation for rectangles may be the one with a side segment [(x0, y0), (x1,y1)] and an angle between the segment and the diagonal. In this case we are lucky to reduce this representation to the previous one, using basic geometry. Therefore, the procedures for the perimeter and the area calculations remain untouched.
(define (make-rectangle2 segment alpha)
(let ((width (* (tan alpha) (length-segment segment))))
(make-rectangle segment width)))
Exercise2-2 <---> Exercise2-4
Comments
| Hey I don't think this 2nd version works. You changed the interface - it breaks the client code! You should calculate the "alpha" by the inputed segment and width thus use it only internally. | ||||
| Posted by 58 | ||||
The comment below is correct. In make-rectangle2, width is formed as an integer, not a data structure, and so won't work with length-segment. I can't think of a way to form width as a line segment using only side and alpha, but I suspect it can be done. I'll post a solution if I think of something. | ||||
| Posted by knot at 2008-07-24 19:50:30 X | ||||
;Assuming square and sqrt from previous exercises
;For the exercise we can define a rectangle fully as
;(a) the points which make its diagonal
;OR
;(b) Two adjascent sides
; Then we use an abstraction barrier in the form of 2 selectors which for both (a) and (b) returns the 2 adjascent sides. These selectors may then be used to commonly define the perimeter and area procedures for (a) and (b).
;(a)
(define (make-rect p1 p3)
(cons p1 p3))
(define (get-p1 r)
(car r))
(define (get-p3 r)
(cdr r))
;Abstraction barrier for (a)
(define (get-rect-side1 r)
(make-segment (get-p1 r) (make-point (x-point (get-p1 r)) (y-point (get-p3 r)))))
;Abstraction barrier for (a)
(define (get-rect-side2 r)
(make-segment (make-point (x-point (get-p1 r)) (y-point (get-p3 r))) (get-p3 r)))
;(b)
(define (make-rect l1 l2)
(cons l1 l2))
(define (get-l1 r)
(car r))
(define (get-l2 r)
(cdr r))
;Abstraction barrier for (b)
(define (get-rect-side1 r)
(get-l1 r))
;Abstraction barrier for (b)
(define (get-rect-side2 r)
(get-l2 r))
;Helper procedure(define (segment-length l)
(let ((start-point (start-segment l))
(end-point (end-segment l)))
(abs (sqrt (+ (square (- (x-point end-point) (x-point start-point)))
(square (- (y-point end-point) (y-point start-point))))))))
;Common perimeter procedure
(define (perimeter r)
(+ (* 2 (segment-length (get-rect-side1 r)))) (abs (* 2 (segment-length (get-rect-side2 r)))))
;Common area procedure
(define (area r)
(* (segment-length (get-rect-side1 r)) (segment-length (get-rect-side2 r))))
| ||||
| Posted by SriramDevadas at 2009-05-28 06:45:56 | ||||