SICP exercise 2.03
From Drewiki
Problem
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. Then 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?
Solution
Let's start with the point and segment representations from exercise 2.2:
"("","")"
The rectangle constructor takes as arguments 3 points which define a right triangle:
p1 +
|
|
p2 +------+ p3
The line segment p1-p3 is the diagonal of the rectangle.
To find the area and perimeter of a rectangle represented by line segments, we need to know the rectangle's width and height. The width of the rectangle is the length of the line segment p2-p3, and the height is the length of p1-p2. To calculate the length of a line segment, we need a square root procedure:
Most modern Scheme implementations have a sqrt primitive, so let's use that rather than one of the sqrt procedures from chapter 1 of the text.
Let's test the segment-length procedure:
Output:
4.0
Output:
6.0
Output:
5.0
Here are rectangle constructor and the width and height selectors:
Test them (results shown are from Chicken Scheme 3.1 on a MacBook Pro running OS X 10.5):
Output:
5.0
Output:
4.0
Output:
5.3851648071345
Output:
5.3851648071345
And here are the area and perimeter procedures:
Test:
Output:
18.0
Output:
20.0
Output:
21.540659228538
Output:
29.0
The first implementation has a problem: the constructor doesn't
ensure that the 3 points form a right triangle. If they don't, then
the perimeter and area procedures don't produce the correct result.
We could fix the implementation by calculating the height of an arbitrary triangle, but there's a better way: instead of constructing a rectangle by specifying two line segments that define a triangle, we can instead provide to the constructor the two points which define the base of the rectangle, and then a scalar value for the rectangle's height. The line segments that define the sides of the rectangle are implicit in this definition, and we don't need to introduce any trigonometric calculations to find the height of a triangle.
Here's the new implementation. The constructor takes as arguments a single line segment, base, and a scalar value, height.
Test:
Output:
5.0
Output:
4
Output:
18
Output:
20.0
Output:
5.3851648071345
Output:
5.3851648071345
Output:
21.540659228538
Output:
29.0

