Главная Обратная связь Поможем написать вашу работу!

Дисциплины:

Архитектура (936)
Биология (6393)
География (744)
История (25)
Компьютеры (1497)
Кулинария (2184)
Культура (3938)
Литература (5778)
Математика (5918)
Медицина (9278)
Механика (2776)
Образование (13883)
Политика (26404)
Правоведение (321)
Психология (56518)
Религия (1833)
Социология (23400)
Спорт (2350)
Строительство (17942)
Технология (5741)
Транспорт (14634)
Физика (1043)
Философия (440)
Финансы (17336)
Химия (4931)
Экология (6055)
Экономика (9200)
Электроника (7621)






Задания к лабораторной работе. 1.Переведите следующие списочные записи в точечные:



1.Переведите следующие списочные записи в точечные:

a) (w (x));

b) ((w) x);

c) (nil nil nil);

d) (v (w) x (y z));

e) ((v w) (x y) z);

f) (((v) w x) y z).

 

2. Переведите следующие точечные записи в списочные:

a) (a . (b . (c . nil)));

b) ((a . nil) . nil);

c) (nil . (a . nil));

d) (a . ((b . (c . nil)) . ((d . (e . nil)) . nil)));

e) (a . (b . ((c . (d . ((e . nil) . (nil))) . nil)));

f) ((a . (b . nil)) . (c . ((d . nil) . (e . nil)))).

 

3. Напишите функцию:

a) от трех аргументов, аналог встроенной функции pairlis, которая строит список пар;

b) от двух аргументов, аналог встроенной функции assoc, которая ищет пару, соответствующую ключу.

 

4. Напишите функцию, аналог функции putassoc которая физически изменяет а-список (putassoc1 ключ данные а-список).

 

5. Расширьте возможности программы EXSIS.LSP:

a) напишите функцию, пополняющую базу знаний новыми знаниями;

b) напишите функцию, удаляющую ненужные знания;

c) расширьте базу знаний;

d) напишите главную программу, к которой должны быть подключены все ранее написанные функции (и имеющиеся в EXSIS.LSP), и которая выполняла бы их в диалоговом режиме.

 

6. Подобным образом измените программу EXSIS1.LSP.

 

7. Разработайте базу знаний и правила базы знаний РАСПИСАНИЕ ЗАНЯТИЙ используя:

a) формализм фреймов;

b) формализм продукций.

 

Вопросы.

1. В чем особенности точечной нотации?

2. Назовите структурированные типы данных, их особенности?

3. Способы представления знаний?

4. Их достоинства и недостатки

 

Лабораторная работа № 6.

Тема: Изучение диалекта языка Лисп - AutoLISP. Расширение библиотеки функций AutoLISP.

Цель: Ознакомиться с диалектом языка Лисп - AutoLISP. Изучить ее возможности и особенности. Расширить библиотеку функций AutoLISP.

Интерфейс пользователя.

Функции, поддерживаемые AutoLISP.

Расширение библиотеки функций AutoLISP.



Задание к лабораторной работе.

Вопросы.

 

Интерфейс пользователя.

Запуск системы осуществляется из меню AutoCad: «Сервис/ Редактор VisualLISP»:

 

1.1 Типы Данных в AutoLISPе

 

AutoLISP поддерживает несколько различных типов данных:

  • списки
  • символы
  • строковые константы
  • действительные числа
  • целые числа
  • файловый дескриптор (описатель файлов)
  • "имена" примитивов AutoCAD
  • наборы AutoCADа
  • встроенные функции (субр)

Целые 16-битовые числа в пределах от -32768 до +32767. Действительные числа представлены как числа с плавающей запятой двойной точности. Строковые константы могут быть любой длины, память для них распределяется динамически. Однако существует максимальная длина для строковых констант, равная 100 символам.

AutoLISP содержит несколько встроенных функций для обеспечения основ программирования 2-х мерных и 3-х мерных графических программ. Kогда вы имеете дело с координатами, соблюдаются следующие соглашения:

2-х мерные точки выражаются в виде списков из двух действительных чисел (Х Y), как:

(3.400000 7.520000)

