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?
First, we borrow the function from Exercise 2.2 to represent a rectangle. We already have a representation of a line segment, so a rectangle is 2 sets of parallel and equal line segments with perpendicular neighboring edges. For simplicity, set the coordinates of the vertex in the lower left corner of the rectangle to (0, 0), and one of the edges to fall on the x-axis. A rectangle is then determined by using the coordinates of the intersection of the left edge of the rectangle and the diagonal, again for simplicity setting the intersection coordinates to (0, 0). You can see that make-point, x-point, y-point; make-segment, start-segment, end-segment; make-rect, make-rect-by-meeting-point; get-line-length, get-perimeter, get-area are the coordinates of the intersection point. perimeter, get-area are four different layers of functions, and a change in the implementation logic of a function in one layer will not affect the calls to the other layers.
; Determine a rectangle using the lower left vertex and the two neighboring edges passing through that vertex,for simplicity,The coordinates of the lower left vertex are set to(0, 0)
; length, width denote the length and width of the rectangle, respectively
(define (make-rect length width)
(let ((left-bottom (make-point 0 0)))
(cons (make-segment left-bottom (make-point (car left-bottom) (+ (cdr left-bottom) width))) ; The vertical side.
(make-segment left-bottom (make-point (+ (car left-bottom) length) (cdr left-bottom)))))) ; The horizontal side.
; Determine a rectangle by its diagonal intersections and its left edge,for simplicity,The coordinates of the intersection of the diagonals are set to(0, 0)
; left-line Indicates the left edge
(define (make-rect-by-meeting-point left-line)
(cons left-line (make-segment (start-segment left-line) (make-point (- 0 (x-point (start-segment left-line)))
(y-point (start-segment left-line))))))
; Using the formula for the distance between two points d = sqrt(x^2 + y^2) Calculate the length of a line segment
(define (get-line-length segment)
(sqrt (+ (square (- (x-point (end-segment segment))
(x-point (start-segment segment))))
(square (- (y-point (end-segment segment))
(y-point (start-segment segment)))))))
; Calculate the perimeter of a rectangle
(define (get-perimeter rect)
(* 2 (+ (get-line-length (car rect))
(get-line-length (cdr rect)))))
; Calculate the area of a rectangle
(define (get-area rect)
(* (get-line-length (car rect))
(get-line-length (cdr rect))))
; Setting a value of length7cubic centimeterimeter (km)5rectangles
(define test-rect1 (make-rect 7 5))
(display "rectanglestest-rect1perimeter:")
(display (get-perimeter test-rect1))
(newline)
(display "rectanglestest-rect1The area is:")
(display (get-area test-rect1))
(newline)
; Setting a value of length7cubic centimeterimeter (km)5rectangles
(define A (make-point -3.5 -2.5))
(define B (make-point -3.5 2.5))
(define left-line (make-segment A B))
(define test-rect2 (make-rect-by-meeting-point left-line))
(display "rectanglestest-rect2perimeter:")
(display (get-perimeter test-rect2))
(newline)
(display "rectanglestest-rect2The area is:")
(display (get-area test-rect2))
(newline)
; Implementation results
rectanglestest-rect1perimeter:24.000000282646763
rectanglestest-rect1The area is:35.00000070672435
rectanglestest-rect2perimeter:24.000000282646763
rectanglestest-rect2The area is:35.00000070672435