|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[44] экране отрезок между двумя указанными точками. Тогда мы можем создавать из списков отрезков рисовалки для изображений, состоящих из этих отрезков, вроде рисовалки wave с рисунка 2.10, таким образом:27 (define (segments->painter segment-list) (lambda (frame) (for-each (lambda (segment) (draw-line ((frame-coord-map frame) (start-segment segment)) ((frame-coord-map frame) (end-segment segment)))) segment-list))) Отрезки даются в координатах по отношению к единичному квадрату. Для каждого сегмента в списке рисовалка преобразует концы отрезка с помощью отображения координат рамки и рисует отрезок между точками с преобразованными координатами. Представление рисовалок в виде процедур воздвигает в языке построения изображений мощный барьер абстракции. Мы можем создавать и смешивать множество типов элементарных рисовалок, в зависимости от имеющихся возможностей графики. Детали их реализации несущественны. Любая процедура, если она принимает в качестве аргумента рамку и рисует в ней что-нибудь должным образом отмасштабированное, может служить рисовалкой.28 Упражнение 2.48. Направленный отрезок на плоскости можно представить в виде пары векторов: вектор от начала координат до начала отрезка и вектор от начала координат до конца отрезка. Используйте свое представление векторов из упражнения 2.46 и определите представление отрезков с конструктором make-segment и селекторами start-segment и end-segment. Упражнение 2.49. С помощью segments->painter определите следующие элементарные рисовалки: a.Рисовалку, которая обводит указанную рамку. b.Рисовалку, которая рисует «Х», соединяя противоположные концы рамки. c.Рисовалку, которая рисует ромб, соединяя между собой середины сторон рамки. d.Рисовалку wave. 27Процедура segments->painter использует представление отрезков прямых, описанное ниже в упражнении 2.48. Кроме того, она использует процедуру for-each, описанную в упражнении 2.23. 28 Например, рисовалка rogers с рисунка 2.11 была получена из полутонового черно-белого изображения. Для каждой точки в указанной рамке рисовалка rogers определяет точку исходного изображения, которая в нее отображается, и соответствующим образом ее окрашивает. Разрешая себе иметь различные типы рисовалок, мы пользуемся идеей абстрактных данных, описанной в разделе 2.1.3, где мы говорили, что представление рациональных чисел может быть каким угодно, пока соблюдается соответствующее условие. Здесь мы используем то, что рисовалку можно реализовать как угодно, лишь бы она что-то изображала в указанной рамке. В разделе 2.1.3 показывается и то, как реализовать пары в виде процедур. Рисовалки - это наш второй пример процедурного представления данных. Преобразование и комбинирование рисовалок Операции над рисовалками (flip-vert или beside, например) создают новые рисовалки, которые вызывает исходные рисовалки по отношению к рамкам, производным от рамок-аргументов. Таким образом, скажем, flip-vert не требуется знать, как работает рисовалка, чтобы перевернуть ее - ей нужно только уметь перевернуть рамку вверх ногами: перевернутая рисовалка просто использует исходную, но в обращенной рамке. Операции над рисовалками основываются на процедуре transform-painter, которая в качестве аргументов берет рисовалку и информацию о том, как преобразовать рамку, а возвращает новую рисовалку. Когда преобразованная рисовалка вызывается по отношению к какой-либо рамке, она преобразует рамку и вызывает исходную рисовалку по отношению к ней. Аргументами transform-painter служат точки (представленные в виде векторов), указывающие углы новой рамки: будучи отображенной на рамку, первая точка указывает исходную точку новой рамки, а две других - концы краевых векторов. Таким образом, аргументы, лежащие в пределах единичного квадрата, определяют рамку, которая содержится внутри исходной рамки. (define (transform-painter painter origin corner1 corner2) (lambda (frame) (let ((m (frame-coord-map frame))) (let ((new-origin (m origin))) (painter (make-frame new-origin (sub-vect (m corner1) new-origin) (sub-vect (m corner2) new-origin))))))) Вот как перевернуть изображение в рамке вертикально: (define (flip-vert painter) (transform-painter painter (make-vect 0.0 1.0) ; новая исходная точка (make-vect 1.0 1.0) ; новый конец edge1 (make-vect 0.0 0.0))) ; новый конец edge2 При помощи transform-painter нам нетрудно будет определять новые трансформации. Например, можно определить рисовалку, которая рисует уменьшенную копию исходного изображения в верхней правой четверти рамки: (define (shrink-to-upper-right painter) (transform-painter painter (make-vect 0.5 0.5) (make-vect 1.0 0.5) (make-vect 0.5 1.0))) Вот трансформация, которая поворачивает изображение на 90 градусов против часовой стрелки:29 (define (rotate90 painter) (transform-painter painter 29Rotate90 представляет собой чистый поворот только для квадратных рамок, поскольку она еще растягивает и сплющивает изображение так, чтобы оно уместилось в повернутой рамке. (make-vect 1.0 0.0) (make-vect 1.0 1.0) (make-vect 0.0 0.0))) А эта сжимает изображение по направлению к центру рамки:30 (define (squash-inwards painter) (transform-painter painter (make-vect 0.0 0.0) (make-vect 0.65 0.35) (make-vect 0.35 0.65))) Преобразования рамок являются также основой для определения средств комбинирования двух или более рисовалок. Например, процедура beside берет две рисовалки, трансформирует их так, чтобы они работали соответственно в левой и правой половинах рамки-аргумента, и создает новую составную ри-совалку. Когда составной рисовалке передается рамка, она вызывает первую из преобразованных рисовалок над левой половиной рамки, а вторую над правой половиной: (define (beside painter1 painter2) (let ((split-point (make-vect 0.5 0.0))) (let ((paint-left (transform-painter painter1 (make-vect 0.0 split-point (make-vect 0.0 (paint-right (transform-painter painter2 split-point (make-vect 1.0 (make-vect 0.5 (lambda (frame) (paint-left frame) (paint-right frame))))) Обратите внимание, как абстракция данных, и особенно представление рисо-валок в виде процедур, облегчает реализацию beside. Процедуре beside не требуется ничего знать о деталях рисовалок-компонент, кроме того, что каждая из них что-то изобразит в указанной ей рамке. Упражнение 2.50. Определите преобразование flip-horiz, которое обращает изображение вокруг горизонтальной оси, а также преобразования, которые вращают рисовалки против часовой стрелки на 180 и 270 градусов. Упражнение 2.51. Определите для рисовалок операцию below. Below принимает в качестве аргументов две рисовалки. Когда получившейся рисовалке передается рамка, она рисует в нижней ее половине при помощи первой рисовалки, а в верхней при помощи второй. Определите below двумя способами - один раз аналогично процедуре beside, как она приведена выше, а второй раз через beside и операции вращения (см. упражнение 2.50). 30Ромбовидные изображения на рисунках 2.10 и 2.11 были получены с помощью squash-inwards, примененной к wave и rogers. 0.0) 1.0))) 0.0) 1.0)))) |
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||