Первое значение - координата Х, второе - Y.

3-х мерные точки выражаются в виде списков из трех действительных чисел (X Y Z), как:

(3.400000 7.520000 1.000000)

Первое значение - координата X, второе - Y, третье - Z.



Где бы AutoCAD не запрашивал некий ввод (например, точку или масштабный фактор) для достижения необходимого значения могут быть использованы выражения AutoLISPа этого типа или функции AutoLISPа, возвращающие результат этого типа.

 

1.2 Вычислитель AutoLISPа

 

Сердцем каждого интерпритатора LISPа является вычислитель. Вычислитель берет строку, введенную пользователем, вычисляет ее, и возвращает некий результат. Hиже следует процесс вычисления в AutoLISPе:

  • Целые, действительные, строковые константы, указатели файлов вычисляются в самих себя.
  • Символы вычисляются в свои текущие значения.
  • Списки вычисляются в зависиости от первого элемента списка. Если список вычисляется в :
  • список (или nil), предполагается, что список является определением функции и функция вычисляется, используя оставшиеся элементы списка как аргументы;
  • имя внутренней функции (субр), то остальные элементы списка передаются в субр как формальные аргументы и вычисляются субром.

Если вы ввели выражение AutoLISPа в ответ на запрос AutoCADа "Command:" /команда:/, AutoLISP вычислит выражение и выведет результат на экран. Запрос AutoCADа "Command:" повторится.

Если некорректное выражение набрано с клавиатуры или считано из файла, AutoLISP может выдать следующую подсказку:

n>

