Вы находитесь на странице: 1из 194

ГЛАВА 1.

ВВЕДЕНИЕ
_________________________________________________________________

AutoLISP является реализацией языка программрования LISP, в


рамках пакета ADE-3 системы AutoCAD. AutoLISP дает возможность
пользователям и разработчикам системы AutoCAD писать макросы и
функции, ориентируясь на машинную графику языковых средств высокого
уровня. Язык программирования LISP прост для изучения и использования
и обладает большой гибкостью.

ВНИМАНИЕ: Для эффективной работы с Автокадом совсем не обязательно


уметь программировать на Автолиспе: при отсутствии опыта
программирования ,вполне достаточно ознкомиться с
процедурой установки (инсталляции) Автолиспа,описанной в
главе 2.
Если же программирование доставляет вам удовольствие,то
следует прочитать все Руководство: владея
Автолиспом,можно превратить универсальную
систему,каковой является Автокад,в личный инструмент
графики.

Это руководство является справочным; оно не обучает


программированию на языке LISP. Несмотря на то, что в главе 3 и
приводится практический пример использования AutoLISPа, мы рекомендуем
приобрести различные тексты на языке LISP, с тем чтобы изучить язык
программирования. Можно воспользоваться книгами по языку LISP Уинстона
и Хорна (второе издание) и Looking at LISP Тони Хейзмера, обе книги
напечатаны в издательстве Эддисон Уэсли. Язык LISP имеет множество
диалектов: MacLISP, InterLISP, ZetaLISP и Common LISP. Язык AutoLISP
очень схож по синтаксису и условным обозначениям со стандартным
LISPом, хотя и является только маленьким подмножеством его и имеет ряд
дополнительных функций, которые характерны для AutoCAD. В этом
справочном руководстве включено описание всех функций AutoLISPа и даны
рекомендации по их использованию.

1.1 Почему Лисп ?

Лисп выбран в качестве интерфейсного языка Автокада по следующим


причинам:

- Лисп превосходно работает с наборами разнородных


объектов,образующих группы различного размера,с которыми обычно
манипулируют системы,подобные Автокаду;
- интерпретатор Лиспа идеально подходит для нестуктурированных
отношений,которые характерны для процесса проектирования;
- Лисп является одним из наиболее легких языков программирования;
- Лисп как правило является основным языком программирования в
научных исследованиях и разработках в области искуственного интеллекта
и экспертных систем;
- интерпретатор Лиспа занимает мало памяти ,благодаря очень
простому синтаксису языка и к тому же изучение его не вызывает
затрудненений !

Возможно, в будующем Автокад будет дополнен другими интерфейсными


языками. Однако фирма Автодеск и далее собирается поддерживать
Автолисп,рассматривая новые языки как дополнения к Автолиспу.
1.2. Типы данных в AutoLISP

Язык AutoLISP поддерживает несколько типов данных. Это

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

Целые являются 16-разрядными числами со знаком, поэтому диапозон


их составляет от -32768 до +32767.На 32-разрядных машинах целые числа
в Автолиспе представляются 32 двойчными разрядами и их значения могут
находиться в педелахот -2 147 483 648 до +2 147 483 647, хотя между
Автолиспом и Автокадом передаются только 16-разрядные числа.
Действительные числа представляются как числа с плавающей точкой с
двойной точнотстью.Память для них распределяется динамически,но
максимальная длина строковых констант ограничена ста символами .
AutoLISP содержит несколько встроенных функций для программирования
вычерчивания двумерных и трехмерных графических объектов. Для работы с
координатами предусмотрены следующие условные обозначения.

Двумерные точки - это списки, состоящие из двух вещественных


чисел (X,Y), например (3.400000 7.520000) Первое значение есть
координата X, а второе - координата Y.

Трехмерные точки - это списки, состоящие из трех вещественных


чисел (X Y Z) например (3.400000 7.520000 1.000000) Первое значениеэто
координата X, второе значение - координата Y и третье значение
-координата Z.

Всякий раз, когда система AutoCAD запрашивает ввод определенной


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

1.3. Вычислитель AutoLISPа

Центральное место интерпретатора занимает вычислитель. Он берет


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

- Целые, вещественные, строки, указатели файлов и встроенные функции


сами являются значениями,

- Символы имеют то значение, которое им присвоено,


- Списки оцениваются согласно первому элементу списка. Если
элементом является:

- список (или nil), то список считается определеним функции, а


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

Если вы в ответ на запрос "Command:" системы AutoCAD вводите


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

Если печатается или считывается из файла неправильное выражение,


AutoLISP может выдать запрос:

n>

где n является целым числом, указывающим на то, сколько уровней


левых скобок остается незакрытыми. Если появляется этот запрос, то,
чтобы выйти из данного состояния, вы должны ввести n правых скобок.
Стандартная ошибка заключается в том, что обычно забывают закрыть
кавычки в текстовой строке; в этом случае правые скобки
интерпретируются, как часть строки и не оказывают влияния на n. Чтобы
исправить такую ситуацию, введите кавычки, а затем n правых скобок.

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

Данные в AutoLISP можно вводить несколькими способами. Их можно


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

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


символов, кроме:

() . ' " ;

- Следующие символы будут завершать имя символа или числовую


константу:

() ' " ; пробел перевод строки

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

- Несколько пробелов между символами эквивалентно одному


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

- В именах символов и функций не не делается различий


между верхним и нижним регистрами AutoLISP. Имена не могут
начинаться с цифры.
- Целые константы могут начинаться со вспомогательного символа
"+" или "-". Как упоминалось ранее, диапозон их изменения от
-32768 до +32767.

- Вещественные константы состоят из одной или более цифр, за


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

- Символьными строками являются последовательности букв и цифр,


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

\\ означает символ обратной косой "\"


\e означает ESC
\n означает новую строку
\r означает возврат каретки
\t означает табуляцию /tab/
\nnn означает символ, восьмеричный код которого - nnn

Например, следующая функция выдаст запрос на новой строке

(prompt "\nEnter first point: ")

- Символ апострофа может использоваться в качестве сокращения для


функции QUOTE. Таким образом:

'foo

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

(quote foo)

- В загружаемые с диска программы AutoLISP могут включаться


комментарии. Комментарии начинаются с точки с запятой и
продолжаются до конца строки. Например:

; This entire line is comment


/Вся эта строка является комментарием/

(setq area (* pi r r )) ;Вычислить площадь круга

1.5. Условные обозначения

Для описания работы функций в этом справочном руководстве


используются следующие условные обозначения. Например:

(moo <string> <number> ... )

Имя функции записывается так, как оно должно вводиться. Элементы


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

В этом примере функция "moo" имеет два обязательных аргумента;


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

Учитывая формат вызова функции "moo", показанный выше, следующие


обращения к "moo" будут верными:

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

В следующих примерах предписанный формат не соблюдался,


результатом чего явились ошибки:

(moo 1 2 3 ) (первый аргумент должен быть строкой)


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

Когда необязательный аргумент появляется один раз, но не может


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

(foo <string> [<number>])

В данном случае входными данными для функции "foo" будет один


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

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

Ниже даны примеры ошибок из-за несоблюдения предписанного


формата:

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


(foo "foe" 44 13) (слишком много аргументов)

1.6. Обработка ошибок

Если AutoLISP в процессе оценки встречает ошибку, он печатает


следующее сообщение:

error: text

где text является описанием ошибки. Если определена функция


*ERROR* (не равная nil), AutoLISP выполняет эту функцию ("text"
передается

в качестве единственного аргумента) вместо того, чтобы печатать


сообщение. Если функция *ERROR* не определена, или если она получает
значение nil вычислитель AutoLISPа прекратит работу и протрассирует
вызывающую последовательность функций до глубины в 100 уровней.
ГЛАВА 2. УСТАНОВКА AutoLISPа

2.1. Комплект поставки


AutoLISP поставляется с копией системы AutoCAD, при наличии
пакета ADE-3. Никакой специальной установки не требуется.
Для операционных систем PC-DOS/MS-DOS файл"acadl.ovl" на
дистрибутивной дискете AutoCAD является оверлейным файлом
интерпретатора AutoLISPа.
Одна из дистрибутивных дискет системы AutoCAD включает файл под именем
"readme.doc". Выведите его на печать; он содержит самые последние
изменения или модификации документации системы AutoCAD и программного
обеспечения AutoLISP.
Для работы в операционных системах PC-DOS/MS-DOS поставляется
дополнительная версия Автолиспа ,так называемый Расширенный
Автолисп,содержащий файлы "acadlx.ovl", и "remlisp.exe".

2.2 Обычный Автолисп

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


Расширенный Автолисп.Для арботы с Автолиспом версии 10 необходимы:

- компьютер, на котором может работать Автокад,с оперативной


памятью не менее 640К и жестким диском;
- система Автокад версии 10 с модулем ADE-3.

2.2.1 Настройка

При настройке Автокада одним из рабочих параметров является


отключение Автолиспа по желанию пользователя.Кроме того ,в
операционных системах PC-DOS/MS-DOS конфигуратор дополнительно
запрашивает,будет ли использоваться Расширенный Автолисп.При
использовании обычного Автолиспа на этот запрос необходимо ответить
"НЕТ".(Подробнее см. Руководство по установке и эксплуатации системы
Автокад.)

2.2.2 Переменные среды

В системах PC-DOS/MS-DOS для Автолиспа должна быть выделена


определенная часть свободной оперативной памяти . В случае
одновременной работы с каким либо другим прикладным пакетом,таким как
Автокад AEC,следует ознакомиться с содержащимися в его описании
рекомендациями по установке значений переменных среды LISHEAP и
LISPSTACK.(Подробнее см.гл.6 настоящего Руководства.)

2.3 Расширенный Автолисп

Для работы расширенного Автолиспа версии 10 требуется:

- компьютер на базе микропроцессора типа Intel 80286 или 80386,на


котором может работать Автокад,с оперативной памятью не менее 640К и
жестким диском;

- не менее 512К байт расширенной памяти типа IBM AT extended


memory (не типа Lotus/Intel/Microsoft expended memory),не занятых для
других целей (таких как виртуальный диск);
- операционная система PC-DOS/MS-DOS версии 2.0 или выше ;

- система Автокад версии 10 с модулем ADE-3.

При наличии перечисленных устройств можно вместо обычного Автолиспа


выбрать Расширенный Автолисп.Он действует в "защищенном" режиме
микропроцессора 80286/80386 и размещается в расширенной памяти и
позволяет работать с большими по размеру программами и с большими
наборами данных,чем обычный Автолисп,Кроме того ,использование
Расширенного Автолиспа высвобождает всю оперативную память (640К) для
работы самого Автокада.Расширенный Автолисп не работает на компьютерах
класса PC/XT,так процессоры 8088 или 8086 не поддерживают "защищенный
режим работы.
Кроме различий в механизме использования памяти ,между обычным и
Расширенным Автолиспом разницы нет.Определения функций в Раширенном
Автолиспе остались прежними ,и программы написанные для обчного
Автолиспа,можно использовать без изменений.

2.3.1 Настройка

При настройке Автокада Автолисп можно отключить вообще.Кроме того,


в операционных системах PC-DOS/MS-DOS можно выбрать обычный или
Расширенный Автолисп. (Подробнее см. Руководство по установке и
эксплуатации системы Автокад.)

2.3.2 Переменные среды

Размером области расширенной памяти ,которая будет использоваться


Расширенным Автолиспом ,мжно управлять с помощью переменной среды
LISPXMEM.(Если переменная LISPXMEM не задана ,Расширенный Автолисп
использует всю имеющуюся расширенную память ,кроме занятой виртуальным
диском.) Расширенный Автолисп сообщает Автокаду,какую область памяти
он использует,делая тем самым эту область недоступной для
использования самим Автокадом.
Определенная часть расширенной памяти ,предназначенной для
Автолиспа,устанавливается для использования как область "стека".В
случае одновременной работы с каким либо другим прикладным
пакетом,таким как Автокад AEC,следует ознакомиться с содержащимися в
его описании рекомендациями по установке значения переменной среды
LISPSTACK . (Расширенный Автолиспн не использует переменную среды
LISPHEAP ).(Подробнее см.Руководство по установке и эксплуатации
системы Автокад и гл.6 настоящего руководства .)

2.3.3 Использование Расширенного Автолиспа

Расширенный Автолисп действует как самостоятельная программа


EXTLISP,котруюнеобходимо запустить перед запуском Автокада.EXTLISP
является резидентной программой,которая размещаеется в расширенной
памяти и связанной с Автокадом через оверлейный файл "acadlx.ovl".Для
автоматического запуска программы EXTLISP ее можно поместить в файл
"autoexec.bat".
Кроме того, программу EXTLISP можно удалить из памяти после
окончания сеанса работы с Автокадом.Для этого в ответ на подсказку
операционной системы следует ввести команду REMLISP.При этом REMLISP
возвращает в систему ту часть памяти ,которая была занята программой
EXTLISP.Если EXTLISP была последней загруженной резидентной
программой,то размер свободной памяти будет таким же ,как до запуска
программы EXTLISP.
2.4. Автоматический загрузчик функции - файл "acad.lsp"

Всякий раз, когда начинается сеанс Редактора чертежей системы


AutoCAD, AutoLISP загружает файл "acad.lsp" (если он есть). Вы можете
поместить определения часто используемых функций в этот файл, и они
будут автоматически оцениваться всякий раз, когда начинается
редактирование чертежа. Смотрите подробности описания функции DEFUN в
главе 4.

ГЛАВА 3. ПО тропинке - в AutoLISP


_________________________________________________________________

Большим преимуществом системы AutoCAD является возможность


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

внести в нее некоторые специальные средства, которыми вы часто


пользуетесь. Вы можете добавлять последовательн ости часто
используемых команд в экранные, клавишные меню или в меню планшета. Вы
можете определять новые типы линий, образцы штриховки или текстовые
шрифты. Если вы это делаете, то значит вы пользуетесь преиму ществами
открытой архитектуры системы AutoCAD - способностью расширять ее и
превращать в собственный, личный инструмент проектирования, отвечающий
уровню вашего интеллекта.
Наиболее мощным средством расширения системы AutoCAD является язык
AutoLISP. Это средство, предусмотренное во всех пакетах ADE-3 системы
AutoCAD, является реализацией языка программрования LISP,
подсоединенного к системе AutoCAD. Создавая программы на языке
AutoLISP, вы можете добавлять команды в AutoCAD и по сути
модифицировать систему, т.е. выходите на уровень разработчика
программного обеспечения.

Через несколько минут мы добавим новую команду в AutoCAD. В


процессе мы объясним, как действует AutoLISP и как им пользоваться.
Команда, которую мы хотим разработать, предназначена для планировки
садов или парков, но концепции програмирования одни и те же,
независимо от области применения.

3.1. Что необходимо знать, прежде чем приступить к созданию


команды

Мы предполагаем, что вы достаточно квалифицированный пользователь


системы AutoCAD - то есть, что вы знакомы с командами системы и общими
концепциями, используемыми в ней. Мы также предполагаем, что вы имеете
доступ к текстовому редактору, который создает файлы в кодах ASCII. Мы
будем давать текст программы, а вы, по желанию, можете использовать
текстовый редактор или нет.
В этом примере мы будем использовать многочисленные функции AutoLISPа.
В последующих главах данного руководства содержатся полные объяснения
всех этих функций.
3.2. Цель

Наша цель заключается в том, чтобы создать новую команду для


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

Commmand: PATH
Start point of path: начальная точка
End point of path: конечная точка
Half width of path: число
Radius of tiles: число
Spacing between tiles: число
/Команда ...
Начальная точка дорожки ...
Конечная точка дорожки ...
Половина ширина дорожки ...
Расстояние между плитами ... /

где начальная точка и конечная точка задают центральную линию дорожки.


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

3.3. Начало работы

Мы создадим эту прикладную программу по принципу снизу вверх. В


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

; Преобразование градусов в радианы

(defun dtr (a)


(* pi (/ a 180.0))
)

Давайте рассмотрим, что эта программа делает. Мы определяем


функцию, используя функцию DEFUN в AutoLISP. Эта функция называется
DTR (сокращение "преобразование градусов в радианы"). Она берет один
аргумент, "A", угол в градусах. Результатом ее работы является
выражение:

PI * (a / 180 . 0)

которое следует читать как " PI умножить на A и делить на 180.0".


PI заранее определяется в AutoLISPе как 3.14159... Строка,
начинающаяся с точки с запятой, является комментарием - AutoLISP
игнорирует весь текст строки после точки с запятой.

Запишите файл на диск, затем войдите в AutoCAD для создания


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

Command: (load "gp")

AutoLISP загрузит вашу функцию и выдаст ее имя "DTR". С этого


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

Теперь проверим функцию путем выполнения ее с различными


значения- ми. Из вышеупомянутого определения радианов, нулевые градусы
должны равняться нулевым радианам, поэтому введите строку:

Command: (dtr 0)

в систему AutoCAD. Если строка начинается с левой скобки, то


систе- ма AutoCAD передаст строку на оценку в 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
/Команда ...
Действительно хотите отменить все изменения чертежа? /

и ответьте вводом :

в главном меню для возврата в DOS. С этого момента, когда мы


будем говорить "Выйти из AutoCADа", мы будем иметь ввиду эту
процедуру.

3.4. Организация ввода данных

Наша команда вычерчивания садовой дорожки запросит у пользователя


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

; Преобразование градусов в радианы


(defun dtr (a)
(* pi (/ a 180.0))
)

│ ; Собрать информацию для вычерчивания садовой дорожки/

│ (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 "\nSpacing between tiles: " sp))
│ ; /... начальная точка дорожки...
│ ; ... конечная точка дорожки ...
│ ; ... половиннай ширины дорожки ...
│ ; ... расстояние между плитами .../

│ (setq pangle (angle sp ep))
│ (setq plength (distance sp ep))
│ (setq width (* 2 hwidth))
│ (setq angp90 (+ pangle (dtr 90))) ;Угол дорожки + 90 градусов
│ (setq angm90 (- pangle (dtr 90))) ; Угол дорожки - 90 градусов
│ )

Нет необходимости форматировать программу. Фактически, вы можете


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

Мы здесь определили функцию, именованную GPUSER. Ей не нужны


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

После того, как получен ввод от пользователя, вычисляется


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

Запишите обновленную программу на диск, войдите в AutoCAD и


загру- зите программу. Теперь мы проверим эту функцию ввода и
убедимся, что она работает соответствующим образом. Активизируйте
функцию вводом:

Command: (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 Расстояние между плитами.../

Функция GPUSER использует ваши ответы для вычисления


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

Command: !sp
(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.
3.5. Ориентация дорожки

Теперь, когда мы запросили у пользователя место расположения


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

(defun dtr (a)


(* pi (/ a 180.0))
)
;Сбор информации о дорожке

(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))) ;Угол дорожки в 90
(setq angm90 (-pangle (dtr 90))) ; Угол дорожки -90
)


│ ; Вычертить контур дорожки

│ (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, для вычерчивания контура дорожки. Контур
дорожки вычерчивается как полилиния. Функция DRAWOUT использует
функцию COMMAND для передачи команд и данных системе AutoCAD. Функция
COMMAND является механизмом, при помощи которого функции AutoLISPа
передают системе AutoCAD команды и данные для выполнения. Функция
COMMAND берет любое количество аргументов и передает каждый из них
системе AutoCAD. В этом случае мы передаем "pline" системе AutoCAD,
активизируя команду вычерчивания полилинии. Затем мы передаем четыре
вершины контура. Каждая вычисляется с помощью функции POLAR и
запоминается во временной переменой P. Первым аргументом функции POLAR
является точка, вторым - угол и третьим - расстояние. POLAR вычисляет
точ- ку, находящуюся на заданном расстоянии и под заданным углом от
началь- ной точки. В этом случае мы вычисляем четыре вершины контура
дорожку. Завершаем полилинию вводом строки "close", что дает
возможность вычер- тить четвертую сторону дорожки и вернуться к
запросу команды системы AutoCAD.

Чтобы проверить эту функцию, запишите обновленный файл GP.LSP,


начните новый чертеж и загрузите файл LISPа как ранее. Активизируйте
функцию ввода информации пользователя:

Command: (gpuser)

и введите данные, как в последнем случае. Затем проверьте новую


функцию DRAWOUT, вызывая ее следующим образом:

Command: (drawout)

Вы увидите, как функция передает команды системе AutoCAD для вы-


черчивания границы дорожки, и эта граница отобразится на экране. После
проверки функции выйдите AutoCADа.

3.6. Вычерчивание плиток

Теперь, когда мы разработали и проверили функцию ввода информации


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

; Преобразование углов из градусов в радианы


(defun dtr (a)
(* pi (/ a 180.0))
)
; Ввод информации о дорожке
(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 (dtr90)))
(setq angm90 (- pangle (dtr 90)))
)
; Отрисовка контуров дорожки
(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"
)
)
│ ; Разместить один ряд плит вдоль дорожки с учетом расстояния между
│ ; плитками и, возможно сместить его

│ (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 pctile 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)))
│ )
│ )

│ ; Вычертить ряды плит

│ (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 (dtr60))))
│ (setq off 0.0)
│ )
│ )
│ )

Чтобы понять действие этих функций, необходимо обратиться к


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

Второй цикл функции WHILE вычерчивает плитки в ряду в другом


направлении до тех пор, пока не встретится край дорожки.

DRAWTILES является функцией, которая несколько раз вызывает


функцию DROW для вычерчивания всех рядов плиток. Цикл WHILE вызывает
DROW для каждого ряда. Плиты в смежных рядах образуют равносторонний
треугольник, как показано на рисунке 2. Сторона этого треугольника
равна сумме диаметра и расстояния между плитками. Поэтому, расстояние
между рядами вдоль дорожки равно произведению стороны треугольника и
синуса в 60 градусов., кратным этому количеству, а смещение нечетных
рядов равно произведению стороны и косинуса 60 градусов.

Обратите внимание на то, как функция IF используется в функции


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

Чтобы проверить эту функцию, запишите файл, затем войдите в


AutoCAD и загрузите программу. Введите:

Command: (qpuser)

и предоставьте информацию о дорожке как раньше.

Command: (DRAWOUT)

и контур должен вычерчиваться точно также, как и прежде. Наконец,


введите:

Command: (DRAWTILES)

и все плиты должны вычерчиваться в пределах границы.

3.7. Добавление новой команды в систему AutoCAD

Наконец, мы готовы объединить части в команду AutoCAD. Если мы


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

Чтобы добавить указанные строки в файл GP.LSP, воспользуйтесь


редактором, а затем войдите в AutoCAD и загрузите программу.

;Преобразовать градусы в радианы

(defun dtr (a)


(* pi (/ a 180.0)
)

;Получить информацию о садовой дорожке

(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))) ;Угол дорожки в+90
(setq angm90 (-pangle (dtr 90))) ;Угол дорожки в-90
)

; Вычертить контур дорожки

(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"
)
)

; Поместить один ряд плит на заданном расстоянии по длине


; дорожки и, возможно, сместить его

(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)))
)
)

; Вычертить ряды плиток

(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)
)
)
)
│ ;Выполнить команды, которые вызывают составляющие функции

