Thursday, September 30, 2010

SICP 2.2: Line segments in a plane

From SICP section 2.1.2 Abstraction Barriers

Exercise 2.2 asks us to define a constructor and selectors for creating line segments in a plane. A line segment is represented by a starting point and an ending point. We'll also need to create a constructor and selectors for creating points in a plane, where a point is represented by an x and a y value. Finally, using these constructors and selectors we need to define a midpoint-segment procedure that takes a line segment as its argument and returns the midpoint of that segment. A procedure for printing points is provided.
(define (print-point p)   (newline)   (display "(")   (display (x-point p))   (display ",")   (display (y-point p))   (display ")"))
If you watched lecture 2B on compound data, you already know that the procedures for defining points in a plane are going to be very similar to the original procedures for defining rational numbers. All we need to do to construct a point is glue its two parts together.
; point constructor(define (make-point x y) (cons x y)); point selectors(define (x-point p) (car p))(define (y-point p) (cdr p))

The procedures for defining segments are almost the same, only the names will change.
; segment constructor(define (make-segment a b) (cons a b)); segment selectors(define (start-segment s) (car s))(define (end-segment s) (cdr s))

Remember that we're just gluing two "things" together. It only matters conceptually (which is pretty important, really) that the two things in this case are points, while before they were primitive numbers. The mechanism for combining them is the same.

Next we need to use the midpoint formula to define a procedure for computing the midpoint of a segment. The midpoint is defined as the average of the x-values and the y-values of the two endpoints of the segment.

Our new procedure needs to take a segment and return a point.
(define (midpoint-segment s)    (make-point (/ (+ (x-point (start-segment s))                     (x-point (end-segment s)))                  2)               (/ (+ (y-point (start-segment s))                    (y-point (end-segment s)))                  2)))

There are a few examples illustrating the midpoint formula on Purplemath. I'll use those to test with.

Find the midpoint between (–1, 2) and (3, –6).
> (define a (make-point -1 2))> (define b (make-point 3 -6))> (define s (make-segment a b))> (define m (midpoint-segment s))> (print-point m)(1,-2)

Find the midpoint between (6.4, 3) and (–10.7, 4).
> (define a (make-point 6.4 3))> (define b (make-point -10.7 4))> (define s (make-segment a b))> (define m (midpoint-segment s))> (print-point m)(-2.1499999999999995,7/2)