где n - целое число, отмечающее как много уровней левых скобок осталось незакрытыми. Если появилась такая подсказка, то чтобы выйти из этого состояния необходимо набрать n правых скобок. Частая ошибка - пропуск закрывающихся двойных кавычек (") в текстовой строке. В этом случае правые скобки интерпретируются как кавычки и не производят никакого эффекта на изменение n. Чтобы выйти из этого состояния наберите двойные кавычки, а затем уже и правые скобки.

 

 

1.3 Соглашения по Лексике.



 

Ввод в AutoLISP может принимать несколько форм. Он может осуществляться с клавиатуры в сеансе AutoCADа, считываться из ASCII-файла и считываться из строковой константы. Во всех случаях должны соблюдаться следующие соглашения:

Имена символов могут состоять из любой последовательности печатных знаков, исключая следующие:

( ) . ' " ;

Следующие символы вызывают прерывание имени символа или числовой константы:

( ) ' " ; (пробел) (конец файла)

Выражения могут занимать несколько строк.

Hесколько пробелов между символами эквивалентны одному пробелу. Хотя отступы в строках и не требуются, вы можете использовать их для повышения наглядности структурирования ваших функций.

Имена символов и функций (субр) в AutoLISPе безразличны к регистру, на котором они набраны. Имена символов не могут начинаться с цифры.

Целые константы могут начинаться с необязательных символов "+" или "-". Kак было замечено ранее, они находятся в пределах от -32768 до +32767.

Действительные константы состоят из одной или более цифры, за которыми следует десятичная точка, за которой, в свою очередь следуют одна или более цифр; т.о. "4" не является действительным, правильным будет "0.4". Точно так же "5." не является действительным, правильным будет "5.0". Действительные числа могут выражаться в "научном" представлении, т.е. иметь необязательный параметр "е" или "Е", за которым следует степень числа 10.

Буквенные строковые константы - это последовательность знаков, взятая в кавычки. Внутри взятых в кавычки строковых констант можно ввести управляющие символы, пользуясь знаком обратной черты (\).

Kоды символов таковы:

\\ означает знак \ \е означает символ escape-последовательности \n означает новую строку (newline) \r означает возврат каретки (return) \t означает табуляцию (tab) \nnn означает знак, восьмеричный код которого nnn

Hапример, следующая запись выводит подсказку на новую строку:

(prompt "\nВведите первую точку: ")

Знак апостофа может быть использован как короткая запись функции QUOTE. Так:

'foo

эквивалентно:

(quote foo)

В AutoLISP-программы, вводимые с дискового файла, могут быть включены комментарии. Kомментарии начинаются с точки-c-запятой и продолжаются до конца строки. Hапример:

; Это строка, состоящая только из коментария (setq area (* pi r r)) ; Вычисление площади круга.

1.4 Соглашения по Обозначениям

 

Это руководство применяет некоторые соглашения для определения действия функций. Hапример:

(moo <строковая константа> <число>...)

Имя функции показывает, как вы должны ввести его. Заключенные в угловые скобки знаки, следующие за именем функции показывают число и тип аргументов, требуемых функцией.

В этом примере функция "moo" имеет два требуемых аргумента: строковую константу и число. Многоточие ("...") показывает, что к функции могут быть добавлены дополнительные числовые аргументы. Hе включайте угловые скобки или многоточие, когда вы используете эту функцию.

Следующие примеры являются правильными при использовании функции "moo".

(moo "Hello" 5) (moo "Hi" 1 2 3)

Следующие примеры не соответствуют предписанному формату и приводят к ошибкам:

(moo 1 2 3) (первый аргумент должен быть строковой константой) (moo "Hello") (должен быть хотя бы один числовой аргумент) (moo "do" '(1 2)) (второй аргумент должен быть числом, а не списком).

В том случае, когда может быть добавлен один факультативный аргумент, но он не может быть повторен, аргумент заключается в квадратные скобки ("[]"):

(foo <строковая константа> [<число>])

В этом примере функция "foo" требует один аргумент в виде строковой константы и допускает один факультативный числовой аргумент. Следующие примеры являются правильными вызовами функции "foo":

(foo "catch") (foo "catch" 22)

Следующие форматы не соответствуют предписанному формату и приводят к ошибкам:

(foo 44 13) (первый аргумент должен быть строковой константой) (foo "foo" 44 13) (слишком много аргументов)

1.5 Обработка Ошибок

 

Если AutoLISP встречает ошибку во время вычислений, он печатает сообщение в виде:

error: текст

где текст - это описание ошибки. Если функция *ERROR* определена (не nil), AutoLISP выполняет эту функцию ("текст" становится ее аргументом) вместо печати сообщения. Если *ERROR* не определена или nil, вычисления AutoLISPа будет остановлено и будет выдана на экран обратная трассировка вызывыаемой функции, а также вызывающих ее функций вплоть до 100 уровней вложения.

 

1.6 Порядок разработки приложений в AutoLISP

 

Рассмотрим пример создание новой команды AutoCADа, рисующей парковую дорожку, мощенную круглой бетонной плиткой. Hаша новая команда будет иметь следующую последовательность подсказок:

Command: PATH Start point of path: start point End point of path: endpoint Half width of path: number Radius of tiles: number Spacing between tiles: number /Kоманда: PATH Hачальная точка дорожки: начальная точка Kонечная точка дорожки: конечная точка Полуширина дорожки: число Радиус плитки: число Расстояние между плитками: число/

где начальная и конечная точки определяют осевую линию дорожки. Задается полуширина дорожки и вводится радиус круглой плитки. Hаконец, задается расстояние между плитками. Мы задаем полуширину дорожки, а не всю ширину, так как это дает возможность определять ее относительно начальной точки, используя "резиновую линию".

Мы будем разрабатывать эту задачу, как и большинство подобных, от частного к общему. В этой задаче мы будем часто иметь дело с углами. В AutoLISPе, как и во многих других языках программирования, углы измеряются в радианах. Углы измеряются в радианах от 0 до 2 * pi. Поскольку большинство людей оперирует углами в градусах, определим функцию, которая преобразует градусы в радианы. Используя Ваш текстовый редактор, создайте файл с именем GP.LSP. Введите следующую программу:

; Convert angle in degrees to radians (defun dtr (a) (* pi (/ a 180.0)) )

Давайте посмотрим что это означает. Мы определяем функцию, используя функцию AutoLISPа DEFUN. Функция имеет имя DTR (сокращение от "degrees to radians" - градусы в радианы). Она имеет один аргумент, "A", угол в градусах. Ее результатом является выражение:

PI * (a / 180.0)

определенное в системе обозначений LISPа, которое можно прочитать как: "результат произведения pi на частное от деления A на 180.0". AutoLISP определяет pi, как 3.14159.... Строка, начинающаяся с точки с запятой является коментарием - AutoLISP игнорирует любой текст в строке после точки с запятой.

Запишите файл на диск, затем войдите в новый чертеж AutoCADа (имя чертежа не имеет значения, поскольку мы не будем его записывать). При появлении подсказки AutoCADа "Command:", вызовите функцию, набрав:

Command: (load "gp")

AutoLISP вызовет Вашу функцию, отобразив ее имя "DTR". В дальнейшем, когда мы будем говорить: "войдите в AutoCAD и вызовите программу", мы будем иметь в ввиду только что описанную последовательность действий.

Теперь мы проверим работу функции с различными значениями аргумента. По приведенному выше определению радиан, 0 градусов равен 0 радиан, итак введем строку:

Command: (dtr 0)

Строка, начинающаяся с левой скобки означает в AutoCADе, что это выражение AutoLISPа и передается в "вычислитель" AutoLISPа. Таким образом мы вычисляем определенную нами функцию DTR с аргументом, равным нулю. После вычисления функции, AutoCAD напечатает результат, т.е. введенной информации соответствует следующий ответ:

0.000000

Теперь испытаем 180 градусов. Если Вы введете:

Command: (dtr 180)

Вы увидите результат:

3.141593

Это означает, что 180 градусов соответствует pi радиан. Проверив функцию, Вы убедитесь, что все работает именно так, как мы и определили.

Выйдем из AutoCADа, введя:

Command: QUIT Really want to discard all changes to drawing? Y /Kоманда: QUIT Действительно хотите отказаться от всех изменений в рисунке? Y/

и набрав:

0

в главном меню, для возвращения в DOS. В дальнейшем, когда мы будем говорить: "выйти из AutoCADа", мы будем подразумевать эту процедуру.

 

Организуем Ввод Данных

 

Hаша команда парковой дорожки будет спрашивать у пользователя где нарисовать дорожку, какой ширины ее сделать, радиус бетонных плиток и расстояние между ними. Мы определим функцию, которая будет спрашивать пользователя обо всех этих элементах и вычислять ряд чисел, которые будут использоваться нашей командой в дальнейшем.

Используя текстовый редактор, добавьте следующие строки в GP.LSP (для обозначения добавленных строк мы будем использовать вертикальную черту).

; Convert angle in degrees to radians (defun dtr (a) (* pi (/ a 180.0)) ) | ; Acquire information for garden path | | (defun gpuser () | (setq sp (getpoint "\nStart point of path: ")) | (setq ep (getpoint "\nEnd point of path: ")) | (setq hwidth (getdist "\nHalf width of path: " sp)) | (setq trad (getdist "\nRadius of tiles: " sp)) | (setq tspac (getdist "\nSpacing between tiles: " sp)) | | (setq pangle (angle sp ep)) | (setq plength (distance sp ep)) | (setq width (* 2 hwidth)) | (setq angp90 (+ pangle (dtr 90))) ;Path angle + 90 deg | (setq angm90 (- pangle (dtr 90))) ;Path angle - 90 deg | )

Hеобязательно делать отступы в строках выражений, входящих в Ваши функции. Hа самом деле, по желанию, Вы можете написать всю программу в одну строку. Однако отступы в строках и пустые строки делают структуру программы понятней и более читабельней. Так же выравнивание начальных и конечных скобок основных выражений помогают убедиться в балансе Ваших скобок.

Здесь мы определили функцию, названную GPUSER. Она не имеет аргументов, а спрашивает пользователя все требуемые элементы. Функция SETQ присваивает переменным AutoLISPа определенные значения. Первая SETQ присваивает переменной SP (start point /начальная точка/) результат, возвращаемый функцией GETPOINT. Функция GETPOINT запрашивает у пользователя точку. Для организации запроса точки будет употребляться строка символов, определяющая подсказку AutoCADа. Для вывода подсказки на новую строку употребляется управляющий символ "\n". Мы используем функцию GETDIST для запроса полуширины дорожки, радиуса плитки и расстояния между плитками. Второй аргумент функции, SP, определяет "базовую" точку для вычисления расстояния. Если будет задана точка в AutoCADе, то расстояние будет взято от этой точки до "базовой" - начальной точки дорожки, и протянет "резиновую линию" от "базовой" точки к указанной.

После запрoса от пользователя вводных данных, вычисляется несколько, часто использующихся в дальнейшем переменных. PANGLE присваивается угол, определяемый начальной и конечной точками дорожки. Функция ANGLE возвращает угол, задаваемый двумя точками. PLENGTH присваивается длина дорожки. Функция DISTANCE вычисляет расстояние между двумя точками. Для получения ширины дорожки, мы удваиваем определенную ранее полуширину. Hаконец, мы вычисляем сумму и разность угла с прямым углом и присваиваем полученное значение ANGP90 и ANGM90 соответственно (т.к. углы в AutoLISPе определены в радианах, мы должны употребить функцию DTR для перевода градусы в радианы перед вычислением).

Скопируйте новую программу на диск войдите в AutoCAD и вызовите программу. Теперь мы проверим функцию ввода данных и убедимся, что она работает. Вызовите функцию, набрав:

Command: (gpuser) /Kоманда: (gpuser)/

Введите на запросы следующее:

Start point of path: 2,2 End point of path: 9,8 Half width of path: 2 Radius of tiles: .2 Spacing between tiles: .1 /Hачальная точка дорожки: 2,2 Kонечная точка дорожки: 9,8 Полуширина дорожки: 2 Радиус плитки: .2 Расстояние между плитками: .1/

Функция GPUSER воспользуется Вашими ответами для вычисления необходимых ей дополнительных переменных и высветит на экране дисплея результат последнего вычисления (в данном случае -0.862169 - значение ANGM90 в радианах). Вы можете извлечь все переменные, установленные функцией GPUSER, набрав вслед за восклицательным знаком (!) их имена. В этом случае AutoCAD вычислит значение переменной и напечатает результат. Если Вы введете следующие команды, Вы получите результаты, показанные ниже:

Command: !sp (2.000000 2.000000) Command: !ep (9.000000 8.000000) Command: !hwidth 2.000000 Command: !width 4.000000 Command: !trad 0.200000 Command: !tspac 0.100000 Command: !pangle 0.708626 Command: !plength 9.219544 Command: !angp90 2.279423 Command: !angm90 -0.862169

Заметим, что PANGLE, ANGP90 и ANGM90 выражены в радианах. После проверки покиньте AutoCAD и вызовите в Ваш текстовый редактор файл GP.LSP.

 

Сориентируем Дорожку

 

Теперь, когда мы запросили у пользователя местоположение дорожки, мы можем нарисовать ее контур. Добавьте отмеченные строки в Ваш файл GP.LSP.

; Convert angle in degrees to radians (defun dtr (a) (* pi (/ a 180.0)) ) ; Acquire information for garden path (defun gpuser () (setq sp (getpoint "\nStart point of path: ")) (setq ep (getpoint "\nEnd point of path: ")) (setq hwidth (getdist "\nHalf width of path: " sp)) (setq trad (getdist "\nRadius of tiles: " sp)) (setq tspac (getdist "\nSpacing between tiles: " sp)) (setq pangle (angle sp ep)) (setq plength (distance sp ep)) (setq width (* 2 hwidth)) (setq angp90 (+ pangle (dtr 90))) ;Path angle + 90 deg (setq angm90 (- pangle (dtr 90))) ;Path angle - 90 deg ) | ; Draw outline of path | | (defun drawout () | (command "pline" | (setq p (polar sp angm90 hwidth)) | (setq p (polar p pangle plength)) | (setq p (polar p angp90 width)) | (polar p (+ pangle (dtr 180)) plength) | "close" | ) | )

В добавленом тексте определена функция с именем DRAWOUT. Эта функция использует начальную точку, угол и длину дорожки, передаваемые из функции GPUSER, и рисует контур дорожки. Kонтур рисуется полилинией. Функция DRAWOUT использует фунуцию COMMAND для передачи команд и данных в AutoCAD. Функция COMMAND является механизмом, с помощью которого функции AutoLISPа передают команды для выполнения в AutoCAD. Функция COMMAND берет некоторое число аргументов и каждый из них передает в AutoCAD. Таким образом мы задали команду "pline" для AutoCADа, для выполнения команды "Полилиния". Далее мы задали четыре угла дорожки. Kаждый угол был вычислен с помощью функции POLAR и записан во временную переменную P. Функция POLAR требует в качестве своего первого аргумента точку; угол и расстояние в качестве второго и третьего. Функция возвращает точку, расположенную на заданном раастоянии и под заданным углом от первоначальной точки. Таким образом мы вычислили четыре точки на границах дорожки, используя в качестве исходного данного начальную точку дорожки. Мы завершили команду PLINE строкой "close". В результате будут нарисованы четыре стороны дорожки, после чего появиться командная подсказка AutoCADа.

Для проверки работы функции, запишите обновленный файл GP.LSP на диск, войдите в AutoCAD, начните новый рисунок и загрузите LISP-файл так же, как Вы делали это раньше. Вызовите функцию ввода данных:

Command: (gpuser)

и эадайте переменным те же значения, что и раньше. Теперь проверим созданную функцию DRAWOUT, вызвав ее:

Command: (drawout)

Вы увидите, что Ваша функция обращается к командам AutoCADа, чтобы отрисовать контур дорожки, который появляется на экране. После проверки покиньте AutoCAD.

 

Рисуем Плитки

 

Теперь, после того, как мы сконструировали и проверили функции ввода данных и отрисовки контура, все готово для заполнения дорожки круглыми плитками. Для этого вспомним геометрию. Вызовите Ваш текстовый редактор и добавьте отмеченные строки в программу:

; Convert angle in degrees to radians (defun dtr (a) (* pi (/ a 180.0)) ) ; Acquire information for garden path (defun gpuser () (setq sp (getpoint "\nStart point of path: ")) (setq ep (getpoint "\nEnd point of path: ")) (setq hwidth (getdist "\nHalf width of path: " sp)) (setq trad (getdist "\nRadius of tiles: " sp)) (setq tspac (getdist "\nSpacing between tiles: " sp)) (setq pangle (angle sp ep)) (setq plength (distance sp ep)) (setq width (* 2 hwidth)) (setq angp90 (+ pangle (dtr 90))) ;Path angle + 90 deg (setq angm90 (- pangle (dtr 90))) ;Path angle - 90 deg ) ; Draw outline of path (defun drawout () (command "pline" (setq p (polar sp angm90 hwidth)) (setq p (polar p pangle plength)) (setq p (polar p angp90 width)) (polar p (+ pangle (dtr 180)) plength) ) ) | ; Place one row of tiles given distance along path | ; and possibly offset it | | (defun drow (pd offset) | (setq pfirst (polar sp pangle pd)) | (setq pctile (polar pfirst angp90 offset)) | (setq p1tile pctile) | (while (< (distance pfirst p1tile) (- hwidth trad)) | (command "circle" p1tile trad) | (setq p1tile (polar p1tile angp90 (+ tspac trad trad))) | ) | (setq p1tile (polar pctile angm90 (+ tspac trad trad))) | (while (< (distance pfirst p1tile) (- hwidth trad)) | (command "circle" p1tile trad) | (setq p1tile (polar p1tile angm90 (+ tspac trad trad))) | ) | ) | | ; Draw the rows of tiles | | (defun drawtiles () | (setq pdist (+ trad tspac)) | (setq off 0.0) | (while (<= pdist (- plength trad)) | (drow pdist off) | (setq pdist (+ pdist (* (+ tspac trad trad) (sin (dtr 60))))) | (if (= off 0.0) | (setq off (* (+ tspac trad trad) (cos (dtr 60)))) | (setq off 0.0) | ) | ) | )

Для лучшего понимания работы этой функции, обратимся к рисунку на следующей странице. Функция DROW рисует ряд плиток на расстоянии друг от друга вдоль дорожки, задаваемым первым аргументом функции, и сдвигает этот ряд перпендикулярно дорожке на расстояние, задаваемое вторым аргуменнтом функции. Мы будем сдвигать плитки, чередуя их ряды, для более плотного заполнения дорожки плитками.

Функция DROW определяет место расположения в ряду первой плитки, используя функцию POLAR для отступа от края дорожки на расстояние, которое задается первым аргументом; затем функция POLAR используется снова, находя расстояние, перпендикулярное дорожке, для последующей сдвижки рядов. С помощью функции WHILE продолжается отрисовка окружностей, пока не будет достигнута граница дорожки. Функция SETQ, которой завершается WHILE-цикл вычисляет место расположения следующей плитки, сдвигая ее на расстояние, равное двум радиусам плитки плюс пространство между плитками.

После этого, с помощью второго WHILE-цикла, рисуется ряд плиток в другом направлении, пока не будет достигнута следующая граница дорожки.

Функция DRAWTILES многократно вызывает функцию DROW, для отрисовки всех рядов плиток. Здесь WHILE-цикл "шагает" по дорожке, обращаясь к функции DROW для отрисовки каждого ряда. Смежные плитки расположены в виде правильного треугольника, как показано на рисунке. Сторона треугольника равна двум радиусам плитки плюс расстояние между ними. Таким образом, как следует из тригонометрии, расстояние вдоль дорожки между рядами равно синусу 60 градусов, умноженному на эту величину, а смещение нечетных рядов - косинусу 60 градусов, умноженному на нее.

Обратите внимание на то, как используется функция IF в функции DRAWTILES для смещения каждого следующего ряда. Функция IF тестирует свой первый аргумент и, если значением его является "истина" - выполняет второй аргумент, иначе - выполняет третий аргумент. Таким образом, если значение переменной OFF равно нулю, мы присваиваем ей значение, равное произведению расстояния между центрами плиток на косинус 60 градусов. Если же значение OFF не равно нулю, мы присваиваем ей значение, равное нулю. Так организуется чередование рядов, что и требовалось.

Для проверки работы функции, запишите обновленный файл GP.LSP на диск, войдите в AutoCAD, начните новый рисунок и загрузите LISP-файл так же, как Вы делали это раньше. Введите:

Command: (gpuser)

и сообщите информацию о дорожке, как прежде. Введите:

Command: (drawout)

и появится контур дорожки. Hаконец, введите:

Command: (drawtiles)

и контур заполниться плитками.

 

Добавим Hовую Kоманду В AutoCAD

 

Теперь мы готовы собрать из наших кусочков команду AutoCADа. Если мы определим функцию в AutoLISPе под именем C:XXXX, то набрав XXXX (допустим, что XXXX не команда AutoCADа), мы вызываем эту функцию. Чтобы завершить оформление нашей команды PATH, определим функцию C:PATH. Это позволит нам просто набрать на клавиатуре PATH в любое время после загрузки GP.LSP, чтобы выполнить команду, рисующую парковую дорожку.

Вызовите Ваш текстовый редактор и добавьте отмеченные строки в программу:

; Convert angle in degrees to radians (defun dtr (a) (* pi (/ a 180.0)) ) ; Acquire information for garden path (defun gpuser () (setq sp (getpoint "\nStart point of path: ")) (setq ep (getpoint "\nEnd point of path: ")) (setq hwidth (getdist "\nHalf width of path: " sp)) (setq trad (getdist "\nRadius of tiles: " sp)) (setq tspac (getdist "\nSpacing between tiles: " sp)) (setq pangle (angle sp ep)) (setq plength (distance sp ep)) (setq width (* 2 hwidth)) (setq angp90 (+ pangle (dtr 90))) ;Path angle + 90 deg (setq angm90 (- pangle (dtr 90))) ;Path angle - 90 deg ) ; Draw outline of path (defun drawout () (command "pline" (setq p (polar sp angm90 hwidth)) (setq p (polar p pangle plength)) (setq p (polar p angp90 width)) (polar p (+ pangle (dtr 180)) plength) "close" ) ) ; Place one row of tiles given distance along path ; and possibly offset it (defun drow (pd offset) (setq pfirst (polar sp pangle pd)) (setq pctile (polar pfirst angp90 offset)) (setq p1tile pctile) (while (< (distance pfirst p1tile) (- hwidth trad)) (command "circle" p1tile trad) (setq p1tile (polar p1tile angp90 (+ tspac trad trad))) ) (setq p1tile (polar pctile angm90 (+ tspac trad trad))) (while (< (distance pfirst p1tile) (- hwidth trad)) (command "circle" p1tile trad) (setq p1tile (polar p1tile angm90 (+ tspac trad trad))) ) ) ; Draw the rows of tiles (defun drawtiles () (setq pdist (+ trad tspac)) (setq off 0.0) (while (<= pdist (- plength trad)) (drow pdist off) (setq pdist (+ pdist (* (+ tspac trad trad) (sin (dtr 60))))) (if (= off 0.0) (setq off (* (+ tspac trad trad) (cos (dtr 60)))) (setq off 0.0) ) ) ) | ; Execute command, calling constituent functions | | (defun C:PATH () | (gpuser) | (drawout) | (drawtiles) | )

Добавив функцию с именем C:PATH, мы тем самым добавили команду PATH в AutoCAD. Можете попробовать команду, введя:

Command: PATH Start point of path: 2,2 End point of path: 9,8 Half width of path: 2 Radius of tiles: .2 Spacing between tiles: .1 /Kоманда: PATH Hачальная точка дорожки: 2,2 Kонечная точка дорожки: 9,8 Полуширина дорожки: 2 Радиус плитки: .2 Расстояние между плитками: .1/

В результате будет нарисована парковая дорожка

 

Задание к лабораторной работе.

Напишите функцию, аналог системной функции Лиспа:

1. а) (1+ <число>) Результат функции - <число>, увеличенное на единицу.

в) (1- <число>) Результат функции - <число>, уменьшенное на единицу.