│ (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 Расстояние между плитами .../

3.8. Очистка экрана

По мере выполнения нашей команды PATH, все команды, которые она


передает системе AutoCAD, будут выводиться в область подсказок, и все
выбираемые ею точки будут отображаться на экране в форме маленьких
крестиков-маркеров. Как только команда отлажена, этот вывод можно
заблокировать с тем, чтобы реализуемая программой AutoLISP команда
ничем не отличалась от команды AutoCADа. Чтобы подавить эхо-вывод
команды и прекратить простановку меток, добавьте к файлу GP.LSP
указанные строки:

;Преобразовать градусы в радианы

(defun dtr (a)


(* pi (/ a 180.0))
)

; Получить информацию о садовой дорожке

(defun gpuser ()
(setq sp (getpoint "\nStart point of path: "))
(setq ep (getpoint "\nEnd point: "))
(setq hwidth (getdist "n\Half width of path: "sp))
(setq trad (getdist "\nRadius of tiles: "sp))
(setq tspac (getdist "\n Spacing between tiles: "sp)

(setq pangle (angle sp ep))


(setq plength (distance sp ep))
(setq width (* 2 hwidth))

(setq angp90 (+ pangle (dtr 90))) ;Угол дорожки в +90


(setq angm90 (- pangle (dtr 90))) ;Угол дорожки в - 90
)

; Вычертить контур дорожки


(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"
)
)

; Поместить один ряд плит на заданном расстоянии друг от друг


; по длине дорожки и, возможно, сместить его

(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)))
)
)
; Вычертить ряды плит

(defun drawtiles ()
(setq pdist (+ trad tspac))
(setq off 0.0)
(while (<= pdist (- plegth 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)
)
)
)

; Выполнить команду, которая вызывает составляющие функции

(defun C:PATH ()
(gpuser)
| (setq sblip (getvar "blipmode"))
| (setq scmde (getvar "cmdecho"))
| (setvar "blipmode" 0)
| (setvar "cmdecho" 0)
(drawout)
(drawtiles)

| (setvar "blpmode" sblip)


| (setvar "cmdecho" scmde)
)
Мы используем функцию GETVAR для получения текущих значений
переменных BLIPMODE и CMDECHO системы AutoCAD. Они записываются в
переменные SBLIP и SCMDE посредством функции SETQ. Затем мы используем
функцию SETVAR для обнуления обеих переменных системы AutoCAD,
блокируя режим простановки меток и эхо-вывода команд. Обратите
внимание на то, что мы обнуляем эти переменные только после получения
информации, введенной пользователем посредством функции GPUSER. Мы
хотим оставить метки для подтверждения ввода пользователя.

После завершения вычерчивания дорожки мы используем функцию


SETVAR для возвращения обеим переменным их исходных значений.

Запомните файл, войдите в систему AutoCAD и повторите команду


PATH снова. Проверьте команду, вводя различную информацию с устройства
указания, а также с клавиатуры.

3.9. Выводы

Всего за пару часов вы добавили новую команду в систему AutoCAD.


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

Возможно, вам также захочется просмотреть более подробно на функции,


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

С момента начала работы с AutoLISPом вы переходите к новому


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

ГЛАВА 4. ФУНКЦИИ AutoLISPа


_________________________________________________________________

AutoLISP содержит набор готовых к употреблению функций. Каждая


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

В этой главе вы познакомитесь с основными функциями AutoLISPа. Вы


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

4.1 Системная переменная FLALAND - совместимость


с предыдущими версиями

Автолисп версии 10 поддерживает как новые трехмерные возможности


Автокада,так и совместимость с поцедурами ,написанными для работы в
более раних версиях Автокада.Управление этой совместимостью
обеспечивает системная переменная FLATLAND.Новые трехмерные
возможности поддерживаются ,если ее значение равно нулю;в противном
случае,действие функций не отличается от Автолиспа версии 9.Установка
системной переменной FLATLAND влияет на следующие функции Автолиспа:

DISTANCE GRREAD POLAR


ENTGET INTGET TBLNEXT
GETDIST INTERS TBLSEARCH
GETPOINT OSNAP

Непосредственное влияние системной переменной FLATLAND на эти


функции отмечено в описании каждой функции. FLATLAND является
временным средсвом и будет опущена при следующей существенной
модификации Автокада после версии 10.

4.2. (+ <number> <number> ...)

Эта функция возвращает сумму всех чисел <number>. Она может


использоваться как для вещественных так и для целых чисел. Если все
числа <number> являются целыми, то результатом будет целое число; если
одно из чисел является вещественным, то целые числа преобразуются в
вещественные, и результатом будет вещественное число. Например:

(+ 1 2) возвращает 3
(+1 2 3 4.5) возвращает 10.500000
(+1 2 3 4.0) возвращает 10.000000

4.3. (- <number> <number> ...)

Эта функция вычитает второе число из первого и возвращает


разность. Если задается более, чем два числа, то сумма чисел со
второго по последнее вычитается из первого и возвращается конечный
результат. Если задается только одно число, то возвращается результат
вычитания его из нуля. Эта функция может использоваться как для
вещественных, так и для целых, аналогично рассмотренной выше функции.
Например:

(- 50 40) возвращает 10
(- 50 40.0 2) возвращает 8.000000
(- 50 40.0 2.5) возвращает 7.500000
(- 8) возвращает - 8

4.4. (* <number> <number> ...)

Эта функция возвращает произведение всех чисел. Она может


использоваться для вещественных или целых чисел, подчиняясь
стандартным правилам преобразования. Например:

(* 2 3) возвращает 6
(* 2 3 4 .0) возвращает 24.000000
(* 3 -4.5) возвращает -13.500000
4.5. (/ <number> <number>. . .)
Эта функция делит первое число на второе и возвращает частное.
Если задается более чем два числа, первое число делится на
произведение остальных чисел и возвращается частное. Эта функция может
использоваться с вещественными и целыми числами, подчиняясь
стандартным правилам преобразования. Например:

(/ 100 2) возвращает 50
(/ 100 2.0) возвращает 50.000000
(/ 100 20 2.0) возвращает 2.500000
(/ 100 20.0 2) возвращает 2.500000
(/ 100.0 20 2) возвращает 2.500000
(/ 100 20 2) возвращает 2
(/ 135 360) возвращает 0
(/ 135 360.0) возвращает 0.375000

4.6. (= <atom> <atom> ...)

Это функция проверки равенства. Она возвращает T, если все


заданные атомы имеют одинаковые числовые значения, в противном случае
возвращает nil. Эта функция также использоваться для чисел и строк.
Например:

(= 4 4.0) возвращает T
(= 20 388) возвращает nil
(= 2.4 2.4 2.4) возвращает T
(= 499 499 500) возвращает nil
(= "me" "me") возвращает T
(= "me" "you") возвращает nil

Примечание: Т является сокращением слова true - истина.


Невыполнение отноше- ния, т.е. его ложность соответствует в Лиспе
пустому или нулевому от- ношению, т.е. нулю /nil/.

4.7. (/= <atom1> <atom2>)

Это функция проверки неравенства. Она возвращает T, если


численное значение первого атома не равно численному значению второго
атома и nil в противном случае. Функция не определяется для более двух
аргументов. Например:

(/= 10 20 ) возвращает T
(/= "you" "you") возвращает nil
(/= 5.43 5.44) возвращает T

4.8. (< <atom> <atom> . . .)

Это функция проверки "меньше чем". Она возвращает T, если


численное значение первго атома меньше численного значения второго, в
противном случае возвращает нуль. Если задается более двух чисел, то T
возвращается в том случае, если каждое число меньше или равно числу,
находящемуся справа. Например:

(< 10 20) возвращает T


(< "b" "c") возвращает T
(< 357 33.2) возвращвет nil/нуль/
(< 2 3 88) возвращает T
(< 2 3 4 4) возвращает nil/нуль/

4.9. (<= <atom> <atom> ...)

Это функция проверки "меньше или или равно". Она возвращает T,


если численное значение первого атома меньше или равно численного
значения второго, в противном случае возвращает нуль. Если задается
более двух чисел, T возвращается, когда каждое число меньше или равно
числу справа. Например:

(<= 10 20) возвращает T


(<= "b" "b") возвращает T
(<= 357 33.2) возвращает nil/нуль/
(<= 2 9 9) возвращает T
(<= 2 9 4 5) возвращает nil/нуль/

4.10. (> <atom> <atom> ...)

Это функция проверки "больше чем". Она возвращает T, если первое


число больше второго, в противном случае возвращает нуль. Если
задается более двух чисел, то T возвращается тогда, когда каждое число
больше того, которое находится справа от него. Например:

(> 120 17) возвращает T


(> "c" "b") возвращает T
(> 3.5 1792) возвращает nil/нуль/
(> 77 4 2) возвращает T
(> 77 4 4) возвращает nil/нуль/

4.11. (>= <atom> <atom> ...)

Это функция проверки "больше или равно". Она возвращает T, если


численное значение первого атома равно или больше второго, в противном
случае возвращает нуль. Если задается более двух чисел, T возвращается
тогда, когда каждое число больше или равно числу, находящемуся справа
от него. Например:

(>= 120 17) возвращает T


(>= 57 57) возвращает T
(>= 3.5 1792) возвращает nil/нуль/
(>= 77 4 4) возвращает T
(>= 77 4 9) возвращает nil/нуль/

4.12. (~ <number>)

Эта функция возвращает побитовую функцию NOT (дополнение до


единицы) числа. Число должно быть целым. Например:
(~ 3) возвращает -4
(~ 100) возвращает -101
(~ -4) возвращает 3
4.13. (1+ <number>)

Эта функция возвращает число, увеличенное на единицу. Число может


быть вещественным или целым. Например:

(1+ 5) возвращает 6
(1+ -17.5) возвращает -16.500000

4.14. (1- <number>)

Эта функция возвращает число, уменьшенное на единицу. Число может


быть вещественным или целым. Например:

(1- 5) возвращает 4
(1- -17.5) возвращает -18.500000

4.15. (abs <number>)

Эта функция возвращает абсолютное значение числа. Число может


быть вещественным или целым. Например:

(abs 100) возвращает 100


(abs -100) возвращает 100
(abs -99.25) возвращает 99.250000

4.16. (and <expr> ...)

Эта функция возвращает логическую функцию AND для списка


выражений. Она вычисляет все выражения и, если хоть одно из них nil,
то возвращает nil, в противном случае возвращает Т. Например, учитывая
следующие назначения:

(setq a 103)
(setq b nil)
(setq c "string")

получим:

(and 1.4 a c) возвращает T


(and 1.4 a b c) возвращает nil

4.17. (angle '<pt1> '<pt2>)

Эта функция возвращает угол (в радианах) между точками двумерного


пространства <pt1> и <pt2>, где точка двумерного пространства является
списком двух вещественных чисел. Например:
(angle '(1.0 1.0) '(1.0 4.0)) возвращает 1.570796
(angle '(5.0 1.33) '(2.4 1.33)) возвращает 3.141593

4.18. (angtos <angle> [<mode> [<precision>]])


Функция берет угол <angle> (вещественное число, в радианах) и
возвращает его отредактированным в строку. Аргумент <mode>/режим/
является целым числом, которое определяет тип выполняемого
редактирования. Смотрите ниже:

ANGTOS Mode | Editing format


________________|_____________________________
|
0 | Градусы
1 | Градусы/минуты/секунды
2 | Грады
3 | Радианы
4 | Топографические единицы

Аргумент <precision> /точность/ является целым числом, которое


определяет количество десятичных разрядов. Аргументы <mode> /режим/ и
<precision> /точность/ соотвествуют системным переменным AUNITS и
AUPREC AutoCADа. Если вы опускаете аргументы, то будут использо-
ваться текущие значения AUNITS и AUPREC.

Например, учитывая следующее:

(setq pt1 '(5.0 1.33))


(setq pt2 '(2.4 1.33))
(setq a (angle pt1 pt2))

получим

(angtos a 0 0) возвращает "180"


(angtos a 0 4) возвращает "180.0000"
(angtos a 1 4) возвращает "180d0'0""
(angtos a 4 2) возвращает "3.1416r"
(angtos a 4 2) возвращает "W"

4.19. (append <expr> ...)

Эта функция берет любое число списков (<expr>) и делает из них


один список. Например:

(append '(a b) '(c d) возвращает (A B C D)


(append '((a) (b)) '((c) (d))) возвращает ((A) (B) (C) (D))

Функция APPEND требует, чтобы ее аргументами были списки.

4.20. (apply <function> <list>)

Выполняет функцию <function>, с аргументами, списка <list>.


Например:
(apply '+ '(1 2 3)) возвращает 6
(apply 'stract '("a" "b" "c")) возвращает "abc"

APPLY работает как со встроенными функциями, так и с функциями,


определенными пользователем (теми, которые созданы при помощи DEFUN
или LAMBDA).

4.21. (ascii <string>)

Эта функция возвращает первый символ строки <string>,


преобразованный в код ASCII (целое число). Эта функция подобна функции
ASC на языке BASIC. Например:

(ascii "A") возвращает 65


(ascii "a") возвращает 97
(ascii "BIG") возвращает 66

4.22. (assoc <item> <alist>)

Эта функция отыскивает в ассоциативном списке <alist> элемент


<item> в качестве ключевого элемента и возвращает вхождение этого
элемента в список <alist>. Если элемент <item> не найден в списке
<alist>, то ASSOC возвращает nil. Предположим, например, что список
"al" определен следующим образом:

((name box) (width 3) (size 4.7263) (depth 5))

тогда:

(assoc 'size al) возвращает (SIZE 4.7263)


(assoc 'weight al) возвращает nil

Ассоциативные списки часто используются для записи данных, доступ


к которым осуществляется по ключу. Это аналогично массивам или
структурам в других языках программирования. Функция SUBST, описанная
далее в этом руководстве, обеспечивает удобную ассоциативную замену в
списке.

4.23. (atan <num1> [<num2>])

Если аргумент <num2> не используется, то функция ATAN возвращает


арктангенс <num1> в радианах. <Num1> может быть отрицательным;
диапозон углов составляет от -pi до +pi радиан. Например:

(atan 0.5) возвращает 0.463647


(atan 1.0) возвращает 0.785398
(atan -1.0) возвращает -0.785398
(angtos (atan -1.0) 0 4) возвращает "-45.0000"

Если используются оба аргумента <num1> и <num2>, то возвращается


арктангенс <num1>/<num2> в радианах. Если <num2> является нулем, то
возвращается угол плюс или минус 1.570796 радиана (90 или -90
градусов), в зависимости от знака <num1>. Например:
(atan 2.0 3.0) возвращает 0.588002
(angtos (atan 2.0 3.0) 0 4) возвращает "33.6901"
(atan 2.0 -3.0) возвращает 2.553590
(angtos (atan 2.0 -3.0) 0 4) возвращает "146.3099"
(atan -2.0 3.0) возвращает -0.588002
(atan -2.0 -3.0) возвращает -2.553590
(atan 1.0 0.0) возвращает 1.570796
(angtos (atan 1.0 0.0) 0 4) возвращает "90.0000"
(atan -0.5 0.0) возвращает -1.570796
(angtos (atan -0.5 0.0) 0 2) возвращает "-90.00"

4.24. (atof <string>)

Эта функция возвращает строку, преобразованную в вещественное


число. Например:

(atof "97.1") возвращает 97.100000


(atof "3") возвращает 3.000000

4.25. (atoi <string>)

Эта функция возвращает строку, преобразованную в целое число.


Например:

(atoi "97") возвращает 97


(atoi "3") возвращает 3
(atoi "3.9") возвращает 3

4.26. (atom <item>)

Эта функция возвращает nil, если <item> является списком, в


противном случае возвращает T. Все, что не является списком, считается
атомом. Например, пусть:

(setq a '(x y z))


(setq b 'a)

тогда

(atom 'a) возвращает T


(atom a) возвращает nil/нуль/
(atom 'b) возвращает T
(atom b) возвращает T
(atom '(a b c)) возвращает nil/нуль/

Некоторые версии LISP интерпретируют функцию ATOM по-разному,


поэтому будьте осторожны при переносе программ.

4.27. (Boole <func> <int1> <int2> ...)

Это обобщенная битовая Булева функция. <Func> - идентификатор


функции является целым числом в диапозоне от 0 до 15, представляющим
одну из 16 возможных Булевых функций нескольких переменных. Каждый бит
аргумента <int1> спаривается с соответствующим битом аргумента <int2>.
Результат определяется с помощью таблицы истинности, предс- тавленной
ниже:
___________________________________
| Int1 | Int2 | Func. bit |
|___________|__________|_____________|
| 0 | 0 | 8 |
|___________|__________|_____________|
| 0 | 1 | 4 |
|___________|__________|_____________|
| 1 | 0 | 2 |
| __________|__________|_____________|
| 1 | 1 | 1 |
|___________|__________|_____________|

В строке указано значение битовой константы <func>, при котором


результатом является единица, в противном случае бит будет нулевым.

Некоторые значения аргумента <func> соответствуют стандартным


Булевским операциям AND, OR, XOR и NOT. Они показаны ниже:

_________________________________________________________________
<func> | Операция | Получаемый бит равен единице, если...
_________|__________|____________________________________________
1 | AND | Оба бита на входе установлены на 1
_________|__________|____________________________________________
6 | XOR | Только один из двух битов на входе равен 1
_________|__________|____________________________________________
7 | OR | Один или оба бита на входе установлены на 1
_________|__________|____________________________________________
8 | NOT | Оба бита на входе установлены на 0 (допол-
| | нение единицы)
_________|__________|____________________________________________

Например:

(Boole 1 12 5)

задает логическую функцию AND значений 12 и 5. Результатом будет


4. Аналогично:

(Boole 6 6 5)

задает логическую функцию XOR значений 6 и 5, возвращая 3.

Вы можете использовать другие значения аргумента <func> для


получения других Булевых операций, неимеющих стандартных имен.
Например, если значение аргумента <func> равняется 4, то биты
результата установятся в том случае, если соответствующие биты
установлены в аргументе <int2>, но не в <int1>. Таким образом:

(Boole 4 3 14)
возвратит 12.

4.28. (boundp <atom>)


Эта функция возвратит T, если аргументу <atom> присвоено значение
(не важно какое). Если значение не присвоено аргументу <atom> (или
если ему присвоен nil), то возвращается nil. Например, учитывая
следующее:

(setq a 2)
(setq b nil)

получим:

(boundp 'a) возвращает T


(boundp 'b) возвращает nil /нуль/

4.29. caar, cadr, cddr, cadar, т.д.

AutoLISP поддерживает конкатенации CAR и CDR, глубиной до четырех


уровней. Например, если:

(setq x '((ab) c d))

тоа:

(caar x) равняется (car (car x)) возвращая A


(cdar x) равняется (cdr (car x)) возвращая (B)
(cadar x) равняется (car (cdr (car x))) возвращая B
(cadr x) равняется (car (cdr x)) возвращая C
(cddr x) равняется (cdr (cdr x)) возвращая (D)
(caddr x) равняется (car (cdr (cdr x))) возвращая D

В AutoLISPе функция CADR часто используется для получения


координаты Y точек двумерного/2D/ или трехмерного/3D/ пространства
(второй элемент списка двух или трех вещественных чисел). Аналогично,
функция CADDR может использоваться для получения координаты Z точки
трехмерного пространства /3D/. Например, если:

(setq pt2 '(5.2 1.0)) (двухмерная точка 2D)


(setq pt3 '(5.2 1.0 3.0)) (трехмерная точка 3D)

то:

(car pt2) возвращает 5.200000


(cadr pt2) возвращает 1.000000
(caddr pt2) возвращает nil
(car pt3) возвращает 5.200000
(cadr pt3) возвращает 1.000000
(caddr pt3) возвращает 3.000000

4.30. (car <list>)


Эта функция возвращает первый элемент списка. Если список пустой,
возвращается нуль. Например:

(car '(a b c)) возвращает A


(car '((a b ) c)) возвращает (A B)
(car '()) возвращает nil /нуль/
4.31. (cdr <list>)

Эта функция возвращает список, в который включены все, кроме


первого, элементы списка <list>. Если список пуст, то возвращается
нуль. Например:

(cdr '(a b c)) возвращает (B C)


(cdr '((a b) c)) возвращает (C)
(cdr '()) возвращает nil/нуль/

Когда аргумент <list> является точечной парой (смотрите CONS


ниже), CDR возвращает второй элемент не оформляя его в виде списка.
Например:

(cdr '(a.b)) возвращает B


(cdr '(1."Text")) возвращает "Text"

4.32. (chr <number>)

Эта функция возвращает преобразованное значение целого числа,


представляющего код ASCII, в строку, состоящую из одного символа
(подобно функции CHR$ на языке BASIC. Например:

(chr 65) возвращает "A"


(chr 66) возвращает "B"
(chr 97) возвращает "a"

4.33. (close <file-desс>)

Эта функция закрывает файл и возвращает нуль. Аргумент


<file-desс> является дескриптором файла, полученным из функции OPEN.
После функции CLOSE дескриптор файла остается неизменным, но уже не
будет связан с файлом.

Предположим, например, что X является дескриптором открытого


файла,

(close x)

закроет соответствующий файл и возвратит нуль.

4.34. (command <arqs> ...)

Эта функция выполняет команды системы AutoCAD внутри AutoLISP и


всегда возвращает nil. Команды AutoCADа и их подкоманды представляются
аргументами; каждый аргумент вычисляется и передается системе AutoCAD
в ответ на последовательные запросы. Имена команд и опции передаются в
виде строк, точки двумерного пространства - как списки двух
вещественных чисел, а точки трехмерного пространства - как спис- ки
трех вещественных чисел. Имена команд распознаются системой AutoCAD
только тогда, когда она выдает запрос "Command:". Например:
(setq pt1 '(1.45 3.23))
(setq pt2 (getpoint "Enter a point: "))
(command "line" pt1 pt2)
(command "")

После появления запроса "Command:" системы AutoCAD, вышеуказанная


последовательность выражений устанавливает значение для точки "pt1",
запрашивает точку "pt2" и выполняет команду LINE системы AutoCAD
передавая ей две точки. Аргументами функции COMMAND могут быть строки,
вещественные числа, целые числа или точки, т.е. то, что предполагается
последовательностью запросов выполняемой команды AutoCAD. Пустая
строка ("") эквивалентна вводу пробела с клавиатуры. Вызов COMMAND,
аналогично нажатию на клавиатуре CTRL - C, отменяет большинство команд
AutoCAD.

Команды, выполняемые посредством функции COMMAND, не выводятся на


экран, если системная переменная CMDECHO (доступ к которой
осуществляется при помощи переменных SETVAR и GETVAR) устанавливается
в нуль. Функция COMMAND является основным методом доступа к командам
AutoCADа из AutoLISPа.

Вводимые пользователем функции GETxxx (GETANGLE, GETSTRING,


GETINT, GETPOINT т.д.) не могут использоваться внутри функции COMMAND.
Попытка сделать это приводит к появлению сообщения "error: AutoCAD
reject function" /ошибка: AutoCAD отклонил функцию/ и аварийному

завершению функции. Если требуется пользовательский ввод, выдайте


функции GETxxx заранее, как показано выше, или разместите их между
последовательными вызовами функции COMMAND.

Команды DTEXT и SCETCH считывают данные непосредственно с


клавиатуры или с диджитайзера и, поэтому не могут вызываться с помощью
функции COMMAND. Аналогично обстоит дело с командами PLOT, PRPLOT и
SCRIPT.

Пауза ввода значения пользователем

Если команда AutoCAD находится в процессе выполнения и, если в


качестве одного из аргументов функции COMMAND встречается символ
PAUSE, то выполнение функции COMMAND будет задержано для обеспечения
непосредственного пользовательского ввода (или протягивания). Это
аналогично методу задания паузы посредством обратной косой,
предусмотренному для меню.

Если вы выдаете прозрачную команду во время задержки функции


COMMAND, последняя останется приостановленной. Таким образом, в это
время вы можете масштабировать и смещать изображение при помощи 'ZOOM
и 'PAN. Пауза будет сохраняться до тех пор, пока AutoCAD не получит
нужных данных при условии, что никакая прозрачная команда не находится
в процессе выполнения.
Например:

(command "circle" "5,5" pause "line" "5,5" "7,5" "")

начинает команду CIRCLE, устанавливает центр в точке 5,5, а затем


делает паузу с тем, чтобы дать вам возможность протянуть радиус
окружности на экране. Когда вы выбираете требуемую точку (или вводите
с клавиатуры значение требуемого радиуса), функция восстанавливается,
вычерчивая линию от точки 5,5 до точки 7,5.

Ввод меню не приостанавливается паузой AutoLISPа. Если элемент


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

Замечания:

1. В настоящее время значением символя PAUSE является обратная


косая (строка "\"). Можно вводить обратную косую непосредственно, но
если функция COMMAND вызывается из меню, то приостанавливается не
передаваемая функция, а элемент меню,кторый выполняется в текущий
момент.Кроме того ,механизм прерывния может запрашивать различные
управляющие значения в последующих версиях Автолиспа,поэтому
рекомендуется во всех случаях пользоваться символом PAUSE вмсто
обратной косой.

2. Если символ PAUSE встречается, когда ожидается ввод текстовой


строки, то действие команды приостанавливается только в том случае,
когда системная переменная TEXTEVAL не равна нулю. В противном случае
команда воспринимает значение символа PAUSE, т.е. обратную косую
черту. 3. Приостановленная функция считается активной, следовательно
AutoLisp не может в это время вычислять новое выражение.

4.35. (cond (<test1> <result1>...) ...)

Для этой функции допустимо любое количество списков в качестве

аргументов. Она вычисляет первый элемент в каждом списке (в том


порядке, в котором они вводятся) до тех пор, пока один из не
встретится элемент со значением не равным nil. Затем она оценивает те
выражения, которые следуют за тестируемым элементом, и возвращает
значение последнего выражения из подсписка. Если в подсписке имеется
только одно выражение (т.е. отсутствует результат <result>), то
возвращается значение выражения <test>. COND является основной
условной функцией в AutoLISPе.

Например, в следующей последовательности используется COND для


вычисления абсолютного значения.

(cond ((minusp a) (- a))


(t a)
)

Если значение "a" равно -10, то возвратится 10. Как показано


выше, COND может использоваться в качестве функции типа "case".
Принято использовать T в качестве последнего (по умолчанию) выражения
<test>. Вот еще один простой пример. Пусть ответ пользователя
сохраняется в символе s. Следующая функция проверяет ответ и
возвращает 1, если это "Y"/Да/ или "y", и возвращает 0, если ответом
будет "N" или "n"/Нет/, во всех остальных случаях возвращает нуль.
(cond ((= s "Y") 1)
((= s "y") 1)
((= s "N") 0)
((= s "n") 0)
(t nil)
)

4.36. (cons <new first element> <list>)

Эта функция является базовым КОНСтруктором /CONStructor/ списка.


Она берет элемент (<new first element>) и список (<list>) и добавляет
этот элемент к началу списка. Например:

(cons 'a '(bcd)) возвращает (A B C D)


(cons '(a) '(b c d)) возвращает ((A) B C D)

Обратите внимание на то, что первый элемент может быть атомом или
списком.

При создании структуры, известной под названием точечной пары ,


для функции CONS приемлем также ввод атома вместо аргумента <list>.
Когда точечная пара отображается на экране, AutoLISP печатает точку
между первым и вторым элементом. Точечные пары занимают меньший объем
памяти, чем обычные списки, и функция CDR может использоваться для
возвращения второго элемента. Таким образом:

(cons 'a 'b) возвращает (A . B)


(car (cons 'a 'b) возвращает A
(cdr (cons 'a 'b) возвращает B

4.37. (cos <angle>)

Эта функция возвращает косинус аргумента <angle>/угол/, где


<angle> выражается в радианах. Например:

(cos 0.0) возвращает 1.000000


(cos pi) возвращает -1.000000

4.38. (defun <sym> <argument list> <expr> ...)

Функция DEFUN определяет функцию, с именем <sym>, (обратите


внимание на то, что имя функции автоматически заключается в кавычки,
поэтому кавычки вводить не следует). За именем функции следует список
аргументов (возможно пустой), за которым может идти косая и имя одного
или нескольких локальных символов данной функции. Косая должна
отделяться от первого локального символа и от последнего аргумента по
крайней мере одним пробелом. Если никакие аргументы и локальные
символы не должны декларироваться, то после имени функции должны
вводиться пустые скобки. Например:

(defun myfunc (x y) ...) (функция берет два аргумента)


(defun myfunc (/ a b)...) (функция имеет два локальных
символа)
(defun myfunc (x / temp)...)(один аргумент и один локальный
символ)
(defun myfunc () ...) (аргументы или локальные символы
отсутствуют)

За списком аргументов и локальных символов следует одно или более


выражений, которые должны вычисляться при выполнении функции.

Функция DEFUN сама возвращает имя определяемой функции. Когда


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

(defun add10 (x)


(+ 10 x)
) возвращает ADD10
(add10 5) возвращает 15
(add10 -7.4) возвращает 2.60000

далее:

(defun dots (x y / temp)


(setq temp (strcat x "..."))
(strcat temp y)
) возвращает DOTS
(dots "a" "b") возвращает "a...b"
(dots "from" "to") возвращает "from...to"

Никогда не используйте в качестве <sym> имя встроенной функции


или символа, так как в этом случае будет невозможно получить доступ к
встроенной функции.

4.38.1. Библиотеки функций и автоматическая загрузка

Определения функций могут записываться в файлы и загружаться с

использованием функции LOAD AutoLISPа, описанной далее в этой


главе. Если существует файл "acad.lsp", то AutoLISP будет
автоматически заг- ружать его всякий раз, когда вы входите в Редактор
чертежей; вы може- те использовать эти средства для создания
библиотеки полезных функций с тем, чтобы они всегда были под рукой,
когда потребуются.
Любой библиотечный ".lsp" файл может содержать выражения вне
функции DEFUN.Таким образом ,загружая файл ,вычисляющий некоторые
выражения, включая поименованные функции ,можно выполнять эти
выражения и функции автоматически ,когда бы этот файл ни был
загружен.Однако загрузка файла "acad.lsp" производится еще до полной
инициализации функции COMMAND в файле "acad.lsp"(вне функции
DEFUN).Чтобы заставить файл acad.lsp" при загрузке выполнять
автоматически серию команд,следует в его функцию DEFUN включить
специальную функцию "S::STARTUP".
4.38.2. Функции C:XXX - Добавление команд в AutoCAD

Вы можете добавлять новые команды в AutoCAD посредством DEFUN для


определения функций, реализующих эти команды. Чтобы использовать эти
функции в качестве команд AutoCAD, необходимо следовать следующим
правилам:

1. Функция должна иметь имя имя C:XXX, где все буквы даны в верхнем
регистре. Часть имени "C:" всегда должна присутствовать; частью
"XXX" может быть имя команды по вашему выбору, при условии, если
оно не дублирует никакую другую команду AutoCADа, встроенную или
внешнюю.

2. Функция должна иметь пустой список аргументов (но


допускаются и локальные символы).

Например, следующее определяет функцию для вычерчивания квадрата


с помощью Полилинии.

(defun C: PSQUARE (/pt1 pt2 pt3 pt4 len)


(setq pt1 (getpoint "Lower left corner: ")) ;нижний левый угол
(setq len (getdist pt1 "Length of one side: ") ; длина стороны
(setq pt2 (polar pt1 0.0 len))
(setq pt3 (polar pt2 (/PI 2.0) len))
(setq pt4 (polar pt3 PI len))
(command "PLINE" pt1 pt2 pt3 pt4 "C")
)

Функции, определенные таким образом, могут вызываться вводом


части "XXX" имени функции на запрос "Command:" системы AutoCAD. Если в
части "XXX" находится неизвестная команда, AutoCAD попытается вызвать
функцию "C:XXX" без параметров. Например, для функции C:PSQUARE диалог
будет выглядеть следующим образом:

Command: PSQUARE
Lower left corner: (ввести точку)
Length of one side: (ввести расстояние)

Функция затем вызовет команду PLINE системы AutoCAD и ответит на


ее запросы с тем, чтобы вычертить требуемый квадрат.

Добавление команд в AutoCAD таким образом является очень мощным


средством AutoLISPа. Как только команда определена, она может
использовать все возможности AutoLISPа. При использовании новой
команды не требуется заключать ее имя в скобки, поэтому команда,
реализуемая AutoLISPом, используется аналогично любой другой команде
AutoСADa.

4.38.3 Функция S::XXX - автоматическое выполнение

Опеделеннные пользователем функции,имена которых начинаются с


"S::",будут выполняться автоматически ,как только они будут загружены
в течение сеанса редактирования.Необходимо иметь ввиду ,что "S::" -
специльно зарезервированная приставка к имени функции,поэтому надо
избегать использовать эту приставку с именами функций,которые не
предусматривается использовать как автоматически выполняемые.
В противном случае может возникнуть непредвиденная ситуация.
Внастоящее время можно определить лишь одну автоматически
выполняемую функцию - под именем "S::STARTUP".Если эта функция
определена ,она будет вызываться на выполнение автоматически (без
аргументов) в начале сеанса создания нового или редактрования
существующего рисунка.Таким образом ,можно включить выполнение функции
"S::STARTUP" (с помощью DEFUN ) в файл "acad.lsp" для выполнениялюбых
первоначальных установок передначалом сеанса редактирования.

Пример:
Пусть необходимо переопределить стандартные команды Автокада QUIT и
END.Это можно проделать с помощью автоматичеки загружаемого файла
:acad.lsp",содержащего следующие записи:

(defun C:QUIT ()
....определение....
)
(defun C:END ()
....определение....
)
(defun S::STARTUP()
(command "UNDEFINE" "QUIT")
(command "UNDEFINE" "QUIT")
)

4.39. (distance <pt1> <pt2>)

Эта функция возвращает расстояние между точками двумерного


пространства <pt1> и <pt2>, где двумерная точка является списком двух
вещественных чисел. Например:

(distance '(1.0 2.5) '(7.7 2.5)) возвращает 6.700000


(distance '(1.0 2.0) '(3.0 4.0) возвращает 2.828427

4.40. (eq <expr1) <expr2>)

Эта функция определяют, являются ли аргументы <expr1> и <expr2>


идентичными; т.е. присваивается ли им значение одного и того же
объекта (посредством SETQ, например). EQ возвращает T, если два
выражения являются идентичными, в противном случае возвращает нуль.
Используется в основном для определения идентичности двух списков.
Например:

(setq f1 '(a b c))


(setq f2 '(a b c))
(setq f3 f2)

тогда:

(eq f1 f3) возвращает nil (f1 и f2 - не один список)


(eq f3 f2) возвращает T (f3 и f2 - один и тот же список)

Смотрите также функцию EQUAL ниже.


4.41. (equal <expr1> <expr2>) [<допуск>]

Эта функция определяет равны ли аргументы <expr1> и <expr2>; т.е.


имеют ли одно и то же значение. Например, рассмотрим следующую
последовательность:
(setq f1 '(a b c))
(setq f2 '(a b c))
(setq f3 f2)

затем:

(equal f1 f3) возвращает T (f1 и f3 имеют одинаковые значения)


(equal f3 f2) возвращает T (f3 и f2 - один и тот же список)

Обратите внимание, что несмотря на то, что два списка - EQUAL,


они могут и не быть EQ, а атомы, которые - EQUAL, всегда также и EQ.
Кроме того, любые два списка или атома, которые - EQ, всегда будут
EQUAL.
При сравнении двух действительных чисел (или двух списков
действительных чисел,например точек ) важно осознавть ,что два
"идентичных" числа могунезначительно отличаться друг от друга ,если
они вычисляются различными методами.Однако факультативный
численный аргумент <допуск> позволяет выдавать максимальную точность,с
котороймогу отличаться друг от друга <expr1> и <expr2>, оставаясь
при этом EQUAL.

Пример:
пусть
(setq a 1.123456)
(setq b 1.123457)
тогда
(equal a b) возвращает nil
(equal a b 0.000001) возвращает T

4.42. (eval <expr>)

Функция возвращает результат вычисления <expr>, где аргумент


<expr> является любым выражением LISPа. Например, рассмотрим следую-
щее:

(setq a 123)
(setq b 'a)

затем:

(eval 4.0) возвращает 4.000000


(eval (abs -10)) возвращает 10
(eval a) возвращает 123
(eval b) возвращает 123

4.43. (exp <number>)

Эта функция возвращает число е возведенное в степень <number>.Она


возвращает вещественное число. Например:
(exp 1.0) возвращает 2.718282
(exp 2.2) возвращает 9.025013
(exp -0.4) возвращает 0.670320
4.44. (expt <base> <power>)

Эта функция возвращает аргумент <base>, возведенный в заданную


степень <power>. Если оба аргумента являются целыми числами, резуль-
татом будет целое число. В противном случае результатом будет вещест-
венное число. Например:

(expt 2 4) возвращает 16
(expt 3.0 2.0) возвращает 9.000000

4.45 (findfile <file name>)

Данная функция позволяет отыскивать файл,указанный <file name> ,в


каталогах,хранящих файлы Автокада .(при просмотре каталогов ,хранящих
фалы Автокада ,сначала просматривается текущий каталог,затем каталог в
котором хранится текущий рисунок и,наконец каталог,имя которого
записано в переменной среды ACAD.)
Функция FINDFILE не делает какого-либо предложения,касающегося типа
или определения <filename>;при нобходимости следует его указать.Если
указано неполное имя файла(т.е. не содержит имени
устройства/каталога),Автокад ищет этот файл и возвращает полное имя
файла или NIL,если файл не найден .Если <file name> содержит имя
устройства/каталога ,Автокад просматривает только указанный каталог(не
просматривает вышеперечисленные каталоги).
Полное имя ,возвращаемое функцией FINDFILE,можно передавать фнкции
OPEN.(В примерах,приведенных ниже,использован символ "/" в качестве
разделителя в имени файла;в операционных системах PC-DOS/MS-DOS можно
использовать как "/",так и "\\".)

Пример:
пусть
- текущий каталог - "/acad" в нем хранится файл "abc.lsp";
- редактируется рисунок из каталога "/acad/drawings";
- в переменную среды ACAD установлено значение "/acad/support";
- файл "xyz.txt" хранится только в каталоге "/acad/support";
-файла "nosuch" нет ни в одном из каталогов.

Тогда

(findfile "abc.lsp") возвращает "/acad/abc.lsp"


(findfile "xyz.txt") возвращает "/acad/support/xyz.txt"
(findfile "nosuch") возвращает nil

4.46. (fix <number>)

Эта функция возвращает число <number>, преобразованное в целое


число. Число <number> может быть целым или вещественным. Если это
вещественное число, то оно усекается до ближайшего целого путем
отбрасывания дробной части. Например:

(fix 3) возвращает 3
(fix 3.7) возвращает 3.000000
4.47. (float <number>)

Эта функция возвращает аргумент <number>, преобразованный в


вещественное число. Аргумент <number> может быть целым или
вещественным. Например:

(float 3) возвращает 3.000000


(float 3.7) возвращает 3.700000

4.48. (foreach <name> <list> <expr> ...)

Эта функция осуществляет последовательное назначение элементов


списка <list> имени <name>, вычисляя каждое выражение <expr> для
каждого элемента в списке <list>. Может быть задано любое количество
аргументов <expr>. Функция FOREACH возвращает результат последнего
выражения <expr>. Например:

(foreach n '(a b c) (print n))

эквивалентно выражениям:

(print a)
(print b)
(print c)

с тем лишь исключением, что функция FOREACH возвращает результат


только последнего вычисленного выражения.

4.49. (qcd <num1> <num2>)

Эта функция возвращает наибольший общий делитель <num1> и <num2>.


Аргументы <num1> и <num2> должны быть целыми числами. Например:

(gcd 81 57) возвращает 3


(gcd 12 20) возвращает 4

4.50. (getangle [<pt>] [<prompt>])

Эта функция ожидает от пользователя ввода значений угла. Аргумент


<prompt> является вспомогательной строкой, которая должна
высвечиваться как подсказка, а <pt> является вспомогательной, опорной
точкой Пользовательской системы координат. Вы можете задать угол
вводом числа в текущем формате единиц измерения угла системы AutoCAD.
Независимо от формата функция всегда возвращает угол в радианах.
Можно задать угол путем набора на клавиатуре в текущих для Автокада
единицах измерения.Заметим,что несмотря на то,что текущая единица
измерения угла может быть градус,град,или какая дибо еще,функция
всегда возвращает угол в радианах.
Вы можете также "показать" AutoLISPу значение угла посредством
двух 2D точек на экране. AutoCAD вычерчивает линию резиновой нити от
первой точки к текущему положению перекрестия для визуализации угла.
Если задан вспомогательный аргумент <pt> функции GETANGLE, то он
задает первую из двух точек, давая вам возможность "показать"
AutoLISPу значение угла путем указания только одной точки.

Ниже даются примеры вызовов функции GETANGLE.


(setq ang (getangle))
(setq ang (getangle '(1.0 3.5))
(setq ang (getangle "Which way? ")
(setq ang (getangle '(1.0 3.5) "Which way? ")

В ответ на запрос функции GETANGLE вы не можете ввести другое


выражение LISPа. Попытка сделать это вызовет сообщение "Can't reenter
AutoLISP" (Повторно ввести выражение AutoLISPа нельзя".) ( Смотрите
функции GETORIENT и INITGET.)

4.51. (getcorner <pt> [<prompt>])

Функция GETCORNER возвращает точку в текущей UCS аналогично


функции GETPOINT. Однако, GETCORNER требует задания базовой точки <pt>
и, по мере перемещения пользователем перекрестия по экрану,
вычерчивает прямоугольник между перекрестьем и базовой точкой.
Смотрите подробности в описании функций GETPOINT и INITGET.Базовая
точка определяется в координатах текущей UCS.Если вводится трехмерная
точка ,то ее координата Z игнорируется ,в качестве координаты Z
используется значение текущего уровня.
В ответ на запрос GETCORNER вы не можете ввести другое выражение
LISPа.

4.52. (getdist [<pt>] [<prompt>])

Эта функция ожидает ввода расстояния. Аргумент <prompt> является


дополнительной строкой, отображаемой в качестве подсказки, а <pt>
является вспомогательной базовой точкой. Вы можете задать расстояние
посредством ввода числа в текущем формате единиц измерения длины
системы AutoCAD. Несмотря на то, что текущий формат может быть в футах
и дюймах (архитектурная система), эта функция всегда возвращает
расстояние как вещественное число.
Вы можете также "показать" значение расстояния AutoLISPу путем
указания двух точек на графическом экране. AutoCAD вычерчивает линию
резиновой нити от первой точки до текущего расположения перекрестия.
Если задан аргумент <pt>, то эта точка является первой и резиновая
нить закрепляется в ней.
Факультативный аргумент GETDIST < точка > подразумевается как первый
из этих двух точек,позволяя "показать" Автолиспу расстояние путем
указания в любуюдругуя точку.
Если применяется метод двух точек ,функция GETDIST тестирует
значение системной переменной FLATLAND и флага "трехмерные точки"
функции INITGET.Если хначение системной переменной FLATLAND не ноль,то
возвращается расстояние между трехмерными точками только в том
случае,если установлен флаг "трехмерные точки "функции INITGET;в
потивном случае функция GETDIST обрабатывает только двумерные точки.

Ниже даны примеры использования функции GETDIST.


(setq dist (getdist))
(setq dist (getdist '(1.0 3.5))
(setq dist (getdist "How far ")
(setq dist (getdist '(1.0 3.5) "How far? ")

Вы не можете ввести выражение LISPа в качестве ответа на запрос


GETDIST. Смотрите также INITGET.

4.53 (getenv <имя - переменной>)

Данная функция возвращает строковое значение ,присвоенное


переменной среды.Аргумент <имя-переменной> - строковая
константа,которая представляет собой имя переменной среды.Если эта
переменная не определена,то возвращается NIL.

Пример:
Если переменная среды ACAD имеет значение "/acad/support",а
переменная NOSUCH не определена,тогда

(getenv "ACAD") возвращает "/acad/support"


(getenv "NOSUCH") возвращает nil

Заметим,что в операционной системе UNIX,"ACAD" и "acad" разные


переменные,ибо UNIX "чувствителен"к к регистру,на котором набрана
строка .

4.54. (getint [<prompt>])

Эта функция ожидает ввода целого числа и возвращает это целое


число.Числа могут быть в диапазоне от -32 768 до +32 767. Аргумент
<prompt> является дополнительной строкой, которая должна отображаться
в качестве подсказки. Например:

(setq num (getint))


(setq num (getint "Enter a number: "))

Вводить выражение LISPа в качестве ответа на запрос функции


GETINT нельзя. Смотрите также функцию INITGET.

4.55. (getkword [<prompt>])

Функция GETKWORD запрашивает у пользователя ключевое слово. Перед


вызовом функции GETKWORD устанавливается список допустимых ключевых
слов с помощью функции INITGET (описанной ниже). Функция GETKWORD
возвращает строку, соответствующую вводимому пользователем ключевому
слову. AutoCAD повторит запрос, если ни одно из этих ключевых слов
было введено. Пустой ввод возвращает nil (если такой пустой ввод
допустим). Если ключевые слов а неопределены, то также возвращается
nil. Например последовательность:

(initget 1 "Yes No")


(setq x (getkword "Are you sure? (Yes or No) "))

выдаст запрос пользователю и присвоит символу X "Yes" или "No", в


зависимости от ответа пользователя. Если ответ не совпадает ни с каким
ключевым словом, или если пользователь дает пустой ответ, система
AutoCAD выдает повторный запрос.
Вы не можете ввести другое выражение LISPа в ответ на запрос
функции GETANGLE.
4.56. (getorient [<pt>] [<prompt>])

Углы в AutoLISPе всегда представлены в радианах, с осью отсчета


вправо (на восток) и увеличением углов в направлении против часовой
стрелки. Таким образом, если пользователь выбрал другую ось отсчета
или другое направление увеличения углов посредством использования ко-
манды UNITS или системных переменых ANGBASE или ANGDIR, то потребуется
некоторое преобразование.

Функция GETORIENT подобна функции GETANGLE, но результет ее рабо-


ты завивит от положения оси и направления осчета углов. GETANGLE
долж- на использоваться, когда вам требуется величина поворота
(относитель- ный угол), тогда как GETORIENT используется для получения
направления (абсолютного угла).

Предположим, что команда UNITS системы AutoCAD используется для


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

----------------------------------------------------------------
Ввод | GETANGLE | GETORIENT |
(в градусах) | | |
---------------------------------------------------------------|
0 | 0.000000 | 1.570796 |
---------------------------------------------------------------|
-90 | 1.570796 | 3.141593 |
---------------------------------------------------------------|
180 | 3.141593 | 4.712389 |
---------------------------------------------------------------|
90 | 4.712389 | 0.000000 |
----------------------------------------------------------------

Как указано в таблице, GETANGLE учитывает направление увеличе-


ния углов и игнорирует ось отсчета. Таким образом, вы можете исполь-
зовать функцию GETANGLE для получения величины поворота вставки бло-
ка, т.к. ввод нулевых градусов всегда возвращает нулевые радианы. С
другой стороны, GETORIENT учитывает как ось отсчета, так и направле-
ние увеличения угла. Таким образом, вы должны использовать GETORIENT
для получения таких углов, как угол наклона базовой линии Текста.
Например, учитывая вышеупомянутые установки команды UNITS, направле-
ние базовой линии для нормальной горизонтальной линии текста будет 90
градусов.Функция GETORIENT (как и GETANGLE) всегда возвращает угол в
радианах относително текущей плоскости построений.
В ответ на запрос функции GETORIENT вы не можете ввести другое
выражение AutoLISPа. Смотрите также GETANGLE и INITGET.

4.57. (getpoint [<pt>] [<prompt>])


Эта функция ожидает ввода точки. Аргумент <pt> является
вспомогательной дву-трехмерной опорной точкой в текущей UCS, а
<prompt> - вспомогательной строкой, отображаемой в качестве запроса.
Вы можете задать точку указанием или вводом
ее координат в формате текущих единиц измерения. Если
присутствует до- полнительный аргумент опорной точки <pt>, то AutoCAD
изображает линию резиновой нити от этой точки к текущему
местонахождению перекрестия. Например:

(setq p (getpoint))
(setq p (getpoint "Where? "))
(setq p (getpoint '(1.5 2.0) "Second point: "))

Обычно GETPOINT возвращает точку выраженную в координатах текщей


UCS (список двух вещественных чисел). Используя функцию INITGET для
установки флажка "3D", вы можете заставить функцию GETPOINT вернуть
точку трехмерного пространства (список трех вещественных чисел).

В ответ на запрос функции GETPOINT нельзя ввести другое выражение


LISPа. Смотрите также GETPOINT и INITGET.

4.58. (getreal [<prompt>])

Эта функция ожидает ввода пользователем вещественного числа и


возвращает это вещественное число. Аргумент <prompt> является
дополнительной строкой, которая должна отображаться в качестве
запроса. Например:

(setq val (getreal))


(setq val (getreal "Scale factor: "))

В ответ на запрос функции GETREAL ввести другое выражение LISPа


нельзя. Смотрите также INITGET.

4.59. (getstring [<cr>] [<prompt>])

Функция GETSTRING ожидает ввода пользователем строковой константы


и возвращает эту строку. Если <cr> задан и не равен нулю, строка может
содержать пробелы (должна, поэтому, заканчиваться вводом RETURN). В
противном случае ввод строки завершается пробелом или RETURN. Аргумент
<prompt> является дополнительной строкой, которая должна отображаться
в качестве запроса п поле подсказки. Например:

(setq s (getstring))
(setq s (getstring "What's your first name? "))
(setq s (getstring) T "What's your full name? "))

Если вводом пользователя должно быть одно из ключевых слов, то


вместо этой функции следует пользоваться функцией GETKWORD.

В ответ на запрос GETSTRING вы не можете ввести другое выражение


LISPа.
4.60. (getvar <varname>)

Эта функция возвращает значение системной переменной AutoCADа.


Имя переменной должно заключаться в двойные кавычки. Например, если
предположить, что последний заданный радиус сопряжения был 0.25 единиц
измерения, то:
(getvar "FILLETRAD") возвратит 0.250000

Список текущих системных переменных AutoCAD можно найти в прило-


жении А справочного руководства AutoCAD. Смотрите также функцию
SETVAR. Если в данной версии отсутствует указанная переменная, то воз-
вращается nil.

4.61. (graphscr)

Функция GRAPHSCR выполняет переключение экрана с текстового


режима на графический на одноэкранных системах (подобно функциональной
клавише "FLIP SCREEN" системы AutoCAD). Функция GRAPHSCR всегда
возвращает нуль. Смотрите также функцию TEXTSCR.

4.62. (if <testexpr> <thenexpr> [<elseexpr>])

Если аргумент <testexpr> - не равен nil, то функция вычисляет


аргумент <thenexpr>, в противном случае - аргумент <elseexpr>.
Последнее выражение (<elseexpr>) является необязательным. IF
возвращает значение выбранного выражения; если <elseexpr> отсутствует,
а <testexpr> равняется nil, то IF возвращает nil. Например:

(if (= 1 3) "YES!!" "no.") возвращает "no."


(if (= 2 (+ 1 1)) "YES!!") возвращает "YES!!"
(if (= 2 (+ 3 4)) "YES!!") возвращает nil

4.63. (initget [<bits>] [<string>])

Эта функция устанавливает различные опции для последующих функций


GETxxx (кроме GETSTRING и GETVAR). INITGET всегда возвращает nil.
Вспомогательный аргумент <bits> является целым числом со следующими
значениями:

____________________________________________________________
| INITGET Bits | Значение |
| /Биты функции/ | |
|__________________|_________________________________________|
| 1 | Запретить пустой ввод. |
|__________________|_________________________________________|
| 2 | Запретить ввод нуля . |
|__________________|_________________________________________|
| 4 | Запретить отрицательные значения. |
|__________________|_________________________________________|
| 8 | Не проверять соблюдение пределов, даже |
| | если LIMCHECK в активном состоянии. |
|__________________|_________________________________________|
| 16 | Возвратить трехмерные точки, а не дву- |
| | мерные. |
|__________________|_________________________________________|
| 32 | Использовать пунктирные линии для ре- |
| | зиновых нити и прямоугольника |
|__________________|_________________________________________|
Эти биты могут складываться в любой комбинации для задания
значения между 0 и 63.(Последующие версии Автолиспа могут включать
дополнительные управляющие биты,так что следует избегать
незадокументированных битов.) Если значение системной переменной
FLATLAND равно нулю ,то считается что установлен бит "трехмерная
точка".Если ввод пользователя не отвечает одному или более из заданных
условий (например, ввод нулевого значения, когда нулевые значения не
разрешаются), то AutoCAD высветит сообщение и запросит пользователя
повторить ввод снова. Например, на запрос:

(initget (+ 1 2 4))
(setq age (getint "How old are you? "))

будет получен ответ о возрасте пользователя, и в случае пустого


ответа, ввода отрицательного или нулевого значения система
автоматически повторит запрос. Если аргумент <bits> не задается, то
предполагается нуль (отсутствие условий). Управляющие биты учитываются
только теми функциями GETxxx,для которых они имеют смысл, как показано
в следующей таблице.

Если системная пременная POPUP равна нулю, т.е. отсутствует


усовершенствованный интерфейс пользователя, то бит 32 не учитывается
функциями GETxxx.

_______________________________________________________________________
| Учитываемые биты управления INITGET
|
Функция
|______________________________________________________|
| Нет | Нет | Нет | Нет | Точки
|Пунктир|
| пусто- | нуля | отриц. | соблю- | 3D |
|
| го | | ввода | дения | |
|
| ввода | | | пределов| |
|

________________|________|______|__________|__________|________|_______|
GETINT | . | . | . | | |
|

________________|________|______|__________|__________|________|_______|
GETREAL | . | . | . | | |
|

________________|________|______|__________|__________|________|_______|
GETDIST | . | . | . | | . | .
|

________________|________|______|__________|__________|________|_______|
GETANGLE | . | . | | | | .
|

________________|________|______|__________|__________|________|_______|
GETORIENT | . | . | | | | .
|

________________|________|______|__________|__________|________|_______|
GETPOINT | . | | | . | . | .
|

________________|________|______|__________|__________|________|_______|
GETCORNER | . | | | . | . | .
|

________________|________|______|__________|__________|________|_______|
GETKWORD | . | | | | |
|

________________|________|______|__________|__________|________|_______|
GETSTRING | | | | | |
|

________________|________|______|__________|__________|________|_______|
GETVAR | | | | | |
|

________________|________|______|__________|__________|________|_______|

Управляющий бит со значением 32 воспринимается функциями


GETPOINT,GETCORNER,GETDIST,GETANGLE и GETORIENT,когда присутствует
аргумент <базовая точка> ,и устанавливат режим использования
пунктирной (или подсвеченной ) линии в качестве "резиновой линии"
или рамки,отрисовываемых курсором от заданной базовой точки.Если
системная переменная POPUPS равна нулю,т.е. драйвер монитора не
поддерживает Развитый интерфейс пользователя,то Автокад
проигнорирует этот бит функции INITGET.
Дополнительный аргумент <string>/строка/ функции INITGET
определяет список ключевых слов, которые должны проверяться следующим
запросом функции GETxxx, если пользователь не вводит предполагаемый
тип данных (например, точку для функции GETPOINT). Если пользователь
вводит одно из ключевых слов этого списка, это ключевое слово
возвращается функцией GETxxx как строка. Пользовательская программа
может проверять ключевые слова и выполнять требуемое действие для
каждого ключевого слова. Если пользовательский ввод не соответствует
требуемому типу данных и ни одному из ключевых слов, то AutoCAD
запросит повторный ввод.

Список ключевых слов должен быть следующей формы: "Key1 KEY2


KEY3,ABBREV3". Между ключевыми словами должны быть пробелы.
Использование сокращений является вспомогательным средством, и
программой поддерживаются два метода задания их. Требуемую часть можно
выделить прописными

буквами, остальную - строчными, или требуемую часть можно повторить,


отделив от ключевого слова запятой. Второй метод способствует
разработке прикладных программ на иностранных языках, когда
преобразование букв из прописных в строчные и наоборот может быть
затруднительно или невозможно. В обоих методах длина требуемой части
является минимальной длиной строки, которая должна быть задана. (Для
метода с разграничительной запятой предполагается, что строка
сокращений является соответсвующим поднабором начала ключевого слова.)
Например:

"LTYPE, LT" и
"LType"

являются эквивалентными определениями. Каждое их них указывает на


то, что ввод пользователем "LTYPE", "LTYP", "LTY", или "LT" приемлем,
но ввод "L" недостаточен, а ввод "LTSCALE" и "LTYPEX" не годится.

Рассмотрим следующую определенную пользователем функцию:

(defun getnum (/ x)
(initget 1 "Pi Two-pi")
(setq x (getreal "Pi/Two-pi/<number>: "))
(cond ((eq x "Pi") pi)
((eq x "Two-pi") (* 2.0 pi))
(T x)
)
)

Эта функция запрещает пустой ввод и устанавливает список двух


ключевых слов, "Pi" и "Two-pi". Функция GETREAL затем используется для
получения вещественного после выдачи запроса "Pi/Two-pi/<number>:", и
результат помещается в локальный символ X. Если пользователь вводит
число, то число это возвращается посредством GETNUM. Однако, если
пользователь вводит ключевое слово "Pi" (или просто "P"), функция
GETPOINT возвращает ключевое слово "Pi". Функция COND обнаруживает это
и возвращает в этом случае значение pi. Ключевое слово "Two-pi"
обрабатывается аналогичным образом.
Управляющие биты и список ключевых слов, устанавливаемых функцией
INITGET, используются только до следующего вызова функции GETxxx, а
затем автоматически сбрасываются. Это устра- няет необходимость
сбрасывать эти специальные состояния вызовом дополнительной функции.

4.64. (inters <pt1> <pt2> <pt3> <pt4> [<onseg>])

Функция INTERS проверяет две линии и возвращает точку, в которой


они пересекаются, или nil, если они не пересекаются. <pt1> и <pt2>
являются конечными точками первой линии, а <pt3> и <pt4> - конечными
точками второй линии.Все точки выражены в координатах текущей UCS.
Если значение переменной FLATLAND равно нулю .то все четыре точки
являются трехмерными точками ,а INTERS контролирует пересечение в
трехмерном пространстве .В противном случае INTERS проецирует отрезки
на текущую плоскость построений и контролирует пересечение на
плоскости. Если присутствует вспомогательный аргумент <onseg> и если
он равен nil, то линии будут считаться бесконечными, и функция INTERS
возвратит точку, в которой они пересекаются, даже если эта точка лежит
за пределами одного или обоих отрезков. Если аргумент
<onseg> пропущен, или если он не равен nil^ точка пересечения должна
лежать на обоих отрезках, в противном случае функция INTERS возвратит
nil. Например, если:

(setq a '(1.0 1.0) b '(9.0 9.0))


(setq c '(4.0 1.0) d '(4.0 2.0))

то:

(inters a b c d) возвращает nil/нуль/


(inters a b c d T) возвращает nil/нуль/
(inters a b c d nil) возвращает (4.000000 4.000000)

4.65. (itoa <int>)

Эта функция возвращает целое число, преобразованное в строку.


Например:

(itoa 33) возвращает "33"


(itoa -17) возвращает "-17"

4.66. (lambda <arguments> <expr>...)

LAMBDA определяет "безымянную" функцию. Обычно она используется


тогда, когда затраты на определение новой функции не оправданы. Эта
функция также позволяет программисту поместить функцию туда, где она
будет использоваться. Функция LAMBDA возвращает значение последнего
выражения <expr> и часто используется в сочетании с функциями APPLY
и/или MAPCAR для выполнения функции на списке. Например:
(apply '(lambda (x y z)
(* x (- y z))
)
'(5 20 14)
) возвращает 30
и:

(mapcar '(lambda (x)


(setq counter (1+ counter))
(* x 5)
)
'(2 4 -6 10.2)
) возвращает (10 20 -30 51.000000)

4.67. (last <list>)

Эта функция возвращает последний элемент в списке <list>.


Аргумент <list> не должен быть nil. Например:

(last '(a b c d e)) возвращает E


(last '(a b c (d e))) возвращает (D E)

Как показано, функция LIST может возвращать атом или список.

При первом рассмотрении, LAST может показаться идеальным


средством для выделения координаты Y какой-то точки. Это
действительно верно для точки двумерного пространства/2D/
(списка двух вещественных чисел), функция LAST будет возвращать
координату Z трехмерной точки 3D. Чтобы ваши функции срабатывали
одинаково верно как для трехмерных, так и для двумерных точек,
мы предлагаем использовать CADR для выделения координаты Y и
CADDR для выделения координаты Z.

4.68. (length <list>)

Эта функция возвращает целое число, равное количеству элементов в


списке. Например:

(length '(a b c d)) возвращает 4


(length '(a b (c d))) возвращает 3
(length '() ) возвращает 0

В Автолиспе эта функция часто используется для определения значений


дву- и трехмерных точек (список из двух или трех действительных
чисел).

4.69. (list <expr>...)

Эта функция берет любое количество выражений (<expr>), объединяет


их в список. Например:

(list 'a 'b 'c) возвращает (A B C)


(list 'a '(b c) 'd) возвращает (A (B C) D)
(list 3.9 6.7) возвращает (3.90000 6.70000)
В AutoLISPе эта функция часто используется для определения
точечной переменной 2D или 3D (списка двух или трех вещественных
чисел).
4.70. (listp <item>)

Эта функция возвращает T, если аргумент <item> является списком,


и nil в противном случае. Например:

(listp '(a b c)) возвращает T


(listp 'a) возвращает nil/нуль/
(listp 4.343) возвращает nil/нуль/

4.70. (load <filename>) [<ошибка>]

Эта функция загружает в файл выражений AutoLISPа и вычисляет эти


выражения. Аргумент <filename> является строковая константа, которая
представляет имя файла без расширения (предполагается расширение
".lsp"). <filename> может включать префикс каталога, как например,
"/function/test_1". В системах MS-DOS/PC-DOS допускается также
идентификатор накопителя, и вы можете использовать вместо прямой косой
обратную косую (но помните, что для получения одной обратной косой в
строке необходимо использовать "\\".)
Если операция проходит успешно, функция LOAD возвращает имя
последней определенной в файле функции. Если операция не
выполнена,обычно вызывается стандартный обработчик ошибок
Автолиспа.Однако,если имеется аргумент <ошибка>,то LOAD возвращает
этот аргумент вместо стандартной обработки ошибки. Это позволяет при
выэове функции LOAD в прикладных программах на Автолиспе иметь
альтернативное действие при ошибке.Конечно ,необходимо помнить ,что
аргумент <ошибка> должен отличаться от последнего выражения в
загружаемом файле;в противном случае смысл значения ,возвращаемого
функцией LOAD ,будет не понятен.

Пример: предположим, что файл "/fred/test1.lsp" содержит

(defun MY-FUNC1 (x)


........содежание функции....
)
(defun MY-FUNC2 (x)
.......содержание функции .....
)

и что файл "test2.lsp" не существует.Тогда

(load "/fred/test1") возвращает MY-FUNC2


(load "/fred/test1" "Bed") возвращает MY-FUNC2
(load "test2" "Bed") возвращает "Bad"
(load "test2") возвращает обработчик ошибок
Автолиспа

Функция LOAD может вызываться из другой функции Автолиспа или


даже рекурсивно (в загруженном файле).
Всякий раз, когда начинается сеанс редактирования чертежей
AutoCADа, AutoLISP загружает файл "acad.lsp", если он существует. Вы
можете поместить в этот файл определения функций и часто используемые
команды, и они будут автоматически вычисляться всякий раз, когда вы
начинаете сеанс редактирования.При необходимости иметь серию команд
Автокада или функций Автолиспа ,выполняемых автоматически в начале
сеанса редактирования,можно поместить функцию DEFUN специальной
функции "S::STARTUP" в файле "acad.lsp".(Примеры см.в описании функции
DEFUN.)
4.72. (log <number>)

Эта функция возвращает натуральный логарифм аргумента <number> в


виде вещественного числа. Например:

(log 4.5) возвращает 1.504077


(log 1.22) возвращает 0.198850

4.73. (logand <number> <number> ... )

Эта функция возвращает результат логической битовой функции AND


применяемой к списку чисел <number>... . Числа должны быть целыми, и
результат также является целым числом. Например:

(logand 7 15 3) возвращает 3
(logand 2 3 15) возвращает 2
(logand 8 3 4) возвращает 0

4.74. (loqior <number> <number>...)

Эта функция возвращает результат логической битовой функции


"ИЛИ" для списка чисел <number> ... . Например:

(logior 1 2 4) возвращает 7
(logior 9 3) возвращает 11

4.75. (lsh <num1> <numbits>)

Эта функция возвращает результат логического битового сдвига


числа <num1> на количество битов <numbits>. Аргументы <num1>
и <numbits> должны быть целыми числами и результат также является
целым числом.
Если аргумент <numbits> положителен, то <num1> сдвигается влево;
если отрицателен, то - вправо. В любом случае включаются нулевые биты,
а бины выходящие за пределы разрядной сетки теряются. Если происходит
перенос "1" в старший бит или из старшего, (16-ого) бита целого числа,
то знак его меняется.

Например:

(lsh 2 1) возвращает 4
(lsh 2 -1) возвращает 1
(lsh 40 2) возвращает 160
(lsh 16384 1) возвращает -32768 для 16-разрядных машин
(lsh 16384 1) возвращает 32768 для 32-разрядных машин
4.76. (mapcar <function> <list1>...<listn>)

Функция MAPCAR возвращает результат выполнения функции <function>


над отдельными элементами списков от <list1> до <listn>, передаваемыми
в функцию в качестве аргументов. Число списков должно соответствовать
числу аргументов, требуемых функцией. Например:
(mapcar '1+ '(10 20 30)) возвращает (11 21 31)

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

(1+ 10)
(1+ 20)
(1+ 30)

за исключением того, что MAPCAR возвращает результат в виде


списка. Аналогично:

(mapcar '+ ' (10 20 30) '(4 3 2)) возвращает (14 23 32)

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

(+ 10 4)
(+ 20 3)
(+ 30 2)

Функция LAMBDA может задавать "безымянную" функцию, выполняемую


посредством MAPCAR. Это полезно, когда несколько аргументов функции
являются постоянными, или задаются какими-то другими методами.

Например:
(mapcar '(lambda (x) (+ x 3)) '(10 20 30)) возвращает (13 23 33)

и:

(mapcar '(lambda (x y z)
(* x (- y z))
)
'(5 6) '(20 30) '(14 5.0)
) возвращает (30 150.0)

4.77. (max <number> <number> ...)

Эта функция возвращает максимальное чисел <number>. Каждое число


может быть вещественным или целым. Например:

(max 4.07 -144) возвращает 4.07


(max -88 19 5 2) возвращает 19

4.78. (member <expr> <list>)

Эта функция отыскивает в списке <list> вхождение аргумента <expr>


и возвращает остаток списка, начиная с первого вхождения <expr>. Если
аргумент <expr> отсутствует в списке, то функция MEMBER возвращает
nil. Например:

(member 'c '(a b c d e)) возвращает (C D E)


(member 'q '(a b c d e)) возвращает nil

4.79. (menucmd <string>)


Функция MENUCMD обеспечивает программное средство переключения
подстраниц в меню AutoCADа. Таким образом, программа LISPа может
работать синхронно с файлом меню, отображая соответствующее подменю
всякий раз, когда требуется пользовательский ввод. Функция всегда
возвращает nil. Аргумент <string> функции MENUCMD имеет следующую
форму:

section=submenu
раздел=подменю

где:

section/раздел/ - задает раздел меню. Верными именами будут


следующие:

S (для ЭКРАННОГО меню)


B (для КНОПОЧНОГО меню)
I для пиктографического меню
P1-P10 для падающих меню с первого по десятое
T1-T4 меню ПЛАНШЕТА с первого по четвертое
A1 (для меню AUX1)

submenu /подменю/ - определяет какое подменю необходимо


активизировать. Именем может быть либо одно из названий подменю (без
"**") в файле меню, загруженном в данный момент, либо имя раздела
главного меню.

Смотрите более подробную информацию в приложении B справочного


руководства AutoCADа. Обратите внимание на то, что ведущий символ $,
используемый для обращения к подменю в файле меню, не используется
здесь. Например:

(menucmd "S=OSNAP")

вызывает появление подменю OSNAP на экране (при условии, если


такое подменю существует в текущем файле меню). Аналогично:

(menucmd "B=MY-BUTTONS")

присвоит подменю "MY-BUTTONS" кнопкам.

Для пиктографического и падающего меню "*" является допустимым


именем подменю и вызывает визуализацию подменю, присвоенного данному
разделу. Например:

(menucmd "P1=NUMERIC")
(menucmd "P1=*")

присвоит подменю NUMERIC падающему меню 1, а затем поместит его


на экран.MENUCMD всегда возвращает ноль.
4.80. (min <number> <number>... )

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


Каждое число может быть вещественным или целым. Например:
(min 683 -10.0) возвращает -10.0
(min 73 2 48 5) возвращает 2

4.81. (minusp <item>)

Эта функция возвращает T, если аргумент <item> является


отрицательным вещественным или целым числом, в противном случае
возвращает nil. Она не определяется для других типов аргумента <item>.
Например:

(minusp -1) возвращает T


(minusp -4.293) возвращает T
(minusp 830.2) возвращает nil

4.82. (not <item>)

Эта функция возвращает T, если выражение равно nil, и возвращает


нуль в противном случае. Обычно функция NULL используется для списков
и NOT используется для других типов данных вместе с некоторыми
управляющими функциями. Например, если имеются следующие выражения:

(setq a 123)
(setq b "string")
(setq c nil)

то:

(not a) возвращает nil(нуль)


(not b) возвращает nil(нуль)
(not c) возвращает T
(not '() ) возвращает T

4.83. (nth <n> <list>)

Эта функция возвращает элемент n-тый из списка, где <n> является


номером элемента, который необходимо возвратить (нуль - это первый
элемент). Если <n> больше количества элементов в списке, то
возвращается nil. Например:

(nth 3 '(a b c d e)) возвращает D


(nth 0 '(a b c d e)) возвращает A
(nth 5 '(a b c d e)) возвращает nil(нуль)

4.84. (null <item>)

Эта функция возвращает T, если аргументу <item> присваивается


nil, в противном случае возвращается nil. Например, рассмотрим
следующее:

(setq a 123)
(setq b "string")
(setq c nil)
тогда:

(null a) возвращает nil(нуль)


(null b) возвращает nil(нуль)
(null c) возвращает T
(null '()) возвращает T

4.85. (numberp <item>)

Эта функция возвращает T, если элемент <item> - вещественное или


целое число, и nil в противном случае. Например, если:

(setq a 123)
(setq b 'a)

то:

(numberp 4) возвращает T
(numberp 3.8348) возвращает T
(numberp "Howdy") возвращает nil
(numberp 'a) возвращает nil(нуль)
(numberp a) возвращает T
(numberp b) возвращает nil/нуль/
(numberp (eval b)) возвращает T

4.86. (open <filename> <mode>)

Эта функция открывает файл для обеспечения доступа к нему с


помощью функций ввода/вывода AutoLISPа. Она возвращает дескриптор
файла, который должен использоваться другими функциями ввода/вывода,
поэтому результат выполнения данной функции должен присваиваеться
некому символу с помощью SETQ. Например:

(setq a (open "file.ext" "r"))

<filename> это строка, задающая имя и расширение открываемого


файла. <mode> - режим чтения/записи. Он должен быть строкой из одной
буквы,набранной нанижнем регистре. Допустимые коды режимов описаны в
следующей таблице:

__________________________________________________________________
режим | ОПИСАНИЕ |
OPEN | |
__________|______________________________________________________|
"r" | Окрыт для чтения. Если <filename> не существует, |
| то возвращается nil. |
__________|______________________________________________________|
"w" | Открыт для записи. Если <filename> не существует, то|
| создается и открывается новый файл. Если <filename> |
| существует, то его данные перезаписываются. |
__________|______________________________________________________|
"a" | Окрыт для добавления. Если <filename> не существует,|
| то создается и открывается новый файл. Если <имя|
| файла> уже существует, то он открывается и новые |
| данные, которые вы записываете в файл, будут |
| добавляться вслед за существующими. |
| |
| В системах DOS некоторые программы и редакторы |
| текстов записывают текстовые файлы с меткой конца|
| файла (CTRL Z, десятичный ASCII код 26) после |
| текста. При считывании текстового файла, когда|

| встречается метка CTRL Z, DOS возвращает состояние|


| конца файла даже в том случае, когда после нее идут|
| данные. Если вы намереваетесь использовать режим "a"|
| функции OPEN для добавления данных в файлы,|
| создаваемые другой программой, убедитесь в том, что|
| другая программа не вставляет метки CTRL Z в конце|
| своих текстовых файлов. |
__________|______________________________________________________|

Предположим, что файлы, рассмотренные в следующих примерах,не


существуют:

(setq f (open "new.tst" "w")) возвращает <File #nnn>


(setq f (open "nosuch.fil" "r")) возвращает nil
(setq f (open "logfile" "a")) возвращает <File #nnn>

Имя файла может включать префикс каталога, как например,


"/test/func3". В системах MS-DOS/PC-DOS допускается также
идентификатор накопителя, и вы можете использовать вместо прямой косой
обратную (но помните, что для получения одной косой в строке
необходимо использовать "\\").

Например:

(setq f (open "/x/new.tst" "w")) возвращает <File #nnn>


(setq f (open "nosuch.fil" "r")) возвращает nil/нуль/

4.87. (or <expr> ...)

Эта функция возвращает результат логического ИЛИ для списка


выражений. Если все выражения равны nil, то OR возвращает nil, в
противном случае возвращает T. Например:

(or nil 'a '()) возвращает T


(or nil '()) возвращает nil

4.88. (osnap <pt> <mode-string>)

Эта функция возвращает точку, которая является результатом


использования режимов объектной привязки объекта, заданных аргументом
<mode-string> для точки <pt>. Аргумент <mode-string> является строкой,
состоящей из одного или более допустимых идентификаторов режима
фиксации объектов, таких как "midpoint"/ середина/, "center"/центр/,
т.д., разделенных запятой. Например:

(setq pt2 (osnap pt1 "midp"))


(setq pt2 (osnap pt1 "midp,endp,center"))

Если аргумент <pt> является точкой двумерного пространства


(списком двух вещественных чисел), то возвращается двумерная точка.
Если аргумент <pt> - точка трехмерного пространства (списком трех
вещественных чисел), то возвращается точка трехмерного пространства.
Если для данной точки <pt> не найдена ни одна точка фиксации объекта,
соответствующая заданному режиму, то возвращается nil.
Действия этой функции зависит от текущего трехмерного вида и от
значения системной переменной FLATLAND.(Подробнее см.Рукводство по
системе Автокад,гл.8 и приложение D).

4.89. pi

Это не функция, а постоянная pi. Она равна приблизительно


3.1415926.

4.90. (polar <pt> <angle> <distance>)

Эта функция возвращает точку в UCS,под углом <angle> на


расстоянии <distance> от точки <pt>.Угол измеряется в радианах в
направлении против часовой стрелки от оси X .Хотя точки могут быть
трехмерными ,<угол> всегда определяется в текущей плоскости
построений. Если значение переменной FLATLAND равно нулю ,то
возвращаются трехмерные точки ,а в противном случае - двумерные.

Например:
Предположим ,что значение переменной FLATLAND равно 0

(polar '(1.0 1.0 3.5) 0.785398 1.414214) возвращает (2.0 2.0 3.5)

4.91. (prin1 <expr> [<file-desc>])

Эта функция выводит выражение <expr> на экран и возвращает


<expr>. Аргументом <expr> может быть любое выражение; необязательно,
чтобы это была строка. Если <file-desc> присутствует (и является
дескриптором открытого для записи файла), то <expr> записывается в
файл точно в таком виде, в каком оно появилось бы на экране.
Печатается только заданное выражение; никаких новых строк или пробелов
не включается. Например, если:

(setq a 123)
(setq b '(a))

то:

(print1 'a) печатает A и возвращает A


(print1 a) печатает 123 и возвращает 123
(print b) печатает (A) и возвращает (A)
(print "Hello") печатает "Hello" и возвращает "Hello"
Каждая из записей предыдущих примеров выводится на экран, т.к. не
задавался дескриптор файла <file-desc>. Предположим, что F является
верным дескриптором открытого для записи файла:

(print1 "Hello" f)
запишет "Hello" в заданный файл и возвратит "Hello".

Если <expr> является строкой, содержащей символы управления,


PRIN1 отредактирует эти символы с помощью приставки "\" следующим
образом:

\e для ESC
\n для новой строки
\r для возврата
\t для табуляции
\nnn для символа, восьмеричным кодом которого является nnn

Таким образом:

(prin1 (chr 2)) печатает "\002" и возвращает "\002"


(prin1 (chr 10)) печатает "\n" и возвращает "\n"

PRINT1 может использоваться без аргументов. В этом случае она


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

обеспечивает красивое завершение.

Пример:
пусть
(defun C:SETUP ()
(setvar "LUNITS" 4)
(setvar "BLIPMODE" 0)
(print1)

Тогда
Command:SETUP
исполнит определенную пользователем команду ,отвечая на запросы
функции SETVAR,и вернется к подсказке Автокада "Command" нне выводя на
экран никаких лишних сообщений.

4.92. (princ <expr> [<file-desc>])

Эта функция подобна функции PRIN1 за исключением того, что


символы управления в <expr> печатаются без расширения. В общем, PRIN1
предназначена для того, чтобы печатать выражения таким образом, чтобы
они были совместимы с LOAD, тогда как PRINC будет печатать их
пригодными для считывания такими функциями, как READ-LINE.

4.93. (print <expr> [<file-desc>])

Эта функция аналогична функции PRIN1 с тем лишь исключением, что


перед <expr> вводится новая строка, а после <expr> вводится пробел.
4.94. (progn <expr> ...)

Эта функция последовательно вычисляет каждое выражение <expr> и


возвращает значение последнего выражения. Вы можете использовать
функцию PROGN для вычисления нескольких выражений там, где
предполагается только одно. Например:

(if (= a b) (progn
(setq a (+ a 10))
(setq b (- b 10))
)
)

Если условное выражение имеет любое значение, кроме nil, то


функция IF обычно вычисляет одно выражение "then". В этом примере мы
использовали PROGN для вычисления двух выражений.

4.95. (prompt <msg>)

Эта функция отображает <msg> в экранной области подсказок и


возвращает nil. Аргумент <msg> является строкой. На системах AutoCAD с
двумя экранами PROMPT отображает <msg> на обоих экранах, и поэтому
является более предпочтительной, чем PRINC. Например:

(prompt "New value: ")

отображает "New value: " на экране(экранах) и возвращает nil.

4.96. (quote <expr>)

Возвращает аргумент <expr> не вычисляя его. Это может быть также


записано следующим образом:

'expr

Например:

(qoute a) возвращает A
(qoute cat) возвращает CAT
(quote (a b)) возвращает (A B)

'a возвращает A
'cat возвращает CAT
'(a b) возвращает (A B)

(Последние три примера не сработают, если будут вводиться


непосредственно с клавиатуры в ответ на запрос AutoCADа. Помните, что
такой ввод должен начинаться с "(" или "!" с тем, чтобы он был
распознан выражением LISPа).

4.97. (read <string>)

Эта функция возвращает первый список или атом, выделенный из


строки <string>. Например:

(read "hello") возвращает HELLO


(read "hi") возвращает HI
(read " (a)") возвращает (A)
4.98. (read-char [<file-desc>])

Эта функция считывает один символ из буфера клавиатуры или из


открытого файла, с дескриптором <file-desc>. Она возвращает целое
число (код ASCII считанного символа).
Если дескриптор файла не задан, и символов в буфере клавиатуры
нет, то функция READ-CHAR ожидает ввода с клавиатуры, (который
завершается клавишей RETURN). Например, предположим, что буфер
клавиатуры пуст:

(read-char)

будет ждать какого-либо ввода. Если вы введете "ABC", а затем


RETURN, то функция READ-CHAR возвратит 65 (код ASCII для буквы "A").
Следующие три вызова функции READ-CHAR возвратят 66, 67 и 10 (новая
строка) соответственно. В случае еще одного обращения к READ-CHAR, она
будет снова ожидать какого-либо ввода.
В операционных системах используются различные соглашения по
симвлам конца строки в текстовых (ASCII) файлах.Операционная система
UNIX например,использует оддин символ возврата каретки (ASCII код
10),в то время как операционные системы MS-DOS/PC-DOS используют два
символа:символ перехода на новую строку и символ возврата кареки
(ASCII коды 13 и 10 )для тех же целей.Во избежание двусмысленности при
работе в различных операционных средах функция READ-CHAR учитывает все
эти соглашения,возвращая один символ перехода на новую строку (ASCII
код 10) при чтении символа (символов) конца строки.

4.99. (read-line [<file-desc>])

Эта функция считывает строку, введенную с клавиатуры или из


открытого файла, определенного при помощи дескриптора <file-desc> .
Если встречается конец файла, то READ-LINE возвращает nil, в противном
случае возвращает считанную строку. Например, предположим, что F
является дескриптором открытого файла:

(read-line f)

возвратит следующую строку из файла или nil, если достигнут конец


файла.

4.100. (redraw [<ename> [<mode>]])

Действие этой функции зависит от количества аргументов. Если


функция вызывается без аргументов:

(redraw)

то она перечерчивает весь чертеж подобно команде REDRAW системы


AutoCAD. Если же функция вызывается с аргументом, которым является имя
примитива:

(redraw <ename>)

то она перечертит выбранный примитив. Это полезно для выделения


примитива на экране после использования GRCLEAR для очистки экрана.
Имена примитивов описаны в главе 5 данного руководства.

Посредством вызова функции REDRAW с двумя аргументами осуществля-


ется полный контроль над перечерчиванием примитива:

(redraw <ename> <mode>)

где <ename> есть имя перечерчиваемого примитива, а <mode> - целое


число, имеющее одно из следующих значений:

-----------------------------------------------------------------
REDRAW режим | Действие |
| |
----------------|-----------------------------------------------|
1 | Перечертить примитив на экране. |
----------------|-----------------------------------------------|
2 | Отменить перечерчивание примитива(стирает) |
----------------|-----------------------------------------------|
3 | Высветить примитив более ярким светом (если|
| это позволяет дисплей) |
----------------|-----------------------------------------------|
4 | Отменить высвечивание примитива (если |
| позволяет дисплей) |
-----------------------------------------------------------------

Если аргумент <ename> является заголовком сложного примитива


(Полилинии или Блока с атрибутами), и если аргумент <mode>
положительный, то обрабатываться будет головной примитив и его
подпримитивы. Если аргумент <mode> отрицательный, то функцией REDRAW
обрабатываться будет только головной.

Функция REDRAW всегда возвращает nil, если не возникает никаких


ошибок.

4.101. (rem <num1> <num2> ...)

Эта функция делит <num1> на <num2> и возвращает остаток (<num1>


mod <num2>). Функция REM может использоваться с вещественными или
целыми числами, при этом действуют стандартные правилам
преобразования. Например:

(rem 42 12) возвращает 6


(rem 12.0 16) возвращает 12.0
(rem 60 3) возвращает 0

4.102. (repeat <number> <expr> ...)

В этой функции аргумент <number> представляет любое положительное


число. Функция оценивает каждый аргумент <expr> столько раз, сколько
указывается аргументом <number>, и возвращает значение последнего
выражения. Например, если:

(setq a 10)
(setq b 100)
то:

(repeat 4
(setq a (+a 10))
(setq b (+b 10))
) возвращает: 140

4.103. (reverse <list>)

Эта функция возвращает список <list> с элементами, расположенными


в обратном порядке. Например:

(reverse '((a) b c)) возвращает (C B (A))

4.104. (rtos <number> [<mode> [<precision>]])

Эта функция возвращает строку, которая представляет аргумент


<number> (вещественное число) в соответствии с значениями аргументов
<mode>/режим/, <precision>/точность/ и системной переменной DIMZIN
системы AutoCAD. Аргументы <mode> и <precision> являются целыми
числами, которые определяют формат и точность метрических единиц.

Значения аргумента <mode>, перечислены в следующей таблице.

----------------------------------------------------------------
RTOS Mode | Формат редактирования |
/Режим/ | |
--------------|------------------------------------------------|
1 | Научный |
--------------|------------------------------------------------|
2 | Десятичный |
--------------|------------------------------------------------|
3 | Технический (футы и десятичные доли дюймов) |
--------------|------------------------------------------------|
4 | Архитектурный (футы и дробные дюймы) |
--------------|------------------------------------------------|
5 | Произвольные дробные единицы |
----------------------------------------------------------------

Аргументы <mode>/режим/ и <precision>/точность/ соответствуют


переменным LUNITS и LUPREC системы AutoCAD. Если вы опускаете эти
аргументы, то будут использоваться текущие установки LUNITS и LUPREC.
Примеры использования функции RTOS даны ниже:

Пусть DIMZIN=0

(rtos 17.5 1 4) возвращает "1.7500E+01"


(rtos 17.5 2 2) возвращает "17.50"
(rtos 17.5 3 2) возвращает "1'-5.50""
(rtos 17.5 4 2) возвращает "1'-5 1/2""
(rtos 17.5 5 2) возвращает "17 1/2"
- 54 -

4.105. (set <sym> <expr>)


Эта функция приписывает значение <sym> (где <sym> есть имя
символа с предшествующей кавычкой) аргументу <expr> и возвращает
значение выражения. Например:

(set 'a 5.0) возвращает 5.0 и устанавливает символ A


(set (quote b) 'a) возвращает A и устанавливает символ B

Если SET используется с именем символа без кавычки, то она может


непосредственно присвоить новое значение другому символу. Например,
учитывая выше указанные примеры:

(set b 640) возвратит 640

и присвоит значение 640 символу A (т.к. именно это значение


содержит символ B). Смотрите также функцию SETQ ниже.

4.106. (setq <sym1> <expr1> [<sym2> <expr2>] ...)

Эта функция присваивает значение <sym1> аргументу <expr1>, <sym2>


- аргументу <expr2>, т.д. Это основная функция присвоения значений в
AutoLISPе. Она возвращает последний аргумент <expr>. Например:

(setq a 5.0) возвращает 5.0

и устанавливает символ A на 5.0. Всякий раз, когда оценивается A,


будет выбираться вещественное число 5.000000. Ниже даются другие
примеры:

(setq b 123 с 4.7) возвращает 4.7


(setq s "it") возвращает "it"
(setq x '(a b)) возвращает (A B)

Функции SET и SETQ создают или модифицируют общие символы, если


не используются внутри DEFUN для присвоения значения аргументу функции
или символу, объявленному как локальный по отношению к этой DEFUN.
Например:

(setq glo1 123) ;Создает общий символ


(defun demo (arg1 arg2 / loc1 loc2)
(setq arg1 234) ;Локально присваивает новое значение
(setq loc1 345) ;Локально присваивает новое значение
(setq glo1 456) ;Глобально присваивает новое значение
(setq glo2 567) ;Создает новый общий символ
)

Доступ к общим символам и модификация их может осуществляться


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

__________________________________________________________
| Функции SET и SETQ могут присваивать новые значения |
| встроенным символам AutoLISPа и именам функций, игнорируя|
| первоначальные значения или делая их недоступными. |
| Некоторые пользователи пытались ошибочно сделать |

| следующее: |
| |
| (setq angle (...)) ;Неправильно! |
| (setq length (...)) ;Неправильно! |
| (setq max (...)) ;Неправильно! |
| (setq t (...)) ;Неправильно! |
| (setq pi 3.0) ;Неправильно!!! |
| |
| Чтобы избежать ошибок подобного рода, будьте осторожны |
| при выборе имен для ваших собственных символов. НИКОГДА |
| НЕ ИСПОЛЬЗУЙТЕ ВСТРОЕННЫЙ СИМВОЛ ИЛИ ИМЯ ФУНКЦИИ ДЛЯ |
| ВАШЕГО СОБСТВЕННОГО СИМВОЛА! (Перед загрузкой любой |
| функции AutoLISP введите "!ATOMLIST" в ответ на запрос |
| системы AutoCAD "Command:", чтобы узнать, какие символы |
| не следует использовать. |
|__________________________________________________________|

4.107. (setvar <varname> <value>)

Эта функция присваивает переменной <variable> системы AutoCAD


заданное значение <value> и возвращает это значение. Имя переменной
должно заключаться в кавычки. Например:

(setvar "FILLETRAD" 0.50) возвращает 0.5

устанавливает радиус сопряжения равным 0.5 единиц.Для системных


переменных с целыми значениями <value> должно быть в диапазоне от -32
768 до +32 767.Некоторые команды Автокада выбирают системные
переменные без всяких подсказок.При использовании SETVAR для установки
нового значения системной переменной в процессе выполнения некоторой
команды эта установка будет иметь силу только при выполнении следующей
команды Автокада.
Список текущих переменных системы AutoCAD можно найти в
приложении A справочного руководства AutoCADа. Смотрите также функцию
GETVAR.

4.108. (sin <angle>)

Эта функция возвращает синус угла <angle> как вещественное число,


где угол выражается в радианах. Например:

(sin 1.0) возвращает 0.841471


(sin 0.0) возвращает 0.0

4.109. (sqrt <number>)

Эта функция возвращает квадратный корень числа <number> как


вещественное число. Например:
(sqrt 4) возвращает 2.0
(sqrt 2.0) возвращает 1.414214

4.110. (strcase <string> [<which>])


Функция STRCASE принимает строку, заданную аргументом <string>, и
возвращает копию со всеми буквенными символами, преобразованными в
верхний или нижний регистр, в зависимости от значения второго
аргумента <which>. Если аргумент <which> пропускается или указывает на
nil, то все буквенные символы в строке будут преобразованы в верхний
регистр. Если аргумент <which> используется, и значение его не равно
нулю, то все буквенные символы в строке преобразовываются в нижний
регистр. Например:

(strcase "Sample") возвращает "SAMPLE"


(strcase "Sample" T) возвращает "sample"

4.111. (strcat <string1> <string2> ...)

Эта функция возвращает строку, которая является конкатенацией


аргументов <string1>, <string2>, т.д. Например:

(strcat "a" "bout") возвращает "about"


(strcat "a" "b" "c") возвращает "abc"
(strcat "a" "" "c") возвращает "ac"

4.112. (strlen <string>)

Эта функция возвращает длины строки <string> в виде целого числа.


Например:

(strlen "abcd") возвращает 4


(strlen "ab" возвращает 2
(strlen "") возвращает 0

4.113. (subst <newitem> <olditem> <list>)

Эта функция отыскивает в списке <list> аргумент <olditem>/старый


элемент/ и возвращает копию списка с аргументом <newitem>/новый
элемент/ вместо каждого вхождения аргумента <olditem>/старый элемент/.
Если аргумент <olditem> не найден в списке, функция SUBST возвращает
список неизменным. Например:

(setq sample ' (a b (c d) b))

Тогда:

(subst 'qq 'b sample) возвращает (A QQ (C D ) QQ)


(subst 'qq 'z sample) возвращает (A B (C D) B)
(subst 'qq '(c d)sample) возвращает (A B QQ B)
(subst '(qq rr) '(c d) sample) возвращает (A B (QQ RR) B)
(subst '(qq rr) 'z sample) возвращает (A B (C D) B)

Когда функция SUBST используется вместе с ASSOC, то она


обеспечивает удобное средство замены значения, связанного с ключом в
ассоциативном списке. Например, если принять во внимание:
(setq who '((first join) (mid q) (last public)))

тогда:

(setq old
(assoc 'first who)
) возвращает (FIRST JOHN)
(setq new '(first j)) возвращает (FIRST J)
(subst new old who) возвращает (FIRST J) (MID Q) (LAST PUBLIC)

4.114. (substr <string> <start> [<length>])

Эта функция возвращает подстроку строки <string>, начиная с


начальной/<start>/ позиции символа в строке <string> длиной <length>
символов. Если аргумент <length>/длина/ не задан, то подстрока
продолжается до конца строки <string>. Аргументы <start> (и <length>,
если имеется) должны быть положительными целыми числами. Первым
символом строки будет символ номер один. Например:

(substr "abcde" 2) возвращает "bcde"


(substr "abcde" 2 1) возвращает "b"
(substr "abcde" 3 2) возвращает "cd"

4.115. (terpri)

Эта функция печатает новую строку на экране. Она также возвращает


символ перевода строки. Функция TERPRI не используется для файла .
Чтобы ввести новую строку в файл, используйте функции PRINT или PRINC.

4.116. (textscr)

Функция TEXTSCR служит для переключения с экрана графического


режима в текстовый в случае одноэкранных систем (аналогично
функциональной клавише "FLIP SCREEN" системы AutoCAD). Функция TEXTSCR
всегда возвращает nil. Смотрите также функцию GRAPHSCR.

4.117. (trace <function> ...)

Эта функция является средством отладки. Она устанавливает режим


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

(trace my-func) возвращает MY-FUNC

и устанавливает режим прослеживания для функции MY-FUNC. Смотрите


также функцию UNTRACE.

4.118 (trans <точка> <из> <в> [<вектор>]

Данная функция преобразует координаты точки (или величину


перемещения) из одной системы координат в другую.Аргумент
<точка>-список трех действительных чисел,который можно
интерпретировать либо как трехмерную точку,либо как трехмерное
перемещение (вектор).<из>-код системы координат в которой находится
указанная <точка>, а <в>-код системы координат,в которой происходит
преобразование координат точки.Если присутствует факультативный
аргумент <вектор> и его значение не равно нулю,то аргумент <точка>
будет трактоваться как трехмерное перемещение.Аргументы <из> и <в>
могут иметь следующие значения:
Целочисленный код берется из следующей таблицы:

-----------------------------------------------------------
| Код | Система координат |
-----------------------------------------------------------
| 0 | Мировая (WCS) |
-----------------------------------------------------------
| 1 | Пользовательская (текущая UCS) |
-----------------------------------------------------------
| 2 | Экранная (DCS текущего видового экрана) |
-----------------------------------------------------------

- Имя примитива ,которое возвращается такими функциями,как


ENTNEXT,ENTLAST,ENTSEL и SSNAME (см.гл.5),что позволяетпреобразовать
координаты точки из и в Объектную систему координат (OCS) отдельно
взятого примитива.(Для некоторых примитивов OCS тождественна WCS;для
таких примитивов преобразования между OCS и WCS - пустая операция.)

- Трехмерный вектор выдавливания (список трех действительных


чисел).Это еще один метод преобразования из и в OCS.Однако такой метод
не имеет смысла для тех примитивов,для которых OCS тождественна WCS.
Функция TRANS возвращает трехмерную точку (или перемещение) с
координатами,преобразованными в указанную аргументом < к > систему
координат.
Пример: Пусть UCS повернута на угол 90 градусов против часовой
стрелки вокруг оси Z относительно WCS.

(trans ' (1.0 2.0 3.0) 0 1) возвращает (2.0 -1.0 3.0)


(trans ' (1.0 2.0 3.0) 1 0) возвращает (-2.0 1.0 3.0)

Ниже дается описание систем координат,между которыми может


осуществлять преобразования функция TRANS, а также их применения.

WCS - Это "базовая " система координат .Все остальные системы


координат определяются относительно WCS.WCS - единственная неизменная
система координат.Все величины ,измеренные относительно WCS,не
изменяются при переходе к другим системам координат.
UCS - Это "рабочая "система координат ,создаваемая пользователем с
целью упрощения некоторых задач редактирования (или с другой
целью).Любое указание точки (включая точки ,возвращаемые выражениями
Автолиспа,но исключая точки,которым предшествует "*") воспринимается
относящимся к этой системе координат.Поэтому ,если необходимо передать
значения координат из WCS,OCS или DCS командам Автокада следует
преобразовать их в UCS с помощью функции TRANS.
OCS - Значения координат точки,возвращаемой функцией ENTGET
(см.гл.5),берутся в этой системе координат .Такие точки не
используются без преобразования в систему координат,в которой они
будут в дальнейшем применяться.
Если ,например,необходимо построить отрезок из точки вставки строки
текста (нее пользуясь объектной привязкой или функцией OSNAP),следует
преообразовать координаты точки вставки примитива текст(TEXT) из OCS
этого примитива в UCS

(trans <точка-вставки-текста> <имя-примитива-TEXT> 1)

и передать результат в качестве ответа на подсказку "From point:"


Однако следует произвести обратное преобразование значений
координат точки (или перемещения) в соответсвующую OCSперед тем,как
передать их функции.Если, например, необходимо переместить круг(не
пользуясь командой MOVE) на величину 1,2,3 в UCS,следует преобразовать
это перемещение из UCS в OCS примитива круг (CIRCLE)

(trans '(1 2 3) 1 <имя-примитива-CIRCLE> 1)

после чего добавить получившееся перемещение к координатам центра


круга.
DCS - Экранная система координат-это система координат,в которую
преобразуется изображение перед тем,как оно появляется на
экране.Начало отсчета - это точки ЦЕЛИ,ось Z - это направление
взгляда.Пользователь всегда находится "в плане" DCS (т.е. ось Y
направлена вверх,а ось X направлена вправо при взгляде на видовой
экран).Применяется DCS для того,чтобы определить,как то или иное
изображение будет выглядеть для пользователя.
Например ,если пользователь ввел точку и необходимо определить,
какой из концов LINE ВИЗУАЛЬНО ближе к этой точке,следует
преобразовать пользовательскую точку из UCS в DCS

(trans <точка -пользователя> 1 2)

а каждый конец из OCS в DCS:

(trans <конечная-точка> <имя-примтива-LINE> 2)

после чего можно вычислить расстояние между точкой пользователя и


каждым из концов LINE (игнорируя координату Z),тем самым определив
какой из концов ВИЗУАЛЬНО ближе.

Функция TRANS может также преобразовывать и двумерные точки.Это


осуществляется методом "подбора" в качестве компоненты Z
соответствующего значения.Компонента Z берется в зависимости от
указанной системы координат "из",а также от того,является ли
преобразуемая величина точкой или перемещением."Подбор " Z зависит от:

--------------------------------------------------------------
| Из | Точка | Перемещение |
--------------------------------------------------------------
| WCS | 0.0 | 0.0 |
--------------------------------------------------------------
| UCS | Текущий уровень | 0.0 |
--------------------------------------------------------------
| OCS | 0.0 | 0.0 |
--------------------------------------------------------------
| DCS | Проецируется на текущую| 0.0 |
| | плоскость построений | |
| |(плоскость XY UCS + | |
| | текущий уровень ) | |
--------------------------------------------------------------

4.119. (type <item>


Эта функция возвращает тип аргумента <item>, где тип имеет одно
из следующих значений:

REAL вещественные числа


FILE дескрипторы файлов
STR строки
INT целые числа
SYM символы
LIST списки (и пользовательские функции)
SUBR внутренние функции AutoLISPа
PICKSET совокупности отборов AutoCADа
ENAME имена примитивов AutoCADа
PAGETB таблицы страниц функций

Например, пусть:

(setq a 123 r 3.45 s "Hello!" x ' (a b c))

(setq f (open "name" "r"))

тогда:

(type 'a) возвращает SYM


(type a) возвращает INT
(type f) возвращает FILE
(type r) возвращает REAL
(type s) возвращает STR
(type x) возвращает LIST
(type +) возвращает SUBR

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

(defun isint (a)


(if (= (type a) 'INT) ; целое число?
T ; да, возвращает T
nil ; нет, возвращает нуль
)
)

4.120. (untrace <function> ...)

Эта функция сбрасывает режим прослеживания для заданных функций и


возвращает имя последней функции. Она выборочно блокирует средство
отладки TRACE. Например:

(untrace my-func) возвращает MY-FUNC

и отменяет режим прослеживания для функции MY-FUNC. Смотрите


также функцию TRACE.
4.121. (ver)

Эта функция возвращает строку, которая содержит номер текущей


версии AutoLISPа. Она должна использоваться (с EQUAL) для проверки
совместимости программ. Строка имеет следующую форму:
"AutoLISP version X.X"

где X.X является номером текущей версии. Например:

(ver) должна вернуть "AutoLISP version 10.0"

В Расширенном Автолиспе функция VER возвращает строку в следующем


формате:
"Расширенный Автолисп версия X.X"
таким образом программа пользователя может определить работает она
в среде обычного или Расширенного Автолиспа.

4.122 (vports)

Данная функция возвращает список дескрипторов действующих в


настоящий момент видовых экранов.Каждый дескриптор видового экрана -
это список ,содержащий номер видового экрана и координаты его нижнего
левого и верхнего правого углов.Значения координат находятся в
интервале от 0.0 до 1.0,где (0.0 0.0) - координаты нижнего левого угла
графического экрана,а (1.0 1.0) - координаты ее верхнего правого угла.

Пример:
Пусть имеется конфигурация с одним видовым экраном,тогда функция
VPORTS может возвратить
((1 (0.0 0.0) (1.0 1.0)))
а если имеется конфигурация с четырьмя видовыми экранами
одинакового размера,то функция VPORTS может возвратить

((5 (0.5 0.0) (1.0 0.5))


(2 (0.5 0.5) (1.0 1.0))
(3 (0.0 0.5) (0.5 1.0))
(4 (0.0 0.0) (0.5 0.5)) )

причем дескриптор действующнго в данный момент видового экрана


всегда стоит в списке первым.В данном примере текущим видовым экраном
является видовой экран номер 5.

4.123. (while <testexpr> <expr> ...)

Эта функция вычисляет аргумент <testexpr> и, если значение его не


равно nil, вычисляет остальные выражения <expr>, а затем снова
<testexpr>. Это продолжается до тех пор, пока значение <testexpr> не
будет равно nil. Функция WHILE затем возвращает последнее значение
последнего аргумента <expr>. Например, если:

(setq a 1)

то:

(while (<= a 10)


(some-func a)
(setq a (1+ a))
)

десять раз вызовет пользовательскую функцию SOME-FUNC; A будет


принимать значения с 1 по 10. WHILE затем вернет значение 11, которое
является значением последнего вычисленного выражения.

4.124. (write-char <num> [<file-desc>])

Эта функция записывает один символ на экран или в открытый файл,


описанный посредством дескриптора <file-desc>. Аргумент <num>
представляет собой код ASCII записываемого символа, а также значение,
возвращаемое функцией. Например:

(write-char 67) возвращает 67

и отображает букву C на экране. Предположим, что F является


дескриптором открытого файла:

(write-char 67 f) возвращает 67

и записывает букву C в файл.

В различных операционных системах используются различные


соглашения по символам конца строки в текстовых (ASCII)
файлах.Операционная система UNIX например,использует один символ
возврата каретки (ASCII код 10),в то время как операционные системы
MS-DOS/PC-DOS используют два символа:символ перехода на новую строку и
символ возврата каретки (ASCII коды 13 и 10 )для тех же целей.Во
избежание двусмысленности при работе в различных операционных средах
функция READ-CHAR преобразует символ перехода на новую строку (ASCII
код 10) в символ (символы) конца строки,используемый в применяемой
операционной системе.Так в операционной системе PC-DOS/MS-DOS

(write-char 10 f) возвращает 10

но в файл записывается последовательность символов: символ перехода


на новую строку и символ возврата каретки (ASCII коды 13 и 10).Функция
WRITE-CHAR не можеь записывать символ NUL (ASCII-код 0).

4.125. (write-line <string> [<file-desc>])

Эта функция отображает аргумент <string> на экране или записывает


в открытый файл, определенный аргументом <file-desc>. Она возвращает
заключенный в кавычки аргумент <string> обычным образом, но опускает
кавычки, когда производит запись в файл. Например, предположим, что F
является верным дескриптором открытого файла:

(write-line "Test" f) записывает Test, а возвращает "Test"

4.126. (zerop <item>)

Эта функция возвращает T, если аргумент <item> является целым или


вещественным числом, и возвращает nil в противном случае. Она не
определяется для других типов <item>. Например:
(zerop 0) возвращает T
(zerop 0.0) возвращает T
(zerop 0.0001) возвращает nil
4.127. (*error* <string>)

Эта определенная пользователем функция служит для обработки


ошибок. Если значение ее не равно nil, то всякий раз, когда возникает
ошибка AutoLISPа, эта функция выполняется. Ей передается один аргумент
- строка, содержащая описание ошибки. Например:

(defun *error* (msg)


(princ "error: ")
(princ msg)
(terpri)

Эта функция выполняет то же самое, что и стандартный обработчик


ошибок AutoLISPа: выдает на экран дисплея "error:" и описание этой
ошибки.

ГЛАВА 5.
_________________________________________________________________
ДОСТУП К ПРИМИТИВАМ И УСТРОЙСТВАМ АВТОКАДА

Обширный набор функций AutoLISPа обеспечивает доступ к примитивам


AutoCADа и к экрану и устройствам ввода. Вы можете выбирать примитивы,
получать их характеристики и модифицировать их. Совокупности отбора
могут сохраняться в переменных AutoLISPа, что дает возможность
работать с наборами примитивов. Никаких функций для непосредственного
создания примитивов не предусмотрено, т.к. это могут делать обычные
команды AutoCAD путем использования функции COMMAND.

5.1. Специальные типы данных

Два специальных типа данных используются для обеспечения доступа


к примитивам AutoCADа: имя примитива и совокупность отбора. Эти типы
данных обрабатываются только специальными функциями, и их внутренняя
структура не должна беспокоить программиста LISPа. Имя примитива
фактически является указателем в файле, Редактора чертежей AutoCADа, в
котором AutoLISP может отыскать запись о примитиве и его векторах
(если они есть на экране). Совокупность отбора является набором имен
примитивов.

_____________________________________________________
| Имена примитивов и совокупности отбора дос- |
| тупны только в сеансе редактора чертежей, |
| во время которого обеспечивается доступ к ним из |
| AutoCADа. |
|_____________________________________________________|
Кроме того, функции, связанные с примитивами могут манипулировать с
метками примитивов, являющимися постоянными идентификаторами,
присвоенными Автокадом примитивам.Автолисп воспринимает эти метки как
строки, состоящие из шестнадцатиричных чисел.

5.2. Функции обработки набора примитивов


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

5.2.1. (ssget [<mode>] [<pt1> [<pt2>]])

Вы можете получить совокупность отбора с помощью функции SSGET.


Дополнительный аргумент <mode> является строкой, которая задает способ
получения совокупности. Этим способом может быть "W", "C", "L" или
"P", соответствующие следующим режимам выбора примитивов системы
AutoCAD: "окно", "перекрестие", "последний" и "предыдущий". Аргументы
<pt1> и <pt2> являются списками, которые задают точки, интерпретация
которых завивит от способа формирования совокупности. Задание точки
без аргумента <mode> равносильно выбору примитива путем его указания.
Если все аргументы опускаются, то SSGET через AutoCAD выдает
пользователю обычный запрос "Select objects:", позволяя интерактивно
конструировать совокупность отбора. Примеры функции SSGET приведены
ниже:

(ssget) Запрашивает у пользователя обычный


выбор примитива.
(ssget "P") Выбирает последнюю совокупность
отбора
(ssget "L") Выбирает последний добавленный в файл
чертежа примитив

(ssget '(2 2)) Выбирает примитив, проходящий


через точку 2,2
(ssget "W" '(0 0) '(5 5)) Выбирает примитивы внутри окна от
точки 0,0 до точки 5,5
(ssget "C" '(0 0) '(1 1)) Выбирает примитивы, пересекающие
прямоугольник от 0,0 до 1,1

(ssget "X" <filter-list>) Выбирает примитивы, соответствующие


фильтру <filter-list>.

Выбранные объекты подсвечиваются только в том случае, если SSGET


используется без аргументов. Никакой информации о том, как выбирался
примитив, не сохраняется (в качестве альтернативного варианта смотрите
ENTSEL). Совокупности отбора используют временные файлы, поэтому язык
LISP не может иметь более 6 открытых файлов одновременно. Когда этот
предел достигается, AutoCAD не создает бсовокупности отбора и
возвращает nil в ответ на все вызовы SSGET.

Переменная, значением которой является совокупность отбора может


передаваться в AutoCAD в ответ на любой запрос "Select objects:", при
котором допустима опция "LAST". Переменная эквивалентна совокупности
отбора и система будет работать так, как будто выбор осуществлялся при
помощи окна (но обратите внимание на то, что примитивы, которые
выбираются таким образом, необязательно должны быть на экране).
SSGET фильтры (ssget "X")

Вариант функции (ssget "X") формирует совокупность отбора,


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

(ssget "X" <filter-list>)

<filter-list> является списком точечных пар, аналогичным тому,


ко- торый возвращает функция ENTGET. Этот список определяет, какие
свой- ства примитивов следует проверять и в каком диапазоне должны
ледать проверяемые параметры. Например,

(ssget "X" '((0 . "CIRCLE")))

формирует и возвращает совокупность отбора, состоящую из всех


окруж- ностей (код группы 0 является кодом типа примитива). Аналогично

(ssget "X" '((8 . "FLOOR3")))

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


слоя "FLOOR3" (группа 8 кодирует имя слоя). Если в списке
<filter-list> имеется несколько точечных пар, то в совокупность отбора
входят только те примитивы, для которых удовлетворяются все условия.
Например:

(ssget "X" '((0 . "CIRCLE") (8 . "FLOOR3") (62 . 1)))

возвращает совокупность отбора, содержащую все красные окружности


в слое FLOOR3.

Функция SSGET не позволяет использовать любые коды групп в

списке фильтров. Если примитив удовлетворяет всем элементам


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

В следующей таблице даны коды групп, допустимые для использования


в SSGET.

Код Значение

0 Тип примитива

2 Имя блока для описания блока (INSERT)

6 Тип линии

7 Имя гарнитуры для определений текста и атрибутов

8 Имя слоя

38 Уровень (действительное число)(будет опущено при


следующем обновлении)
39 Высота (действительное число)

62 Код цвета (0-BYBLOK,256-BYLAYER)

66 Следующй за атрибутом флаг в описании


блока(INSERT)
210 Вектор направления выдавливания (список из трех
действительных чисел)

Для проверки соответствия со значением характеристики, помеченной


как вещественная, нужно задать вещественное число. Так, чтобы выбрать
примитивы на высоте 2.0, нужно задать

(ssget "X" '((38 . 2.0))) а не


(ssget "X" '((38 . 2)))

Если вы укажате неверный код группы, то функция вернет nil.Из


этого вытекает, что программы на Автолиспе,использующие SSGET"X",будут
продолжать работать при появлении в будующем дополнительных кодов.

5.2.2. (sslength <ss>)

Эта функция возвращает целое число, содержащее количество


примитивов в совокупности отбора <ss>. Совокупность отбора никогда не
содержат несколько экземпляров одного и того же примитива. Если
количество примитивов превышает 32767, то оно возвращается в формате
вещественного числа.
Пример:
(setq sset (sset "p")) ;помещает последний объект в набор SSET
(sslength sset) ;возвращает 1

5.2.3. (ssname <ss> <index>)

Эта функция возвращает имя примитива с номером <index>


совокупности отбора <ss>. Если аргумент <index> отрицательный или
больше числа примитивов в совокупности, то возвращается nil. Первый
элемент совокупности имеет нулевой номер. Имена примитивов ,
полученные с помощью функции SSGET, всегда будут именами главных
примитивов. Подпримитивы (атрибуты Блоков и вершины Полилиний)
возвращаться не будут (смотрите функцию ENTNEXT ниже, которая
обеспечивает доступ к ним).
Пример:
(setq sset (ssget)) ;создает набор под именем SSET
(setq ent1 (ssname sset 0)) ;получает имя первого примитива в SSET
(setq ent4 (ssname sset 3)) ;получат имя четвертого примитива
в SSET

Для получения примитива, номер которого больше 32767, этот номер


следует задать, как вещественное число.
Пример:
(setq entx (ssname sset 50843.0)) ;получает имя 50843 примитива в
SSET

5.2.4. (ssadd [<ename> [<ss>]])

Если эта функция вызывается без аргументов, SSADD создает новую


пустую совокупность отбора. Если она вызывается с аргументом - именем
одного примитива, SSADD создает новую совокупность отбора, содержащую
это имя. Если функция вызывается с именем примитива и совокупностью
отбора <ss>, то она добавляет именованный примитив к совоокупности
отбора. SSADD всегда возвращает новую или модифицированную
совокупность. Обратите внимание на то, что при добавлении примитива к
совокупности, новый примитив действительно включается в существующую
совокупность <ss>, возвращаемую в качестве результата. Таким образом,
если совокупность присвоена другим переменным, они также будут
отражать это добавление. Если именованный примитив уже находится в
совокупности, действие функции SSADD будет пустым; ни о каких ошибках
сообщений не поступит.

Примеры:
(setq el (entnext)) ;присваивает в E1 имя примитива в
рисунке
(setq ss (ssadd)) ;устанавливает нулевой набор SS
(ssadd el ss) ; возвращает набор SS, в котором добавлен
примитив по имени E1
(setq e2 (entnext el)) ;получает примитив,следующий за E1
(ssadd e2 ss) ;возвращает набор SS,в который добавлен
примитив E2

5.2.5. (ssdel <ename> <ss>)

SSDEL стирает имя примитива <ename> из совокупности отбора <ss> и


возвращает имя совокупности <ss>. Обратите внимание на то, что
примитив физически стирается из совокупности отбора, а не создается
новая совокупность без удаляемого примитива (смотри рассуждение в
предыдущем разделе касательно присвоений другим переменным). Если
примитива нет в совокупности, то возвращается nil.Вследующем примере
дано,что имя примитива E1 содержится в наборе SS, а E1 нет:

(ssdel el ss) ; возвращает набор SS, из которого удален примитив E1


(ssdel e2 ss) ; возвращает nil (не меняя SS)

5.2.6. (ssmemb <ename> <ss>)

Эта функция проверяет, является ли имя примитива <ename> членом


совокупности отбора <ss>. Если да, функция SSMEMB возвращает имя
примитива (<ename>). В противном случае, она возвращает nil.
Вследующем примере дано ,что имя примитива Е1 содержится в наборе
SS, а Е2 нет:
(ssmemb el ss) ;возвращает имя примитива Е1
(ssmemb e2 ss) ;возвращает nil

Функции для работы с именами примитивов

Следующие функции выполняют различные операции над именами


примитивов. Имена примитивов могут передаваться в AutoCAD в ответ на
любой запрос "Select objects:", когда допустимо использование ответа
"LAST". В результате выбирается именованный примитив так, как если бы
для выбора использовался метод окна.

5.2.7. (entnext [<ename>])


Если эта функция вызывается без аргументов, то она возвращает имя
первого нестертого примитива в файле чертежа. Если функция ENTNEXT
вызывается с аргументом - именем примитива <ename>, то она возвращает
имя первого нестертого примитива, следующим за <ename> в чертеже. Если
в чертеже отсутствует следующий примитив, то возвращается nil. Функция
ENTNEXT возвращает как главные примитивы, так и подпримитивы.
Примитивы, выбираемые функцией SSGET, являются главными
примитивами, а не атрибутами Блоков или вершинами Полилиний. Вы можете
получить доступ к внутренней структуре этих сложных примитивов путем
простого прослеживания подпримитивов функцией ENTNEXT. Как только вы
получите доступ к имени подпримитива, вы можете работать с последним

так же, как с любым другим примитивом. Если вы получили доступ к


имени подпримитива посредством ENTNEXT, то можно отыскать родительский
примитив путем продолжения прослеживания функцией ENTNEXT до тех пор,
пока не будет найден примитив SEQEND (т.е. конец последовательности),
и путем извлечения группы -2 из этого примитива, которая является
именем главного примитива.

Пример:
(setq el (entnext)) ;
присваивает Е1 имя первого примитива в
рисунке
(setq e2 (entnext el)) ; присваивает Е2 имя примитива,следующего
за Е1

5.2.8. (entlast)

Эта функция возвращает имя последнего нестертого главного


примитива в базе данных. Функция часто используется для получения
имени нового примитива, который добавлен при помощи функции COMMAND.
Примитив не обязан изображаться на экране или находиться на
размороженном слое.
Пример:
(setq el (entlast)) ;присваивает Е1 имя последнего примитива в
рисунке
(setq e2 (entnext el)) ;присваивает Е2 nil(или имя субпримитива
атрибут или вершина)
Если требуется узнать имя самого последнего нестертого примитива
(основного примитива или субпримитива ),то можно определить
функцию,подобную приведенной ниже, и вместо ENTLAST обращаться к ней .

(defun lastent (/a b)


(if (setq a (entlast)) ;взять последний основной примитив
(while (setq b (entnext a)) ;если следуют субпримитивы,
(setq a b) ;то действует цикл
)
)
a ;возвращает последний основной субпримитив
)

5.2.9. (entsel [<prompt>])

Иногда, работая с примитивами, желательно одновременно выбирать


примитив и сохранять точку, с помощью которой он выбирался. Примерами
этого может служить использование режимов объектной фиксации и команд
BREAK, TRIM и EXTEND системы AutoCAD. Функция ENTSEL предоставляет
возможность программам AutoLISPа выполнять эту операцию. ENTSEL
выбирает один примитив, пользуясь для этого заданием некоторой его
точки. Она возвращает список, первым элементом в котором является имя
выбранного примитива, а вторым элементом - координаты точки,
используемой для выбора примитива. Если задана строка для аргумента
<prompt>, то она будет выдаваться пользователю в качестве запроса
примитива. В противном случае запросом, по умолчанию, будет "Select
objects:". Следующий диалог AutoCADа иллюстрирует использование
функции ENTSEL.

Command: LINE
From point: 1,1
To point: 6,6
To point: RETURN

Command: (setq e (entsel "Please choose an entity:"))


Please choose an entity: 3,3 /Выберите примитив/
(<Entity name: 60000014> (3.0 3.0 0.0))

Список данной формы, возвращаемый функцией ENTSEL, может


предоставляться системе AutoCAD в ответ на любой запрос выбора
объекта. Он будет восприниматься системой AutoCAD как выбор этого
примитива посредством указания заданной точки.

5.2.10 (handent <метка>)

Имя примитива может изменяться в разных сеансах редактирования;в то


время как его метка останется неизменной.При указанном аргументе
строки метки <метка> функция HENDENT возвращает имя примитива,
связанного с этой меткой в текущем сеансе проектирования.После того
как имя примитива было получено,оно может быть использовано для
манипулирования с данным приимитивом другими функциями.

Пример:
(handent "5A2") вернет <Имя примитива: 60004722>

в определенном сеансе редактирования.Использованный в этом же


рисунке, но в другом сеансе редактирования такой же вызов может
вернуть другое имя примитива.Но при этом происходит обращение к одному
и томуже примитиву;его метка остается прежней,хотя имя можети
меняться.
Если в рисунке не используются метки или HANDENT наткнулась на
неверную метку или какому либо примитиву в рисунке не присоена метка,
то возвращается NIL.Функция HANDENT будет возвращать стертые в текущем
сеансе редактирования примитивы;если требуется, их можно восстановить
спомщью функции ENTDEL.

5.3. Функции обработки данных о примитивах

Следующие функции дают вам возможность отыскивать и


модифицировать данные, определяющие примитив. Все эти функции
используют имена для задания тех примитивов, с которыми необходимо
будет работать.

5.3.1. (entdel <ename>)


Примитив, определяемый аргументом <ename>, стирается с чертежа,
если он там в данный момент присутствует, и восстанавливается снова,
если он был стерт ранее, во время данного сеанса редактирования.
Стертые примитивы удаляются с чертежа при выходе из Редактора
чертежей, поэтому функция ENTDEL может восстановить их только во время
того
сеанса редактирования, в течении которого они были стерты. ENTDEL
обрабатывает только главные примитивы; атрибуты и вершины Полилиний не
могут стираться независимо от своих родительских примитивов (используя
функцию COMMAND, вы можете сделать это посредством команд ATTEDIT или
PEDIT).

Пример:
(setq el (entnext)) ;присваивает Е1имя первого примитива в рисунке
(entdel el) ;удаляет примитив Е1
(entdel el) ;восстанавливает удаленный примитив Е1

5.4.2. (entget <ename>)

Примитив с именем <ename> отыскивается в файле чертежа и


возвращается в качестве списка основных характеристик. Этот список
является ассоциативным; элементы его могут легко отыскиваться с
помощью функции ASSOC. Объекты в списке кодируются с помощью кодов
группы DXF системы AutoCAD.

Для следующего примера допустим,что:


- текущий слой - "0";
- текущий тип линии - "CONTINUOUS"(значение по умолчанию);
- текущий уровень равен нулю (значение по умолчанию);
_ примитивы не имеют меток;
- значение переменной FLATLAND равно нулю.
Предположим,был нарисован отрезок с помощью следующей командной
последовательности:

Command: LINE
From point: 1,2
To point: 6,6
To point: RETURN
Теперь можно получить данные о нарисованном отрезке после ввода

Command: (setq a (entget (entlast)))

установит A равным списку (отформатированному для удобства чтения):

( (-1 . <Entity name: 60000014>)


(0 . "LINE") ;Тип примитива
(8 . "0") ;Слой
(10 1.0 2.0 0.0) ;Начальная точка
(11 6.0 6.0 0.0) ;Конечная точка
)

Элемент -1 в начале списка содержит имя примитива,


представляемого данным списком. Функция ENTMOD, описанная ниже,
использует его для идентификации модифицируемого примитива.

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


отыскиваться при помощи функции ASSOC. CDR используется для получения
значений групп. Кодами групп примитива являются коды, используемые в
файле DXF и описанные в приложении C руководства по AutoCADу. Так же,
как и в случае с DXF, элементы заголовка примитива (цвет и тип линии,
признак сложного примитива (ATFLAG), толщина высота по Z) по- падают в
список только в том случае, если они не равны значениями по умолчанию.
В отличие от DXF, вспомогательные поля определения примитивов всегда
попадают в список. Смысл этого действия заключается в том, чтобы
упростить обрабатывающие программы.Кроме того, в отличие от формата
DXF координаты X,Y и Z одной точки сгруппированы в один
список,например (10 1.0 2.0 3.0),а не в виде отдельных групп 10,20,30.

Обратите внимание на то, что подсписки точек не являются


точечными парами, как остальные элементы. Принято, что CDR в подсписке
возвращает значение, кодируемое группой. Так как точка есть список
двух вещественных чисел, то это делает всю группу списком трех
элементов. CDR из этой группы возвращает список двух элементов, т.е.
точку, поэтому правило, что CDR всегда возвращает значение,
сохраняется.

Обязательно проверьте то, что функция обработки этих списков


примитивов функции не зависит от порядка следования подсписков.
Использование ASSOC гарантирует это условие. Группа -1 с именем
примитива дает возможность легко передавать список примитива в
функцию, выполняющую его модификацию, и устраняет необходимость
сохранять имя примитива в параллельной структуре. Примитив SEQEND в
конце Полилинии или набора атрибутов содержит группу -2, CDR которой
является именем главного примитива. Это позволяет находить имя
примитива-родителя в подпримитиве посредством перехода к SEQEND и
дальнейшего использования CDR для группы -2.

В следующем примере показано представление более сложного


примитива в качестве списка.Допустим,что текущая UCS повернута под
углом 40 градусов против часовой стрелки вокруг оси Z WCS,что
примитивам присвоены метки и что значение системной переменной
FLATLAND равно нулю.

Command: ELEV
New current elevation <0.0000>: 3.5
New current thickness <0.0000>: 0

Command: LINTYPE
?/Create/Load/Set: SET
New entity linetype <BYLAYER>: DASHED

Command: COLOR
New entity color <BYLAYER>: BLUE

Command: LAYER
?/Make/Set/New/On/Off/Color/Ltype/Freeze/Thaw: MAKE
New current layer <0>: ANNOTATION
?/Make/Set/New/On/Off/Color/Ltype/Freeze/Thaw: RETURN

Command: TEXT
Start point or Align/Center/Fit/Middle/Right/Style: 2,2
Height <0.2000>: .3
Rotation angle <0>: 30
Text: So long and thanks for all the fish!
Command: (setq e (entget (entlast)))

В этом случае E будет присваиваться списку, представленному ниже.


Чтобы хорошо понять смысл этого списка, прочитайте справочное
руководство AutoCAD (приложение C).
( (-1 . <Entity name: 6000003C>)
(0 . "TEXT") ;тип примитива
(8 . "ANNOTATION") ;Слой
(6 . "DASHED") ;Тип линии
(62 . 5) ; Цвет
(5 ."7Е) ;Метка
(10 2.0 2.0 0.0) ;Начальная точка
(40 . 0.3) ;Высота
(1 . "So long, and thanks for all the fish!")
(50 . 0.523598) ;Угол поворота (радианы)
(41 . 1.0) ;Степень оастяжения
(51 . 0.0) ;Угол наклона
(7 ."STANDARD") ;Гарнитура шрифта
(71 . 0) ;Флаги генерации
(72 . 0) ;Тип выравнивания
(11 0.0 0.0 0.0) ;Точка выравнивания
(210 0.0 -0.642788 0.766044) ;Вектор направления выдавливания
)

Координаты всех точек, относящихся к объекту,выражаются в Объектной


системе координат (OCS),относящейся к данному объекту.Что касается
таких примитивов,как точка,отрезок,3D линия,3D грань,3D полилиния,3D
сеть и элементов размеров,OCS совпадает WCS .OCS для других примитивов
может быть вычислена из положения WCS и величины выдавливания
примитива (группа 210).При работе с примитивами, ктоторые были созданы
в системе координат,отличной от WCS (например, текст в предыдущем
примере),принадлежащие им точки должны быть переведены в координаты
текущей UCS или UCS при помощи функции TRANS.Для текста предыдущего
примера
(setq p (cdr (assoc 10 ed))) возвращает (2.0 2.0 3.5)

присваивает P точку вставки текста выраженную в координатах OCS


текстовой строки.(Заметим,что список имеет указанный формат
независимоот текущей UCS в момент употребления функции ENTGET.)
Теперь:

(trans p e 0) возващает (2.0 -0.717668 3.96673)

Употебляет Е (имя пимитива текста) ка кол "из" системы коодинат, и


ееводит точку вставки текста из OCS в WCS (Мировая система координат).
Если системнная переменная FLATLAND имеет ненулевое значение,OCS
тождественна WCS, функция ENGET возвращает двуиерные точки в WCS.
Группа 38 обозначает уровень объекта по оси Z (если он не равен нулю).
Группа 210 (направление выдавливания в этом случае не возвращается.

5.3.3. (entmod <elist>)

Функции ENTMOD передается список (<elist>) в формате,


возвращаемом функцией ENTGET, и она обновляет информацию в файле
чертежа для примитива, имя которого задается группой -1 в списке
<elist>. Поэтому
основной механизм обновления чертежа сводится к поиску примитива
функцией ENTGET, модифиции списка, определяющего примитив (обратите
внимание на то, что функция SUBST AutoLISPа особенно полезна для
этого), и обновлению этго примитива в файле чертежа функцией ENTMOD.

(setq en (entnext)) ; устанавливает в EN имя первого примитива


рисунка
(setq ed (entget en)) ; ed присваивается списку характеристик
; примитива с именем en
(setq ed
(subst (cons 8 "0")
(assoc 8 ed) ;изменить в групу слоя в ED
ed ;на слой "0"
)
)
(entmod ed) ; внести изменения в слой примитива EN
в чертеже

Функция ENTMOD налагает некоторые ограничения на изменения,


которые она выполняет. Прежде всего, нельзя изменять тип примитива.
(Если вы хотите сделать это, используйте функцию ENTDEL и создайте
новый примитив функцией COMMAND.) Все объекты, на которые делается
ссылка в списке примитивов, должны быть известны системе AutoCAD перед
выполнением функции ENTMOD. Таким образом, текстовый шаблон, тип
линии, Форма и имя Блока перед тем как они будут использоваться в
списке примитивов функцией ENTMOD, должны быть определяться в чертеже.
Исключение составляют имена слоев - ENTMOD создаст новый слой со
стандартными значениями по умолчанию, используемыми командой "LAYER
NEW", если слой не был определен.

ENTMOD воспринимает целые значения и преобразует их в значения с


плавающей точкой для полей примитивов, содержащих значения с плавающей
Аналогично, если задано значение с плавающей точкой для целочисленного
поля примитива (такого как номер цвета),то ENTMOD преобразует его в
целочисленное.

Функция ENTMOD осуществляет такую же проверку предоставляемого ей


списка, какую функция DXFIN выполняет по отношению к данным из файла
DXF. Если обнаруживается настолько серъезная ошибка, что выполнение не
может быть продолжено, то возвращается nil. В противном случае,
функция ENTMOD возвращает список, переданный ей в качестве аргумента.
ENTMOD не будет изменять внутренние поля, такие как имя примитива
SEQUEND в группе -2 - попытки сделать это просто игнорируются.

Когда обновляется главный примитив, функция ENTMOD изменит


примитив и модифицирует его изображение на экране (включая
подпримитивы). Когда ENTMOD используется для обновления подпримитива
(вершин Полилинии или атрибута Блока), то подпримитив будет
обновляться в файле чертежа, но изображение на экране перечерчиваться
не будет. После модификации всех подпримитивов, функция ENTUPD,
описанная ниже, может использоваться для внесения изменений в
изображение на экране.

5.3.4. (entupd <ename>)

Как описано выше, когда вершина Полилинии или атрибут Блока


модифицируется при помощи функции ENTMOD, весь сложный примитив не
обновляется на экране. Если, например, необходимо модифицировать 100
вершин сложной Полилинии, то перерасчет и повторное отображение
Полилинии по мере изменения каждой вершины будет недопустимо
медленным. Функция ENTUPD может использоваться для обновления
модифицированной Полилинии или Блока на экране. Функция ENTUPD
вызывается с именем подпримитива любой части Полилинии или Блока. Это
необязательно должен быть главный примитив - ENTUPD отыщет начало.
Несмотря на то, что функция ENTUPD предназначена для Полилиний и
Блоков с атрибутами, она может вызываться фактически для всех
примитивов. Она всегда будет регенерировать примитив на экране,
включая все подпримитивы.
Пример: Пусть первый примитив в рисунке- полилинияс несколькими
вершинами, тогда:
(setq el (entnext)) ;устанавливает в Е1 имя полилинии
(setq e2 (entnext el)) ;Устанавливает Е2 первую вершину полилинии
(setq ed (entget e2)) ;Устанавливает в ED список данных о вершине
(setq ed
(subst '(10 1.0 2.0)
(assoc 10 ed) ;Изменяет положение вершины в ED
) ;на точку с координатами 1,2
)
(entmod ed) ;перемещает вершину в рисунке
(entupd ed) ;регенерирует полилинию Е1

5.3.5. Ограничения

Имена примитивов и совокупности отбора являются верными только


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

ENTMOD - модифицировать существующий примитив


ENTUPD - регенерировать модифицированный сложный примитив
ENTDEL - восстановить и регенерировать стертый примитив

5.4. Использование имен примитивов и наборов


с системой AutoCAD

Имена примитивов и совокупностей отбора могут передаваться из


LISPа в ответ на запросы выбора системы AutoCAD. Таким образом, имена
примитивов, переданные из LISPа, могут обрабатываться командами
AutoCADа. В ответ на запрос "Select objects:" LISP может предоставить
имя примитива, которое задает один примитив или совокупности отбора,
которая задает все содержащиеся в ней примитивы. Передача из LISPа
имен примитивов или совокупностей отбора является допустимой тогда,
когда системой AutoCAD разрешается выбор "Last" (как AutoCAD, так и
LISP обладают способностью выбирать примитивы независимо от видимости
и не только путем указания точки).

Всякий раз, когда система AutoCAD разрешает выбор указанием


объекта, можно передавать в систему список в форме, формируемой
функцией ENTSEL. Такой список идентифицирует примитив, так как будто
была заданы точка с помощью устройства указания. Это дает возможность
LISPу передавать точки указания таким командам, как
BREAK,FILLET,CHAMFER, TRIM и EXTEND. Списки формы ENTSEL могут
использоваться и для процедур выбора, когда указание точками допустимо
для команды.

5.5 Замечания по процессу сглаживания и апроксимации полилиний


сплайном

Проходя пошагово по вершинам полилинии с помощью функции


ENTNEXT,можно встретить некоторое число вершин, которые нпосредственно
не задавались. Это дополнительные вершины, автоматически добавленные
опциями команды PEDIT "Fit curve" и "Spline curve",и при желании их
можно проигнорировать, так как изменения, внесенные в эти вершины,
будут отброшены при последующих применениях этих опций команды PEDIT к
полилинии.
При необходимости можно выяснить с помощью флагов группы 70
полилиний, была ли полилиния сглажена (битовое значение 2) или
апроксимирована сплайном (битовое значение 4).Если ни один изэтих
битов не установлен, то полилиния состоит из обычных вершин.Однако
если установлен битсглаживания (2),то дополнительные вершины полилинии
будут содержать в своей группе 70 флагов значения 1,которые добавлены
процессом сглаживания.Если применяется функция ENTMOD для перемещения
вершин такой полилинии с целью заново аппроксимировать кривую с
помощью команды PEDIT,то вершины необходимо проигнорировать.

Также,если установлен битовый флаг сплайн-аппроксимации (4)


полилинии, то часть вершин будетсодержать флаговый бит со значением 1
(вставлены в процессе сглаживания при системной переменной SPLINESEGES
с отрицательным значением),часть вершин со значением 8 (вставлены в
процессе сплайн- аппроксимации);и все остальные с битовым значением 16
(опорные точки фрейма сплайна). Если также используется функция
ENTMODдля перемещения вершин и необходимо в последствии заново
выполнить аппроксимацию сплайном, то следует перемещать толбко
вершины- опорные точки.

5.6. Доступ к таблице символов

Доступ "только для чтения" к символьным таблицам слоев, типов


линий, именованных видов, текстовых шаблонов и определений блоков
системы AutoCAD обеспечивается описанными ниже функциями TBLNEXT и
TBLSEARCH.

5.6.1. (tblnext <table name> [<first>])

Эта функция используется при просмотре всей таблицы символов.


Первый аргумент является строкой, идентифицирующей интересующую вас
символьную таблицу.Допустимые имена таблиц "LAYER", "LTYPE", "VIEW",
"STYLE","BLOCK", "UCS", и "VPORT". Строка необязательно должна быть
представлена буквами верхнего регистра. При повторном использовании
функции TBLNEXT обычно каждый раз возвращает следующий вход в
указанную таблицу.(В функции TBLSEARCH, описанной ниже, мохно з
адавать "следующий" вход для вызова.) Однако если присутствует
<первый> аргумент, и, если значение его не равно nil, то таблица
символов просматривается сначала со следующей точки входа. Если
элементов в таблице больше нет, возвращается nil. Стертые элементы не
могут быть выбраны с помощью этого механизма.

Если точка входа найдена,элемент возвращается в виде списка


точечных пар с кодами групп, аналогичными DXF и значениями ,
аналогично тем, что возвращаются функцией ENTGET.
Например:

(tblnext "layer" T) (выбрать первый слой)


может вернуть:

((0."LAYER") (тип символа)


(2. "0") (имя символа)
(70. 0) (флаги)
(62. 7) (номер цвета, отрицательный,
если слой выключен)
(6. "CONTINUOUS") (имя типа линии)
)

Обратите внимание на то, что группа "-1" отсутствует. AutoCAD


запоминает последний, возвращенный элемент каждой таблицы, и
возвращает следующий элемент всякий раз, когда вызывается TBLNEXT для
данной таблицы. Когда вы начинаете просматривать таблицу, обязательно
задайте второй аргумент с ненулевым значением, чтобы попасть на начало
таблицы и выбрать первый элемент.

Результат, выбираемый из таблицы "BLOCK", включает группу "-2" с


именем первого примитива в определении блока. Таким образом, для блока
"BOX" можно получить:

(tblnext "block") (найти определение блока)

может вернуть:

((0 . "BLOCK") (тип символа)


(2 . "BOX") (имя символа)
(70 . 0) (флаги)
(10 9.0 2.0 0.0) (базовая точка X,Y,Z)
(-2 . <Entity name: 40000126>) (первый примитив)
)

Имя примитива в группе "-2" может приниматься функциями ENTGET и


ENTNEXT, но только этими функциями доступа к примитивам. Это означает,
что вы не можете использовать ни функцию ENTMOD для модификации такого
примитива, ни функции SSADD или ENTSEL для включения его в
совокупность отбора. Задавая имя примитива из группы "-2" функции
ENTNEXT, вы можете просмотреть примитивы, содержащиеся в определении
блока; ENTNEXT возвращает nil после последнего примитива в определении
блока.
Если системная переменная FLATLAND равна нулю, то TBLNEXT всегда
возвращает трехмерные точки как четырехэлементный список типа (10 1.0
2.0 3.0).Если системная переменная FLATLAND не равна нулю, то
отдельные трехмерные точки возвращаются ка трехэлементные (двумерные)
списки с координатой Z в виде отдельных точечных пар группы 30.

5.6.2. (tblsearch <table name> <symbol> <следующий>)

Эта функция производит поиск в символьной таблице с именем <table


name> (имена такие же как для TBLNEXT), отыскивая символ, заданный
аргументом <symbol>. Оба имени автоматически преобразуются в верхний
регистр. Если найдено вхождение для заданного имени символа, то оно
возвращается в формате, описанным для функции TBLNEXT. Если вхождение
не найдено, то возвращается nil. Например:

(tblsearch "style" "standard") (отыскать гарнитуру текста)

может вернуть:
((0 . "STYLE") (тип символа)
(2 . "STANDARD") (имя символа)
(70 . 0) (флаги)
(40 . 0.0) (фиксированная высота)

(41 . 1.0) (коэффициент ширины)


(50 . 0.0) (угол наклона букв)
(71 . 0) (флаги генерации)
(3 . "txt") (файл шрифта по умолчанию)
(4 . "") (файл большого шрифта)
)

На порядок элементов, возвращаемых TBLNEXT, не влияет функция


TBLSEARCH.Однако, если аргумент <next> существует изначение его не
nil, точка входа TBLNEXT изменяется таким образом, чтобы следующий
вызов TBLNEXT возвращал точку ввода, следующую после возвращенной в
этом вызове функции TBLSEARCH.
Средство <next> наиболее полезно при работе с символьной таблицей
VPORT,поскольку все видовые экраны одной конфигурации имеют одно и то
же имя. Например,чтобы найти и обработать все видовые экраны в
конфигурации "4VIEW", можно использовать следующую последовательность:

(setq v (tblsearch "4VIEW" T)) ; находит первую точку входа


(while (and v (= (cdr (assoc 2 v)) "4VIEW"))
.........выполнение входа............
(setq v (tblnext "VPORT")) ;получает следующий вход
)

Если системная переменная FLATLAND равна нулю,то TBLSEARCHH всегда


возвращает трехмерные точки как четырехэлементный список типа (10 1.0
2.0 3.0). Если системная переменная FLATLAND не равна нулюю,отдельные
трехмерные точки возвращаются как трехэлементные (двумерные) списки с
координатой Z в виде отдельных точечных пар группы 30.

5.7. Доступ к графическому экрану и устройствам ввода

Функции AutoLISPа, описанные в этом разделе, обеспечивают прямой


доступ к экрану с графическим изображением и устройствам ввода и дают
возможность реализуемым посредством LISPа командам работать с
пользователем в интерактивном режиме так, как будто они реализованы
внутри AutoCADа. Эти команды могут разрушить изображение на экране.
Однако, экран можно восстановить последовательностью:

(grtext)
(redraw)

поэтому не о чем беспокоиться. Эти функции предназначены только


для квалифицированных разработчиков прикладных программ. В большинстве
программ LISPа эти функции не требуются. Следует предупредить тех, кто
пользуется этими функциями о том, что от версии к версии действие их
может изменяться, поэтому фирма "Autodesk Inc." не гарантирует
дальнейшую совместимость прикладных программ, в которых используются
данные функции. Прикладные программы, которые используют также функции
GRTEXT и GRREAD, вероятно, не будут одинаково работать на всех
конфигурациях систем, если разработчик не будет точно следовать
правилам по их использованию, описанным ниже.
5.7.1. (grclear)

Эта функция очищает экран с графическим изображением AutoCAD.


(На одноэкранных системах сначала произойдет переключение с текстового
режима в графический.) Области команд/подсказок, статуса и меню
остаются неизменными. Исходное содержимое графического экрана может
восстанавливаться функцией REDRAW.

5.7.2. (grdraw <from> <to> <color> [<highlight>])

Функция GRDRAW вычерчивает вектор между двумя точками. Аргументы


<from>/от/ и <to>/до/ являются точками (списками двух или трех
вещественных чисел), которые задают конечные точки как координаты в
текущей UCS (Пользовательской системе координат). Конечные точки
задаются как значения с плавающей точкой в системе координат чертежа,
а вектор будут отсекаться по границе экрана. Вектор будет
вычерчиваться цветом, заданным целочисленным аргументом <color>.
Значение -1 задает цвет "XOR ink" , который дополняет цвет той зоны на
которой вычерчивается вектор, и становится невидимым при повторном
вычерчивании. Если задается целочисленный аргумент <highlight>, и если
он не равен нулю, то вектор будет вычерчиваться так, как это делается
в дисплейном устройстве для подсвечиваемях, выбранных объектов (обычно
пунктирной линией). Если аргумент <highlight> опускается, или если он
задается, но равен nil, то будет использоваться стандартный режим
дисплея.

5.7.3. (qrtext [<box> <text> [<highlight>]])

Функция GRTEXT дает возможность AutoLISPу записывать текст в


специальные области графического экрана. Если функция вызывается с
порядковым номером <box> в диапозоне от 0 до максимального номера
прямоугольника экранного меню минус 1, то она высветит строку <text> в
заданном прямоугольнике экранного меню. Если строка <text> слишком
длинна и не помещается в прямоугольнике, то он будет усекаться, а если
слишком коротка - то дополняться пробелами. Если используется
вспомогательный аргумент <highlight> и значение его не равно нулю, то
высвечивание текста в заданном прямоугольнике будет выполняться с
подсветкой (обратите внимание на то, что подсвечивание другого
прямоугольника автоматически отменяет подсветку выделенного ранее
прямоугольника). Если вы производите запись в прямоугольник меню, то
сначала текст должен быть записан без аргумента <highlight> и только
затем подсвечиваться. Одна и та же текстовая строка должна участвовать
в обоих вызовах, как без подсветки, так и с подсветкой. В результате
несоблюдения этих правил программа LISPа, будет по разному вести себя
на разных дисплеях. Обратите внимание на то, что эта функция просто
отображает заданный текст в области меню на экране; она не самих
элементов меню. Более того,на некоторых типах мониторов действие
обычной подсветки пункта меню заключается в изменении цвета этого
пункта,так что GRTEXT может возвращать текст пункта меню в предыдущее
состояние, если пользователь подсвечивает этот пункт экранного меню.
На других дисплеях зона меню переписыватся при выполнении действий по
переключению или перерисовке экрана командами REDAW или REGEN и
т.д. Однако на большинстве дисплеев текст функции GRTEXT будет
оставаться в зоне экранного меню до тех пор,пока егоне перепишет новая
страница меню.

Если функция GRTEXT вызывается с номером -1, текст будет


записываться в строку статуса в область режимов. Длина подстроки
режимов зависит от типа дисплея (большинство дисплев допускают, по
крайней мере, 40 символов; исключение составляет адаптор CGA фирмы
IBM). Текст будет отсекаться с тем, чтобы он смог поместиться в
заданной области.

Если используется номер бокса -2, текст будет записываться в окно


координат строки статуса. Обратите внимание на то, что если
активизировано прослеживание координаты, то значения, записанные в это
поле, будут перезаписываться, как только указатель передаст другой
набор координат. Аргумент <highlight> игнорируется как для номера
<бокс> -1, так и для номера -2.

Наконец, GRTEXT может вызываться без аргументов для


восстановления всех областей текста на экране в стандартное состояние.

5.7.4. (grread [<track>])

Функция GRREAD дает вам возможность выполнять считывание


непосредственно с устройств ввода AutoCADа и, если нужно
контролировать устройства указания по мере их перемещения. Наиболее
распространенный способ ввода данных в AutoLISPе осуществляется
посредством таких функций "GETxxx", как GETSTRING, GETREAL и т.д.
Аргумент <track>, если он есть и не равен nil, возвращает координаты
от устройств указания, не требуя при этом нажатия клавиши фиксации.
Именно этот метод система AutoCAD использует для реализации
отслеживания.

Функция GRREAD возвращает список, первым элементом которого


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

2 Символ клавиатуры - код ASCII в качестве второго


элемента
3 Выбранная точка - координаты в виде списка
4 Выбранная ячейка экранного меню - номер бокса, в
качестве второго элемента

- 73 -

5 Координаты режима отслеживания в качестве второго элемента.


Возвращается, если задан аргумент и не равен nil
6 Выбран элемент меню BUTTONS - номером клавиши является
второй элемент
7 Выбран элемент меню TABLET1 - номер бокса - второй элемент

8 Выбран элемент меню TABLET2 - номер бокса - второй элемент


9 Выбран элемент меню TABLET3 - номер бокса - второй элемент

10 Выбран элемент меню TABLET4 - номер бокса - второй элемент

11 Выбран элемент меню AUX1 - номер бокса - второй элемент


12 Координаты, связанные с кнопкой устройства указания,
возвращенные в качестве второго элемента. Всегда следует
за списком с кодом 6

13 Вводом с клавиатуры осуществляется выбор подсвеченного элемента


экранного меню. Номер бокса возвращается в качестве
второго элемента.

Если второй элемент в возвращенном списке является точко, то в


зависимости от значения системной переменной FLATLAND определяется,
является ли эта точка двумерной или трехмерной. Если FLATLAND равна
нулю,то возвращается трехмерная точка относительно текущей UCS; в
противном случае-двумерная.

Если функция GRREAD находится в процессе выполнения, ввод CTRL-C


прервет программу LISPа. Любой другой ввод будет передаваться
непосредственно к функции GRREAD, давая полный контроль над
устройствами ввода.

ГЛАВА 6.
___________________________________________________________________
УПРАВЛЕНИЕ ПАМЯТЬЮ

Переменные, функции, определенные пользователем, и стандартные


функции, описанные в этом руководстве, запоминаются в памяти вашей
вычислительной системы только на время сеанса редактирования AutoCADа.
Когда запускается AutoLISP, то для него самого требуются две большие
области памяти. Первая область, называемая хипом (heap), служит для
запоминания всех функций и переменных называемых также нодами (nodes);
чем больше у вас переменных и функций (и чем сложнее эти функции), тем
большая область хипа используется. Вторая область,называемая стэком
(stak).Она хранит аргументы функций и промежуточные результаты; чем
глубже "вкладываются" функции, и чем насыщеннее рекурсия, тем большая
часть этой области используется.

6.1 Использование памяти Автолиспом

В данном разделе речь пойдет о работе Автолиспа и его расширенной


версии в операционных системах MS-DOS/PC-DOS, поскольку в других
средах программы на Автолиспе и объем данных не ограничиваются по
размеру.

Размеры хипа и стэка, по умолчанию:


Heap = 40 000 байт (для обычного Автолиспа)
Stack = 3 000 байт

и выбраны как соответствующие большинству областей


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

Insufficient node space. - исчерпано пространство нодов или


- исчерпано строковое пространство

и завершит выполнение текущей функции. Если нет достаточного


объема памяти для загрузки AutoLISPа, то на экране отобразится
сообщение:

Insufficient memory -- AutoLISP disabled.


/Недостаточный объем памяти -- AutoLISP блокируется/

AutoLISP не будет действовать до тех пор, пока не будет


предоставлен больший объем памяти.
*****
Если вы опытный программист и знакомы с концепциями использования
обдасти хипа и стэка, то вам, возможно, захочется воспользоваться
командой "SET" системы DOS для изменения того объема памяти, который
выделяется AutoLISPу для динамической и стэковой областей. Например,
команды:

C>SET LISPHEAP=30000
C>SET LISPSTACK=10000

резервируют для AutoLISPа 30000 байтов области памяти хипа и


10000 - стэковой. Общий объем двух областей не должен превышать 45000
байтов. Вы можете поместить предложения подобные тем, что умомянуты
выше, в ваш файл "autoexec.bat" с тем, чтобы они выполнялись всякий
раз, когда вы запускаете операционную систему. Эти команды SET влияют
только на AutoLISP и не занимают памяти компьютера,когда Автолисп
отключен.
Расширенный Автолисп игнорирует установку LISPHEAP. В этом случае
место и размер области расширенной памяти под Автолисп и используемой
под хип и стек, определяютсяпеременной среды LISPXMEM. Соответствующая
установка этой переменной позволяет расширенному Автолиспу
сосуществовать с другими программами (в том том числе с
Автокадом),использующими эту часть памяти. Если переменная LISPXMEM не
задана,то расширенный Автолисп использует всю расширенную память , не
занятую под виртуальный диск (VDISK). В расширенном Автолиспе под хип
и стек отводится до 14 Мегабайт расширенной памяти, если таковая
имеется.
LISPXMEM устанавливается командой SET операционной системы DOS
перед запуском программы EXTLISP. Для этого можно использовать один из
следующих форматов команды:

1.drive> SET LISPXMEM=начало


2.drive> SET LISPXMEM=начало,размер
3.drive> SET LISPXMEM=,размер
Превый формат определяет наименьший начальный адрес,который может
быть использован расширенным Атолиспом и значение которого варьируется
от 0 100 000 до до 01 000 000 или от 1024К до 16 384К. Другими
словами, эта величина может быть выражена или как абсолютный адрес,или
в килобайтах. В последнем случае после числа должна стоять буква "К"(т
.е 1024К=0 100 000). При этом подразумевается десятеричное число,если
только оно не начинается с "0" или "0х" (что означает
шестнадцатеричное число). Это число устанавливает нижнюю границу
области,которая,возможно ,будет занята расширенным Автолиспом.
Если,например,начальный адрес указан в середине буфера виртуального
диска,то область расширенного Автолиспа будетначинаться с конца буфера
виртуального диска.
Второй формат определяет диапазон адреса от "начала" до
"начало+размер", которым будет ограничен расширенный Автолисп.
Аргумент "размер" имеет ту же форму, что и аргумент "начало". Как
"начало", так и "начало+размер" должны находиться в диапазоне от 0 100
000 (1024) до 01 000 000 (16 384). Например, чтобы выделить для
расширенного Автолиспа один мегабайт расширенной памяти, начиная с
1664К (оставляя первые 640 килобайт для использования другой
программой), можно выполнитьследующую команду:

drive> SET LISPXMEM=0x1a0000,0x100000


drive> SET LISPXMEM=1664K,1024K

Третий формат определяет максимальный размер области памяти,


занятой расширенным Автолиспом,а начальный адрес определяется обычным
путем.
Если значение переменной среды LISPXMEM установить не в одном из
трех разрешенных форматах,то расширенный Автолисп будет использовать
по умолчанию всю имеющуюся расширенную память.
По форме и значению LISPXMEM аналогична переменной среды Автокада
ACADXMEM. Однако ACADXMEM имеет четверртый формат ("=нет"), который не
используется в LISPXMEM,и,кроме того, управляет расширенным
пространством ввода/вывода в Автокаде,в то время как LISPXMEM
управляет использованием расширенной памяти Автолиспом. Расширенную
память можно использовать различными способами, в частности задавая
неперекрывающие друг друга значения. Пример:

drive> SET LISPXMEM=4096k,2048K


drive> SET ACADXMEM=6144K

Если подразумевается,что на компьютере имеется не менее пяти


мегабайт расширенной памяти, причем два мегабайта отведены для
расширенного Автолиспа, а первые три мегабайта отведены для
использования другой программой или под виртуальный диск. Расширенная
область ввода/вывода Автокада следует после расширенного Автолиспа и
будет использовать остаток расширенной памяти (но не более четырех
мегабайт - текущего предела для Автокада ).

6.2. Восстановление пространства нодов

Допустим, вы создали функции и переменные, которые требуются


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

(setq setup nil)


и избавиться от нее. Пространство нодов восстанавливается и его
можно использовать для других функций и переменных.

Если требуется освободить пространство нодов, используемое


переменной типа FILE(значение которой возвращается функцией OPEN), то
перед ее установкой ее на nil следует использовать функцию CLOSE. В
противном случае возникает ощибка, в результате которой файл не будет
закрыт,ограничивая тем самым количество новых файлов,которые можно
открыть.

Если требуется аннулировать все загруженные или определенные во


время сеанса редактирования функции или переменные, то можно легко
сделать и это. В AutoLISPе имеется список ATOMLIST, который
первоночально содержит имена всех, определенных системой функций и
переменных. (Если вы хотите посмотреть на его содержимое, то в ответ
на запрос "Command:" системы AutoCAD, введите "!atomlist".) Если вы
создаете новые функции и переменные, то их имена добавляются к началу
списка ATOMLIST. Вы можете удалить все, что создали путем возврата к
первоночальному содержимому списка ATOMLIST. Проявляйте осторожность,
чтобы не удалить функции, определенные системой.

Если вы поместите следующую функцию в свой файл "acad.lsp":

(defun C:CLEAN (/ i item)


(setq i 0)
(while (not (equal (setq item (nth i atomlist)) 'C:CLEAN))
(if (=(type (eval item) 'FILE)
(close (evel item)))
(setq i (1+i))
)
(setq atomlist (member 'C:CLEAN atomlist))
'DONE
)

то можно вводить команду CLEAN, всякий раз, когда вам потребуется


удалить ATOMLIST и восстановить динамическую область памяти,
используемую всеми вашими функциями и переменными. Если C:CLEAN
является последней функцией в вашем файле "acad.lsp", то те функции,
которые вы определили в файле ранее, сохранятся. CLEAN удаляет только
те функции и переменные, которые определялись после нее, поэтому все,
что создано в файле "acad.lsp" ранее, воспринимается как определенные
системой функции.

ПРИМЕЧАНИЕ: ATOMLIST не является стандартным средством LISPа и


может меняться в новых версиях AutoLISPа. Метод отсечения ATOMLIST не
может также использоваться при наличии виртуальной памяти.

6.3. Средство разбивки на страницы

Если ваша прикладная программа AutoLISPа становится слишком


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

(vmon)

перед первой функцией DEFUN в вашей программе. Это активизирует


средство разбивки на страницы для текущего сеанса Редактора чертежей
AutoCADа. Если средство разбивки на сртаницы включено, его нельзя
заблокировать. Для разбивки на страницы могут выбираться только те
функции, которые создаются при помощи DEFUN, после VMON, поэтому если
вы определяете функции перед VMON, они не будут разбиваться на
страницы и могут опять завершаться сообщением о нехватке памяти.
После того, как функция VMON выполнена, AutoLISP будет выгружать
из памяти страницы с редко используемыми функциями, и автоматически
считывать их обратно, по мере необходимости. Вам не не следует
задумываться об этой разбивке на страницы, т.к. она происходит
автоматически и является прозрачной для вашей программы. Функции
сбрасываются во временный файл, который находится под управлением
средства разбивки на страницы. Таким образом, если у вас имеется
достаточно расширенной или дополнительной памяти последняя может
использоваться для сброса функций, что обеспечивает ускорение по
сравнению с выгрузкой на диск.

Обратите внимание на то, что система виртуальной памяти разбивает


на страницы только функции; вам по прежнему нужна динамическая область
памяти для включения всех списков данных, используемых вашей
программой, также как и имен функций и переменных. Следовательно,
несмотря на то, что разбивка на страницы дает возможность работать с
большой программой, используя меньший объем памяти, необходимо
все-таки определять оптимальный размер хипа и соответственно
устанавливать переменную LISPHEAP. Установка LISPSTACK не зависит от
активизации виртуальной памяти.

6.4 Технические замечания

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


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

6.4.1 Пространство нодов

Нод - это единица памяти,способная представлять все типы данных


Автолиспа. В системах PC-DOS/MS-DOS нод имеет размер 10 байт, а в
системе OS.2 и на 32-разрядных компьютерах - 12 байт.
Расширенный Автолисп также имеет ноды по 12 байт. Чтобы избежать
разделения памяти и превышения хипа,ноды из хипа размещаются в группы
,называемые сегментами. Поо умолчанию сегмент равен 512 нодам (5 120
байт при 10-байтовых нодах ).
Автолисп управляет списком " свободных " нодов (т.е. не занятых в
данный момент переменными ). Если необходим нод для размещения
переменной или значения, то для нахождения свободного нода Автолисп
просмтривает список "свободный". В случае отсутствия свободных нодов
автоматически выполняется действие по "сбору мусора": все не занятые
символами ноды помещаются в список "свободный". После этого один из
нодов заполняется . Если освобождается недостаточное количество нодов,
Автолисп запрашивает дополнительный сегмент из хипа . При выполнении
запроса в список "свободный" помещаются новые ноды и один из них
выбирается для удовлетворения первоначального требования нодов. Если в
хипе нет дополнительных сегментов,то используется постраничная
организация виртуальной памяти (если есть) для освобождения нескольких
нодов удаление мамой первой из используемых функций; в противном
случае выдается сообщение "Исчерпано пространство нодов" и функция
,требующая дополнительного пространства нодов ,прерывается. Следует
заметить ,что пространство нодов никогда не возвращается в хип до
выхода из Автокада.
"Сбор мусора" может быть выполнен искусственно с помощью функции
GC:
(gc)
Поскольку,однако "сбор мусора" - довольно прдолжительный процесс,то
лучше его оставлять Автолиспу: при этом процесс выполняется
автоматически и только в случае крайней необходимости.

6.4.2 Строковое пространство

Пространство для хранения строк отводится в том же хипе,что и


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

6.4.3 Хранение переменных

В структуре данных щироко используются указатели. При этом как сами


указатели, так и данные хранятся в нодах, структура которых полностью
описывает программу. Простым действием по присваиванию переменной
значения является

(setq longsym 3.1415)

операция требующая три нода: первый для размещения переменной в


ATOMLIST, второй для хранения имени переменной и третий для хранения
ее значения. Если в имени переменной имеется не более шести знаков, то
оно будет храниться непосредственно в ноде имени переменной; в
противном случае для хранения имени из хипа выделяется строковое
пространство, а нод имени переменной указывает на эту строку . Таким
образом ,использование коротких имен переменных (не более шести
знаков) уменьшает потребность в строковом пространстве и фрагментации
хипа.

6.4.4 Ручное распределение

С помощью функций ALLOC и EXPAND можно управлять распределением


пространства для нодов и строк, увеличив тем самым эффективность
пользовательских программ. Используя эти выражения в начале файла
"acad.lsp", можно заранее распределить пространство для нодов,а также
сохранить строковое пространство. Это приведет к уменьшению частоты
"сбора мусора" и, следовательно, к сокращению времени, необходимогодля
выполнения программы.

Функцию ALLOC можно использовать для изменения размерров сегментов


хипа в нодах.

(alloc <namber>)
ALLOC устанавливает размер сегмента, равный <числу> нодов, и
возвращает предыдущую установку.
Используя функцию EXPAND, можно вручную распределить пространство
нодов,задавая число сегментов.

(expand <namber>)
****
6.4.6 Постраничная организация виртуальной памяти
После выполнения функции VMON, все DEFUN помещает новый узел,
называемый страничной таблицей/page table/ в начале каждого списка
определения функций. Этот узел добавляется перед списком формальных
аргументов. Узлы страничной таблицы служат только для использования
средств разбивки на страницы и никоим образом не должны обрабатываться
пользовательскими программами. Функция TYPE возвращает PAGETB для этих
узлов.

Когда AutoLISP исчерпает всю область динамической памяти,


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

Функции, созданные посредством DEFUN, в AutoLISPе являются просто


списками и могут обрабатываться как любой другой список. Программы,
которые делают это, должны быть осведомлены о средстве разбивки
страниц (или никогда не должны использовать функцию VMON). Прежде
всего, созданные посредством DEFUN функции, имеют впереди узел
страничной таблицы, поэтому вы должны пропускать его, когда
просматриваете функцию. Если вы сами создаете функцию как список (не
используя DEFUN), , то такую функцию нельзя будет выгрузить, поэтому
вы быстро исчерпаете память. Чтобы зафиксировать функцию в памяти,
достаточно переопределить ее, удалив таблицу страниц. Например, чтобы
заблокировать функцию, определенную под именем ZORP при помощи DEFUN,
вы могли бы использовать:

(setq zorp (cdr zorp))

Страничные таблицы выводятся в качестве пробела, когда вы


распечатываете функцию. Таким образом, страничную функцию можно
отличить по наличию пробела после первой левой скобки.

Если вы пытаетесь сканировать функцию как данные, и если функция


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

Когда функция выгружается, то предполагается, что ATOMLIST не


изменяется во время выгрузки (если разбивка на страницы работает не
так, то она займет гораздо больше дискового пространства и будет
выполняться в пять раз медленнее). Чтобы ATOMLIST не менялся, в момент
первой выгрузки , блокируется доступ к ATOMLIST путем удаления
ATOMLIST из списка символов, доступных для пользователя. Если вы
производите разбивку на страницы, оставьте ATOMLIST в покое!