Сначала простое. Рисовалка, обводящая рамку просто строит 4 отрезка, которые являются сторонами рамки, то есть соединяют точки (0, 0), (1, 0), (1, 1) и (0, 1):
(define outline-painter
(segments->painter (list (make-segment (make-vect 0 0)
(make-vect 1 0))
(make-segment (make-vect 1 0)
(make-vect 1 1))
(make-segment (make-vect 1 1)
(make-vect 0 1))
(make-segment (make-vect 0 1)
(make-vect 0 0)))))
Рисовалка, соединяющая противоположные концы рамки еще проще:
(define X-painter
(segments->painter (list (make-segment (make-vect 0 0)
(make-vect 1 1))
(make-segment (make-vect 1 0)
(make-vect 0 1)))))
Ромб - это контур с вершинами в точках (0.5, 0), (1, 0.5), (0.5, 1) и (0, 0.5):
(define diamond-painter
(segments->painter (list (make-segment (make-vect 0.5 0)
(make-vect 1 0.5))
(make-segment (make-vect 1 0.5)
(make-vect 0.5 1))
(make-segment (make-vect 0.5 1)
(make-vect 0 0.5))
(make-segment (make-vect 0 0.5)
(make-vect 0.5 0)))))
Для того, чтобы построить рисовалку wave, нам нужно будет пострить 17 отрезков. Для сокращения записи введем две вспомогательные процедуры:
- polyline генерирует список отрезков, составляющих ломаную линию, по набору векторов, обозначающих вершины,
- contour генерирует список отрезков, составляющих замкнутый контур, по набору векторов, обозначающих вершины.
Определения этих процедур выглядят так:
(define (polyline vectors)
(if (null? (cdr vectors))
null
(cons (make-segment (car vectors) (cadr vectors))
(polyline (cdr vectors)))))
(define (contour vectors)
(polyline (append vectors
(list (car vectors)))))
Идея процедуры contour в том, что контур - это ломаная линия, к которой начальная точка добавлена еще раз в конец.
Теперь мы можем укоротить с помощью этих новых процедур рисовалки outline-painter и diamond-painter:
(define outline-painter
(segments->painter (contour (list (make-vect 0 0)
(make-vect 1 0)
(make-vect 1 1)
(make-vect 0 1)))))
(define diamond-painter
(segments->painter (contour (list (make-vect 0.5 0)
(make-vect 1 0.5)
(make-vect 0.5 1)
(make-vect 0 0.5)))))
Рисовалка wave может быть записана таким образом (обратите внимание, как я объединяю 5 ломаных линий, составляющих изображение в набор отрезков):
(define wave-painter
(segments->painter
(append (polyline (make-vect 0 0.15)
(make-vect 0.15 0.4)
(make-vect 0.3 0.35)
(make-vect 0.4 0.35)
(make-vect 0.35 0.15)
(make-vect 0.4 0))
(polyline (make-vect 0.6 0)
(make-vect 0.65 0.15)
(make-vect 0.6 0.35)
(make-vect 0.75 0.35)
(make-vect 1 0.65))
(polyline (make-vect 1 0.85)
(make-vect 0.6 0.55)
(make-vect 0.75 1))
(polyline (make-vect 0.6 1)
(make-vect 0.5 0.7)
(make-vect 0.4 1))
(polyline (make-vect 0.25 1)
(make-vect 0.35 0.5)
(make-vect 0.3 0.4)
(make-vect 0.15 0.6)
(make-vect 0 0.35)))))
Координаты векторов взяты приближенно (но достаточно правдоподобно) по исходному рисунку.