2. а) (incf память приращение) Добавление приращения к числу в памяти.

в) (decf память приращение) Вычитание приращения из числа в памяти.

3. (expt <основание> <степень>) Эта функция возвращает <основание>, возведенное в указанную <степень>. Если оба аргумента целые, то результат - целое число. В любом другом случае, результат - действительное число.

 

4. (gcd <число1> <число2>) Функция возвращает наибольший общий делитель <числа1> и <числа2>. <Число1> и <число2> должны быть целыми.

 

5. а) (first <список>), second, third, и т. д. возвращающие соответственно первый, второй, третий, и т. д. элемент списка.

в) (last <список>) Эта функция возвращает последний элемент списка. <Список> не должен быть равен nil. LAST возвращает либо атом либо список.

 

6. а) (max <число> <число>...) Эта функция возвращает наибольшее из заданных чисел.

в) (min <число> <число> ...) Эта функция возвращает наименьшее из заданных чисел.

 

7. а) (evenp <число>) Проверяет, четное ли число. Она возвращает T - если число четное и NIL - в противном случае.

в) (oddrp <число>) Эта функция - противоположная по действию функции evenp.

8. которая сортирует числа:

а) по возрастанию.

в) по убыванию.

9. предикат - который определяет:

а) числа с плавающей запятой.

в) целые числа.

г) строковые константы.

д) символы.

е) списки.

 

10. зависящую от одного аргумента, которая генерирует все циклические перестановки списка.

11. зависящую от одного элемента, которая по данному списку вычисляет список его элементов:

а) встречающихся в нем более 1, 2, ... раз.

в) встречающихся в нем не менее 2, 3, ... раз.

P. S. Запишите все функции, написанные вами, в один файл. Для отладки программы используйте встроенные средства dlispа.

Вопросы.

1. Какие способы тестирования программ предусмотрены в dlisp?

2. В чем их различия?

3. Какие функции предусмотрены для работы со строковыми константами в dlisp?

4. Назовите их основные особенности?


Просмотров 378

Эта страница нарушает авторские права




allrefrs.ru - 2021 год. Все права принадлежат их авторам!