Цель лекции: приобрести навыки работы с функциями .
Основным средством разработки приложений в системе AutoCAD является язык программирования - вариант языка LISP, в который добавлены функции доступа к объектам и таблицам AutoCAD. Основой языка LISP является работа со списками, которые могут иметь произвольную длину и включать элементы разной природы (числа, текстовые строки и т. д.). В то же время в языке пользователю доступны обычные арифметические вычисления, логические операции, работа с файлами и т. д.
С помощью можно писать программы или вводить в командной строке выражения, которые затем выполняет система AutoCAD. Для чтения и разбора выражений в систему AutoCAD встроен интерпретатор .
Интерпретатор , начинает работать, если вы в командной строке в ответ на стандартную подсказку Command: введете открывающую скобку. В этот момент AutoCAD настраивается на прием и вычисление выражения . Это выражение, которое должно иметь форму списка, т. е. начинаться открывающей скобкой и заканчиваться закрывающей скобкой, а элементы списка должны отделяться друг от друга пробелами.
Например, для получения суммы трех чисел вы можете ввести выражение:
(+ 223.75 16.002 89.899)
Как только вы завершите ввод своего выражения нажатием на клавишу <Enter< , система AutoCAD вычислит его и выдаст результат (рис.3.1). Точка в вещественных числах играет роль разделителя между целой и дробной частями.
(рис 3.1) Вычисление выражений интерпретатором AutoLISP
Клавиатурный ввод выражений встречается сравнительно редко. Обычно выражения записываются в текстовый файл с расширением , который затем загружается в AutoCAD с помощью функции load.
В приведенном примере для вычисления было дано выражение, открывающееся и закрывающееся круглыми скобками и состоящее из четырех элементов: первый - имя функции сложения ("+"), остальные - аргументы функции, т. е. слагаемые (223.75, 16.002 и 89.899). Это иллюстрирует форму вычисляемых выражений языка :
(<функция< [<аргумент1> [<аргумент2> ... [<аргументN> ]...]])
Здесь <функция> - это имя функции; <аргумент1>, <аргумент2>, ... , <аргументN> - аргументы функции, разделяемые, по крайней мере, одним пробелом. Квадратные скобки в приведенной форме указывают на то, что, начиная с некоторого места, аргументы могут быть опущены. Количество аргументов зависит от синтаксиса функции. Существуют функции, которые вызываются без аргументов.
С точки зрения все, что заключено в круглых скобках, является списком, который нужно обработать как вычисляемое выражение. Метод обработки определяет функция, которая должна стоять сразу после открывающей скобки. Если список содержит только аргументы (данные), то перед скобкой нужно поставить апостроф.
Основное правило - баланс скобок, т.е. сколько скобок открыто, столько должно быть и закрыто. Иначе AutoCAD, обнаружив дисбаланс (например, если пользователь забыл ввести конечную скобку), выдаст об этом соответствующее сообщение (рис. 3.2).
(рис 3.2) Сообщение о дисбалансе скобок
Для разрешения ситуации, изображенной на рис. 3.2, необходимо ввести закрывающую скобку и нажать клавишу <Enter>. После этого вы получите результат вычисления. В интегрированной среде разработки Visual LISP предусмотрены механизмы проверки скобок в файлах с текстами программ.
Выражения могут быть как простыми, так и составными. В выражениях могут в качестве элементов использоваться другие выражения, причем разделяющими знаками являются круглые скобки, пробелы и двойные кавычки, которые ограничивают с двух сторон текстовые константы. Например:
(- (+ 56.022 78.11) (+ 123.77 78.0))
Здесь "-" - имя функции (вычитание), имеющей два аргумента в виде выражений, каждое из которых является операцией сложения. Сначала интерпретатор вычислит выражения во внутренних скобках (в нашем примере получатся результаты 134.132 и 201.77), а затем подставит полученные значения и вычислит выражение (-134.132 201.77), что должно дать результат -67.638.
Интерпретатор вычисляет значение каждого введенного выражения и возвращает его в среду AutoCAD. Возвращаемое значение, в свою очередь, либо может быть передано для дальнейших вычислений в выражение более высокого уровня, , либо может быть сохранено в переменной - в именованном участке памяти для хранения данных. Присвоение переменной значения производится с помощью функции присвоения setq, имеющей следующий синтаксис:
(setq <переменная1> <выражение1glt; [<переменная2> <выражение2> ... [<переменнаяN> <выражениеN>] ... ] )
Функция setq может использоваться с любым количеством аргументов, которое должно быть обязательно четным и не менее 2. В качестве аргументов <переменная> могут использоваться любые символы (имена) , не занятые в наименованиях функций. В качестве аргументов <выражение> могут использоваться выражения , имена переменных или константы (например, числа или строки).
Функция setq - основное средство для сохранения значений, возвращаемых другими выражениями. Сохраним результат вычислений в переменной result:
(setq result (- (+ 56.022 78.11) (+ 123.77 78.0)))
В дальнейшем прочитать значение переменной result можно с помощью операции ! (восклицательный знак). Если в командной строке системы AutoCAD в ответ на стандартную подсказку Команда: (Command:) ввести !result, то система выдаст текущее значение переменной result (в нашем примере: 329.651).
В текст программы полезно вставлять комментарии, поясняющие, например, особенности алгоритма. Комментарием считается часть строки, начиная с символа ";" (точка с запятой), после которого не следует сразу же символ "|", и кончая последним символом строки. Закомментированной может быть вся строка программы.
Если комментарий нужно вставить в середину строки, тогда началом комментария должны быть символы ";|", а концом комментария - символы "|;" (причем конец комментария может располагаться на другой строке).
Примеры (для наглядности комментарии подчеркнуты):
; Закомментирована вся строка (setq two_pi (+ pi pi)) ; Закомментирован конец строки (setq md (+ 56.022 ;| внутренний комментарий |;78.11)) (command "_CIRCLE" '(0 0) 50); рисование окружности
Символы - это слова, состоящие из группы буквенно-цифровых знаков и являющиеся именами функций или переменных, используемых для хранения данных пользователя. В символах не должны использоваться разделители выражений, к которым относятся круглые скобки, пробелы и двойные кавычки, и служебные знаки -"." (точка), "," (запятая), ";" (точка с запятой), " ' " (апостроф), "/" (косая черта), "\" (обратная косая черта). Написание символов не должно соответствовать написанию чисел (символ не должен состоять из одних цифр).
Зарезервированными (служебными) являются символы, используемые как имена функций, а также некоторые обозначения констант. В именах символов регистр (верхний или нижний) не имеет значения. Поэтому setq, SETQ, SETq, Setq, SETQ обозначают одну и ту же функцию setq.
работает с объектами следующих типов:
AutoCAD;VLA -объект.Символам могут быть присвоены значения любых типов. Тип символа может быть получен с помощью функции type. Есть функции, которые преобразуют значения из одного типа в другой (например, функции atoi, fix, float, и др.). Пользователь в явном виде может задавать константы следующих типов: целые, вещественные, строковые и списки.
Целые числа могут быть как положительными, так и отрицательными или нулями. Диапазон допустимых значений варьируется от -2,147,483,648 до +2,147,483,647 (крайние значения включены в допустимые: запятые могут использоваться как разделители триад).
К целым числам относятся слова, состоящие только из цифр. Кроме того, целые числа могут иметь знак "+" или "-". Функция getint, запрашивающая ввод целого числа, допускает только значения в диапазоне между -32768 и +32767. Если пользователь пытается задать целое число, не лежащее между описанными выше предельными значениями, то вводимое число преобразуется в вещественное.
Вещественные числа - это слова, которые состоят из цифр и содержат внутри только одну десятичную точку. Могут иметь знак "+" или "-". В состав вещественного числа может входить латинский символ "е" или "Е" с показателем степени числа 10 (научная форма представления вещественных чисел).
Строковые константы начинаются и заканчиваются кавычками (сами кавычки в длину константы не входят) и содержат внутри себя текст, который может состоять из любых знаков, в том числе, пробелов, скобок, апострофов. Особо рассматривается знак "\", который является служебным и используется для ввода в текстовую строку некоторых специальных знаков (например, кавычек и самого знака "\"). Константа "" считается строкой нулевой длины. В строковые константы могут входить управляющие знаки печати, например: "\n" - переход на новую строку, "\t" - символ табуляции.
Списковые константы - это списки, состоящие из постоянных элементов любого типа (списки, как и функции, открываются и закрываются круглыми скобками). Для того чтобы система AutoCAD не вычисляла выражение как функцию, постоянные списки предваряются апострофом перед открывающей скобкой.
Примеры констант:
57
-100092
12.98207
11.1e+8
"string(2) for printing"
"52\\_l" (первая косая черта является служебной, вторая - значащим символом; если распечатать такую строку, то получим 52\_1)
'(1 5 100 -2)
'("Аа" "Бб" "Вв" "Гг" "Дд" "Ее")
'("Первый" 15 "online" 90.22 "")
Функция setq возвращает значение, совпадающее со значением выражения, присваиваемого последней переменной (<переменная>), поэтому тип результата также совпадает с типом этого выражения.
К зарезервированным (предопределенным) символам, которые пользователям не рекомендуется применять, помимо имен функций, относятся следующие:
т - единственная логическая константа, имеющая значение "истина";nil - пустое значение (оно же в логических операциях играет роль и значения "ложь"). Это значение не эквивалентно числу 0 или пустой строке ("");pi - постоянная, равная отношению длины окружности к диаметру (3.14159);pause - постоянная, позволяющая ввести паузу при работе команды системы AutoCAD (используется в функции command).В функциях, требующих в качестве аргумента логическое значение, вместо т можно вводить любое значение, отличное от nil (например, число, строку и т. д.).
При введении пользователем новых переменных для хранения данных к той части оперативной памяти, которая отведена для текущего рисунка, добавляются участки, занимаемые переменными. Если переменной присвоить значение nil, то такая переменная из памяти удаляется и ее место освобождается для других операций .
В многодокументном режиме (когда в одном сеансе системы AutoCAD открыто несколько рисунков) переменные одного рисунка обычно недоступны в другом. Для передачи требуется экспортировать переменные во внедокументное пространство символов.
Переменные могут использоваться в любых выражениях, например:
(setq уу2 (+ 20.56 уу0))
Ввод в командную строку с клавиатуры выражений не всегда удобен. Поэтому обычно записывают предварительно строки на языке в файл с расширением . Затем загружают этот файл с помощью функции load. Синтаксис функции load следующий:
(load <файл> [<сообщение>])
Здесь <файл> - это строка с именем загружаемого файла, а <сообщение> - это строка с текстом сообщения, которое нужно вывести, если загружаемый файл не будет обнаружен. Возвращаемое значение в случае удачной загрузки - результат последнего выражения или имя последней функции, если в файле находятся определения функций. В случае если загружаемый файл не найден, возвращается текст сообщения об ошибке.
Например:
(load "longwid.lsp" "Файл не найден")
Аргумент <сообщение> может быть опущен, в этом случае при ошибке загрузки выдается стандартное сообщение AutoCAD. Аргумент <файл> обычно содержит только имя файла, который ищется в соответствии с настройкой рабочего каталога и путей поиска файлов поддержки. Однако можно указывать и полное имя с маршрутом, - например, "f:/" или "f:\\". В качестве разделителя каталогов может использоваться косая черта или обратная косая черта, но обратная черта должна обязательно удваиваться.
Если расширение в имени файла опущено, то система AutoCAD пытается выполнить загрузку, поочередно добавляя следующие расширения:
vix fas lsp
Расширение vix соответствует файлам приложений, fas - компилированным LISP-файлам, - исходным LISP-файлам. Для непосредственного редактирования пользователю доступны только файлы с расширением , т. к. файлы с расширениями vix и fas не являются текстовыми.
Очень важной является функция command, которая имитирует ввод пользователя в командной строке AutoCAD с клавиатуры.
Синтаксис функции:
(command [<параметр1> [<параметр2> ... [<параметрN>] ... ] ] )
Возвращаемое значение - nil.
Функция может вызываться без параметров - это равносильно нажатию клавиши <Esc>, что прерывает действие активной команды. Если параметры используются, то их количество может быть любым. Каждый из параметров обычно является текстовой строкой, имитирующей набор символов строки на клавиатуре с последующим нажатием клавиши <Enter>. Возвращаемое значение - nil.
Предположим, что нужно нарисовать отрезками рамку формата размером 210 на 297 (левый нижний угол рамки взять в точке 0,0 и верхний правый - в точке 210,297). Вспомним, что команда рисования отрезков в системе AutoCAD называется LINE. Если вы не уверены, что ваша программа будет работать на машине с русской версией AutoCAD, то используйте английские имена команд с подчеркиванием (в данном случае - _LINE). С такими именами команды будут выполняться в любой версии системы. Если бы вы выполняли задачу без программы, то вводили бы с клавиатуры следующие команды и опции:
_LINE 0,0 210,0 210,297 0,297 _С
По этим указаниям AutoCAD вызовет команду _LINE, возьмет в качестве первой точки 0,0, в качестве второй - 210,0, в качестве третьей - 210,297, в качестве четвертой - 0,297, а _С (соответствует опции Close) замкнет отрезки на первую точку (опции тоже желательно вводить английские и с подчеркиванием). Программа, имитирующая описанный алгоритм, занимает одну строку и выглядит так:
(command "_LINE" "0,0" "210,0" "210,297" "0,297" "_С")
Можно координаты точек задавать не как строку, а как списки из двух чисел целого или вещественного типа.
(command "_LINE" '(0 0) '(210 0) '(210 297) '(0 297) "_С")
Апостроф опускать нельзя, т. к. выражение (210 0) без апострофа будет рассматриваться как обращение к функции 210 с аргументом 0.
Там, где требуется ввод чисел, можно в качестве аргументов подавать функции command именно числа, а не строки с числами, например:
(command "_COLOR" "1") (command "_COLOR" 1)
Оба выражения выполняют одну и ту же операцию (в качестве текущего устанавливают красный цвет, который имеет номер 1), но в первом случае номер цвета задается как строка, а во втором - как целое число.
Можно в одной функции command обратиться сразу к нескольким командам системы AutoCAD, например:
(command "_COLOR" 1 "_ZOOM" "_E")
Эта программная строка выполнит команду COLOR для установки красного цвета и команду ZOOM с опцией EXTENTS (ГРАНИЦЫ).
Часто пользователь вместо ввода опции нажимает на клавишу <Enter>. Для имитации этого варианта в качестве параметра функции command выступает текстовая строка нулевой длины ("").
Мы уже рассмотрели некоторые функции , встроенные в систему AutoCAD (setq, load, command). Встроенные функции по своему назначению можно классифицировать следующим образом:
ActiveX.К арифметическим относятся следующие функции (вместе с описанием функций приводится их синтаксис):
(+ [<число1> [<число2> ... [<числоN>] ... ] ]) - сложение любого количества чисел;(- [<число1> [<число2> ... [<числоN>] ... ]]) - вычитание из первого числа суммы любого количества чисел;(* [<число1> [<число2> ... [<числоN>] ... ]]) - перемножение любого количества чисел;(/ [<число1> [<число2> ... [<числоN>] ... ]]) -деление первого числа на произведение любого количества чисел;(1+ <число>) - увеличение числа на 1;(1- <число>) - уменьшение числа на 1;(∼ <число>) - дополнение числа до - 1;(abs <число>) - Все
Примеры:
(+1 3) - возвращает 4; (- -2 1.1 0.3) - возвращает - 3.4; (* -2 1.1 0.3) - возвращает - 0.66; (/ -2 1.1 0.3) - возвращает - 6.06061; (/ 5 12) - возвращает 0 (оба аргумента целые!); (1 + 1.1) - возвращает 2.1; (1 - 1.1) - возвращает -0.1; (∼ 3) - возвращает - 4; (abs -1.1) - возвращает 1.1.
Логические функции выполняют различные операции: проверки, логические операции, организуют повторения и циклы.
Следующие функции выполняют операции сравнения:
(= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - проверка на равенство любого количества аргументов (рекомендуется использовать для чисел или строк); (/= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - проверка на неравенство любого количества аргументов (рекомендуется использовать для чисел или строк); (< <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - проверка на возрастание любого количества аргументов, слева направо (для чисел или строк); (> <аргумент1> [<аргумент2> ... [<аргументN> ]...]) -Проверка на убывание любого количества аргументов, слева направо (для чисел или строк); (<= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - Проверка на неубывание любого количества аргументов, слева направо (для чисел или строк); (>= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - Проверка на невозрастание любого количества аргументов, слева направо (для чисел или строк).При сравнении строк на возрастание (убывание) используются коды буквенно-цифровых знаков строк, начиная с первого, по действующей T или nil), nil эквивалентно значению "ложь".
Примеры:
(= -10.0 -10 -10.000) - возвращает T; (= "STR56" "str56" "Str56") - возвращает nil; (= "abcde" "abcde") - возвращает Т; (/= -1.0 -1) - возвращает nil; (/= "STR56" "Str56" "Str56") - возвращает T; (/= "abcde" "abcde") - возвращает nil; (< "a" "b" "k") - возвращает T; (> 2 2 30) - возвращает nil; (<= "q" "qa") - возвращает T; (>= "qa" "q") - возвращает T.
Следующие функции выполняют логические операции:
(and [<аргумент1> [<аргумент2> ... [<аргументN>]...]]) - операция логического "И" для любого количества аргументов (все, что отлично от nil, рассматривается как т); (or [<аргумент1> [<аргумент2> ... [<аргументN>]...]]) - операция логического "ИЛИ" для любого количества аргументов (все, что отлично от nil, рассматривается как Т); (not <аргумент>) - операция логического "НЕ" (все, что отлично от nil, рассматривается как Т); (null <аргумент>) - операция проверки на nil (все, что отлично от nil, рассматривается как Т); идентична функции not.Примеры:
(and т т nil) - возвращает nil; (and "a" "b" "k") - возвращает T; (or т nil т) - возвращает T: (or "а" "b" "k") - возвращает T; (not nil) - возвращает T; (not 15.88) - возвращает nil; (null '()) - возвращает T; (null "Tram") - возвращает nil.
Условная операция типа if-then-else (если-то-иначе) осуществляется с помощью функции IF:
(if <условие> <выражение1> [<выражение2>])
Типы аргументов: любые.
Возвращаемое значение: вычисленное значение <выражение1>, если значение <условие> отлично от nil (nil в логических операциях используется как "ложь"); или значение <выражение2>, если значение <условие> равно nil (когда <выражение2> опущено, тогда вместо >выражение2< возвращается nil).
Примеры:
(if (> a b) 1 10) - возвращает 1, если a>b, и 10 - в других случаях; (if (= h1 h2) (+ h1 15) (* h1 2.5)) - возвращает результат вычисления выражения (+ h1 15), если значения h1 и h2 равны; иначе - результат вычисления выражения (* h1 2.5); (if (< a b) "a<b") - возвращает строку "а<b" или nil (т.к. <выражение2> опущено); (if nil "Point") - возвращает nil (т. к. <условие> всегда ложно).
Если функция if используется для выполнения по условию не одного выражения, а нескольких, то эти выражения следует объединить с помощью функции рrоgn (иначе будет синтаксическая ошибка, вызванная неправильным количеством аргументов при обращении к функции if):
(рrоgn <выражение1> <выражение2> ... [<выражениеN>])
Функция объединяет несколько (не менее двух) выражений в одно, когда по синтаксису языка может использоваться только одно (как в функции if).
Типы аргументов: любые.
Рассмотрим использование функции progn. Пусть при выполнении условия (< а b) нужно выполнить выражения (setq с -1), (setq d (-cab)) и (* d b) , а при невыполнении условия - выполнить выражения (setq с 2), (setq d (* а b) ) и (* d с) .
Пример совместного использования функций if и progn:
(if (> а b) (progn (setq с -1) (setq d (-cab)) (* d b) ); конец progn (progn (setq с 2) (setq d (* а b)) (* d с) ) ; конец progn ); конец if
Для удобства чтения в этом фрагменте текста программы в начале некоторых строк добавлены отступы. Открывающая скобка должна быть на одном уровне с закрывающей, а внутренние выражения должны быть смещены относительно ближайших внешних вправо. К закрывающим скобкам даны комментарии, согласно правилам их написания.
Условная операция типа case с любым количеством условий осуществляется с помощью функции cond:
(cond (<условие1> [<выражение1> ... ] ) [ (<условие2> [<выражение2> ... ])] ...)
Аргументы: любое количество списков, в каждом из которых на первом месте стоит проверяемое условие, а затем следуют выражения, которые должны быть выполнены (вычислены), если это условие оказалось истинным.
Возвращаемое значение функции cond - последнее вычисленное выражение. Если вычисляемое выражение отсутствует (не задано в списке), то возвращается результат вычисления последнего аргумента <условие>. Если аргументы функции cond не заданы, то возвращается nil.
Примеры:
(cond) - возвращает nil; (cond (14)) - возвращает 14.
Впрочем, использование функции cond с неполным количеством аргументов не имеет особого смысла.
Рассмотрим пример: переменной mycolor нужно присвоить текстовое значение с наименованием одного из основных цветов AutoCAD ("красный", "желтый", "зеленый", "голубой", "синий") в зависимости от текущего значения переменной сс, которая принимает значения 1, 2, 3, 4, 5. В случае если значение переменной сс оказалось отличным от перечисленных, то переменной mycolor нужно присвоить "" (пустая строка).
Пример 1 использования функции cond:
(setq mycolor
(cond
((= cc 1) "красный")
((= cc 2) "желтый")
((= cc 3) "зеленый")
((= cc 4) "голубой")
((= cc 5) "синий")
(Т "")
); конец cond
); конец setq
Функция setq присваивает переменной mycolor результат вычисления функции cond. Значение, возвращаемое функцией cond, вычисляется по следующей схеме. Сначала рассматривается ((= cc 1) "красный") - и проверяется условие, являющееся первым элементом этого списка. Если оказалось, что значение переменной cc равно 1 и, значит, первое условие возвращает "истину", то дальнейшее рассмотрение аргументов функции cond прекращается. В качестве возвращаемого значения принимается "красный". Если первое условие не вычислилось как "истина", то проверяется второе условие и т. д. В качестве последнего, шестого, условия стоит Т, т. е. "истина" при любых значениях. При этом, если значение переменной cc не совпало с 1, 2, 3, 4, 5, то в качестве возвращаемого значения функции cond будет принято "" (пустая строка).
Еще один пример иллюстрирует случай, когда по истинности значения <условие> выполняются несколько операторов.
Пример 2 использования функции cond
(cond
((= cc 1)
(setq abc "красный")
(command "_PLINE" "-50,120.45" "97.66,23.124" "45.7,800" "_С")
); = cc 1
((= cc 2)
(setq abc "желтый")
(command "_CIRCLE" "-50,120.45" "100")
); = cc 2
) ; конец cond
В этом примере функция cond проверяет значение переменной cc. Если оно равно 1, то функция setq присваивает переменной abc значение "красный", а затем AutoCAD рисует замкнутую полилинию с тремя вершинами. Если значение cc равно 2, то функция setq присваивает переменной abc значение "желтый", a AutoCAD рисует окружность радиуса 100. Если окажется, что значение cc не равно ни 1, ни 2, то функция cond вернет nil, не изменяя при этом значения переменной abc и не строя никаких новых примитивов AutoCAD. Поскольку функция command является последним выражением, как в первом, так и во втором условиях функции cond, то во всех трех случаях будет возвращено значение nil (nil является возвращаемым значением функции command). Однако в данном примере функция cond применена не ради возвращаемого значения, а ради изменения значения переменной abc и построения дополнительной
Существует несколько проверочных функций, которые проверяют конкретные значения или типы:
(minusp <число>) - проверка числа на отрицательность; (zerop <число>) - проверка числа на ноль; (numberp <аргумент>) - проверка типа аргумента на число; (listp <аргумент>) - проверка типа аргумента на список; (boundp <символ>) - проверка, присвоено ли значение символу AutoLISP ; для указания на имя функции его следует предварять апострофом.Все эти функции возвращают значение Т, если аргумент удовлетворяет требуемому условию, и nil - если не удовлетворяет.
Примеры:
(minusp (-52 24 39)) -возвращает т; (zerop 0.0) - возвращает т; (numberp -10.0) - возвращает т; (numberp "1") - возвращает nil; (listp "1") - возвращает nil; (listp ' (-21.82)) - возвращает т; (boundp ' +) - возвращает т.
Функция eq проверяет равенство двух аргументов (аналогична функции =):
(eq <аргумент1> <аргумент2>)
Типы аргументов: любые.
Тип возвращаемого значения: логическое (т, если значения аргументов совпали, и nil, если не совпали).
Примеры:
(eq -10.0 -10) - возвращает т; (eq о 3) - возвращает nil; (eq "abc" "АBC") - возвращает nil.
Функция equal проверяет равенство двух объектов (для чисел и списков из числовых величин равенство проверяется в пределах допуска):
(equal <аргумент1> <аргумент2> [<допуск>])
Типы аргументов: любые.
Тип возвращаемого значения: логическое (т, если абсолютная величина разности аргументов не превосходит значение аргумента <допуск>, и nil, если не совпали; если >допуск< не задан, то его значение считается равным нулю). Для аргументов, не являющихся числами или списками из чисел, <допуск> не используется.
Примеры:
(equal -10.0 -10) - возвращает Т; (equal 3.000 3.002 0.002) - возвращает Т; (equal "font" "font") - возвращает т; (equal ' (1.00 2.13 2.99) ' (1 2.13 3.0) 0.1) - возвращает Т.
Функция while позволяет организовывать операции цикла по многократно проверяемому условию:
(while <условие> <выражение1> [<выражение2> ... [<выражениеN>] ... ] )
Типы аргументов: любые.
Возвращаемое значение функции while: значение <выражение>, когда последнее вычисленное значение аргумента <условие> отлично от nil. При неудачном задании цикл, организуемый с помощью функции while, может оказаться бесконечным.
Рассмотрим пример. Пусть надо вычислить значение n! (факториал), т. е. произведение целых чисел от 1 до n. В данном разделе восклицательный знак используется как знак
Пример использовании функции while (вычисление факториала)
(setq i 1 factorial 1) (while (< i n) (setq i (1+ i)) (setq factorial (* factorial i)) ); конец while
Рассмотрим работу примера, когда число n равно 11 (т. е. вычисляется 11!).
В программе используются переменные i (это переменная, являющаяся счетчиком цикла) и factorial (переменная, которая накапливает произведение чисел, формирующее факториал). Перед входом в цикл они получают начальные значения - соответственно, 1 и 1 (по определению 1! считается равным 1).
Функция while проверяет условие (< i n) для текущего значения i и, если результат вычисления условия отличен от nil, то выполняет внутренние операции (две операции с участием функции setq). Таким образом, при первом входе в цикл i равно 1, проверяемое условие (< 1 n) возвращает значение т ("истина"), и функция while увеличивает i на l (получается i=2) и умножает переменную factorial на i: factorial=l*2 (не что иное как 2!).
Далее снова передается управление на вход в цикл (уже при i=2). Проверка условия опять дает результат "истина", поэтому i получает значение 3 (2+1), a factorial - 6 (2*3). И так далее, пока i не станет равным n (11) и программа покинет цикл, не выполняя внутренних операций. Результат: при n=11 factorial=39,916,800 (запятые разделяют триады цифр).
Функция repeat используется для организации цикла с фиксированным количеством повторений:
(repeat <количество> [<выражение1> ...] )
Типы аргументов: <количество> - целое число (имеют смысл только положительные числа), <выражение1> - любое выражение. После аргумента <выражение1> могут идти другие выражения, которые нужно выполнить внутри цикла.
Возвращаемое значение - значение последнего вычисленного выражения. Если аргумент <количество> имеет нулевое или отрицательное значение, или после аргумента <количество> не заданы выражения, то функция repeat возвращает nil.
Воспользуемся функцией repeat вместо while в предыдущем примере.
Пример использования функции repeat (вычисление факториала)
(setq i 1 factorial 1) (repeat (1- n) (setq i (1+ i)) (setq factorial (* factorial i)) ); конец repeat
Поскольку входные значения i=1 и factorial = l! =1, то остается умножить factorial на 2, 3, ... , n. Количество таких умножений равно n-1, что на языке записывается как (1- n) . Остальное работает как в предыдущем примере.
К основным вычислительным функциям относятся следующие функции:
(fix <число>) - усечение числа до целого (отбрасывается дробная часть); (rem [<число1> [<число2> ... [<числоN>] ... ]]) - получение остатка от деления аргументов <число1> на <число2>, затем остатка от деления результата на аргумент <число3> и т. д.; (mах [<число1> [<число2> ... [<числоN>] ... ]]) - определение максимального из чисел; (min [<число1> [<число2> ... [<число1N>] ... ]]) - определение минимального из чисел; (gcd <число1> <число2>) - вычисление наибольшего общего делителя для двух положительных целых чисел; (angle <точка1> <точка2>) - вычисление угла, в радианах, между осью Х текущей системы координат и вектором, идущим из точки, заданной аргументом >точка1< в точку, заданную аргументом >точка2<; (distance <точка1> <точка2>) - вычисление расстояния между двумя точками, заданными аргументами <точка1> и <точка2>; (sqrt <число>) - вычисление квадратного корня; (sin <число>) - вычисление синуса угла; (cos <число>) - вычисление косинуса угла; (atan <число1> [<число2>]) - вычисление арктангенса; если второй аргумент опущен, то вычисляется арктангенс от первого аргумента <число1>; если заданы оба аргумента, то вычисляется арктангенс частного от деления первого аргумента на второй <число1>/<число2>; если аргумент <число2> равен нулю, то возвращается угол +pi/2 или -pi/2 (знак выбирается по знаку аргумента >число1<); (ехр <число>) - вычисление натурального антилогарифма- результата возведения в степень постоянной е (2.71828); (expt <основание> >степень<) - возведение числа в степень; (log <число>) - вычисление натурального логарифма.Примеры:
(fix -10.083) - возвращает -10; (fix 40.45) - возвращает 40; (rem 14 2) - возвращает 0 (результат целый, т. к. оба аргумента целые); (rem 12.9 3.5) - возвращает 2.4; (max 7 3.4 2.0092) - возвращает 7.0 (результат вещественный, поскольку есть вещественные аргументы); (min 7 3.4 2.0092) - возвращает 2.0092; (gcd 42 12) - возвращает 6; (angle ' (0 0) ' (50.0 50.0)) - возвращает 0.785398; (distance ' (0 0) ' (250.0 0.0)) - возвращает 250.0; (sqrt 25) - возвращает 5.0; (sin 0.0) - возвращает 0.0; (cos 0.0) - возвращает 1.0; (atan 1) - возвращает 0. 785398; (atan -1 0) - возвращает -1.5708; (ехр 1) - возвращает 2.71828; (expt 2 2) - возвращает 4 (оба аргумента целые); (expt -2 2.0) - возвращает 4.0; (log 1) - возвращает 0.0.
К вычислительным можно отнести также функции побитовых операций:
(logand [<число1> [<число2> ... [<числоN> ]...]]) - вычисление побитового "и" для списка целых чисел; (logior [<число1> [<число2> ... [<числоN>]...]]) - вычисление побито-вого "или" для списка целых чисел; (lsh [<число> [<сдвиг>] ]) - вычисление побитового сдвига целого числа; (Boole <оператор> <число1> [<число2> ... ] ]) - универсальная побитовая булева функция.Все функции побитовых операций работают с целыми аргументами и возвращают целые значения.
Функция logand (побитовое "и") работает следующим образом. Каждое целое число может быть представлено в двоичном виде (иначе говоря, в виде суммы степеней числа 2, в которой перед степенью 2 стоит множитель 0 или 1; показатель степени в данной сумме может быть от 0 до 30). Например:
31-й (старший) разряд в таком представлении отводится под знак (минусу соответствует 1, плюсу соответствует 0). После перевода всех чисел в двоичное представление, выполняется поразрядная (побитовая) операция "и" по следующему правилу:
(logand 0 0)= (logand 1 0)= (logand 0 1)= 0; (logand 1 1) = 1.
Если аргументы не заданы, то возвращается 0. Если задан только один аргумент, то возвращается <число1>.
Пример:
(logand 3 5) - возвращает 1.
Функция logior (побитовое "или") работает по следующему правилу:
(logior 1 0)= (logior 0 1)= (logior 1 1)= 1; (logior 0 0) = 0.
Если аргументы не заданы, то возвращается 0. Если задан только один аргумент, то возвращается <число1>.
Примеры:
(logior 3 5) - возвращает 7; (logior 2) - возвращает 2.
Побитовый сдвиг (функция lsh) выполняется для двоичного представления чисел. Побитовый сдвиг выполняется влево, если аргумент <сдвиг> положителен, и вправо, если - отрицателен. Целые числа могут иметь не более чем 32 бита (нумерация битов от 0 для младшего разряда до 31 - этот разряд является знаковым), поэтому если старшие разряды при сдвиге влево выходят за 31-й разряд, то они теряются. При сдвиге вправо младшие разряды теряются.
Если аргументы не заданы, то возвращается 0. Если задан только один аргумент или аргумент <сдвиг> равен 0, то возвращается >число<.
Примеры:
(lsh 2 l) - возвращает 4; (lsh 3 30) - возвращает -1073741824.
В функции Boole аргумент <оператор> должен иметь значение от 0 до 15, что соответствует 16-ти вариантам булевых функции. Остальные аргументы - произвольные целые числа.
Все булевые функции двуместные, т. е. имеют два аргумента, каждый из которых может быть 0 или 1. Номер любой булевой функции кодируется следующим образом:
1=2^0;2=2^1;4=2^2;8=2^3.При таком кодировании рассмотренные выше функции logand и logior получат номера 1 и 7.
Булева функция применяется побитно к аргументам <число1> и <число2>, затем к результату и аргументу <число3> и т. д. Если заданы только два аргумента (<оператор> и <число1>), то возвращается <число1>.
Примеры:
(Boole 15 -3 45) - возвращает - l; (Boole 8 16 17) - возвращает - 18.
Функция type позволяет определять тип символа :
(type <символ>)
Тип аргумента: <символ> (имя функции или переменной).
Если аргумент <символ> не является именем функции или переменной с присвоенным значением, то возвращается nil. Другие варианты возвращаемого значения:
ENAME - имя примитива AutoCAD;EXRXSUBR - имя приложения ObjectARX;FILE - указатель (дескриптор) файла;INT - целое число;LIST - список;PAGETB - таблица диспетчера страничной организации памяти;PICKSET - набор выбора;REAL - вещественное число;SAFEARRAY - безопасный массив;STR - строка;SUBR - встроенная функция AutoLISP ;SYM - символ;VARIANT - вариант;USUBR - пользовательская функция AutoLISP ;VLA -object - объект Visual LISP, использующий технологию ActiveX.Некоторые из перечисленных вариантов возвращаемого значения доступны только при использовании других средств разработки приложений.
Примеры:
(type 15) - возвращает INT; (type l+) - возвращает SUBR; (type "15") - возвращает STR; (type '(l5 16 17)) - возвращает LIST.
К функциям преобразовании относятся следующие:
(float <число>) - преобразование целого числа в вещественное;(itoa <целое>) - преобразование целого числа в строку;(rtos <число> [<режим> [<точность>]]) - преобразование вещественного числа в строку;(atoi <строка>) - преобразование строки в целое число;(atof <строка>) - преобразование строки в вещественное число; (angtof <строка> [<представление>]) - преобразование строки, представляющей значение угла в различных форматах, в вещественное число, являющееся величиной угла в радианах; (angtos <угол> [<представление> [<точность>]]) - преобразование значения угла в радианах в строку, в соответствии с форматом; (distof <строка> [<режим>]) - преобразование строки, представляющей вещественное значение в одном из форматов линейных единиц, в вещественное число; (trans <точка> <СК-из> <СК-в> [<признак>]) - преобразование координат точки из одной системы координат (СК) в другую.Примеры:
(float 15) - возвращает 15.0; (float -l5) - возвращает -15.0; (itoa -29031) - возвращает "-29031"; (itoa 0) - возвращает "0"; (atoi "-29031") - возвращает -29031; (atof "-29.03l") - возвращает -29. 031.
Функция , преобразующая вещественное число в строку, имеет следующие аргументы:
<число> - вещественное или целое число;<режим> - целое (номер режима представления вещественных чисел);<точность> - количество десятичных знаков в представлении вещественных чисел.Аргументы <режим> и <точность> имеют тот же смысл и принимают те же значения, что и системные переменные LUNITS и LUPREC. Если аргументы <режим> и <точность> опущены, то в качестве их значений принимаются текущие значения LUNITS и LUPREC. На форму возвращаемого значения может оказывать влияние системная переменная UNITMODE.
Допустимые значения аргумента <режим>:
Возвращается строка, являющаяся результатом преобразования аргумента <число> в символьное представление с заданной точностью.
Примеры:
(rtos 10.9453 1 3) - возвращает "1.095Е+01"; (rtos 10.9453 2 3) - возвращает "10.945".
Функция angtof преобразует строку, представляющую значение угла в различных форматах, в вещественное число, являющееся величиной угла в радианах. Функция angtof по своему действию является обратной к функции angtos.
Аргументы функции angtof: <строка> - строка, <представление> - целое число. Значения аргумента <представление> соответствуют значениям системной переменной AUNITS. Если аргумент <представление> опущен, то в качестве его значения принимается текущее значение переменной AUNITS.
Допустимые значения аргумента <представление>:
Возвращается вещественное значение угла в радианах, для которого аргумент <строка> является строковым представлением (возможно, в другом формате представления углов). Если аргумент <строка> задан в неправильном формате, то возвращается nil.
Примеры:
(angtof "30" 0) - возвращает 0.523599 (перевод угла из градусов в радианы); (angtof "334.365g" 2) - возвращает 5.25219.
Функция angtos преобразует значения угла в радианах в строку, в соответствии с форматом (функция angtos является обратной к функции angtof).
Аргументы функции angtos:
<угол> - вещественное или целое значение угла в радианах;<представление> и <точность> - целые числа.Значения аргумента <представление> соответствуют значениям системной переменной AUNITS, значения аргумента <точность> - значениям системной переменной AUPREC. Если аргументы <представление> и <точность> опущены, то в качестве их значений принимаются текущие значения переменных AUNITS и AUPREC.
Возвращается строка, являющаяся строковым представлением значения угла. На форму результата оказывает влияние значение системной переменной UNITMODE. Необходимо также учитывать значение переменной ANGBASE.
Примеры:
(angtos l.00 0) - возвращает "57.296"; (angtos 1 0) - возвращает "57.296"; (angtos 3.14000 0) - возвращает "179.909".
Функция distof выполняет преобразование строки, представляющей вещественное значение в одном из форматов линейных единиц, в обычное вещественное число. Функция distof является обратной по отношению к функции .
Аргументы: <строка> - строка, представляющая число в одном из форматов; <режим> - целое число, значения которого соответствуют значениям системной переменной LUNITS (см. описание функции ). Если аргумент <режим> опущен, то в качестве его значения принимается текущее значение системной переменной LUNITS.
Возвращаемое значение - вещественное число. Если аргумент <строка> имеет неправильную структуру, то возвращается nil.
Примеры:
(distof "l" 2) - возвращает 1.0; (distof "1.0945E+01" l) - возвращает 10.945.
Функция trans преобразует координаты точки из одной системы координат (СК) в другую. Аргументы функции:
<точка> - точка (список из двух или трех чисел, соответствующий двумерной или трехмерной точке);<СК-из> - код СК, в которой аргументом <точка> задана точка (т. е. СК, из которой нужно преобразовать точку), может быть целым числом или именем примитива AutoCAD;<СК-в> - код СК, в которую нужно преобразовать точку, заданную аргументом <точка>, может быть целым числом или именем примитива AutoCAD;<признак> - необязательный аргумент, если он задан и отличен от nil (например, Т), то меняет интерпретацию аргумента <точка>. В этом случае список из двух или трех чисел рассматривается не как координаты точки, а как координаты вектора перемещения.Аргументы <СК-из> и <СК-в> могут принимать следующие значения:
ssname, entsel, nentsel, entnext, entlast);Цифровой код системы координат может принимать такие значения:
СК (МСК) ;СК (ПСК ) ;СК (ЭСК) ;СК листа (ЭСКЛ).Имеются определенные условия использования этих кодов в аргументах <СК-из> и <СК-в> (иначе говоря, не всякое значение аргумента <ск-из> сочетается с любым значением аргумента <СК-в>, и наоборот).
Коды 0 и l могут использоваться в аргументах <СК-из> и <СК-в> в любых сочетаниях. Это означает, что если <СК-из> = 0, то аргумент <СК-в> может быть или любым цифровым кодом (от 0 до 3), или именем примитива, или вектором выдавливания; аналогично: если <СК-в> = о, то аргумент <СК-из> может быть или любым цифровым кодом (от 0 до 3), или именем примитива, или вектором выдавливания.
Цифровой код 2 сочетается с разными вариантами, но его интерпретация зависит от цифрового кода другой СК. Если вторая СК имеет код 0 или l, то первая СК (с кодом 2) является ЭСК текущего
Цифровой код 3 (ЭСКЛ) используется только в паре с цифровым кодом 2 другой СК (разобран в предыдущем абзаце).
Имя примитива в качестве аргумента <СК-из> используется в том случае, когда координаты точки, хранящейся вместе с примитивом (например, начальная или конечная точки отрезка, центр окружности, вершина entmake) возникает необходимость пересчитать точку в СКО - здесь имя примитива будет фигурировать в качестве аргумента <СК-в>.
Некоторые объекты (например, трехмерные
Свои преимущества имеет и способ, когда трехмерный вектор выдавливания применяется в качестве аргументов <СК-в> или <СК-из> (например, при проектировании объекта на плоскость с известным вектором нормали). Этот способ не может использоваться для тех объектов, у которых в качестве СКО фигурирует МСК.
Возвращаемым значением функции trans является список из трех координат точки (или вектора перемещения) в новой СК. Если значения аргументов <СК-из> и <СК-в> заданы противоречиво, то возвращается nil, - например, если функция trans вызывается с цифровым кодом СК, равным 3, из
Как было сказано выше, в качестве аргумента <точка> может фигурировать двумерная точка. В этом случае AutoCAD преобразует точку из двумерной в трехмерную, добавляя координату Z по следующему алгоритму.
Если задан аргумент <признак> и его значение отлично от nil (т. е. аргумент <точка> интерпретируется не как точка, а как вектор перемещения), то добавляемая координата Z получает значение 0. Если признак не задан или равен nil, то значение координаты Z зависит от аргумента <СК-из> и выбирается по табл. 3.1..
| СК-из | Значение Z |
| МСК | 0.0 |
Текущий уровень (значение системной переменной ) |
|
| СКО | 0.0 |
| ЭСК | В проекции на текущую плоскость построений (т. е. плоскость ТСК + текущий уровень) |
| ЭСКЛ | В проекции на текущую плоскость построений (т. е. плоскость ТСК + текущий уровень) |
Рассмотрим пример. Предположим, в качестве X=10, Y=10, Z=10. Тогда:
(trans '(1 1 1) 0 1) - возвращает (-9.0 -9.0 -9.0); (trans '(1 1 1) 0 1 T) - возвращает (1.0 1.0 1.0).
К функциям, работающим со строками, относятся следующие:
(chr <целое>) - получает буквенно-цифровой символ (строку из одного буквенно-цифрового символа) по коду действующей таблицы символов; (ascii <строка>) - получает код первого символа строки текста по действующей таблице символов; (read <строка>) - читает строку-аргумент до первого пробела (или до конца, если пробелов нет) и возвращает прочитанное значение как символ AutoLISP (т. е. имя функции или переменной); (strcase <строка> [<признак>]) - преобразует строку в верхний или нижний регистр (если аргумент <признак> опущен или равен nil, то функция strcase выполняет преобразование всех буквенно-цифровых символов строки в верхний регистр; если аргумент <признак> задан, и его значение отлично от nil, то выполняется преобразование строки в нижний регистр); (strcat [<строка1> [<строка2> ... [<строкаN>] ... ]]) - конкатенация (сцепление)строк; (strlen [<строка1> [<строка2> ... [<строкаN>] ... ]]) - вычисляет суммарную длину всех строк-аргументов (длина строки - это количество буквенно-цифровых знаков в строке); (substr <строка> <начало> [<количество>]) - выделяет подстроку, начиная с заданной позиции; если количество аргументом <количество> не задано или задано больше, чем осталось в строке, определяемой аргументом <строка>, начиная с позиции, определяемой аргументом <начало>, то возвращается полный остаток строки от заданного места.Примеры:
(chr 192) - возвращает "А" (русская буква); (chr 48) - возвращает "0"; (ascii "A") - возвращает 192 (русская буква); (ascii "A") - возвращает 65 (латинская буква); (ascii "ABCDEFGH") - возвращает 65 (все буквенно-цифровые знаки, кроме первого, игнорируются); (read "B C D E F") - возвращает B; (read "23.55") - возвращает 23.55; (read "10 масса") - возвращает 10; (strcase "AbcdE FGh-38") - возвращает "ABCDE FGH-38"; (strcase "AbcdE FGh-38" Т) - возвращает "abcde fgh-38"; (strcat "Happy N" "ew " "Year") - возвращает "Happy New Year"; (strcat (itoa 12) "-я линия") - возвращает "12-я линия"; (strlen "Happy N" "ew " "Year") - возвращает 14; (strlen "Петербург") - возвращает 9; (substr "Happy New Year" 7 3) - возвращает "New"; (substr "Happy New Year" 7) - возвращает "New Year".
Функция wcmatch проверяет строку на соответствие образцу (шаблону):
(wcmatch <строка> <образец>)
Аргументы: <строка> - строка, структуру которой нужно проверить; <образец> - особая строка, определяющая требования к проверяемой структуре. Аргумент <образец> может содержать как обычные алфавитно-цифровые знаки, так и специальные групповые знаки (wild-card-characters), рассматриваемые в табл. 3.2.. Можно в строке, определенной аргументом <образец>, задать сразу несколько шаблонов, на соответствие каждому из которых аргумент <строка> будет проверен; шаблоны должны разделяться с помощью запятой.
| Знак | Назначение |
|---|---|
# |
Заменяет одну любую цифру |
@ |
Заменяет одну букву |
. (точка) |
Заменяет любой символ, не являющийся ни буквой, ни цифрой |
* |
Заменяет любую последовательность любых символов, даже пустую; может использоваться в любом месте аргумента <образец> |
? |
Заменяет ровно один любой символ |
∼ |
Если стоит в начале образца, заданного аргументом <образец>, то означает "все, кроме определенного аргументом <образец>" |
[...] |
Заменяет любой из символов, перечисленных в скобках |
[∼. . .] |
Заменяет любой символ, кроме перечисленных в скобках |
- |
Между двумя однотипными знаками указывает на диапазон |
, (запятая) |
Разделяет два шаблона |
' (обратный апостроф) |
Превращает специальный знак в обычный |
В квадратных скобках любой знак рассматривается не как специальный, поэтому его не надо предварять обратным апострофом. Символ "\" является служебным, поэтому его использование отвечает изложенным выше правилам.
Возвращаемое значение: т - если аргумент <строка> соответствует аргументу <образец>, nil - если не соответствует.
Примеры:
(wcmatch "Happy New Year" "H*") - возвращает T, т. к. проверяемая строка начинается с буквы "Н"; (wcmatch "Happy New Year" "h*") - возвращает nil (при проверке внутри строк символы "Н" и "h" считаются разными); (wcmatch "Happy New Year" "??ppy*, *New*, * * *") - возвращает Т, т. к. все три шаблона соблюдены; (wcmatch "Happy New Year" "*#*") - возвращает nil, т. к. нет ни одной цифры; (wcmatch "Happy New Year" "H[adgt]*") - возвращает Т; (wcmatch "Happy***day" "Happy'*'*'**") - возвращает Т; (wcmatch "Year 2000" "@ea@ [1-6]000") - возвращает Т.
Следующая группа функций - это функции, работающие со списками и точечными парами. Точечная пара - это двухэлементный список вида (а . b) , в котором в качестве особого разделителя выступает точка (точка в такой записи отделяется пробелом как от первого, так и от второго элементов). Точечные пары используются для хранения в файлах системы AutoCAD данных о графических примитивах Первый элемент точечной пары обычно является целым числом и называется -кодом, а второй - данными этого кода. Основной способ получения точечных пар - функция cons.
Есть отличия в работе некоторых функций со списками и с точечными парами.
Функция list - это основная функция, позволяющая создать список:
(list (<элемент1> [<элемент2> ... [<элементN>] ... ] ] )
В качестве аргументов <элементы>, из которых образуется список, могут выступать любые объекты, которыми оперирует . Самый распространенный список - это список из двух или трех вещественных чисел, представляющий точку.
В качестве элементов списка могут выступать другие списки или точечные пары.
Примеры:
(list 12.12 0.34 5.88) - возвращает (12.12 0.34 5.88); (list 1 "ad2" (list 0 1 2)) - возвращает (1 "ad2" (0 1 2)) (третьим элементом нового списка является список из чисел 0, 1 и 2).
Следующие функции выполняют основные операции со списками:
(append [<список1> [<список2> ... [<списокN>] ... ] ] ) - слияние списков в один; (nth <номер> <список>) - извлечение из списка элемента по порядковому номеру (нумерация элементов списка выполняется слева направо и начинается с нуля); (reverse <список>) - переворот списка; (car <список>) - извлечение первого элемента списка или точечной пары; (cdr <список>) - извлечение из списка подсписка путем удаления первого элемента, если аргумент <список> является простым списком (т. е. не точечной парой), или извлечение второго элемента, если <список> является точечной парой.Примеры:
(append '(14 16) '(12.12 0.34 5.88)) - возвращает (14 16 12.12 0.34 5.88); (nth 0 '(12.12 0.34 5.88)) - возвращает 12.12; (reverse '(12.12 0.34 5.88)) - возвращает (5.88 0.34 12.12); (car '(12.12 0.34 5. 88)) - возвращает 12.12; (car '(62 . 1)) - возвращает 62; (cdr '(12.12 0.34 5.88)) - возвращает (0.34 5.88); (cdr ' (62 . 1)) - возвращает 1.
От функции car и cdr путем их повторения в разных комбинациях от двух до четырех раз в языке образованы следующие функции (их двадцать восемь):
(сааr <список>) -равносильно (car (car <список>)) ; (cadr <список>) -равносильно (car (cdr <список>)) ; (cdar <список>) -равносильно (cdr (car <список>)) ; (cddr <список>) -равносильно (cdr (cdr <список>)) ; (саааr <список>) - равносильно (car (car (car <список>))) (caadr <список>) - равносильно (car (car (cdr <список>))) (cadar <список>) - равносильно (car (cdr (car <список>))) (caddr <список>) - равносильно (car (cdr (cdr <список>))) (cdaar <список>) - равносильно (cdr (car (car <список>))) (cdadr <список>) -равносильно (cdr (car (cdr <список>))) (cddar <список>) - равносильно (cdr (cdr (car <список>))) (cdddr <список>) -равносильно (cdr (cdr (cdr <список>))) (caaaar <список>) -равносильно (car (car (car (car <список>)))) ; (caaadr <список>) -равносильно (car (car (car (cdr <список>)))) .Аналогичным методом раскрываются оставшиеся функции (caadar, caaddr, cadaar, cadadr, caddar, cadddr, cdaaar, cdaadr, cdadar, cdaddr, cddaar, cdddar, cddadr, cddddr).
Функция cons добавляет к списку первый элемент или создает точечную пару:
(cons <аргумент1> <аргумент2>)
Если <аргумент2> является списком, то функция cons добавляет в него <аргумент1> в качестве нового первого элемента. Если <аргумент2> является атомом (т. е. не списком), то функция cons создает точечную пару типа (<аргумент1> . <аргумент2>).
Примеры:
(cons 67.4 '(10.3 12.9 -3.9)) - возвращает (67.4 10.3 12.9 -3.9);
(cons "Happy" '("New" "Year")) - возвращает ("Happy" "New" "Year");
(cons 2 4) - возвращает (2 . 4);
(cons 8 "0") - возвращает (8 . "0");
(cons 62 l) - возвращает (62 . l).
Функция member проверяет принадлежность элемента списку:
(member <элемент> <список>)
Если функция member обнаруживает <элемент> в аргументе <список>, то возвращает остаток списка, начиная с этого места. Если <элемент> в аргументе <список> не обнаруживается, то функция возвращает nil.
Примеры:
(member 1 '(4 50 1 2)) - возвращает (1 2); (member 4 '(4 50 1 2)) - возвращает (4 50 1 2); (member 0 '(4 50 1 2)) - возвращает nil.
Функция assoc применяется к списку, в котором элементами являются списки или точечные пары, и выбирает из этих элементов тот, у которого первый элемент имеет заданное значение:
(assoc <код> <список>)
Если в аргументе <список> имеется несколько элементов, удовлетворяющих требуемому условию, то в качестве возвращаемого значения выбирается первый из них. Функция assoc - основной инструмент в операциях выборки из списка с характеристиками примитива AutoCAD того элемента, который содержит точечную пару с нужным -кодом свойства (цвета, типа линии, веса и т. д.).
Примеры:
(assoc 8 '((8 . "Walls") (62 .4) (6 . "ACAD_IS005W100") ) ) - возвращает (8 . "walls"); (assoc 62 '((8 . "Walls") (62 .4) (6 . "ACAD IS005W100") ) ) - возвращает (62 . 4).
Следующие три функции (apply, ) позволяют выполнять операции сразу над всеми элементами списка.
(apply '<функция> <список>) - применение функции, заданной аргументом <функция> поочередно ко всем элементам списка, заданного аргументом <список>.
Примеры:
(apply '* (list 2 3 5)) - равносильно (* 2 3 5), поэтому возвращает 30; (apply 'max (list 2 3 5)) - возвращает 5.
Последний пример показывает, что функция apply удобна, когда какую-то операцию нужно выполнить над аргументами, количество которых заранее неизвестно. Поэтому следует сформировать список, к которому затем применить функцию apply с именем нужной функции в качестве первого аргумента. Обратите внимание на употребление перед аргументом апострофа.
( - применение функции, заданной аргументом <функция> сначала к первым элементам каждого из списков (<список1>, , <списокN>), затем - ко вторым элементам и т. д.; результаты объединяются в новый список, который является возвращаемым значением.
Пример:
(mapcar '* '(2 3) '(l 5)) возвращает (2 15), т. к. первый элемент результирующего списка вычисляется как (* 2 l), а второй - как (* 3 5).
Функция foreach позволяет организовать циклическое выполнение выражений (их может быть несколько), поочередно подставляя вместо переменной цикла элементы списка:
(foreach <имя> <список> [<выражение1> [<выражение2>... [ <выражениеN> ] ... ] ] )
Функция возвращает значение последнего вычисленного выражения. Если аргументы <выражение1> ... <выражениеN> не заданы, то функция foreach возвращает nil.
Пример:
(setq s1 0 s2 l) (foreach p '(1 2 3 4 5) (setq s1 (+ s1 p) ) (setq s2 (* s2 p) ) ) - возвращает 120 (результат вычисления s2 - произведения чисел списка); кроме того, в переменной s1 сформируется сумма чисел списка.
Функция eval позволяет сформировать список и затем вычислить его (evaluate) как выражение. В таком списке на первом месте должно стоять имя функции.
Пример:
(setq mylist (list 'max 1.7 9.34 6.7)); (eval mylist) - возвращает 9.34 (вычисляется выражение (max l.7 9.34 6.7)).
Функция quote является обратной по отношению к функции eval и позволяет обрабатывать выражение как список, т. е. не вычисляя его. Сокращенным вариантом имени функции quote является одинарная кавычка.
Примеры:
(quote (6 7 8 2 1)) - возвращает (67821); '(16 23 90) - возвращает (16 23 90).
Функция acad_strlsort позволяет отсортировать по возрастанию список, элементами которого являются строки.
Пример:
(acad_strlsort '("Пн" "Вт" "Ср" "Чт" "Пт" "Сб" "Bс"))- возвращает ("Вс" "Вт" "Пн" "Пт" "Сб" "Ср" "Чт").
Эти функции дают возможность пользователю вводить данные в интерактивном режиме. К основным функциям ввода данных и указания объектов относятся следующие:
(initget [<флаг>] [<строка>]) - задание ключевых слов и ограничений ввода для функций getint, getreal, getdist, getangle, getorient, getpoint, getcorner, getkword entsel, nentsel и nentselp; (getkword [запрос]) - ввод ключевого слова; (getint [запрос]) - ввод целого числа в диапазоне от -32768 до +32767; (getreal [запрос]) - ввод вещественного числа; (getdist [<точка1>] [запрос]) - получение расстояния (как вещественного числа) с помощью ввода числа (на клавиатуре в (getangle [<точка1>] [запрос]) - получение угла (как вещественного числа в радианах) с помощью ввода числа (на клавиатуре в ANGBASE и ANGDIR; возвращаемое значение учитывает значение ANGBASE и игнорирует значение ANGDIR; (getorient [<точка1>] [запрос]) - получение угла как в функции getangle, однако возвращаемое значение не учитывает значений ANGBASE и ANGDIR (т. е. как будто ANGBASE=0, ANGDIR=0); (getpoint [<точка1>] [запрос]) - ввод точки с помощью клавиату-ры или мыши; если задан аргумент <точка1>, то при вводе точки с помощью мыши рисуется резиновая нить, начинающаяся в точке, заданной аргументом <точка1>; (getcorner <точка1> [запрос]) - ввод точки с помощью клавиатуры или мыши; при вводе точки с помощью мыши рисуется резиновая рамка, начинающаяся в точке, заданной аргументом <точка1>; (getstring [<флаг>] [<запрос>]) - ввод строки; если задан аргумент <флаг> и он отличен от nil, то в строке, вводимой пользователем, допускаются пробелы (признаком конца является <Enter>); если аргумент <флаг> отсутствует или задан равным nil, то признаком конца строки является пробел или <Enter>; (getvar <имя>) - чтение текущего значения системной переменной с наименованием, заданным аргументом <имя>; (getenv <имя>) - чтение текущего значения переменной окружения с наименованием, заданным аргументом <имя>; (getcfg <строка>) - извлечение данных приложения из раздела AppData файла acad.cfg; строка, заданная аргументом <строка>, должна иметь вид "АррDаtа/имя_приложения/имя_раздела/ ... /имя_параметра"; (getcname <имя>) - получение имени команды в локализованной или английской версии AutoCAD; (getfiled <заголовок> <имя> <расширение> <флаг> - вызов диалогового окна поиска файла. Аргумент <заголовок> используется как заголовок диалогового окна; аргумент <имя> - это имя искомого файла или папки, с которой предлагается начать поиск; аргумент <расширение> - расширение искомого файла (<расширение>, равное "", заменяется на "*"); аргумент <флаг> - опции функции (см. ниже).Вызов функции initget должен предшествовать в программе обращению к функциям getint, getreal, getdist, getangle, getorient, getpoint, getcorner, getkword, entsel, nentsel и nentselp, поскольку устанавливает в этих функциях ограничения на ввод пользователем данных. В частности, initget может сохранять за пользователем возможность нажатия клавиши <Enter> вместо ввода данных (например, для выбора значения по умолчанию), а может и не сохранять. Аргумент <флаг> функции initget - это битовый флаг, который должен быть целым числом (от 0 до 255), являющимся суммой битов с соответствующими каждому из них весовыми значениями (нумеруются по степеням числа 2). Биты описываются в табл. 3.3. Если бит не установлен, то его значение в битовом флаге считается равным нулю.
| Бит | Назначение |
|---|---|
| 1 | Не разрешает пустой ввод (пустой ввод- это нажатие только клавиши <Enter>) |
| 2 | Не разрешает ввод нуля |
| 4 | Не разрешает ввод отрицательных чисел |
| 8 | Разрешает указание точек за пределами лимитов, несмотря на значение системной переменной LIMCHECK |
| 16 | Данный бит не задействован |
| 32 | Заставляет AutoCAD использовать штриховую линию вместо сплошной для резиновой нити и резиновой рамки; если значение системной переменной POPUPS равно нулю, то AutoCAD игнорирует данный бит |
| 64 | Запрещает ввод третьей координаты для точки в функции getdist |
| 128 | Разрешает произвольный ввод в качестве ключевого слова; преобладает над другими битами и ключевыми словами; в частности, данный бит позволяет игнорировать значение бита 1 |
Примеры использования битового флага:
(initget 1) - не разрешен пустой ввод; (initget 3) - не разрешены пустой ввод и ввод нуля (3=1+2) ; (initget 7) - не разрешены пустой ввод, ввод нуля и ввод отрицательных чисел (7=1+2+4) ; (initget 6) - разрешен пустой ввод, но не разрешены ввод нуля и ввод отрицательных чисел (6=2+4) .Аргумент <строка> функции initget - это строка, ограниченная двойными кавычками с двух сторон, которая задает ключевые слова, являющиеся допустимыми вариантами ввода. В аргументе <строка> различные варианты ключевых слов разделяются одним или большим количеством пробелов, например: "А Б В Г Д". Если пользователю при выборе ключевого слова разрешаются сокращенные варианты, тогда обязательная часть ключевого слова и аргументе <строка> должна быть указана в верхнем регистре, например: "ПЕРесечение". В этом случае допустимыми вариантами ввода являются "ПЕР", "пер", "ПЕРЕ", "пере", "перес", "ПЕРЕСЕЧЕН", "ПЕРЕСЕЧЕНИЕ" (после трех обязательных букв может идти любое количество необязательных букв, вплоть до набора полного ключевого слова; при вводе букв верхний и нижний регистры равноправны); недопустимыми вариантами будут "П", "ПЕ", "п", "пе".
Возможны случаи, когда вариант сокращенного ввода начинается не с первой буквы ключевого слова, например:
(initget "выход") - здесь допустимыми вариантами ввода будут "х", "хо", "ход" или "выход", "вых", "выхо".
Если ключевое слово в аргументе <строка> указано только в верхнем или только в нижнем регистре, то рядом через запятую можно указать сокращенный вариант: "КРАСНЫЙ, КР" - равносильно записи "красный".
В локализованных версиях системы AutoCAD в аргументе <строка> могут присутствовать варианты ввода для локализованной и английской версий. Тогда в начале должны идти локализованные ключевые слова, а затем их английские аналоги с символом подчеркивания. Количество локализованных ключевых слов должно равняться количеству английских ключевых слов. Например: "прямой криволинейный _straight curved".
Сама функция initget всегда возвращает nil. Однако за ней (не обязательно в следующей строке) должна идти функция, для которой функция initget установила ограничения ввода. В качестве возвращаемого значения эта функция (например, getreal) выдает допустимое значение, указанное пользователем, а в случае ввода сокращенного варианта ключевого слова - полный вариант ключевого слова.
Пример 1 использования функции getint
(initget 6) (setq numb (getint "Введите номер участка (<1>): "))
В этом примере сначала устанавливаются ограничения на будущий ввод целого числа (не допускаются ноль и отрицательные числа). Допускается пустой ввод. Функция getint выводит на экран запрос "Введите номер участка (<1>) : ". Ее возвращаемым значением будет nil, если пользователь ответит простым нажатием клавиши <Enter>, или введенное пользователем допустимое целое число (например, 17). В случае ввода пользователем недопустимого целого числа (например, 0 или -2) функция getint выведет сообщение об ошибочном значении и будет ожидать допустимого варианта ввода.
В программе, приведенной выше, далее должна быть предусмотрена обработка пустого ввода для того, чтобы в этом случае присвоить переменной numb значение по умолчанию (1): (if (not numb) (setq numb 1))
Пример 2 использования функции getint
(initget 6 "Левый Правый Нижний Верхний") (setq numb (getint "Введите номер участка (<1>) или [Левый/Правый/Нижний/ Верхний]: "))
В этом примере устанавливаются ограничения на будущий ввод целого числа (не допускаются ноль и отрицательные числа), однако допускаются пустой ввод и ввод одного из четырех ключевых слов. Далее в программе должен идти анализ значения переменной numb на nil, на положительное целое число и на ключевые слова ("левый", "правый", "нижний", "верхний").
Пример использования функции getkword
(initget 1 "Да Нет") (setq reply (getkword "Продолжить цикл [Да/Нет]: "))
В этом примере переменной reply присваивается значение "да" или "нет", пустой ввод не допускается (хотя можно было бы разрешить пустой ввод и далее использовать его для выбора значения по умолчанию).
Поскольку не все биты функции initget используются со всеми функциями ввода данных, то в табл. 3.4 разбираются варианты применения (в случае возможности использования ставится плюс).
| Функция | Бит1 | Бит 2 | Бит 4 | Бит8 | Бит 32 | Бит 64 | Бит 128 |
|---|---|---|---|---|---|---|---|
getint |
+ | + | + | + | |||
getreal |
+ | + | + | + | |||
getdist |
+ | + | + | + | + | + | |
getangle |
+ | + | + | + | |||
getorient |
+ | + | + | + | |||
getpoint |
+ | + | + | + | |||
getcorner |
+ | + | + | + | |||
getkword |
+ | + |
Функции entsel, nentsel и nentselp не используют биты функции initget и управляются только ключевыми словами.
Функция getstring не использует ни биты, ни ключевые слова функции initget.
Функции getvar и getenv позволяют прочитать значения, соответственно, системных переменных AutoCAD и переменных окружения.
Примеры:
(getvar "CECOLOR") - возвращает значение системной переменной "CECOLOR"; (getvar "PDMODE") - возвращает значение системной переменной "PDMODE"; (getenv "CONFIG") - возвращает значение переменной окружения "CONFIG".Функция getfiled позволяет вызвать диалоговое окно выбора файла в удобном виде.
Пример:
(getfiled "Выберите файл данных для расчета" "d: \\Tests\\AuroLISP\\Fields" "rtf" l6) - вызывает окно, приведенное на рис. 3.3:
(рис 3.3) Диалоговое окно, вызываемое функцией getfiled
Второй аргумент функции getfiled, в зависимости от значения четвертого аргумента (<флаг>), может задавать либо имя файла по умолчанию, либо папку, с которой предлагается начать поиск. Битовый флаг, задаваемый аргументом <флаг> получается как сумма тех битов, нумеруемых степенями числа 2, которые будут установлены. Описание битов приведено в табл. 3.5:
| Бит | Значение |
|---|---|
| 1 | Подсказка имени при создании нового файла (нельзя использовать для выбора существующего файла) |
| 2 | Не используется |
| 4 | Разрешает вводить имя файла с любым расширением (или без расширения) |
| 8 | Если бит 1 не установлен, то система AutoCAD выполняет поиск файла, имя которого задано в аргументе <имя> по списку путей, заданных в настройке, причем getfiled возвращает имя файла без пути; в противном случае возвращается полное имя файла (с путем) |
| 16 | Аргумент <имя> трактуется как имя папки, в которой нужно искать файл; при этом в поле Имя файла: (File name:) ничего не вписывается по умолчанию (см. рис.3.4); аналогичный эффект достигается и в том случае, если аргумент <имя> заканчивается обратной косой чертой |
| 32 | Если установлен бит 1, то не будет выводиться предупреждающее сообщение при записи поверх существующего файла |
| 64 | Не передает файл, если в качестве имени задан URL-адрес |
| 128 | Не допускается использование URL-адресов |
С функциями getvar и getenv тесно связаны функции, выполняющие обратные операции:
(setvar <имя> <значение>) - установка значения системной переменной с наименованием, заданным аргументом <имя>; (setenv <имя> <значение>) - установка значения переменной окружения с наименованием, заданным аргументом <имя>.В обеих функциях аргументы <имя> и <значение> должны быть текстовыми строками.
Функция setcfg является обратной по отношению к функции getcfg:
(setcfg <имя> <значение>) - запись данных приложения в раздел AppData файла acad.cfg; аргумент <имя> должен иметь вид "AppData/ имя_приложения/имя_раздела/ ... /имя_параметра" (до 496 символов длиной); возвращаемое значение функции setcfg - аргумент <значение> или nil (в случае ошибки).
В данном разделе рассматриваются функции, выполняющие операции с файлами (поиск, открытие и закрытие), операции чтения и записи строк или символов в файл, а также вывода на экран различных сообщений:
(findfile <файл>) - поиск файла по имени (краткому или полному) или поиск папки по полному имени; если аргумент не содержит полного пути, то поиск выполняется по стандартным путям поиска файлов для системы AutoCAD; возвращается полное имя файла (папки), если он найден, или nil в противном случае; (open <файл> <режим>) - открытие файла с именем, заданным аргументом <файл>; аргумент <режим> - это строка из одного символа, определяющего режим, в котором открывается файл ("w" или "W" - запись, "а" или "А" - дополнение, "г" или "R" - чтение); в предыдущих версиях AutoLISP не допускалось указание режима в верхнем регистре; если аргумент <файл> указывает на несуществующий файл в режимах "w", "W", "а" и "А", то он создается; возвращаемое значение - дескриптор файла (при успешном открытии) или nil (при неудаче); (close <дескриптор>) - закрытие файла; единственным аргументом является <дескриптор> - переменная, создаваемая функцией open и управляющая процессами записи и чтения: функция close возвращает nil, если указан действительный дескриптор, или сообщение об ошибке; (read-line [<дескриптор>]) - чтение строки из файла с заданным дескриптором; если аргумент <дескриптор> опущен, то выполняется чтение строки с клавиатуры (строка должна закончиться нажатием клавиши <Enter>); (write-line <строка> [<дескриптор>]) - запись строки, заданной аргументом <строка> в файл с заданным дескриптором; если аргумент <дескриптор> опущен или равен nil, то система AutoCAD выводит строку на экран; при записи строка, заданная аргументом <строка>, заносится в файл (или на экран) без ограничивающих ее двойных кавычек; (princ [<аргумент> [<дескриптор>]]) - запись аргумента, который может быть любым выражением AutoLISP (а также числом, списком, строкой, именем примитива и т. д.), в файл с заданным дескриптором. Если аргумент <дескриптор> опущен или равен nil, то <аргумент> выводится на экран. Если <аргумент> - строка, то при записи она заносится в файл (или на экран) без ограничивающих ее двойных кавычек. Если опущены оба аргумента, то функция осуществляет так называемый тихий выход, т. е. не возвращает никакого значения, в том числе nil; (prinl<аргумент> [<дескриптор>] ]) - функция аналогична princ, но если <аргумент> - строка, то при записи она заносится в файл (или на экран) с ограничивающими двойными кавычками; специальные символы (обратная косая черта, кавычки, конец строки и т. п.) предваряются обратной косой чертой; если опущены оба аргумента, то функция prinl тоже осуществляет тихий выход; (print [<аргумент> [<дескриптор>]]) - функция аналогична prini, но при выводе добавляет перед аргументом символ конца строки предыдущей записи, а после аргумента - пробел; тоже может осуществлять тихий выход; (read-char [<дескриптор>]) - чтение символа из файла. Если аргумент не задан, то производится чтение символа из буфера клавиатуры. Возвращает код прочитанного символа (аналогично функции ascii); нажатие на клавишу <Enter> возвращает код 10; (write-char <код> [<дескриптор>]) - запись символа с заданным кодом в файл; если аргумент не задан, то вывод символа на экран; возвращает код символа; невозможно с помощью данной функции записать символ с кодом 0; (prompt <сообщение>) - вывод сообщения на экран (если используется установка системы AutoCAD на двухэкранный вычислительный комплекс, то на оба экрана; чтобы избежать этого, можно пользоваться для вывода сообщений функцией princ).Приведенные выше функции дают пользователю возможность работы только с файлами последовательного доступа. Указателем позиции в файле, с которой далее будет происходить чтение (запись), является переменная, в которой хранится дескриптор этого файла. Механизм работы с файлами виден на следующем примере.
Пример использования функций работы с файлами
; Операции записи (setq ff (open "с:\\test.txt" "w")) (write-line "Первая строка" ff) (write-char 65 ff) (write-char 67 ff) (write-line "Вторая строка" ff) (close ff) ; Операции чтения (setq ff (open "c:\\test.txt" "r")) (setq s1 (read-char ff)) (setq s2 (read-char ff)) (setq strl (read-line ff)) (setq str2 (read-line ff)) (setq str3 (read-line ff)) (close ff) (setq ff nil)
Первое выражение - (setq ff (open "c: \\test.txt" "w")) - создает переменную ff, в которую заносится дескриптор файла c:\test.txt, открываемого для записи (в первом аргументе функции open обратная косая черта удваивается). Затем выражение (write-line "первая строка" ff) заносит в открытый файл первую запись (текст "Первая строка" из 13 символов) и символы с кодами 13 и 10, которые в файлах последовательного доступа разделяют записи.
В операционной системе UNIX признаком конца записи является один символ с кодом 10.
После этого указатель файла показывает на начало второй записи, куда поочередно - с помощью двукратного применения функции write-char - заносятся символы с кодами 65 (буква "А") и 67 ("С"). Затем в продолжение второй записи файла с помощью функции write-line заносится текст "вторая строка" (13 символов) и добавляются символы с кодами 13 и 10, означающие конец второй записи файла. Вслед за этим файл с дескриптором ff закрывается функцией close.
Вторая часть листинга начинается функцией открытия того же файла, но уже в режиме чтения. Затем с помощью двукратного применения функций read-char читаются два первых символа первой записи, которые запоминаются в переменных s1 и s2. После этого в переменную strl читается остаток первой записи. Далее в переменную str2 читается вторая запись файла. Третья операция чтения с помощью функции read-line приносит nil, поскольку в файле c:\test.txt третьей записи нет. По окончании выполнения рассмотренной программы переменная ff очищается (в ней хранился дескриптор файла). Другие переменные получат такие значения:
s1 = 207 (код символа "П"); s2 = 229 (код символа "е"); strl = "рвая строка"; str2 =: "АСВторая строка"; str3 = nil.
Функции princ, prini, print и prompt чаще всего используются для вывода сообщений в командную строку системы AutoCAD, причем prini и print выводят сообщения в кавычках (другие особенности описаны выше). Вместо функции write-line для записи в файл можно пользоваться функцией princ, но заносить признак конца записи, который выглядит как "\n", пользователь должен сам. Например:
(princ "Первая запись\n" ff)
Рисунок в системе AutoCAD имеет организацию, аналогичную организации базы данных, в которой элементы (графические примитивы и неграфические объекты) имеют 3DFACE, 3DSOLID, ACAD_PROXY_ENTITY, ARC, ARCALIGNEDTEXT, ATTDEF, ATTRIB, BODY, CIRCLE, DIMENSION, ELLIPSE, . Как правило, наименование типа совпадает с английским именем команды системы AutoCAD, которая создает графический объект.
Функции, рассматриваемые в данном разделе, работают с примитивами рисунка, обращаясь непосредственно к их внутренней структуре. имеет средства выбора графических объектов, как по их порядковому номеру, так и по определенным признакам (цвету, слою и т. п.).
Функция entlast извлекает последний неудаленный основной примитив рисунка:
(entlast)
Функция возвращает nil, если в рисунке нет неудаленных примитивов (например, когда вы только что создали новый рисунок); иначе возвращается имя последнего основного примитива в следующем виде:
(<Entity name: 14а4158>)
Полученное имя следует сохранить в переменной, например:
(setq eela (entlast))
Функция entnext позволяет перейти в рисунке к следующему примитиву (подпримитиву):
(entnext [<примитив>])
В качестве единственного аргумента функции entnext может выступать ранее полученное имя примитива текущего рисунка. Если функция вызывается без аргумента, то она возвращает имя первого неудаленного примитива в базе рисунка. При наличии аргумента функция возвращает имя следующего примитива, либо nil, если база графических объектов рисунка исчерпана.
Пример:
(setq el (entnext)) - возвращает имя первого неудаленного примитива; (setq e2 (entnext е2)) - возвращает имя примитива, следующего за e1; (setq еЗ (entnext еЗ)) - возвращает имя примитива, следующего за e2.Функция entlast возвращает имя последнего основного примитива. Это означает, что если последним созданным графическим объектом рисунка является сложный объект (например, полилиния типа ), то вслед за ним в базе рисунка следуют подпримитивы, т. е. вершины (имя примитива - ), а завершается перечисление подпримитивов SEQEND.
Пример (в предположении, что объект типа является последним основным примитивом):
(setq eela (entlast)) - возвращает имя основного примитива последней (setq v1 (entnext eela)) - возвращает имя примитива, являющегося первой вершиной (setq v2 (entnext v1)) - возвращает имя примитива, являющегося второй вершиной Замечание:
В легкой LWPOLYLINE) нет подпримитивов и информация обо всех вершинах может быть извлечена из основного примитива.
Функция entsel предлагает пользователю указать один объект, выдавая соответствующий запрос:
(entsel [запрос] )
Здесь аргумент <запрос> - любая строка текста. Функция возвращает список, состоящий из двух элементов: имени выбранного примитива и точки, которой пользователь указал объект (такая точка, как правило, оказывается вне самого примитива, поскольку точность указания мышью зависит от величины прицела). Можно указать объект вводом с клавиатуры ключевого слова Last - тогда в возвращаемом списке координаты точки будут нулевыми.
Пример:
(setq esl (entsel "Выберите объект: ")) - возвращает (<Entityname: 14а9960> (301.791 138.438 0.0)).
Имя указанного пользователем объекта может быть извлечено из такого списка, например, с помощью функции car.
Функция entdel позволяет удалять неудаленные основные примитивы и восстанавливать примитивы, ранее удаленные в данном сеансе редактирования:
(entdel <примитив>)
Функция возвращает имя удаляемого (восстанавливаемого) примитива. Следует иметь в виду, что при операции сохранения рисунка все примитивы, помеченные как удаленные, из рисунка стираются и уже больше не могут быть восстановлены.
Функция entget является основным инструментом извлечения информации о примитиве, т. к. получает список с его характеристиками:
(entget <примитив> [<приложения>])
Здесь аргумент <примитив> - это имя примитива для получения его данных, аргумент <приложения> - это список с именами приложений, с помощью которых к примитиву привязаны расширенные данные (о расширенных данных см. ниже).
Предположим, в рисунке первым объектом является отрезок (тип примитива - LINE). Тогда выражение (setq le (entget (entnext) ) ) должно вернуть примерно такой список:
((-1 . <Имя объекта: 14а4158>) (0 . "LINE") (330 . <Имя объекта: 14a40f8>) (5 . "2В") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 201.536 140.622 0.0) (11 285.148 96.5053 0.0) (210 0.0 0.0 1.0))
В этом списке элементами являются точечные пары и списки, причем и в тех, и в других первыми элементами- выступают целые числа, называемые -кодами. Под соответствующим кодом в точечных парах и списках находятся данные определенного типа:
LINE"),assoc можно из списка с характеристиками объекта извлечь нужную точечную пару, а затем, применив функцию cdr, получить данные необходимого DXF -кода.Продолжим пример с отрезком:
(cdr (assoc 0 le)) - возвращает "LINE" (тип примитива); (cdr (assoc 8 le)) - возвращает "0" (имя слоя); (cdr (assoc 10 le)) - возвращает (201.536 140.622 0.0); (cdr (assoc 11 le)) - возвращает (285.148 96.5053 0.0).Кроме того, по коду 62 можно было бы извлечь номер цвета примитива, по коду 6 - имя типа линии, по коду 48 - собственный масштаб типа линии, по коду 311 - вес линии (умноженный на 100). В рассмотренном выше списке le точечных пар с такими -кодами нет, поэтому для них действуют значения по умолчанию: BYLAYER (ПОСЛОЮ) или 1.
Рассмотрим, какой примерный список можно было бы получить для окружности (объекта типа CIRCLE):
((-1 . <Имя объекта: 14а4160>) (0 . "CIRCLE") (330 . <Имя объекта: 14a40f8>) (5 . "2С") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbCircle") (10 387.691 142.198 0.0) (40 . 27.8941) (210 0.0 0.0 1.0))
Для окружности -коды -l, 0, 410, 8, 210 имеют тот же смысл, что и для всех примитивов (в том числе и для примитива типа "LINE"). Под кодом 40 находится радиус окружности, а точечная пара с -кодом 10 хранит в себе данные о центре.
Поэтому для рассматриваемой окружности:
(cdr (assoc 40 le)) - возвращает 27.8941 (радиус); (cdr (assoc 10 le) ) - возвращает (387.691 142.198 0.0).Сравнивая справочную информацию, выдаваемую командой LIST, и список, получаемый с помощью функции entget, можно получить геометрический смысл -кодов для примитивов других типов.
Если построить в программе список, описывающий примитив (кроме точечной пары с флагом -1), то можно создать в рисунке такой примитив с помощью следующих функций:
(entmake <список>) - создает новый примитив по списку, структура которого аналогична структуре списка, возвращаемого функцией entget; функция entmake не может создать примитив типа VIEWPORT ; возвращаемое значение - аргумент <список> или nil, если создание объекта невозможно;(entmakex <список>) - создает новый примитив или неграфический объект по списку, аналогично функции entmake; возвращаемое значение - имя нового примитива или nil, если создание объекта невозможно.Пример:
(entmake '((0 . "CIRCLE") (10 500.0 0.0 0.0) (40 . 50.0))) создает новый примитив - окружность с центром в точке (500 0 0) и радиусом 50; остальные свойства (слой, цвет и т. д.), данные о которых отсутствуют в списке, берутся по умолчанию.
Функция entmod похожа на функцию entmake, но получает в качестве аргумента список, который содержит точечную пару с -кодом -1 (т. е. имя существующего в рисунке примитива) и модифицирует примитив в соответствии с новым списком (в списке могут изменяться любые данные, кроме имени примитива, типа примитива и метки):
(entmake <список>)
Функция entmod изменяет примитив в базе рисунка и возвращает аргумент <список> при успешном завершении или nil - при невозможности выполнить изменение. Для перерисовки примитива на экране следует воспользоваться функцией entupd:
(entupd <примитив>)
Здесь аргумент <примитив> - это имя примитива в том виде, в котором оно выводится, например, функцией entlast.
Другие функции доступа к примитивам:
(handent <метка>) - возвращает имя примитива или неграфического объекта по его метке; аргумент <метка> - это текстовая строка с шестнадцатеричной меткой в том виде, в каком она возвращается функцией entget; (nentsel [запрос] ) - запрашивает объект и для простого примитива возвращает такой же список из имени примитива и точки указания, как и функция entsel. Если указанный пользователем примитив является трехмерной POLYLINE ), то первым элементом возвращаемого списка будет имя подпримитива начальной вершины (VERTEX ) участка, на котором указывалась полилиния. Если указанный пользователем объект является вхождением блока (INSERT), то возвращается список из двух или четырех элементов. Если аргумент запроса не задан, то в качестве подсказки выводится запрос: Select object: (nentselp [запрос] [<точка>]) - аналогична функции nentsel, но если указанным примитивом является вхождение блока (INSERT), то возвращает список, в котором третьим элементом является матрица преобразования размером не 4х3, а 4х4 (см. ниже); если задан аргумент <точка>, то запрос не выдается и аргумент выступает в качестве точки указания.Функция nentsel работает с блоками (точнее, с примитивами типа INSERT) следующим образом. В случае, если пользователь указал атрибут блока, то функция возвращает список из двух элементов: первым является имя объекта-атрибута, а вторым - точка указания атрибута. В случае, если пользователь указал не атрибут, а объект, принадлежащий вхождению блока, то возвращается список из четырех элементов:
Матрица размером 4х3, которая выдается в качестве третьего элемента возвращаемого функцией nentsel значения, имеет вид: ((m00 m01 m02) (m10 m11 m12) (m20 m21 m22) (m30 m31 m32)) . Тогда преобразование точек из СКО в МСК идет по системе уравнений:
X' = Х*m00 + Y*m10 + Z*m20 + m30 Y' = Х*m01 + Y*m11 + Z*m21 + m31 Z' = X*m02 + Y*m12 + Z*m22 + m32
Здесь (X Y Z) - координаты точки до преобразования, (X' Y' Z') - координаты точки после преобразования.
Функция nentselp работает аналогично функции nentsel, но в случае, если пользователь указал объект, принадлежащий вхождению блока, то тоже возвращается список из четырех элементов, но третьим элементом является матрица размером 4х4, которая служит для преобразования точек из системы координат объекта (СКО) в МСК. Матрица имеет вид: ((n00 n01 n02 n03) (n10 n11 n12 n13) (n20 n21 n22 n23) (0.0 0.0 0.0 1.0)) . Преобразование точек из СКО в МСК идет по такой системе уравнений:
X' = Х*n00 + Y*n01 + Z*n02 + n03 Y' = X*n10 + Y*n11 + Z*n12 + n13 Z' = X*n20 + Y*n21 + Z*n22 + n33
Смысл списков (X Y Z) и (X' Y' Z') тот же, что и для функции nentsel.
Набор - это временное множество, в которое входят имена основных примитивов рисунка (как правило, они собираются по какому-то признаку-фильтру). Неосновные примитивы (составные части блока или вершины , чтобы затем можно было извлекать из набора нужные примитивы.
При необходимости сохранять наборы примитивов в рисунке следует оформлять их в виде групп с помощью команды GROUP. Группы относятся к неграфическим объектам, существующим внутри рисунка.
Функция ssget формирует набор по запросу или признаку:
(ssget [<метод>] [<точка1> [<точка2>]] [<список>] [<фильтр>])
Аргумент <метод> - это текстовая строка, принимающая одно из следующих значений (в локализованной версии системы AutoCAD все перечисляемые строки должны спереди дополняться символом "_"), характеризующих метод выбора примитивов:
С" - выбор секущей рамкой;СР" - выбор секущим многоугольником;F" - выбор секущей линией;I" - текущий выбор с помощью ручек;L" - выбор последнего видимого примитива;Р" - последний сформированный ранее набор;W" - выбор рамкой;WP" - выбор многоугольником;X" - вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана, с учетом аргумента <фильтр> (в этом случае аргумент <фильтр> не должен быть опущен);А" - вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана;:Е" - все примитивы, попадающие в прицел устройства указания;:N" - выбор основных примитивов с помощью подпримитивов (вершин :S" - допускает выбор только одного объекта.Аргумент <точка1> при отсутствии аргумента <точка2> определяет дополнительное условие для включения в набор: включаемый примитив должен проходить через точку, заданную аргументом <точка1>. Если заданы оба аргумента <точка1> и <точка2>, то заданные ими точки являются углами простой или секущей рамки (когда в качестве метода выбора применяются рамки, т. е. "W" или "С").
Аргумент <список> представляет собой список, элементами которого являются точки, используемые в методах "F", "WP", "СР".
Аргумент <фильтр> - это список со структурой, аналогичной структуре списка, возвращаемого функцией entget, что позволяет оставить только те примитивы, которые удовлетворяют дополнительным признакам (например, определенному цвету, слою, весу и т. д.).
Возвращаемое значение функции ssget - имя созданного набора (или nil, если создать набор невозможно).
Примеры:
(ssget) - выдает стандартный запрос: (Select objects:) и далее создает набор в соответствии с дальнейшими указаниями пользователя; (ssget '(15.78 320.1)) - создает набор из примитивов, проходящих через точку (15.78 320.1); (ssget "_с" '(1.57 -40.4) '(15.78 320.1)) - создает набор из примитивов, выбираемых секущей рамкой с углами в точках (1.57 -40.4) и (15.78 320.1); (ssget "_x" '((0 . "POLYLINE ") (8 . "WALLS"))) - создает набор из всех примитивов рисунка, являющихся POLYLINE и лежащими на слое WALLS; (ssget " А") - создает набор из всех примитивов рисунка, аналогично методу "_Х" с пустым фильтром, т. е. (ssget "_Х" '()) или (ssget "_X" nil) .В рисунке одновременно может быть открыто не более 128 наборов выбора. При достижении такого предела функция ssget отказывается создавать следующие наборы и возвращает nil. Чтобы удалить ненужные наборы, следует присвоить значение nil переменным, хранящим имена этих наборов.
Для манипуляций с наборами в языке предусмотрены следующие функции:
(ssadd [<примитив> [<набор>] ]) - добавление примитива в набор; если аргумент <набор> опущен, а аргумент <примитив> задан, то создается новый набор из одного примитива; если оба аргумента опущены, то создается новый пустой набор (но его значение не равно nil); возвращается имя набора; (ssdei <примитив> <набор>) - удаление примитива из набора, заданных соответствующими аргументами <примитив> и <набор>; возвращается имя набора, если операция удаления выполнена, или nil, если примитив не содержится в наборе и удалить его нельзя; (sslength <набор>) - возвращает количество примитивов в наборе, заданном аргументом <набор>; (ssmemb <примитив> <набор>) - проверка вхождения примитива в набор, заданных соответствующими аргументами <примитив> и <набор>; возвращается имя примитива (т. е. значение аргумента <примитив>), если он входит в рассматриваемый набор, или nil - если не входит; (ssname <набор> <номер>) - извлечение примитива из набора по порядковому номеру, заданных соответствующими аргументами <набор> и <номер>; аргумент <номер> должен быть либо целым числом от 0 до 32 767, либо целым числом в вещественной форме больше 32767.0; нумерация примитивов в наборе начинается с нуля; возвращается имя примитива или nil; (ssnamex <набор> [<номер>]) - извлечение примитива из набора по порядковому номеру (заданных соответствующими аргументами <набор> и <номер>), но при этом выдается дополнительная информация о методах формирования набора (см. ниже); если аргумент <номер> опущен, то выводится информация обо всех примитивах набора; (sssetfirst <набор1> [<набор2>]) - включает ручки у примитивов, входящих в наборы, заданные аргументами <набор1> и <набор2>, но еще и подсвечивает пунктиром примитивы из набора2 (что означает выбор их для следующей операции редактирования); (ssgetfirst) - возвращает список с именами двух наборов, аналогичных по назначению аргументам <набор1> и <набор2> функции sssetfirst (у примитивов набора включены только ручки, у примитивов набора2 включены ручки и подсвечивание).Функция ssnamex возвращает список, в котором элементами являются описания способа выбора примитивов, попавших в набор. Если аргумент <номер> не задан, то длина возвращаемого списка равна количеству элементов, определяемых аргументом <набор>. Если аргумент <номер> задан и задан корректно, то возвращаемым значением будет список из одного элемента - описания способа выбора примитива с порядковым номером, равным значению аргумента <номер>. Если же аргумент <номер> задан неправильно, то функция ssnamex вернет nil.
Описание способа выбора примитива - это список из трех элементов: (<метод> <примитив> <данные>). Параметр <метод> - целое число, которое соответствует методу выбора функции ssget и может принимать такие значения:
0 - неинтерактивный выбор ("L", "А", "X" и т. п.);
1 - выбор указанием точки;
2 - "W" или "WP";
3 - "С" или "СР";
4 - "F".
Если на месте параметра <метод> стоит отрицательное число, то оно определяет многоугольник выбора (см. описание многоугольника ниже).
Параметр <примитив> описания способа выбора примитива является его именем в том виде, в котором оно выводится функцией entlast. Параметр <данные> может быть либо только числом 0, либо числом 0 и списком, уточняющим выбор, либо числом 0 и номером многоугольника. В уточняющем списке может быть точка, с помощью которой выбран объект. Если использован номер многоугольника (а он должен быть отрицательным: -1 , -2 и т. п.), то далее будет следовать описание многоугольника с соответствующим номером.
Описание многоугольника - это список такого вида: (<номер_многоугольника> <точка1> ... <точкаN>) . Нумерация многоугольников начинается с -1 и наращивается путем добавления -1 к очередному номеру.
Описание точки (<точка1> и т. п.) - это список из трех (или двух) элементов: (<код> <база> [<вектор>] ) . Описание точки зависит от вида, на котором она выбиралась, и фактически представляет собой описание прямой, луча или отрезка. Параметр <код> является кодом описания точки (0 - прямая, 1 - луч, 2 - отрезок), параметр <база> представляет собой начальную точку описания, а необязательный параметр <вектор> - это либо направление, в котором продолжается бесконечная линия (прямая или луч), либо смещение в сторону, характерное для отрезка.
Пример:
Если в набор nab5 включен один объект, который был указан точкой (7.51 16.02) на обычном виде сверху в МСК, то выражение (ssnamex nab5 0) возвращает примерно следующее: ((1 <имя объекта: 14аа560> 0 (0 (7.51 16.02 0.0)))) .
В этом примере возвращенный функцией ssnamex список состоит из одного элемента (списка), в котором присутствуют следующие составные части:
Другие примеры значений, возвращаемых функцией ssnamex:
((0 <Имя объекта: 14ае578> 0)) - один примитив, выбранный неинтерактивным методом (например, "L"); ((3 <Имя объекта: 14ае568> О -1) (3 <Имя объекта: 14ае578> 0 -1) (-1 (0 (-147.787 129.133 0.0)) (0 (-64.2728 129.133 0.0)) (0 (- 64.2728 22.3376 0.0)) (0 (-147.787 22.3376 0.0)))) - два примитива, выбранных секущим прямоугольником с номером -1 (для прямоугольника заданы четыре точки); ((1 <Имя объекта: 14ае560> 0 (0 (74.2672 64.8218 0.0))) (2 <Имя объекта: 14ае570> 0 -1) (2 <Имя объекта: 14ае568> 0 -1) (-1 (0 (-177.446 158.755 0.0)) (0 (40.3151 158.755 0.0)) (0 (40.3151 83.1407 0.0)) (0 (-177.446 83.1407 0.0)))) - три примитива, первый из которых выбран указанием с помощью точки (74.2672 64.8218 0.0), а второй и третий выбраны рамкой, которая фигурирует как многоугольник с номером -1.В этих примерах параметр <вектор> описания точек нигде не использован, т. е. объекты выбирались на виде сверху в МСК.
Наборы - удобный инструмент для выбора нужных примитивов рисунка с заданными свойствами. После формирования набора затем из него с помощью функции ssname (или ssnamex) извлекаются нужные объекты, с которыми далее выполняются необходимые операции (например: удаление, модификация и т. д.).
Помимо примитивов в рисунке всегда присутствует определенный объем неграфической информации: описания блоков, таблицы слоев, таблицы видовых экранов, таблицы типов линий, размерные стили и т. п. Все они хранятся в базе рисунка примерно в том же виде, что и примитивы.
Для доступа к табличным объектам в языке имеются такие функции:
(tbinext <таблица> [<признак>]) - чтение характеристик очередного объекта из таблицы. Допустимые значения параметра <таблица> приведены ниже. Если параметр <признак> задан и отличен от nil, то возвращаются данные первого элемента таблицы. Иначе возвращаются данные объекта, следующего за тем, который был прочитан в предыдущем обращении к функции tbinext с той же таблицей. Если требуемого объекта нет или таблица пуста, то возвращается nil; (tbiobjname <таблица> <заголовок>) - определение объекта таблицы по его заголовку (имени блока, слоя и т. п.). Возвращается имя объекта (аналогично имени примитива) в базе рисунка. Если объект не найден, то возвращается nil. (tbisearch <таблица> <заголовок> [<следующий>]) - получение списка с характеристиками объекта таблицы по его заголовку. Возвращается список, соответствующий найденному объекту (или nil, если объект не обнаружен). Если параметр <следующий> задан и не равен nil, то указатель функции tbinext устанавливается на имя элемента <заголовок>. Следующее обращение к функции tbinext вернет данные об объекте, расположенном в таблице после объекта, использованного в качестве аргумента в функции tbisearch.В качестве допустимых значений параметра <таблица> во всех трех функциях могут фигурировать только следующие текстовые строки:
BLOCK" - таблица описаний блоков;LAYER" - таблица слоев;LTYPE" - таблица типов линий;STYLE" - таблица текстовых стилей;DIMSTYLE" - таблица размерных стилей;UCS " - таблица именованных систем координат;VIEW" - таблица именованных видов;VPORT" - таблица конфигураций видовых экранов;APPID" - таблица имен приложений.Схема использования рассмотренных функций будет ясна из примеров:
(5etq lay1 (tbinext "LAYER" T)) - возвращает список с данными первого слоя рисунка (первым слоем должен быть слой с именем "0"), например: ((0 . "LAYER") (2 . "0") (70 . 0) (62 . 7) (6 . "Continuous")). В этом списке в точечной паре с -кодамиотражаются следующие свойства:
0 - находится имя таблицы, в которой ищется неграфический объект,
2 - имя слоя,
6 - тип линий примитивов слоя по умолчанию (т. е. каким типом отображать объекты с типом линии BYLAYER),
62 - цвет слоя по умолчанию,
70 - состояние слоя по отношению к операциям блокирования, замораживания; нетрудно заметить, что аналогичные -коды используются в списке, возвращаемом функцией entget для примитивов.
(setq lay2 (tbinext "LAYER")) - возвращает список с данными второго слоя рисунка, например: ((0 . "LAYER") (2 . "стена1") (70 . 4) (62 . 40) (6 . "ограждение1"));
(setq lay2name (tbiobjname "LAYER" "Стена1")) - возвращает <Имя объекта: 14аа570>; теперь с помощью функции entget можно получить тот же список, что и lay2 в предыдущем примере.
С помощью этих трех функций можно проанализировать наличие в рисунке таких элементов, как описания блоков, пользовательские системы координат или текстовые стили с определенными именами и выбрать соответствующий вариант работы программы.
Свойствами, аналогичными таблицам, обладают в рисунке словари (dictionaries). К ним относятся, например, словари стилей
(dictadd <словарь> <символ> <новый>) - добавление нового объекта к словарю; (dictnext <словарь> [<признак>]) - чтение очередного символа из словаря (аналогична функции tbinext, но работает со словарями); (dictremove <словарь> <символ>) - удаление символа словаря; (dictrename <словарь> <старое> <новое>) - переименование символа словаря; (dictsearch <словарь> <символ> [<следующий>]) - поиск символа в словаре (аналогично функции tbisearch); (layoutlist) - получение списка имен листов текущего рисунка; (namedobjdict) - получение имени корневого словаря неграфических объектов рисунка; (setview <вид> [<в экран>]) - установка вида в видовом экране; (snvalid <имя>) - проверка имени таблицы символов на недопустимые знаки.К любому примитиву рисунка можно добавлять расширенные данные, т. е. текстовые или числовые данные, которые желательно хранить вместе с геометрией (например, марки материалов, наименования узлов, секций и т. п.). Обычно наличие такой информации позволяет разрабатывать программы связи с базами данных (рассмотрение таких программ не является предметом настоящей книги). Расширенные данные связываются с именем определенного приложения. У одного графического примитива могут быть данные нескольких приложений, которые располагаются последовательно в определенной структуре.
Если расширенные данные присоединены к примитиву, то в базе рисунка они следуют за обычными данными (-коды этих данных находятся в диапазоне от -2 до 239). Извлечь расширенные данные можно с помощью функции entget, при обращении к которой нужно указывать имя приложения, с которым они связаны. В списке, возвращаемом функцией entget, расширенные данные находятся в подсписке, начинающемся с -кода -3 (признак наличия расширенных данных), в котором далее располагаются точечная пара с кодом 1001 (начало расширенных данных и имя приложения, с которым они связываются) и точечные пары с -кодами 1000, 1002-1071. Назначение -кодов расширенных данных описывается в табл. 3.6.
| Код | Назначение |
|---|---|
| 1000 | Строковая константа длиной не более 255 знаков (256-й знак зарезервирован под символ с кодом 0) |
| 1001 | Строковая константа, используемая только для указания имени приложения, длиной не более 31 знака (если код 1001 попадает внутрь списка, организуемого с помощью -КОДОВ 1002, то он интерпретируется как обычная константа, а не имя приложения; см. далее описание -кода 1002). Имя приложения должно состоять только из цифр, латинских букв и символов |
| 1003 | Имя слоя, с которым связываются расширенные данные |
| 1005 | Метка объекта в базе чертежа |
| 1010 | Трехмерная точка (три вещественных числа) |
| 1040 | Вещественное число |
| 1070 | 16-битовое целое число (со знаком или без знака) |
| 1071 | 32-битовое целое число со знаком (длинное целое). Хотя система AutoCAD хранит данные группы с кодом 1071 как длинное целое, возвращает их как вещественные числа. Функциям entmake и entmod в точечной паре с кодом 1071 можно подавать либо целые числа, либо вещественные. ObjectARX трактует данные группы 1071 как длинные целые |
| 1002 | Строка, принимающая значения "{" или "}" и имеющая тот же смысл, что и левая и правая круглые скобки в обозначении списка. С помощью группы с кодом 1002 можно формировать в расширенных данных |
| 1004 | Двоичные данные длиной не более 127 байт. Обрабатываются только в ObjectARX |
| 1011 | Трехмерная точка, интерпретируемая как положение в МСК. Такая точка перемещается, масштабируется, поворачивается и симметрируется одновременно с родительским примитивом рисунка. Если точка попадает в рамку выбора команды РАСТЯНУТЬ (STRETCH), то она подвергается операции растягивания вместе с родительским примитивом |
| 1012 | Трехмерная точка, интерпретируемая как перемещение в МСК. Такая точка не перемещается и не растягивается одновременно с основным примитивом, но участвует вместе с ним в операциях масштабирования, поворота и симметрирования |
| 1013 | Трехмерная точка, интерпретируемая как направление в МСК. Такая точка не масштабируется, не перемещается и не растягивается одновременно с основным примитивом, но участвует вместе с ним в операциях поворота и симметрирования. Вектор с координатами, взятыми из группы с кодом 1013, является нормализованным, т. е. единичной длины |
| 1041 | Вещественное число, интерпретируемое как расстояние. Оно масштабируется одновременно с родительским примитивом |
| 1042 | Вещественное число, интерпретируемое как масштабный коэффициент. Масштабируется одновременно с родительским примитивом |
Как было сказано выше, расширенные данные связываются с именем конкретного приложения. Имена приложений хранятся в рисунке в таблице символов "APPID". Чтобы занести имя приложения в эту таблицу, следует пользоваться функцией rеgарр:
(rеgарр <приложение>)
Параметр <приложение> должен быть текстовой строкой (по возможности нужно выбирать имя приложения таким, чтобы оно не совпадало с именами приложений других разработчиков - иначе это приведет к неправильной работе с расширенными данными). Функция rеgарр возвращает nil в случае ошибки (nil возвращается также, если приложение с таким именем уже регистрировалось).
Функция entmake может создать примитив и сразу присоединить к нему расширенные данные. С помощью функции entmod можно добавить расширенные данные к существующему графическому объекту.
Пример
Предположим, что к последнему существующему примитиву рисунка (пусть им является отрезок) нужно добавить расширенные данные, связанные с приложением "GENHULL":
(setq le (entget (entlast) ) ) - сохраняет в переменной le список последнего примитива, у которого еще нет расширенных данных: ((-1 . <Имя объекта: 14аа578>) (0 . "LINE") (330 . <Имя объекта: 14aa4f8>) (5 . "2F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (100 . "AcDbLine") (10 85.4655 223.335 0.0) (11 187.712 167.209 0.0) (210 0.0 0.0 1.0)) ; (setq edata '((-3 ("GENHULL" (1000 . "Пластмасса") (1070 . 57))))) - сохраняет в переменной edata список с расширенными данными, которые будут добавлены к списку le (добавляются текстовая строка с DXF -кодом 1000 и целое число с DXF -кодом 1070); (setq le2 (append le edata)) - объединяет списки le и edata и формирует новый список le2: ((-1 . <Имя объекта: 14аа578>) (0 . "LINE") (330 . <Имя объекта: 14aa4f8>) (5 . "2F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (100 . "AcDbLine") (10 85.4655 223.335 0.0) (11 187.712 167.209 0.0) (210 0.0 0.0 1.0) (-3 ("GENHULL" (1000 . "Пластмасса") (1070 . 57)))) ; (entmod le2) - модифицирует примитив по новому списку и возвращает то же значение, что и предыдущее выражение; (entget (entlast) '("GENHULL")) - получает список нового последнего примитива вместе с расширенными данными, относящимися к приложению "GENHULL": ((-1 . <Имя объекта: 14аа578>) (0 . "LINE") (330 . <Имя объекта: 14aa4f8>) (5 . "2F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (100 . "AcDbLine") (10 85.4655 223.335 0.0) (11 187.712 167.209 0.0) (210 0.0 0.0 1.0) (-3 ("GENHULL" (1000 . "Пластмасса") (1070 . 57)))) .Размер расширенных данных любого примитива не должен превышать 16 килобайт (16383 байта). Поэтому по мере добавления таких данных их размер нужно контролировать. Этой цели служат две функции:
(xdsize <список>) - получает размер в байтах, необходимый для сохранения расширенных данных; аргумент <список> - это список с расширенными данными, начинающийся с DXF -кода -3; (xdroom <примитив>) - возвращает целое число - количество свободных байтов в зоне расширенных данных примитива.Перед записью в зону примитива новой порции расширенных данных нужно проверить, достаточно ли для них места.
Коротко рассмотрим другие функции языка .
Функция alert позволяет вывести на экран диалоговое окно с сообщением системы AutoCAD. Синтаксис функции:
(alert <сообщение>)
Функция возвращает nil. Максимальная длина строки <сообщение> зависит от многих вещей (в частности, от платформы) и может быть вычислена пользователем самостоятельно. В случае превышения допустимой длины AutoCAD обрезает сообщение. При необходимости вывести сообщение в несколько строк нужно использовать знаки конца строки ("\n").
Пример:
(setq lines (strcat "Я вас любил: любовь еще, быть может,\n" "В душе моей угасла не совсем;\nНо пусть она вас больше не тревожит-\n" "Я не хочу печалить вас ничем.")) (alert lines) выводит на экран окно, изображенное на рис. 3.4.
(рис 3.4) Диалоговое окно, вызываемое функцией alert
В данном примере выведены четыре строки, поскольку трижды был использован знак конца строки. Выход из диалогового окна, изображенного на рис.3.5, - щелчок по кнопке ОК.
Рассмотрим несколько полезных геометрических функций.
(inters <точка1> <точка2> <точка3> <точка4> [<признак>]) - если аргумент <признак> отсутствует или задан отличным от nil, функция вычисляет пересечение двух отрезков. Первый имеет концы в точке1 и точке2, а второй - в точкеЗ и точке4. Точки заданы соответствующими аргументами: <точка1>, <точка2>, <точка3> и <точка4>. Если аргумент <признак> задан и равен nil, то функция вычисляет пересечение двух прямых, проходящих через отрезки. Если все аргументы точки являются трехмерными, то функция inters ищет пересечение в трехмерном пространстве. Если хотя бы одна из точек имеет только две координаты, то вычисляется пересечение проекций отрезков на текущую плоскость построений. Точки задаются как списки из двух или трех вещественных чисел; (polar <точка> <угол> <расстояние>) - возвращает координаты точки, которая отстоит от исходной точки, определяемой аргументом <точка> на заданное расстояние с помощью аргумента <расстояние>; вектор, идущий из исходной точки в вычисляемую новую точку, должен образовывать (в проекции на текущую плоскость построений) с осью Х заданный угол, определяемый аргументом <угол>, в радианах; (textbox <список>) - возвращает список из двух точек, являющихся точками диагоналей прямоугольника, описанного вокруг надписи. Надпись задается с помощью аргумента <список>, который должен иметь формат списка текстового примитива (в том виде, в каком его вернула бы функция entget). Если аргумент <список> не содержит каких-либо параметров, то функция textbox при вычислении дополняет его текущими установками рисунка; (osnap <точка> <режим>) - возвращает результат применения к точке, заданной аргументом <точка>, функции объектной привязки с установками режимов, заданными в аргументе <режим>. Режимы привязки указываются с помощью строки, в которой без пробелов, через запятую перечисляются наименования режимов: "_end", "_mid", "_int", "_nea", "_nod" и т. д. На результат операции оказывает влияние значение системной переменной APERTURE .Примеры:
(inters '(2.25 4.50) '(-2.25 6.335) '(1.27 0.50) '(-8.65 -2.30)) - возвращает nil; (inters '(2.25 4.50) '(-2.25 6.335) '(1.27 0.50) '(-8.65 -2.30) nil) - возвращает (7.64593 2.29966); (polar '(16.32 4.782) 0.345 4.79) - возвращает (20.8278 6.40196); (osnap '(16.32 4.782) "_end,_mid") - возвращает координаты точки, уточненной с помощью применяемых одновременно функций объектной привязки к конечной и средней точкам.К полезным функциям, кроме того, относятся функции работы с элементами меню:
menucmd - операции с пунктами меню;menugroup - работа с группой меню.Подробности описания этих функций можно найти в справочной системе AutoCAD.
В языке есть некоторое количество функций для работы с диалоговыми окнами. Функции работы с диалогами - load_dialog, unload_dialog, start_dialog, done_dialog, term_dialog, new dialog.
Функции работы С ПОЛЯМИ - action_tile, get_tile, set_tile, mode tile, get_attr, client_data_tile.
Функции работы с slide_image, start_image, vector image, end_image, dimx_tile, dimy_tile, fill_image.
Функции работы со списками - start_list, end_list, add_list.
К рассматриваемой версии языка в качестве расширения могут быть добавлены более ста функций, реализующих технологию ActiveX и дополняющих возможности пользователя по созданию эффективных программных продуктов на базе системы AutoCAD 2000. Все эти функции начинаются с префиксов vir-, via- и vlax-, и перед первым обращением к любой из них надо выполнить функцию загрузки (без этого они не будут доступны):
(vl-load-com)
Технология ActiveX облегчает и ускоряет доступ к примитивам и их характеристикам. К примитивам рисунка можно прикрепить другие объекты, называемые реакторами. Реакторы отслеживают определенные будущие события (например, перемещение или удаление примитива, открытие, сохранение или закрытие рисунка, вставку блока или внешней ссылки). Как только проверяемое событие происходит, реакторы с помощью специальных средств выполняют запрограммированные операции.
Упражнение
С помощью справочной системы определите назначение функций cons, load, .
Возвращаемое значение - результат вычисления интерпретатором выражения, записанного в процедуре.
Переменная - именованный участок памяти для хранения данных.
Символы - это слова, состоящие из группы буквенно-цифровых знаков и являющиеся именами функций или переменных, используемых для хранения данных пользователя.
Загрузка файла в AutoCAD - операция загрузки файла в программу с помощью функции Load.
Функции присвоения setq - функция, которая присваивает переменной значение выражения.
Функция command - функция , которая имитирует ввод пользователя в командной строке AutoCAD с клавиатуры.
является внутренним языком программы AutoCAD. Процедуры представляют собой набор функций с задаваемыми параметрами и аргументами. Встроенные функции обладают широкими возможностями создания и редактитования чертежных объектов.
AutoLISP ?AutoLISP ?AutoLISP ?Цель лекции: приобрести навыки работы с функциями .
Основным средством разработки приложений в системе AutoCAD является язык программирования - вариант языка LISP, в который добавлены функции доступа к объектам и таблицам AutoCAD. Основой языка LISP является работа со списками, которые могут иметь произвольную длину и включать элементы разной природы (числа, текстовые строки и т. д.). В то же время в языке пользователю доступны обычные арифметические вычисления, логические операции, работа с файлами и т. д.
С помощью можно писать программы или вводить в командной строке выражения, которые затем выполняет система AutoCAD. Для чтения и разбора выражений в систему AutoCAD встроен интерпретатор .
Интерпретатор , начинает работать, если вы в командной строке в ответ на стандартную подсказку Command: введете открывающую скобку. В этот момент AutoCAD настраивается на прием и вычисление выражения . Это выражение, которое должно иметь форму списка, т. е. начинаться открывающей скобкой и заканчиваться закрывающей скобкой, а элементы списка должны отделяться друг от друга пробелами.
Например, для получения суммы трех чисел вы можете ввести выражение:
(+ 223.75 16.002 89.899)
Как только вы завершите ввод своего выражения нажатием на клавишу <Enter< , система AutoCAD вычислит его и выдаст результат (рис.3.1). Точка в вещественных числах играет роль разделителя между целой и дробной частями.
(рис 3.1) Вычисление выражений интерпретатором AutoLISP
Клавиатурный ввод выражений встречается сравнительно редко. Обычно выражения записываются в текстовый файл с расширением , который затем загружается в AutoCAD с помощью функции load.
В приведенном примере для вычисления было дано выражение, открывающееся и закрывающееся круглыми скобками и состоящее из четырех элементов: первый - имя функции сложения ("+"), остальные - аргументы функции, т. е. слагаемые (223.75, 16.002 и 89.899). Это иллюстрирует форму вычисляемых выражений языка :
(<функция< [<аргумент1> [<аргумент2> ... [<аргументN> ]...]])
Здесь <функция> - это имя функции; <аргумент1>, <аргумент2>, ... , <аргументN> - аргументы функции, разделяемые, по крайней мере, одним пробелом. Квадратные скобки в приведенной форме указывают на то, что, начиная с некоторого места, аргументы могут быть опущены. Количество аргументов зависит от синтаксиса функции. Существуют функции, которые вызываются без аргументов.
С точки зрения все, что заключено в круглых скобках, является списком, который нужно обработать как вычисляемое выражение. Метод обработки определяет функция, которая должна стоять сразу после открывающей скобки. Если список содержит только аргументы (данные), то перед скобкой нужно поставить апостроф.
Основное правило - баланс скобок, т.е. сколько скобок открыто, столько должно быть и закрыто. Иначе AutoCAD, обнаружив дисбаланс (например, если пользователь забыл ввести конечную скобку), выдаст об этом соответствующее сообщение (рис. 3.2).
(рис 3.2) Сообщение о дисбалансе скобок
Для разрешения ситуации, изображенной на рис. 3.2, необходимо ввести закрывающую скобку и нажать клавишу <Enter>. После этого вы получите результат вычисления. В интегрированной среде разработки Visual LISP предусмотрены механизмы проверки скобок в файлах с текстами программ.
Выражения могут быть как простыми, так и составными. В выражениях могут в качестве элементов использоваться другие выражения, причем разделяющими знаками являются круглые скобки, пробелы и двойные кавычки, которые ограничивают с двух сторон текстовые константы. Например:
(- (+ 56.022 78.11) (+ 123.77 78.0))
Здесь "-" - имя функции (вычитание), имеющей два аргумента в виде выражений, каждое из которых является операцией сложения. Сначала интерпретатор вычислит выражения во внутренних скобках (в нашем примере получатся результаты 134.132 и 201.77), а затем подставит полученные значения и вычислит выражение (-134.132 201.77), что должно дать результат -67.638.
Интерпретатор вычисляет значение каждого введенного выражения и возвращает его в среду AutoCAD. Возвращаемое значение, в свою очередь, либо может быть передано для дальнейших вычислений в выражение более высокого уровня, , либо может быть сохранено в переменной - в именованном участке памяти для хранения данных. Присвоение переменной значения производится с помощью функции присвоения setq, имеющей следующий синтаксис:
(setq <переменная1> <выражение1glt; [<переменная2> <выражение2> ... [<переменнаяN> <выражениеN>] ... ] )
Функция setq может использоваться с любым количеством аргументов, которое должно быть обязательно четным и не менее 2. В качестве аргументов <переменная> могут использоваться любые символы (имена) , не занятые в наименованиях функций. В качестве аргументов <выражение> могут использоваться выражения , имена переменных или константы (например, числа или строки).
Функция setq - основное средство для сохранения значений, возвращаемых другими выражениями. Сохраним результат вычислений в переменной result:
(setq result (- (+ 56.022 78.11) (+ 123.77 78.0)))
В дальнейшем прочитать значение переменной result можно с помощью операции ! (восклицательный знак). Если в командной строке системы AutoCAD в ответ на стандартную подсказку Команда: (Command:) ввести !result, то система выдаст текущее значение переменной result (в нашем примере: 329.651).
В текст программы полезно вставлять комментарии, поясняющие, например, особенности алгоритма. Комментарием считается часть строки, начиная с символа ";" (точка с запятой), после которого не следует сразу же символ "|", и кончая последним символом строки. Закомментированной может быть вся строка программы.
Если комментарий нужно вставить в середину строки, тогда началом комментария должны быть символы ";|", а концом комментария - символы "|;" (причем конец комментария может располагаться на другой строке).
Примеры (для наглядности комментарии подчеркнуты):
; Закомментирована вся строка (setq two_pi (+ pi pi)) ; Закомментирован конец строки (setq md (+ 56.022 ;| внутренний комментарий |;78.11)) (command "_CIRCLE" '(0 0) 50); рисование окружности
Символы - это слова, состоящие из группы буквенно-цифровых знаков и являющиеся именами функций или переменных, используемых для хранения данных пользователя. В символах не должны использоваться разделители выражений, к которым относятся круглые скобки, пробелы и двойные кавычки, и служебные знаки -"." (точка), "," (запятая), ";" (точка с запятой), " ' " (апостроф), "/" (косая черта), "\" (обратная косая черта). Написание символов не должно соответствовать написанию чисел (символ не должен состоять из одних цифр).
Зарезервированными (служебными) являются символы, используемые как имена функций, а также некоторые обозначения констант. В именах символов регистр (верхний или нижний) не имеет значения. Поэтому setq, SETQ, SETq, Setq, SETQ обозначают одну и ту же функцию setq.
работает с объектами следующих типов:
AutoCAD;VLA -объект.Символам могут быть присвоены значения любых типов. Тип символа может быть получен с помощью функции type. Есть функции, которые преобразуют значения из одного типа в другой (например, функции atoi, fix, float, и др.). Пользователь в явном виде может задавать константы следующих типов: целые, вещественные, строковые и списки.
Целые числа могут быть как положительными, так и отрицательными или нулями. Диапазон допустимых значений варьируется от -2,147,483,648 до +2,147,483,647 (крайние значения включены в допустимые: запятые могут использоваться как разделители триад).
К целым числам относятся слова, состоящие только из цифр. Кроме того, целые числа могут иметь знак "+" или "-". Функция getint, запрашивающая ввод целого числа, допускает только значения в диапазоне между -32768 и +32767. Если пользователь пытается задать целое число, не лежащее между описанными выше предельными значениями, то вводимое число преобразуется в вещественное.
Вещественные числа - это слова, которые состоят из цифр и содержат внутри только одну десятичную точку. Могут иметь знак "+" или "-". В состав вещественного числа может входить латинский символ "е" или "Е" с показателем степени числа 10 (научная форма представления вещественных чисел).
Строковые константы начинаются и заканчиваются кавычками (сами кавычки в длину константы не входят) и содержат внутри себя текст, который может состоять из любых знаков, в том числе, пробелов, скобок, апострофов. Особо рассматривается знак "\", который является служебным и используется для ввода в текстовую строку некоторых специальных знаков (например, кавычек и самого знака "\"). Константа "" считается строкой нулевой длины. В строковые константы могут входить управляющие знаки печати, например: "\n" - переход на новую строку, "\t" - символ табуляции.
Списковые константы - это списки, состоящие из постоянных элементов любого типа (списки, как и функции, открываются и закрываются круглыми скобками). Для того чтобы система AutoCAD не вычисляла выражение как функцию, постоянные списки предваряются апострофом перед открывающей скобкой.
Примеры констант:
57
-100092
12.98207
11.1e+8
"string(2) for printing"
"52\\_l" (первая косая черта является служебной, вторая - значащим символом; если распечатать такую строку, то получим 52\_1)
'(1 5 100 -2)
'("Аа" "Бб" "Вв" "Гг" "Дд" "Ее")
'("Первый" 15 "online" 90.22 "")
Функция setq возвращает значение, совпадающее со значением выражения, присваиваемого последней переменной (<переменная>), поэтому тип результата также совпадает с типом этого выражения.
К зарезервированным (предопределенным) символам, которые пользователям не рекомендуется применять, помимо имен функций, относятся следующие:
т - единственная логическая константа, имеющая значение "истина";nil - пустое значение (оно же в логических операциях играет роль и значения "ложь"). Это значение не эквивалентно числу 0 или пустой строке ("");pi - постоянная, равная отношению длины окружности к диаметру (3.14159);pause - постоянная, позволяющая ввести паузу при работе команды системы AutoCAD (используется в функции command).В функциях, требующих в качестве аргумента логическое значение, вместо т можно вводить любое значение, отличное от nil (например, число, строку и т. д.).
При введении пользователем новых переменных для хранения данных к той части оперативной памяти, которая отведена для текущего рисунка, добавляются участки, занимаемые переменными. Если переменной присвоить значение nil, то такая переменная из памяти удаляется и ее место освобождается для других операций .
В многодокументном режиме (когда в одном сеансе системы AutoCAD открыто несколько рисунков) переменные одного рисунка обычно недоступны в другом. Для передачи требуется экспортировать переменные во внедокументное пространство символов.
Переменные могут использоваться в любых выражениях, например:
(setq уу2 (+ 20.56 уу0))
Ввод в командную строку с клавиатуры выражений не всегда удобен. Поэтому обычно записывают предварительно строки на языке в файл с расширением . Затем загружают этот файл с помощью функции load. Синтаксис функции load следующий:
(load <файл> [<сообщение>])
Здесь <файл> - это строка с именем загружаемого файла, а <сообщение> - это строка с текстом сообщения, которое нужно вывести, если загружаемый файл не будет обнаружен. Возвращаемое значение в случае удачной загрузки - результат последнего выражения или имя последней функции, если в файле находятся определения функций. В случае если загружаемый файл не найден, возвращается текст сообщения об ошибке.
Например:
(load "longwid.lsp" "Файл не найден")
Аргумент <сообщение> может быть опущен, в этом случае при ошибке загрузки выдается стандартное сообщение AutoCAD. Аргумент <файл> обычно содержит только имя файла, который ищется в соответствии с настройкой рабочего каталога и путей поиска файлов поддержки. Однако можно указывать и полное имя с маршрутом, - например, "f:/" или "f:\\". В качестве разделителя каталогов может использоваться косая черта или обратная косая черта, но обратная черта должна обязательно удваиваться.
Если расширение в имени файла опущено, то система AutoCAD пытается выполнить загрузку, поочередно добавляя следующие расширения:
vix fas lsp
Расширение vix соответствует файлам приложений, fas - компилированным LISP-файлам, - исходным LISP-файлам. Для непосредственного редактирования пользователю доступны только файлы с расширением , т. к. файлы с расширениями vix и fas не являются текстовыми.
Очень важной является функция command, которая имитирует ввод пользователя в командной строке AutoCAD с клавиатуры.
Синтаксис функции:
(command [<параметр1> [<параметр2> ... [<параметрN>] ... ] ] )
Возвращаемое значение - nil.
Функция может вызываться без параметров - это равносильно нажатию клавиши <Esc>, что прерывает действие активной команды. Если параметры используются, то их количество может быть любым. Каждый из параметров обычно является текстовой строкой, имитирующей набор символов строки на клавиатуре с последующим нажатием клавиши <Enter>. Возвращаемое значение - nil.
Предположим, что нужно нарисовать отрезками рамку формата размером 210 на 297 (левый нижний угол рамки взять в точке 0,0 и верхний правый - в точке 210,297). Вспомним, что команда рисования отрезков в системе AutoCAD называется LINE. Если вы не уверены, что ваша программа будет работать на машине с русской версией AutoCAD, то используйте английские имена команд с подчеркиванием (в данном случае - _LINE). С такими именами команды будут выполняться в любой версии системы. Если бы вы выполняли задачу без программы, то вводили бы с клавиатуры следующие команды и опции:
_LINE 0,0 210,0 210,297 0,297 _С
По этим указаниям AutoCAD вызовет команду _LINE, возьмет в качестве первой точки 0,0, в качестве второй - 210,0, в качестве третьей - 210,297, в качестве четвертой - 0,297, а _С (соответствует опции Close) замкнет отрезки на первую точку (опции тоже желательно вводить английские и с подчеркиванием). Программа, имитирующая описанный алгоритм, занимает одну строку и выглядит так:
(command "_LINE" "0,0" "210,0" "210,297" "0,297" "_С")
Можно координаты точек задавать не как строку, а как списки из двух чисел целого или вещественного типа.
(command "_LINE" '(0 0) '(210 0) '(210 297) '(0 297) "_С")
Апостроф опускать нельзя, т. к. выражение (210 0) без апострофа будет рассматриваться как обращение к функции 210 с аргументом 0.
Там, где требуется ввод чисел, можно в качестве аргументов подавать функции command именно числа, а не строки с числами, например:
(command "_COLOR" "1") (command "_COLOR" 1)
Оба выражения выполняют одну и ту же операцию (в качестве текущего устанавливают красный цвет, который имеет номер 1), но в первом случае номер цвета задается как строка, а во втором - как целое число.
Можно в одной функции command обратиться сразу к нескольким командам системы AutoCAD, например:
(command "_COLOR" 1 "_ZOOM" "_E")
Эта программная строка выполнит команду COLOR для установки красного цвета и команду ZOOM с опцией EXTENTS (ГРАНИЦЫ).
Часто пользователь вместо ввода опции нажимает на клавишу <Enter>. Для имитации этого варианта в качестве параметра функции command выступает текстовая строка нулевой длины ("").
Мы уже рассмотрели некоторые функции , встроенные в систему AutoCAD (setq, load, command). Встроенные функции по своему назначению можно классифицировать следующим образом:
ActiveX.К арифметическим относятся следующие функции (вместе с описанием функций приводится их синтаксис):
(+ [<число1> [<число2> ... [<числоN>] ... ] ]) - сложение любого количества чисел;(- [<число1> [<число2> ... [<числоN>] ... ]]) - вычитание из первого числа суммы любого количества чисел;(* [<число1> [<число2> ... [<числоN>] ... ]]) - перемножение любого количества чисел;(/ [<число1> [<число2> ... [<числоN>] ... ]]) -деление первого числа на произведение любого количества чисел;(1+ <число>) - увеличение числа на 1;(1- <число>) - уменьшение числа на 1;(∼ <число>) - дополнение числа до - 1;(abs <число>) - Все
Примеры:
(+1 3) - возвращает 4; (- -2 1.1 0.3) - возвращает - 3.4; (* -2 1.1 0.3) - возвращает - 0.66; (/ -2 1.1 0.3) - возвращает - 6.06061; (/ 5 12) - возвращает 0 (оба аргумента целые!); (1 + 1.1) - возвращает 2.1; (1 - 1.1) - возвращает -0.1; (∼ 3) - возвращает - 4; (abs -1.1) - возвращает 1.1.
Логические функции выполняют различные операции: проверки, логические операции, организуют повторения и циклы.
Следующие функции выполняют операции сравнения:
(= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - проверка на равенство любого количества аргументов (рекомендуется использовать для чисел или строк); (/= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - проверка на неравенство любого количества аргументов (рекомендуется использовать для чисел или строк); (< <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - проверка на возрастание любого количества аргументов, слева направо (для чисел или строк); (> <аргумент1> [<аргумент2> ... [<аргументN> ]...]) -Проверка на убывание любого количества аргументов, слева направо (для чисел или строк); (<= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - Проверка на неубывание любого количества аргументов, слева направо (для чисел или строк); (>= <аргумент1> [<аргумент2> ... [<аргументN> ]...]) - Проверка на невозрастание любого количества аргументов, слева направо (для чисел или строк).При сравнении строк на возрастание (убывание) используются коды буквенно-цифровых знаков строк, начиная с первого, по действующей T или nil), nil эквивалентно значению "ложь".
Примеры:
(= -10.0 -10 -10.000) - возвращает T; (= "STR56" "str56" "Str56") - возвращает nil; (= "abcde" "abcde") - возвращает Т; (/= -1.0 -1) - возвращает nil; (/= "STR56" "Str56" "Str56") - возвращает T; (/= "abcde" "abcde") - возвращает nil; (< "a" "b" "k") - возвращает T; (> 2 2 30) - возвращает nil; (<= "q" "qa") - возвращает T; (>= "qa" "q") - возвращает T.
Следующие функции выполняют логические операции:
(and [<аргумент1> [<аргумент2> ... [<аргументN>]...]]) - операция логического "И" для любого количества аргументов (все, что отлично от nil, рассматривается как т); (or [<аргумент1> [<аргумент2> ... [<аргументN>]...]]) - операция логического "ИЛИ" для любого количества аргументов (все, что отлично от nil, рассматривается как Т); (not <аргумент>) - операция логического "НЕ" (все, что отлично от nil, рассматривается как Т); (null <аргумент>) - операция проверки на nil (все, что отлично от nil, рассматривается как Т); идентична функции not.Примеры:
(and т т nil) - возвращает nil; (and "a" "b" "k") - возвращает T; (or т nil т) - возвращает T: (or "а" "b" "k") - возвращает T; (not nil) - возвращает T; (not 15.88) - возвращает nil; (null '()) - возвращает T; (null "Tram") - возвращает nil.
Условная операция типа if-then-else (если-то-иначе) осуществляется с помощью функции IF:
(if <условие> <выражение1> [<выражение2>])
Типы аргументов: любые.
Возвращаемое значение: вычисленное значение <выражение1>, если значение <условие> отлично от nil (nil в логических операциях используется как "ложь"); или значение <выражение2>, если значение <условие> равно nil (когда <выражение2> опущено, тогда вместо >выражение2< возвращается nil).
Примеры:
(if (> a b) 1 10) - возвращает 1, если a>b, и 10 - в других случаях; (if (= h1 h2) (+ h1 15) (* h1 2.5)) - возвращает результат вычисления выражения (+ h1 15), если значения h1 и h2 равны; иначе - результат вычисления выражения (* h1 2.5); (if (< a b) "a<b") - возвращает строку "а<b" или nil (т.к. <выражение2> опущено); (if nil "Point") - возвращает nil (т. к. <условие> всегда ложно).
Если функция if используется для выполнения по условию не одного выражения, а нескольких, то эти выражения следует объединить с помощью функции рrоgn (иначе будет синтаксическая ошибка, вызванная неправильным количеством аргументов при обращении к функции if):
(рrоgn <выражение1> <выражение2> ... [<выражениеN>])
Функция объединяет несколько (не менее двух) выражений в одно, когда по синтаксису языка может использоваться только одно (как в функции if).
Типы аргументов: любые.
Рассмотрим использование функции progn. Пусть при выполнении условия (< а b) нужно выполнить выражения (setq с -1), (setq d (-cab)) и (* d b) , а при невыполнении условия - выполнить выражения (setq с 2), (setq d (* а b) ) и (* d с) .
Пример совместного использования функций if и progn:
(if (> а b) (progn (setq с -1) (setq d (-cab)) (* d b) ); конец progn (progn (setq с 2) (setq d (* а b)) (* d с) ) ; конец progn ); конец if
Для удобства чтения в этом фрагменте текста программы в начале некоторых строк добавлены отступы. Открывающая скобка должна быть на одном уровне с закрывающей, а внутренние выражения должны быть смещены относительно ближайших внешних вправо. К закрывающим скобкам даны комментарии, согласно правилам их написания.
Условная операция типа case с любым количеством условий осуществляется с помощью функции cond:
(cond (<условие1> [<выражение1> ... ] ) [ (<условие2> [<выражение2> ... ])] ...)
Аргументы: любое количество списков, в каждом из которых на первом месте стоит проверяемое условие, а затем следуют выражения, которые должны быть выполнены (вычислены), если это условие оказалось истинным.
Возвращаемое значение функции cond - последнее вычисленное выражение. Если вычисляемое выражение отсутствует (не задано в списке), то возвращается результат вычисления последнего аргумента <условие>. Если аргументы функции cond не заданы, то возвращается nil.
Примеры:
(cond) - возвращает nil; (cond (14)) - возвращает 14.
Впрочем, использование функции cond с неполным количеством аргументов не имеет особого смысла.
Рассмотрим пример: переменной mycolor нужно присвоить текстовое значение с наименованием одного из основных цветов AutoCAD ("красный", "желтый", "зеленый", "голубой", "синий") в зависимости от текущего значения переменной сс, которая принимает значения 1, 2, 3, 4, 5. В случае если значение переменной сс оказалось отличным от перечисленных, то переменной mycolor нужно присвоить "" (пустая строка).
Пример 1 использования функции cond:
(setq mycolor
(cond
((= cc 1) "красный")
((= cc 2) "желтый")
((= cc 3) "зеленый")
((= cc 4) "голубой")
((= cc 5) "синий")
(Т "")
); конец cond
); конец setq
Функция setq присваивает переменной mycolor результат вычисления функции cond. Значение, возвращаемое функцией cond, вычисляется по следующей схеме. Сначала рассматривается ((= cc 1) "красный") - и проверяется условие, являющееся первым элементом этого списка. Если оказалось, что значение переменной cc равно 1 и, значит, первое условие возвращает "истину", то дальнейшее рассмотрение аргументов функции cond прекращается. В качестве возвращаемого значения принимается "красный". Если первое условие не вычислилось как "истина", то проверяется второе условие и т. д. В качестве последнего, шестого, условия стоит Т, т. е. "истина" при любых значениях. При этом, если значение переменной cc не совпало с 1, 2, 3, 4, 5, то в качестве возвращаемого значения функции cond будет принято "" (пустая строка).
Еще один пример иллюстрирует случай, когда по истинности значения <условие> выполняются несколько операторов.
Пример 2 использования функции cond
(cond
((= cc 1)
(setq abc "красный")
(command "_PLINE" "-50,120.45" "97.66,23.124" "45.7,800" "_С")
); = cc 1
((= cc 2)
(setq abc "желтый")
(command "_CIRCLE" "-50,120.45" "100")
); = cc 2
) ; конец cond
В этом примере функция cond проверяет значение переменной cc. Если оно равно 1, то функция setq присваивает переменной abc значение "красный", а затем AutoCAD рисует замкнутую полилинию с тремя вершинами. Если значение cc равно 2, то функция setq присваивает переменной abc значение "желтый", a AutoCAD рисует окружность радиуса 100. Если окажется, что значение cc не равно ни 1, ни 2, то функция cond вернет nil, не изменяя при этом значения переменной abc и не строя никаких новых примитивов AutoCAD. Поскольку функция command является последним выражением, как в первом, так и во втором условиях функции cond, то во всех трех случаях будет возвращено значение nil (nil является возвращаемым значением функции command). Однако в данном примере функция cond применена не ради возвращаемого значения, а ради изменения значения переменной abc и построения дополнительной
Существует несколько проверочных функций, которые проверяют конкретные значения или типы:
(minusp <число>) - проверка числа на отрицательность; (zerop <число>) - проверка числа на ноль; (numberp <аргумент>) - проверка типа аргумента на число; (listp <аргумент>) - проверка типа аргумента на список; (boundp <символ>) - проверка, присвоено ли значение символу AutoLISP ; для указания на имя функции его следует предварять апострофом.Все эти функции возвращают значение Т, если аргумент удовлетворяет требуемому условию, и nil - если не удовлетворяет.
Примеры:
(minusp (-52 24 39)) -возвращает т; (zerop 0.0) - возвращает т; (numberp -10.0) - возвращает т; (numberp "1") - возвращает nil; (listp "1") - возвращает nil; (listp ' (-21.82)) - возвращает т; (boundp ' +) - возвращает т.
Функция eq проверяет равенство двух аргументов (аналогична функции =):
(eq <аргумент1> <аргумент2>)
Типы аргументов: любые.
Тип возвращаемого значения: логическое (т, если значения аргументов совпали, и nil, если не совпали).
Примеры:
(eq -10.0 -10) - возвращает т; (eq о 3) - возвращает nil; (eq "abc" "АBC") - возвращает nil.
Функция equal проверяет равенство двух объектов (для чисел и списков из числовых величин равенство проверяется в пределах допуска):
(equal <аргумент1> <аргумент2> [<допуск>])
Типы аргументов: любые.
Тип возвращаемого значения: логическое (т, если абсолютная величина разности аргументов не превосходит значение аргумента <допуск>, и nil, если не совпали; если >допуск< не задан, то его значение считается равным нулю). Для аргументов, не являющихся числами или списками из чисел, <допуск> не используется.
Примеры:
(equal -10.0 -10) - возвращает Т; (equal 3.000 3.002 0.002) - возвращает Т; (equal "font" "font") - возвращает т; (equal ' (1.00 2.13 2.99) ' (1 2.13 3.0) 0.1) - возвращает Т.
Функция while позволяет организовывать операции цикла по многократно проверяемому условию:
(while <условие> <выражение1> [<выражение2> ... [<выражениеN>] ... ] )
Типы аргументов: любые.
Возвращаемое значение функции while: значение <выражение>, когда последнее вычисленное значение аргумента <условие> отлично от nil. При неудачном задании цикл, организуемый с помощью функции while, может оказаться бесконечным.
Рассмотрим пример. Пусть надо вычислить значение n! (факториал), т. е. произведение целых чисел от 1 до n. В данном разделе восклицательный знак используется как знак
Пример использовании функции while (вычисление факториала)
(setq i 1 factorial 1) (while (< i n) (setq i (1+ i)) (setq factorial (* factorial i)) ); конец while
Рассмотрим работу примера, когда число n равно 11 (т. е. вычисляется 11!).
В программе используются переменные i (это переменная, являющаяся счетчиком цикла) и factorial (переменная, которая накапливает произведение чисел, формирующее факториал). Перед входом в цикл они получают начальные значения - соответственно, 1 и 1 (по определению 1! считается равным 1).
Функция while проверяет условие (< i n) для текущего значения i и, если результат вычисления условия отличен от nil, то выполняет внутренние операции (две операции с участием функции setq). Таким образом, при первом входе в цикл i равно 1, проверяемое условие (< 1 n) возвращает значение т ("истина"), и функция while увеличивает i на l (получается i=2) и умножает переменную factorial на i: factorial=l*2 (не что иное как 2!).
Далее снова передается управление на вход в цикл (уже при i=2). Проверка условия опять дает результат "истина", поэтому i получает значение 3 (2+1), a factorial - 6 (2*3). И так далее, пока i не станет равным n (11) и программа покинет цикл, не выполняя внутренних операций. Результат: при n=11 factorial=39,916,800 (запятые разделяют триады цифр).
Функция repeat используется для организации цикла с фиксированным количеством повторений:
(repeat <количество> [<выражение1> ...] )
Типы аргументов: <количество> - целое число (имеют смысл только положительные числа), <выражение1> - любое выражение. После аргумента <выражение1> могут идти другие выражения, которые нужно выполнить внутри цикла.
Возвращаемое значение - значение последнего вычисленного выражения. Если аргумент <количество> имеет нулевое или отрицательное значение, или после аргумента <количество> не заданы выражения, то функция repeat возвращает nil.
Воспользуемся функцией repeat вместо while в предыдущем примере.
Пример использования функции repeat (вычисление факториала)
(setq i 1 factorial 1) (repeat (1- n) (setq i (1+ i)) (setq factorial (* factorial i)) ); конец repeat
Поскольку входные значения i=1 и factorial = l! =1, то остается умножить factorial на 2, 3, ... , n. Количество таких умножений равно n-1, что на языке записывается как (1- n) . Остальное работает как в предыдущем примере.
К основным вычислительным функциям относятся следующие функции:
(fix <число>) - усечение числа до целого (отбрасывается дробная часть); (rem [<число1> [<число2> ... [<числоN>] ... ]]) - получение остатка от деления аргументов <число1> на <число2>, затем остатка от деления результата на аргумент <число3> и т. д.; (mах [<число1> [<число2> ... [<числоN>] ... ]]) - определение максимального из чисел; (min [<число1> [<число2> ... [<число1N>] ... ]]) - определение минимального из чисел; (gcd <число1> <число2>) - вычисление наибольшего общего делителя для двух положительных целых чисел; (angle <точка1> <точка2>) - вычисление угла, в радианах, между осью Х текущей системы координат и вектором, идущим из точки, заданной аргументом >точка1< в точку, заданную аргументом >точка2<; (distance <точка1> <точка2>) - вычисление расстояния между двумя точками, заданными аргументами <точка1> и <точка2>; (sqrt <число>) - вычисление квадратного корня; (sin <число>) - вычисление синуса угла; (cos <число>) - вычисление косинуса угла; (atan <число1> [<число2>]) - вычисление арктангенса; если второй аргумент опущен, то вычисляется арктангенс от первого аргумента <число1>; если заданы оба аргумента, то вычисляется арктангенс частного от деления первого аргумента на второй <число1>/<число2>; если аргумент <число2> равен нулю, то возвращается угол +pi/2 или -pi/2 (знак выбирается по знаку аргумента >число1<); (ехр <число>) - вычисление натурального антилогарифма- результата возведения в степень постоянной е (2.71828); (expt <основание> >степень<) - возведение числа в степень; (log <число>) - вычисление натурального логарифма.Примеры:
(fix -10.083) - возвращает -10; (fix 40.45) - возвращает 40; (rem 14 2) - возвращает 0 (результат целый, т. к. оба аргумента целые); (rem 12.9 3.5) - возвращает 2.4; (max 7 3.4 2.0092) - возвращает 7.0 (результат вещественный, поскольку есть вещественные аргументы); (min 7 3.4 2.0092) - возвращает 2.0092; (gcd 42 12) - возвращает 6; (angle ' (0 0) ' (50.0 50.0)) - возвращает 0.785398; (distance ' (0 0) ' (250.0 0.0)) - возвращает 250.0; (sqrt 25) - возвращает 5.0; (sin 0.0) - возвращает 0.0; (cos 0.0) - возвращает 1.0; (atan 1) - возвращает 0. 785398; (atan -1 0) - возвращает -1.5708; (ехр 1) - возвращает 2.71828; (expt 2 2) - возвращает 4 (оба аргумента целые); (expt -2 2.0) - возвращает 4.0; (log 1) - возвращает 0.0.
К вычислительным можно отнести также функции побитовых операций:
(logand [<число1> [<число2> ... [<числоN> ]...]]) - вычисление побитового "и" для списка целых чисел; (logior [<число1> [<число2> ... [<числоN>]...]]) - вычисление побито-вого "или" для списка целых чисел; (lsh [<число> [<сдвиг>] ]) - вычисление побитового сдвига целого числа; (Boole <оператор> <число1> [<число2> ... ] ]) - универсальная побитовая булева функция.Все функции побитовых операций работают с целыми аргументами и возвращают целые значения.
Функция logand (побитовое "и") работает следующим образом. Каждое целое число может быть представлено в двоичном виде (иначе говоря, в виде суммы степеней числа 2, в которой перед степенью 2 стоит множитель 0 или 1; показатель степени в данной сумме может быть от 0 до 30). Например:
31-й (старший) разряд в таком представлении отводится под знак (минусу соответствует 1, плюсу соответствует 0). После перевода всех чисел в двоичное представление, выполняется поразрядная (побитовая) операция "и" по следующему правилу:
(logand 0 0)= (logand 1 0)= (logand 0 1)= 0; (logand 1 1) = 1.
Если аргументы не заданы, то возвращается 0. Если задан только один аргумент, то возвращается <число1>.
Пример:
(logand 3 5) - возвращает 1.
Функция logior (побитовое "или") работает по следующему правилу:
(logior 1 0)= (logior 0 1)= (logior 1 1)= 1; (logior 0 0) = 0.
Если аргументы не заданы, то возвращается 0. Если задан только один аргумент, то возвращается <число1>.
Примеры:
(logior 3 5) - возвращает 7; (logior 2) - возвращает 2.
Побитовый сдвиг (функция lsh) выполняется для двоичного представления чисел. Побитовый сдвиг выполняется влево, если аргумент <сдвиг> положителен, и вправо, если - отрицателен. Целые числа могут иметь не более чем 32 бита (нумерация битов от 0 для младшего разряда до 31 - этот разряд является знаковым), поэтому если старшие разряды при сдвиге влево выходят за 31-й разряд, то они теряются. При сдвиге вправо младшие разряды теряются.
Если аргументы не заданы, то возвращается 0. Если задан только один аргумент или аргумент <сдвиг> равен 0, то возвращается >число<.
Примеры:
(lsh 2 l) - возвращает 4; (lsh 3 30) - возвращает -1073741824.
В функции Boole аргумент <оператор> должен иметь значение от 0 до 15, что соответствует 16-ти вариантам булевых функции. Остальные аргументы - произвольные целые числа.
Все булевые функции двуместные, т. е. имеют два аргумента, каждый из которых может быть 0 или 1. Номер любой булевой функции кодируется следующим образом:
1=2^0;2=2^1;4=2^2;8=2^3.При таком кодировании рассмотренные выше функции logand и logior получат номера 1 и 7.
Булева функция применяется побитно к аргументам <число1> и <число2>, затем к результату и аргументу <число3> и т. д. Если заданы только два аргумента (<оператор> и <число1>), то возвращается <число1>.
Примеры:
(Boole 15 -3 45) - возвращает - l; (Boole 8 16 17) - возвращает - 18.
Функция type позволяет определять тип символа :
(type <символ>)
Тип аргумента: <символ> (имя функции или переменной).
Если аргумент <символ> не является именем функции или переменной с присвоенным значением, то возвращается nil. Другие варианты возвращаемого значения:
ENAME - имя примитива AutoCAD;EXRXSUBR - имя приложения ObjectARX;FILE - указатель (дескриптор) файла;INT - целое число;LIST - список;PAGETB - таблица диспетчера страничной организации памяти;PICKSET - набор выбора;REAL - вещественное число;SAFEARRAY - безопасный массив;STR - строка;SUBR - встроенная функция AutoLISP ;SYM - символ;VARIANT - вариант;USUBR - пользовательская функция AutoLISP ;VLA -object - объект Visual LISP, использующий технологию ActiveX.Некоторые из перечисленных вариантов возвращаемого значения доступны только при использовании других средств разработки приложений.
Примеры:
(type 15) - возвращает INT; (type l+) - возвращает SUBR; (type "15") - возвращает STR; (type '(l5 16 17)) - возвращает LIST.
К функциям преобразовании относятся следующие:
(float <число>) - преобразование целого числа в вещественное;(itoa <целое>) - преобразование целого числа в строку;(rtos <число> [<режим> [<точность>]]) - преобразование вещественного числа в строку;(atoi <строка>) - преобразование строки в целое число;(atof <строка>) - преобразование строки в вещественное число; (angtof <строка> [<представление>]) - преобразование строки, представляющей значение угла в различных форматах, в вещественное число, являющееся величиной угла в радианах; (angtos <угол> [<представление> [<точность>]]) - преобразование значения угла в радианах в строку, в соответствии с форматом; (distof <строка> [<режим>]) - преобразование строки, представляющей вещественное значение в одном из форматов линейных единиц, в вещественное число; (trans <точка> <СК-из> <СК-в> [<признак>]) - преобразование координат точки из одной системы координат (СК) в другую.Примеры:
(float 15) - возвращает 15.0; (float -l5) - возвращает -15.0; (itoa -29031) - возвращает "-29031"; (itoa 0) - возвращает "0"; (atoi "-29031") - возвращает -29031; (atof "-29.03l") - возвращает -29. 031.
Функция , преобразующая вещественное число в строку, имеет следующие аргументы:
<число> - вещественное или целое число;<режим> - целое (номер режима представления вещественных чисел);<точность> - количество десятичных знаков в представлении вещественных чисел.Аргументы <режим> и <точность> имеют тот же смысл и принимают те же значения, что и системные переменные LUNITS и LUPREC. Если аргументы <режим> и <точность> опущены, то в качестве их значений принимаются текущие значения LUNITS и LUPREC. На форму возвращаемого значения может оказывать влияние системная переменная UNITMODE.
Допустимые значения аргумента <режим>:
Возвращается строка, являющаяся результатом преобразования аргумента <число> в символьное представление с заданной точностью.
Примеры:
(rtos 10.9453 1 3) - возвращает "1.095Е+01"; (rtos 10.9453 2 3) - возвращает "10.945".
Функция angtof преобразует строку, представляющую значение угла в различных форматах, в вещественное число, являющееся величиной угла в радианах. Функция angtof по своему действию является обратной к функции angtos.
Аргументы функции angtof: <строка> - строка, <представление> - целое число. Значения аргумента <представление> соответствуют значениям системной переменной AUNITS. Если аргумент <представление> опущен, то в качестве его значения принимается текущее значение переменной AUNITS.
Допустимые значения аргумента <представление>:
Возвращается вещественное значение угла в радианах, для которого аргумент <строка> является строковым представлением (возможно, в другом формате представления углов). Если аргумент <строка> задан в неправильном формате, то возвращается nil.
Примеры:
(angtof "30" 0) - возвращает 0.523599 (перевод угла из градусов в радианы); (angtof "334.365g" 2) - возвращает 5.25219.
Функция angtos преобразует значения угла в радианах в строку, в соответствии с форматом (функция angtos является обратной к функции angtof).
Аргументы функции angtos:
<угол> - вещественное или целое значение угла в радианах;<представление> и <точность> - целые числа.Значения аргумента <представление> соответствуют значениям системной переменной AUNITS, значения аргумента <точность> - значениям системной переменной AUPREC. Если аргументы <представление> и <точность> опущены, то в качестве их значений принимаются текущие значения переменных AUNITS и AUPREC.
Возвращается строка, являющаяся строковым представлением значения угла. На форму результата оказывает влияние значение системной переменной UNITMODE. Необходимо также учитывать значение переменной ANGBASE.
Примеры:
(angtos l.00 0) - возвращает "57.296"; (angtos 1 0) - возвращает "57.296"; (angtos 3.14000 0) - возвращает "179.909".
Функция distof выполняет преобразование строки, представляющей вещественное значение в одном из форматов линейных единиц, в обычное вещественное число. Функция distof является обратной по отношению к функции .
Аргументы: <строка> - строка, представляющая число в одном из форматов; <режим> - целое число, значения которого соответствуют значениям системной переменной LUNITS (см. описание функции ). Если аргумент <режим> опущен, то в качестве его значения принимается текущее значение системной переменной LUNITS.
Возвращаемое значение - вещественное число. Если аргумент <строка> имеет неправильную структуру, то возвращается nil.
Примеры:
(distof "l" 2) - возвращает 1.0; (distof "1.0945E+01" l) - возвращает 10.945.
Функция trans преобразует координаты точки из одной системы координат (СК) в другую. Аргументы функции:
<точка> - точка (список из двух или трех чисел, соответствующий двумерной или трехмерной точке);<СК-из> - код СК, в которой аргументом <точка> задана точка (т. е. СК, из которой нужно преобразовать точку), может быть целым числом или именем примитива AutoCAD;<СК-в> - код СК, в которую нужно преобразовать точку, заданную аргументом <точка>, может быть целым числом или именем примитива AutoCAD;<признак> - необязательный аргумент, если он задан и отличен от nil (например, Т), то меняет интерпретацию аргумента <точка>. В этом случае список из двух или трех чисел рассматривается не как координаты точки, а как координаты вектора перемещения.Аргументы <СК-из> и <СК-в> могут принимать следующие значения:
ssname, entsel, nentsel, entnext, entlast);Цифровой код системы координат может принимать такие значения:
СК (МСК) ;СК (ПСК ) ;СК (ЭСК) ;СК листа (ЭСКЛ).Имеются определенные условия использования этих кодов в аргументах <СК-из> и <СК-в> (иначе говоря, не всякое значение аргумента <ск-из> сочетается с любым значением аргумента <СК-в>, и наоборот).
Коды 0 и l могут использоваться в аргументах <СК-из> и <СК-в> в любых сочетаниях. Это означает, что если <СК-из> = 0, то аргумент <СК-в> может быть или любым цифровым кодом (от 0 до 3), или именем примитива, или вектором выдавливания; аналогично: если <СК-в> = о, то аргумент <СК-из> может быть или любым цифровым кодом (от 0 до 3), или именем примитива, или вектором выдавливания.
Цифровой код 2 сочетается с разными вариантами, но его интерпретация зависит от цифрового кода другой СК. Если вторая СК имеет код 0 или l, то первая СК (с кодом 2) является ЭСК текущего
Цифровой код 3 (ЭСКЛ) используется только в паре с цифровым кодом 2 другой СК (разобран в предыдущем абзаце).
Имя примитива в качестве аргумента <СК-из> используется в том случае, когда координаты точки, хранящейся вместе с примитивом (например, начальная или конечная точки отрезка, центр окружности, вершина entmake) возникает необходимость пересчитать точку в СКО - здесь имя примитива будет фигурировать в качестве аргумента <СК-в>.
Некоторые объекты (например, трехмерные
Свои преимущества имеет и способ, когда трехмерный вектор выдавливания применяется в качестве аргументов <СК-в> или <СК-из> (например, при проектировании объекта на плоскость с известным вектором нормали). Этот способ не может использоваться для тех объектов, у которых в качестве СКО фигурирует МСК.
Возвращаемым значением функции trans является список из трех координат точки (или вектора перемещения) в новой СК. Если значения аргументов <СК-из> и <СК-в> заданы противоречиво, то возвращается nil, - например, если функция trans вызывается с цифровым кодом СК, равным 3, из
Как было сказано выше, в качестве аргумента <точка> может фигурировать двумерная точка. В этом случае AutoCAD преобразует точку из двумерной в трехмерную, добавляя координату Z по следующему алгоритму.
Если задан аргумент <признак> и его значение отлично от nil (т. е. аргумент <точка> интерпретируется не как точка, а как вектор перемещения), то добавляемая координата Z получает значение 0. Если признак не задан или равен nil, то значение координаты Z зависит от аргумента <СК-из> и выбирается по табл. 3.1..
| СК-из | Значение Z |
| МСК | 0.0 |
Текущий уровень (значение системной переменной ) |
|
| СКО | 0.0 |
| ЭСК | В проекции на текущую плоскость построений (т. е. плоскость ТСК + текущий уровень) |
| ЭСКЛ | В проекции на текущую плоскость построений (т. е. плоскость ТСК + текущий уровень) |
Рассмотрим пример. Предположим, в качестве X=10, Y=10, Z=10. Тогда:
(trans '(1 1 1) 0 1) - возвращает (-9.0 -9.0 -9.0); (trans '(1 1 1) 0 1 T) - возвращает (1.0 1.0 1.0).
К функциям, работающим со строками, относятся следующие:
(chr <целое>) - получает буквенно-цифровой символ (строку из одного буквенно-цифрового символа) по коду действующей таблицы символов; (ascii <строка>) - получает код первого символа строки текста по действующей таблице символов; (read <строка>) - читает строку-аргумент до первого пробела (или до конца, если пробелов нет) и возвращает прочитанное значение как символ AutoLISP (т. е. имя функции или переменной); (strcase <строка> [<признак>]) - преобразует строку в верхний или нижний регистр (если аргумент <признак> опущен или равен nil, то функция strcase выполняет преобразование всех буквенно-цифровых символов строки в верхний регистр; если аргумент <признак> задан, и его значение отлично от nil, то выполняется преобразование строки в нижний регистр); (strcat [<строка1> [<строка2> ... [<строкаN>] ... ]]) - конкатенация (сцепление)строк; (strlen [<строка1> [<строка2> ... [<строкаN>] ... ]]) - вычисляет суммарную длину всех строк-аргументов (длина строки - это количество буквенно-цифровых знаков в строке); (substr <строка> <начало> [<количество>]) - выделяет подстроку, начиная с заданной позиции; если количество аргументом <количество> не задано или задано больше, чем осталось в строке, определяемой аргументом <строка>, начиная с позиции, определяемой аргументом <начало>, то возвращается полный остаток строки от заданного места.Примеры:
(chr 192) - возвращает "А" (русская буква); (chr 48) - возвращает "0"; (ascii "A") - возвращает 192 (русская буква); (ascii "A") - возвращает 65 (латинская буква); (ascii "ABCDEFGH") - возвращает 65 (все буквенно-цифровые знаки, кроме первого, игнорируются); (read "B C D E F") - возвращает B; (read "23.55") - возвращает 23.55; (read "10 масса") - возвращает 10; (strcase "AbcdE FGh-38") - возвращает "ABCDE FGH-38"; (strcase "AbcdE FGh-38" Т) - возвращает "abcde fgh-38"; (strcat "Happy N" "ew " "Year") - возвращает "Happy New Year"; (strcat (itoa 12) "-я линия") - возвращает "12-я линия"; (strlen "Happy N" "ew " "Year") - возвращает 14; (strlen "Петербург") - возвращает 9; (substr "Happy New Year" 7 3) - возвращает "New"; (substr "Happy New Year" 7) - возвращает "New Year".
Функция wcmatch проверяет строку на соответствие образцу (шаблону):
(wcmatch <строка> <образец>)
Аргументы: <строка> - строка, структуру которой нужно проверить; <образец> - особая строка, определяющая требования к проверяемой структуре. Аргумент <образец> может содержать как обычные алфавитно-цифровые знаки, так и специальные групповые знаки (wild-card-characters), рассматриваемые в табл. 3.2.. Можно в строке, определенной аргументом <образец>, задать сразу несколько шаблонов, на соответствие каждому из которых аргумент <строка> будет проверен; шаблоны должны разделяться с помощью запятой.
| Знак | Назначение |
|---|---|
# |
Заменяет одну любую цифру |
@ |
Заменяет одну букву |
. (точка) |
Заменяет любой символ, не являющийся ни буквой, ни цифрой |
* |
Заменяет любую последовательность любых символов, даже пустую; может использоваться в любом месте аргумента <образец> |
? |
Заменяет ровно один любой символ |
∼ |
Если стоит в начале образца, заданного аргументом <образец>, то означает "все, кроме определенного аргументом <образец>" |
[...] |
Заменяет любой из символов, перечисленных в скобках |
[∼. . .] |
Заменяет любой символ, кроме перечисленных в скобках |
- |
Между двумя однотипными знаками указывает на диапазон |
, (запятая) |
Разделяет два шаблона |
' (обратный апостроф) |
Превращает специальный знак в обычный |
В квадратных скобках любой знак рассматривается не как специальный, поэтому его не надо предварять обратным апострофом. Символ "\" является служебным, поэтому его использование отвечает изложенным выше правилам.
Возвращаемое значение: т - если аргумент <строка> соответствует аргументу <образец>, nil - если не соответствует.
Примеры:
(wcmatch "Happy New Year" "H*") - возвращает T, т. к. проверяемая строка начинается с буквы "Н"; (wcmatch "Happy New Year" "h*") - возвращает nil (при проверке внутри строк символы "Н" и "h" считаются разными); (wcmatch "Happy New Year" "??ppy*, *New*, * * *") - возвращает Т, т. к. все три шаблона соблюдены; (wcmatch "Happy New Year" "*#*") - возвращает nil, т. к. нет ни одной цифры; (wcmatch "Happy New Year" "H[adgt]*") - возвращает Т; (wcmatch "Happy***day" "Happy'*'*'**") - возвращает Т; (wcmatch "Year 2000" "@ea@ [1-6]000") - возвращает Т.
Следующая группа функций - это функции, работающие со списками и точечными парами. Точечная пара - это двухэлементный список вида (а . b) , в котором в качестве особого разделителя выступает точка (точка в такой записи отделяется пробелом как от первого, так и от второго элементов). Точечные пары используются для хранения в файлах системы AutoCAD данных о графических примитивах Первый элемент точечной пары обычно является целым числом и называется -кодом, а второй - данными этого кода. Основной способ получения точечных пар - функция cons.
Есть отличия в работе некоторых функций со списками и с точечными парами.
Функция list - это основная функция, позволяющая создать список:
(list (<элемент1> [<элемент2> ... [<элементN>] ... ] ] )
В качестве аргументов <элементы>, из которых образуется список, могут выступать любые объекты, которыми оперирует . Самый распространенный список - это список из двух или трех вещественных чисел, представляющий точку.
В качестве элементов списка могут выступать другие списки или точечные пары.
Примеры:
(list 12.12 0.34 5.88) - возвращает (12.12 0.34 5.88); (list 1 "ad2" (list 0 1 2)) - возвращает (1 "ad2" (0 1 2)) (третьим элементом нового списка является список из чисел 0, 1 и 2).
Следующие функции выполняют основные операции со списками:
(append [<список1> [<список2> ... [<списокN>] ... ] ] ) - слияние списков в один; (nth <номер> <список>) - извлечение из списка элемента по порядковому номеру (нумерация элементов списка выполняется слева направо и начинается с нуля); (reverse <список>) - переворот списка; (car <список>) - извлечение первого элемента списка или точечной пары; (cdr <список>) - извлечение из списка подсписка путем удаления первого элемента, если аргумент <список> является простым списком (т. е. не точечной парой), или извлечение второго элемента, если <список> является точечной парой.Примеры:
(append '(14 16) '(12.12 0.34 5.88)) - возвращает (14 16 12.12 0.34 5.88); (nth 0 '(12.12 0.34 5.88)) - возвращает 12.12; (reverse '(12.12 0.34 5.88)) - возвращает (5.88 0.34 12.12); (car '(12.12 0.34 5. 88)) - возвращает 12.12; (car '(62 . 1)) - возвращает 62; (cdr '(12.12 0.34 5.88)) - возвращает (0.34 5.88); (cdr ' (62 . 1)) - возвращает 1.
От функции car и cdr путем их повторения в разных комбинациях от двух до четырех раз в языке образованы следующие функции (их двадцать восемь):
(сааr <список>) -равносильно (car (car <список>)) ; (cadr <список>) -равносильно (car (cdr <список>)) ; (cdar <список>) -равносильно (cdr (car <список>)) ; (cddr <список>) -равносильно (cdr (cdr <список>)) ; (саааr <список>) - равносильно (car (car (car <список>))) (caadr <список>) - равносильно (car (car (cdr <список>))) (cadar <список>) - равносильно (car (cdr (car <список>))) (caddr <список>) - равносильно (car (cdr (cdr <список>))) (cdaar <список>) - равносильно (cdr (car (car <список>))) (cdadr <список>) -равносильно (cdr (car (cdr <список>))) (cddar <список>) - равносильно (cdr (cdr (car <список>))) (cdddr <список>) -равносильно (cdr (cdr (cdr <список>))) (caaaar <список>) -равносильно (car (car (car (car <список>)))) ; (caaadr <список>) -равносильно (car (car (car (cdr <список>)))) .Аналогичным методом раскрываются оставшиеся функции (caadar, caaddr, cadaar, cadadr, caddar, cadddr, cdaaar, cdaadr, cdadar, cdaddr, cddaar, cdddar, cddadr, cddddr).
Функция cons добавляет к списку первый элемент или создает точечную пару:
(cons <аргумент1> <аргумент2>)
Если <аргумент2> является списком, то функция cons добавляет в него <аргумент1> в качестве нового первого элемента. Если <аргумент2> является атомом (т. е. не списком), то функция cons создает точечную пару типа (<аргумент1> . <аргумент2>).
Примеры:
(cons 67.4 '(10.3 12.9 -3.9)) - возвращает (67.4 10.3 12.9 -3.9);
(cons "Happy" '("New" "Year")) - возвращает ("Happy" "New" "Year");
(cons 2 4) - возвращает (2 . 4);
(cons 8 "0") - возвращает (8 . "0");
(cons 62 l) - возвращает (62 . l).
Функция member проверяет принадлежность элемента списку:
(member <элемент> <список>)
Если функция member обнаруживает <элемент> в аргументе <список>, то возвращает остаток списка, начиная с этого места. Если <элемент> в аргументе <список> не обнаруживается, то функция возвращает nil.
Примеры:
(member 1 '(4 50 1 2)) - возвращает (1 2); (member 4 '(4 50 1 2)) - возвращает (4 50 1 2); (member 0 '(4 50 1 2)) - возвращает nil.
Функция assoc применяется к списку, в котором элементами являются списки или точечные пары, и выбирает из этих элементов тот, у которого первый элемент имеет заданное значение:
(assoc <код> <список>)
Если в аргументе <список> имеется несколько элементов, удовлетворяющих требуемому условию, то в качестве возвращаемого значения выбирается первый из них. Функция assoc - основной инструмент в операциях выборки из списка с характеристиками примитива AutoCAD того элемента, который содержит точечную пару с нужным -кодом свойства (цвета, типа линии, веса и т. д.).
Примеры:
(assoc 8 '((8 . "Walls") (62 .4) (6 . "ACAD_IS005W100") ) ) - возвращает (8 . "walls"); (assoc 62 '((8 . "Walls") (62 .4) (6 . "ACAD IS005W100") ) ) - возвращает (62 . 4).
Следующие три функции (apply, ) позволяют выполнять операции сразу над всеми элементами списка.
(apply '<функция> <список>) - применение функции, заданной аргументом <функция> поочередно ко всем элементам списка, заданного аргументом <список>.
Примеры:
(apply '* (list 2 3 5)) - равносильно (* 2 3 5), поэтому возвращает 30; (apply 'max (list 2 3 5)) - возвращает 5.
Последний пример показывает, что функция apply удобна, когда какую-то операцию нужно выполнить над аргументами, количество которых заранее неизвестно. Поэтому следует сформировать список, к которому затем применить функцию apply с именем нужной функции в качестве первого аргумента. Обратите внимание на употребление перед аргументом апострофа.
( - применение функции, заданной аргументом <функция> сначала к первым элементам каждого из списков (<список1>, , <списокN>), затем - ко вторым элементам и т. д.; результаты объединяются в новый список, который является возвращаемым значением.
Пример:
(mapcar '* '(2 3) '(l 5)) возвращает (2 15), т. к. первый элемент результирующего списка вычисляется как (* 2 l), а второй - как (* 3 5).
Функция foreach позволяет организовать циклическое выполнение выражений (их может быть несколько), поочередно подставляя вместо переменной цикла элементы списка:
(foreach <имя> <список> [<выражение1> [<выражение2>... [ <выражениеN> ] ... ] ] )
Функция возвращает значение последнего вычисленного выражения. Если аргументы <выражение1> ... <выражениеN> не заданы, то функция foreach возвращает nil.
Пример:
(setq s1 0 s2 l) (foreach p '(1 2 3 4 5) (setq s1 (+ s1 p) ) (setq s2 (* s2 p) ) ) - возвращает 120 (результат вычисления s2 - произведения чисел списка); кроме того, в переменной s1 сформируется сумма чисел списка.
Функция eval позволяет сформировать список и затем вычислить его (evaluate) как выражение. В таком списке на первом месте должно стоять имя функции.
Пример:
(setq mylist (list 'max 1.7 9.34 6.7)); (eval mylist) - возвращает 9.34 (вычисляется выражение (max l.7 9.34 6.7)).
Функция quote является обратной по отношению к функции eval и позволяет обрабатывать выражение как список, т. е. не вычисляя его. Сокращенным вариантом имени функции quote является одинарная кавычка.
Примеры:
(quote (6 7 8 2 1)) - возвращает (67821); '(16 23 90) - возвращает (16 23 90).
Функция acad_strlsort позволяет отсортировать по возрастанию список, элементами которого являются строки.
Пример:
(acad_strlsort '("Пн" "Вт" "Ср" "Чт" "Пт" "Сб" "Bс"))- возвращает ("Вс" "Вт" "Пн" "Пт" "Сб" "Ср" "Чт").
Эти функции дают возможность пользователю вводить данные в интерактивном режиме. К основным функциям ввода данных и указания объектов относятся следующие:
(initget [<флаг>] [<строка>]) - задание ключевых слов и ограничений ввода для функций getint, getreal, getdist, getangle, getorient, getpoint, getcorner, getkword entsel, nentsel и nentselp; (getkword [запрос]) - ввод ключевого слова; (getint [запрос]) - ввод целого числа в диапазоне от -32768 до +32767; (getreal [запрос]) - ввод вещественного числа; (getdist [<точка1>] [запрос]) - получение расстояния (как вещественного числа) с помощью ввода числа (на клавиатуре в (getangle [<точка1>] [запрос]) - получение угла (как вещественного числа в радианах) с помощью ввода числа (на клавиатуре в ANGBASE и ANGDIR; возвращаемое значение учитывает значение ANGBASE и игнорирует значение ANGDIR; (getorient [<точка1>] [запрос]) - получение угла как в функции getangle, однако возвращаемое значение не учитывает значений ANGBASE и ANGDIR (т. е. как будто ANGBASE=0, ANGDIR=0); (getpoint [<точка1>] [запрос]) - ввод точки с помощью клавиату-ры или мыши; если задан аргумент <точка1>, то при вводе точки с помощью мыши рисуется резиновая нить, начинающаяся в точке, заданной аргументом <точка1>; (getcorner <точка1> [запрос]) - ввод точки с помощью клавиатуры или мыши; при вводе точки с помощью мыши рисуется резиновая рамка, начинающаяся в точке, заданной аргументом <точка1>; (getstring [<флаг>] [<запрос>]) - ввод строки; если задан аргумент <флаг> и он отличен от nil, то в строке, вводимой пользователем, допускаются пробелы (признаком конца является <Enter>); если аргумент <флаг> отсутствует или задан равным nil, то признаком конца строки является пробел или <Enter>; (getvar <имя>) - чтение текущего значения системной переменной с наименованием, заданным аргументом <имя>; (getenv <имя>) - чтение текущего значения переменной окружения с наименованием, заданным аргументом <имя>; (getcfg <строка>) - извлечение данных приложения из раздела AppData файла acad.cfg; строка, заданная аргументом <строка>, должна иметь вид "АррDаtа/имя_приложения/имя_раздела/ ... /имя_параметра"; (getcname <имя>) - получение имени команды в локализованной или английской версии AutoCAD; (getfiled <заголовок> <имя> <расширение> <флаг> - вызов диалогового окна поиска файла. Аргумент <заголовок> используется как заголовок диалогового окна; аргумент <имя> - это имя искомого файла или папки, с которой предлагается начать поиск; аргумент <расширение> - расширение искомого файла (<расширение>, равное "", заменяется на "*"); аргумент <флаг> - опции функции (см. ниже).Вызов функции initget должен предшествовать в программе обращению к функциям getint, getreal, getdist, getangle, getorient, getpoint, getcorner, getkword, entsel, nentsel и nentselp, поскольку устанавливает в этих функциях ограничения на ввод пользователем данных. В частности, initget может сохранять за пользователем возможность нажатия клавиши <Enter> вместо ввода данных (например, для выбора значения по умолчанию), а может и не сохранять. Аргумент <флаг> функции initget - это битовый флаг, который должен быть целым числом (от 0 до 255), являющимся суммой битов с соответствующими каждому из них весовыми значениями (нумеруются по степеням числа 2). Биты описываются в табл. 3.3. Если бит не установлен, то его значение в битовом флаге считается равным нулю.
| Бит | Назначение |
|---|---|
| 1 | Не разрешает пустой ввод (пустой ввод- это нажатие только клавиши <Enter>) |
| 2 | Не разрешает ввод нуля |
| 4 | Не разрешает ввод отрицательных чисел |
| 8 | Разрешает указание точек за пределами лимитов, несмотря на значение системной переменной LIMCHECK |
| 16 | Данный бит не задействован |
| 32 | Заставляет AutoCAD использовать штриховую линию вместо сплошной для резиновой нити и резиновой рамки; если значение системной переменной POPUPS равно нулю, то AutoCAD игнорирует данный бит |
| 64 | Запрещает ввод третьей координаты для точки в функции getdist |
| 128 | Разрешает произвольный ввод в качестве ключевого слова; преобладает над другими битами и ключевыми словами; в частности, данный бит позволяет игнорировать значение бита 1 |
Примеры использования битового флага:
(initget 1) - не разрешен пустой ввод; (initget 3) - не разрешены пустой ввод и ввод нуля (3=1+2) ; (initget 7) - не разрешены пустой ввод, ввод нуля и ввод отрицательных чисел (7=1+2+4) ; (initget 6) - разрешен пустой ввод, но не разрешены ввод нуля и ввод отрицательных чисел (6=2+4) .Аргумент <строка> функции initget - это строка, ограниченная двойными кавычками с двух сторон, которая задает ключевые слова, являющиеся допустимыми вариантами ввода. В аргументе <строка> различные варианты ключевых слов разделяются одним или большим количеством пробелов, например: "А Б В Г Д". Если пользователю при выборе ключевого слова разрешаются сокращенные варианты, тогда обязательная часть ключевого слова и аргументе <строка> должна быть указана в верхнем регистре, например: "ПЕРесечение". В этом случае допустимыми вариантами ввода являются "ПЕР", "пер", "ПЕРЕ", "пере", "перес", "ПЕРЕСЕЧЕН", "ПЕРЕСЕЧЕНИЕ" (после трех обязательных букв может идти любое количество необязательных букв, вплоть до набора полного ключевого слова; при вводе букв верхний и нижний регистры равноправны); недопустимыми вариантами будут "П", "ПЕ", "п", "пе".
Возможны случаи, когда вариант сокращенного ввода начинается не с первой буквы ключевого слова, например:
(initget "выход") - здесь допустимыми вариантами ввода будут "х", "хо", "ход" или "выход", "вых", "выхо".
Если ключевое слово в аргументе <строка> указано только в верхнем или только в нижнем регистре, то рядом через запятую можно указать сокращенный вариант: "КРАСНЫЙ, КР" - равносильно записи "красный".
В локализованных версиях системы AutoCAD в аргументе <строка> могут присутствовать варианты ввода для локализованной и английской версий. Тогда в начале должны идти локализованные ключевые слова, а затем их английские аналоги с символом подчеркивания. Количество локализованных ключевых слов должно равняться количеству английских ключевых слов. Например: "прямой криволинейный _straight curved".
Сама функция initget всегда возвращает nil. Однако за ней (не обязательно в следующей строке) должна идти функция, для которой функция initget установила ограничения ввода. В качестве возвращаемого значения эта функция (например, getreal) выдает допустимое значение, указанное пользователем, а в случае ввода сокращенного варианта ключевого слова - полный вариант ключевого слова.
Пример 1 использования функции getint
(initget 6) (setq numb (getint "Введите номер участка (<1>): "))
В этом примере сначала устанавливаются ограничения на будущий ввод целого числа (не допускаются ноль и отрицательные числа). Допускается пустой ввод. Функция getint выводит на экран запрос "Введите номер участка (<1>) : ". Ее возвращаемым значением будет nil, если пользователь ответит простым нажатием клавиши <Enter>, или введенное пользователем допустимое целое число (например, 17). В случае ввода пользователем недопустимого целого числа (например, 0 или -2) функция getint выведет сообщение об ошибочном значении и будет ожидать допустимого варианта ввода.
В программе, приведенной выше, далее должна быть предусмотрена обработка пустого ввода для того, чтобы в этом случае присвоить переменной numb значение по умолчанию (1): (if (not numb) (setq numb 1))
Пример 2 использования функции getint
(initget 6 "Левый Правый Нижний Верхний") (setq numb (getint "Введите номер участка (<1>) или [Левый/Правый/Нижний/ Верхний]: "))
В этом примере устанавливаются ограничения на будущий ввод целого числа (не допускаются ноль и отрицательные числа), однако допускаются пустой ввод и ввод одного из четырех ключевых слов. Далее в программе должен идти анализ значения переменной numb на nil, на положительное целое число и на ключевые слова ("левый", "правый", "нижний", "верхний").
Пример использования функции getkword
(initget 1 "Да Нет") (setq reply (getkword "Продолжить цикл [Да/Нет]: "))
В этом примере переменной reply присваивается значение "да" или "нет", пустой ввод не допускается (хотя можно было бы разрешить пустой ввод и далее использовать его для выбора значения по умолчанию).
Поскольку не все биты функции initget используются со всеми функциями ввода данных, то в табл. 3.4 разбираются варианты применения (в случае возможности использования ставится плюс).
| Функция | Бит1 | Бит 2 | Бит 4 | Бит8 | Бит 32 | Бит 64 | Бит 128 |
|---|---|---|---|---|---|---|---|
getint |
+ | + | + | + | |||
getreal |
+ | + | + | + | |||
getdist |
+ | + | + | + | + | + | |
getangle |
+ | + | + | + | |||
getorient |
+ | + | + | + | |||
getpoint |
+ | + | + | + | |||
getcorner |
+ | + | + | + | |||
getkword |
+ | + |
Функции entsel, nentsel и nentselp не используют биты функции initget и управляются только ключевыми словами.
Функция getstring не использует ни биты, ни ключевые слова функции initget.
Функции getvar и getenv позволяют прочитать значения, соответственно, системных переменных AutoCAD и переменных окружения.
Примеры:
(getvar "CECOLOR") - возвращает значение системной переменной "CECOLOR"; (getvar "PDMODE") - возвращает значение системной переменной "PDMODE"; (getenv "CONFIG") - возвращает значение переменной окружения "CONFIG".Функция getfiled позволяет вызвать диалоговое окно выбора файла в удобном виде.
Пример:
(getfiled "Выберите файл данных для расчета" "d: \\Tests\\AuroLISP\\Fields" "rtf" l6) - вызывает окно, приведенное на рис. 3.3:
(рис 3.3) Диалоговое окно, вызываемое функцией getfiled
Второй аргумент функции getfiled, в зависимости от значения четвертого аргумента (<флаг>), может задавать либо имя файла по умолчанию, либо папку, с которой предлагается начать поиск. Битовый флаг, задаваемый аргументом <флаг> получается как сумма тех битов, нумеруемых степенями числа 2, которые будут установлены. Описание битов приведено в табл. 3.5:
| Бит | Значение |
|---|---|
| 1 | Подсказка имени при создании нового файла (нельзя использовать для выбора существующего файла) |
| 2 | Не используется |
| 4 | Разрешает вводить имя файла с любым расширением (или без расширения) |
| 8 | Если бит 1 не установлен, то система AutoCAD выполняет поиск файла, имя которого задано в аргументе <имя> по списку путей, заданных в настройке, причем getfiled возвращает имя файла без пути; в противном случае возвращается полное имя файла (с путем) |
| 16 | Аргумент <имя> трактуется как имя папки, в которой нужно искать файл; при этом в поле Имя файла: (File name:) ничего не вписывается по умолчанию (см. рис.3.4); аналогичный эффект достигается и в том случае, если аргумент <имя> заканчивается обратной косой чертой |
| 32 | Если установлен бит 1, то не будет выводиться предупреждающее сообщение при записи поверх существующего файла |
| 64 | Не передает файл, если в качестве имени задан URL-адрес |
| 128 | Не допускается использование URL-адресов |
С функциями getvar и getenv тесно связаны функции, выполняющие обратные операции:
(setvar <имя> <значение>) - установка значения системной переменной с наименованием, заданным аргументом <имя>; (setenv <имя> <значение>) - установка значения переменной окружения с наименованием, заданным аргументом <имя>.В обеих функциях аргументы <имя> и <значение> должны быть текстовыми строками.
Функция setcfg является обратной по отношению к функции getcfg:
(setcfg <имя> <значение>) - запись данных приложения в раздел AppData файла acad.cfg; аргумент <имя> должен иметь вид "AppData/ имя_приложения/имя_раздела/ ... /имя_параметра" (до 496 символов длиной); возвращаемое значение функции setcfg - аргумент <значение> или nil (в случае ошибки).
В данном разделе рассматриваются функции, выполняющие операции с файлами (поиск, открытие и закрытие), операции чтения и записи строк или символов в файл, а также вывода на экран различных сообщений:
(findfile <файл>) - поиск файла по имени (краткому или полному) или поиск папки по полному имени; если аргумент не содержит полного пути, то поиск выполняется по стандартным путям поиска файлов для системы AutoCAD; возвращается полное имя файла (папки), если он найден, или nil в противном случае; (open <файл> <режим>) - открытие файла с именем, заданным аргументом <файл>; аргумент <режим> - это строка из одного символа, определяющего режим, в котором открывается файл ("w" или "W" - запись, "а" или "А" - дополнение, "г" или "R" - чтение); в предыдущих версиях AutoLISP не допускалось указание режима в верхнем регистре; если аргумент <файл> указывает на несуществующий файл в режимах "w", "W", "а" и "А", то он создается; возвращаемое значение - дескриптор файла (при успешном открытии) или nil (при неудаче); (close <дескриптор>) - закрытие файла; единственным аргументом является <дескриптор> - переменная, создаваемая функцией open и управляющая процессами записи и чтения: функция close возвращает nil, если указан действительный дескриптор, или сообщение об ошибке; (read-line [<дескриптор>]) - чтение строки из файла с заданным дескриптором; если аргумент <дескриптор> опущен, то выполняется чтение строки с клавиатуры (строка должна закончиться нажатием клавиши <Enter>); (write-line <строка> [<дескриптор>]) - запись строки, заданной аргументом <строка> в файл с заданным дескриптором; если аргумент <дескриптор> опущен или равен nil, то система AutoCAD выводит строку на экран; при записи строка, заданная аргументом <строка>, заносится в файл (или на экран) без ограничивающих ее двойных кавычек; (princ [<аргумент> [<дескриптор>]]) - запись аргумента, который может быть любым выражением AutoLISP (а также числом, списком, строкой, именем примитива и т. д.), в файл с заданным дескриптором. Если аргумент <дескриптор> опущен или равен nil, то <аргумент> выводится на экран. Если <аргумент> - строка, то при записи она заносится в файл (или на экран) без ограничивающих ее двойных кавычек. Если опущены оба аргумента, то функция осуществляет так называемый тихий выход, т. е. не возвращает никакого значения, в том числе nil; (prinl<аргумент> [<дескриптор>] ]) - функция аналогична princ, но если <аргумент> - строка, то при записи она заносится в файл (или на экран) с ограничивающими двойными кавычками; специальные символы (обратная косая черта, кавычки, конец строки и т. п.) предваряются обратной косой чертой; если опущены оба аргумента, то функция prinl тоже осуществляет тихий выход; (print [<аргумент> [<дескриптор>]]) - функция аналогична prini, но при выводе добавляет перед аргументом символ конца строки предыдущей записи, а после аргумента - пробел; тоже может осуществлять тихий выход; (read-char [<дескриптор>]) - чтение символа из файла. Если аргумент не задан, то производится чтение символа из буфера клавиатуры. Возвращает код прочитанного символа (аналогично функции ascii); нажатие на клавишу <Enter> возвращает код 10; (write-char <код> [<дескриптор>]) - запись символа с заданным кодом в файл; если аргумент не задан, то вывод символа на экран; возвращает код символа; невозможно с помощью данной функции записать символ с кодом 0; (prompt <сообщение>) - вывод сообщения на экран (если используется установка системы AutoCAD на двухэкранный вычислительный комплекс, то на оба экрана; чтобы избежать этого, можно пользоваться для вывода сообщений функцией princ).Приведенные выше функции дают пользователю возможность работы только с файлами последовательного доступа. Указателем позиции в файле, с которой далее будет происходить чтение (запись), является переменная, в которой хранится дескриптор этого файла. Механизм работы с файлами виден на следующем примере.
Пример использования функций работы с файлами
; Операции записи (setq ff (open "с:\\test.txt" "w")) (write-line "Первая строка" ff) (write-char 65 ff) (write-char 67 ff) (write-line "Вторая строка" ff) (close ff) ; Операции чтения (setq ff (open "c:\\test.txt" "r")) (setq s1 (read-char ff)) (setq s2 (read-char ff)) (setq strl (read-line ff)) (setq str2 (read-line ff)) (setq str3 (read-line ff)) (close ff) (setq ff nil)
Первое выражение - (setq ff (open "c: \\test.txt" "w")) - создает переменную ff, в которую заносится дескриптор файла c:\test.txt, открываемого для записи (в первом аргументе функции open обратная косая черта удваивается). Затем выражение (write-line "первая строка" ff) заносит в открытый файл первую запись (текст "Первая строка" из 13 символов) и символы с кодами 13 и 10, которые в файлах последовательного доступа разделяют записи.
В операционной системе UNIX признаком конца записи является один символ с кодом 10.
После этого указатель файла показывает на начало второй записи, куда поочередно - с помощью двукратного применения функции write-char - заносятся символы с кодами 65 (буква "А") и 67 ("С"). Затем в продолжение второй записи файла с помощью функции write-line заносится текст "вторая строка" (13 символов) и добавляются символы с кодами 13 и 10, означающие конец второй записи файла. Вслед за этим файл с дескриптором ff закрывается функцией close.
Вторая часть листинга начинается функцией открытия того же файла, но уже в режиме чтения. Затем с помощью двукратного применения функций read-char читаются два первых символа первой записи, которые запоминаются в переменных s1 и s2. После этого в переменную strl читается остаток первой записи. Далее в переменную str2 читается вторая запись файла. Третья операция чтения с помощью функции read-line приносит nil, поскольку в файле c:\test.txt третьей записи нет. По окончании выполнения рассмотренной программы переменная ff очищается (в ней хранился дескриптор файла). Другие переменные получат такие значения:
s1 = 207 (код символа "П"); s2 = 229 (код символа "е"); strl = "рвая строка"; str2 =: "АСВторая строка"; str3 = nil.
Функции princ, prini, print и prompt чаще всего используются для вывода сообщений в командную строку системы AutoCAD, причем prini и print выводят сообщения в кавычках (другие особенности описаны выше). Вместо функции write-line для записи в файл можно пользоваться функцией princ, но заносить признак конца записи, который выглядит как "\n", пользователь должен сам. Например:
(princ "Первая запись\n" ff)
Рисунок в системе AutoCAD имеет организацию, аналогичную организации базы данных, в которой элементы (графические примитивы и неграфические объекты) имеют 3DFACE, 3DSOLID, ACAD_PROXY_ENTITY, ARC, ARCALIGNEDTEXT, ATTDEF, ATTRIB, BODY, CIRCLE, DIMENSION, ELLIPSE, . Как правило, наименование типа совпадает с английским именем команды системы AutoCAD, которая создает графический объект.
Функции, рассматриваемые в данном разделе, работают с примитивами рисунка, обращаясь непосредственно к их внутренней структуре. имеет средства выбора графических объектов, как по их порядковому номеру, так и по определенным признакам (цвету, слою и т. п.).
Функция entlast извлекает последний неудаленный основной примитив рисунка:
(entlast)
Функция возвращает nil, если в рисунке нет неудаленных примитивов (например, когда вы только что создали новый рисунок); иначе возвращается имя последнего основного примитива в следующем виде:
(<Entity name: 14а4158>)
Полученное имя следует сохранить в переменной, например:
(setq eela (entlast))
Функция entnext позволяет перейти в рисунке к следующему примитиву (подпримитиву):
(entnext [<примитив>])
В качестве единственного аргумента функции entnext может выступать ранее полученное имя примитива текущего рисунка. Если функция вызывается без аргумента, то она возвращает имя первого неудаленного примитива в базе рисунка. При наличии аргумента функция возвращает имя следующего примитива, либо nil, если база графических объектов рисунка исчерпана.
Пример:
(setq el (entnext)) - возвращает имя первого неудаленного примитива; (setq e2 (entnext е2)) - возвращает имя примитива, следующего за e1; (setq еЗ (entnext еЗ)) - возвращает имя примитива, следующего за e2.Функция entlast возвращает имя последнего основного примитива. Это означает, что если последним созданным графическим объектом рисунка является сложный объект (например, полилиния типа ), то вслед за ним в базе рисунка следуют подпримитивы, т. е. вершины (имя примитива - ), а завершается перечисление подпримитивов SEQEND.
Пример (в предположении, что объект типа является последним основным примитивом):
(setq eela (entlast)) - возвращает имя основного примитива последней (setq v1 (entnext eela)) - возвращает имя примитива, являющегося первой вершиной (setq v2 (entnext v1)) - возвращает имя примитива, являющегося второй вершиной Замечание:
В легкой LWPOLYLINE) нет подпримитивов и информация обо всех вершинах может быть извлечена из основного примитива.
Функция entsel предлагает пользователю указать один объект, выдавая соответствующий запрос:
(entsel [запрос] )
Здесь аргумент <запрос> - любая строка текста. Функция возвращает список, состоящий из двух элементов: имени выбранного примитива и точки, которой пользователь указал объект (такая точка, как правило, оказывается вне самого примитива, поскольку точность указания мышью зависит от величины прицела). Можно указать объект вводом с клавиатуры ключевого слова Last - тогда в возвращаемом списке координаты точки будут нулевыми.
Пример:
(setq esl (entsel "Выберите объект: ")) - возвращает (<Entityname: 14а9960> (301.791 138.438 0.0)).
Имя указанного пользователем объекта может быть извлечено из такого списка, например, с помощью функции car.
Функция entdel позволяет удалять неудаленные основные примитивы и восстанавливать примитивы, ранее удаленные в данном сеансе редактирования:
(entdel <примитив>)
Функция возвращает имя удаляемого (восстанавливаемого) примитива. Следует иметь в виду, что при операции сохранения рисунка все примитивы, помеченные как удаленные, из рисунка стираются и уже больше не могут быть восстановлены.
Функция entget является основным инструментом извлечения информации о примитиве, т. к. получает список с его характеристиками:
(entget <примитив> [<приложения>])
Здесь аргумент <примитив> - это имя примитива для получения его данных, аргумент <приложения> - это список с именами приложений, с помощью которых к примитиву привязаны расширенные данные (о расширенных данных см. ниже).
Предположим, в рисунке первым объектом является отрезок (тип примитива - LINE). Тогда выражение (setq le (entget (entnext) ) ) должно вернуть примерно такой список:
((-1 . <Имя объекта: 14а4158>) (0 . "LINE") (330 . <Имя объекта: 14a40f8>) (5 . "2В") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 201.536 140.622 0.0) (11 285.148 96.5053 0.0) (210 0.0 0.0 1.0))
В этом списке элементами являются точечные пары и списки, причем и в тех, и в других первыми элементами- выступают целые числа, называемые -кодами. Под соответствующим кодом в точечных парах и списках находятся данные определенного типа:
LINE"),assoc можно из списка с характеристиками объекта извлечь нужную точечную пару, а затем, применив функцию cdr, получить данные необходимого DXF -кода.Продолжим пример с отрезком:
(cdr (assoc 0 le)) - возвращает "LINE" (тип примитива); (cdr (assoc 8 le)) - возвращает "0" (имя слоя); (cdr (assoc 10 le)) - возвращает (201.536 140.622 0.0); (cdr (assoc 11 le)) - возвращает (285.148 96.5053 0.0).Кроме того, по коду 62 можно было бы извлечь номер цвета примитива, по коду 6 - имя типа линии, по коду 48 - собственный масштаб типа линии, по коду 311 - вес линии (умноженный на 100). В рассмотренном выше списке le точечных пар с такими -кодами нет, поэтому для них действуют значения по умолчанию: BYLAYER (ПОСЛОЮ) или 1.
Рассмотрим, какой примерный список можно было бы получить для окружности (объекта типа CIRCLE):
((-1 . <Имя объекта: 14а4160>) (0 . "CIRCLE") (330 . <Имя объекта: 14a40f8>) (5 . "2С") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbCircle") (10 387.691 142.198 0.0) (40 . 27.8941) (210 0.0 0.0 1.0))
Для окружности -коды -l, 0, 410, 8, 210 имеют тот же смысл, что и для всех примитивов (в том числе и для примитива типа "LINE"). Под кодом 40 находится радиус окружности, а точечная пара с -кодом 10 хранит в себе данные о центре.
Поэтому для рассматриваемой окружности:
(cdr (assoc 40 le)) - возвращает 27.8941 (радиус); (cdr (assoc 10 le) ) - возвращает (387.691 142.198 0.0).Сравнивая справочную информацию, выдаваемую командой LIST, и список, получаемый с помощью функции entget, можно получить геометрический смысл -кодов для примитивов других типов.
Если построить в программе список, описывающий примитив (кроме точечной пары с флагом -1), то можно создать в рисунке такой примитив с помощью следующих функций:
(entmake <список>) - создает новый примитив по списку, структура которого аналогична структуре списка, возвращаемого функцией entget; функция entmake не может создать примитив типа VIEWPORT ; возвращаемое значение - аргумент <список> или nil, если создание объекта невозможно;(entmakex <список>) - создает новый примитив или неграфический объект по списку, аналогично функции entmake; возвращаемое значение - имя нового примитива или nil, если создание объекта невозможно.Пример:
(entmake '((0 . "CIRCLE") (10 500.0 0.0 0.0) (40 . 50.0))) создает новый примитив - окружность с центром в точке (500 0 0) и радиусом 50; остальные свойства (слой, цвет и т. д.), данные о которых отсутствуют в списке, берутся по умолчанию.
Функция entmod похожа на функцию entmake, но получает в качестве аргумента список, который содержит точечную пару с -кодом -1 (т. е. имя существующего в рисунке примитива) и модифицирует примитив в соответствии с новым списком (в списке могут изменяться любые данные, кроме имени примитива, типа примитива и метки):
(entmake <список>)
Функция entmod изменяет примитив в базе рисунка и возвращает аргумент <список> при успешном завершении или nil - при невозможности выполнить изменение. Для перерисовки примитива на экране следует воспользоваться функцией entupd:
(entupd <примитив>)
Здесь аргумент <примитив> - это имя примитива в том виде, в котором оно выводится, например, функцией entlast.
Другие функции доступа к примитивам:
(handent <метка>) - возвращает имя примитива или неграфического объекта по его метке; аргумент <метка> - это текстовая строка с шестнадцатеричной меткой в том виде, в каком она возвращается функцией entget; (nentsel [запрос] ) - запрашивает объект и для простого примитива возвращает такой же список из имени примитива и точки указания, как и функция entsel. Если указанный пользователем примитив является трехмерной POLYLINE ), то первым элементом возвращаемого списка будет имя подпримитива начальной вершины (VERTEX ) участка, на котором указывалась полилиния. Если указанный пользователем объект является вхождением блока (INSERT), то возвращается список из двух или четырех элементов. Если аргумент запроса не задан, то в качестве подсказки выводится запрос: Select object: (nentselp [запрос] [<точка>]) - аналогична функции nentsel, но если указанным примитивом является вхождение блока (INSERT), то возвращает список, в котором третьим элементом является матрица преобразования размером не 4х3, а 4х4 (см. ниже); если задан аргумент <точка>, то запрос не выдается и аргумент выступает в качестве точки указания.Функция nentsel работает с блоками (точнее, с примитивами типа INSERT) следующим образом. В случае, если пользователь указал атрибут блока, то функция возвращает список из двух элементов: первым является имя объекта-атрибута, а вторым - точка указания атрибута. В случае, если пользователь указал не атрибут, а объект, принадлежащий вхождению блока, то возвращается список из четырех элементов:
Матрица размером 4х3, которая выдается в качестве третьего элемента возвращаемого функцией nentsel значения, имеет вид: ((m00 m01 m02) (m10 m11 m12) (m20 m21 m22) (m30 m31 m32)) . Тогда преобразование точек из СКО в МСК идет по системе уравнений:
X' = Х*m00 + Y*m10 + Z*m20 + m30 Y' = Х*m01 + Y*m11 + Z*m21 + m31 Z' = X*m02 + Y*m12 + Z*m22 + m32
Здесь (X Y Z) - координаты точки до преобразования, (X' Y' Z') - координаты точки после преобразования.
Функция nentselp работает аналогично функции nentsel, но в случае, если пользователь указал объект, принадлежащий вхождению блока, то тоже возвращается список из четырех элементов, но третьим элементом является матрица размером 4х4, которая служит для преобразования точек из системы координат объекта (СКО) в МСК. Матрица имеет вид: ((n00 n01 n02 n03) (n10 n11 n12 n13) (n20 n21 n22 n23) (0.0 0.0 0.0 1.0)) . Преобразование точек из СКО в МСК идет по такой системе уравнений:
X' = Х*n00 + Y*n01 + Z*n02 + n03 Y' = X*n10 + Y*n11 + Z*n12 + n13 Z' = X*n20 + Y*n21 + Z*n22 + n33
Смысл списков (X Y Z) и (X' Y' Z') тот же, что и для функции nentsel.
Набор - это временное множество, в которое входят имена основных примитивов рисунка (как правило, они собираются по какому-то признаку-фильтру). Неосновные примитивы (составные части блока или вершины , чтобы затем можно было извлекать из набора нужные примитивы.
При необходимости сохранять наборы примитивов в рисунке следует оформлять их в виде групп с помощью команды GROUP. Группы относятся к неграфическим объектам, существующим внутри рисунка.
Функция ssget формирует набор по запросу или признаку:
(ssget [<метод>] [<точка1> [<точка2>]] [<список>] [<фильтр>])
Аргумент <метод> - это текстовая строка, принимающая одно из следующих значений (в локализованной версии системы AutoCAD все перечисляемые строки должны спереди дополняться символом "_"), характеризующих метод выбора примитивов:
С" - выбор секущей рамкой;СР" - выбор секущим многоугольником;F" - выбор секущей линией;I" - текущий выбор с помощью ручек;L" - выбор последнего видимого примитива;Р" - последний сформированный ранее набор;W" - выбор рамкой;WP" - выбор многоугольником;X" - вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана, с учетом аргумента <фильтр> (в этом случае аргумент <фильтр> не должен быть опущен);А" - вся база примитивов рисунка, включая объекты на замороженных слоях и вне видимой части экрана;:Е" - все примитивы, попадающие в прицел устройства указания;:N" - выбор основных примитивов с помощью подпримитивов (вершин :S" - допускает выбор только одного объекта.Аргумент <точка1> при отсутствии аргумента <точка2> определяет дополнительное условие для включения в набор: включаемый примитив должен проходить через точку, заданную аргументом <точка1>. Если заданы оба аргумента <точка1> и <точка2>, то заданные ими точки являются углами простой или секущей рамки (когда в качестве метода выбора применяются рамки, т. е. "W" или "С").
Аргумент <список> представляет собой список, элементами которого являются точки, используемые в методах "F", "WP", "СР".
Аргумент <фильтр> - это список со структурой, аналогичной структуре списка, возвращаемого функцией entget, что позволяет оставить только те примитивы, которые удовлетворяют дополнительным признакам (например, определенному цвету, слою, весу и т. д.).
Возвращаемое значение функции ssget - имя созданного набора (или nil, если создать набор невозможно).
Примеры:
(ssget) - выдает стандартный запрос: (Select objects:) и далее создает набор в соответствии с дальнейшими указаниями пользователя; (ssget '(15.78 320.1)) - создает набор из примитивов, проходящих через точку (15.78 320.1); (ssget "_с" '(1.57 -40.4) '(15.78 320.1)) - создает набор из примитивов, выбираемых секущей рамкой с углами в точках (1.57 -40.4) и (15.78 320.1); (ssget "_x" '((0 . "POLYLINE ") (8 . "WALLS"))) - создает набор из всех примитивов рисунка, являющихся POLYLINE и лежащими на слое WALLS; (ssget " А") - создает набор из всех примитивов рисунка, аналогично методу "_Х" с пустым фильтром, т. е. (ssget "_Х" '()) или (ssget "_X" nil) .В рисунке одновременно может быть открыто не более 128 наборов выбора. При достижении такого предела функция ssget отказывается создавать следующие наборы и возвращает nil. Чтобы удалить ненужные наборы, следует присвоить значение nil переменным, хранящим имена этих наборов.
Для манипуляций с наборами в языке предусмотрены следующие функции:
(ssadd [<примитив> [<набор>] ]) - добавление примитива в набор; если аргумент <набор> опущен, а аргумент <примитив> задан, то создается новый набор из одного примитива; если оба аргумента опущены, то создается новый пустой набор (но его значение не равно nil); возвращается имя набора; (ssdei <примитив> <набор>) - удаление примитива из набора, заданных соответствующими аргументами <примитив> и <набор>; возвращается имя набора, если операция удаления выполнена, или nil, если примитив не содержится в наборе и удалить его нельзя; (sslength <набор>) - возвращает количество примитивов в наборе, заданном аргументом <набор>; (ssmemb <примитив> <набор>) - проверка вхождения примитива в набор, заданных соответствующими аргументами <примитив> и <набор>; возвращается имя примитива (т. е. значение аргумента <примитив>), если он входит в рассматриваемый набор, или nil - если не входит; (ssname <набор> <номер>) - извлечение примитива из набора по порядковому номеру, заданных соответствующими аргументами <набор> и <номер>; аргумент <номер> должен быть либо целым числом от 0 до 32 767, либо целым числом в вещественной форме больше 32767.0; нумерация примитивов в наборе начинается с нуля; возвращается имя примитива или nil; (ssnamex <набор> [<номер>]) - извлечение примитива из набора по порядковому номеру (заданных соответствующими аргументами <набор> и <номер>), но при этом выдается дополнительная информация о методах формирования набора (см. ниже); если аргумент <номер> опущен, то выводится информация обо всех примитивах набора; (sssetfirst <набор1> [<набор2>]) - включает ручки у примитивов, входящих в наборы, заданные аргументами <набор1> и <набор2>, но еще и подсвечивает пунктиром примитивы из набора2 (что означает выбор их для следующей операции редактирования); (ssgetfirst) - возвращает список с именами двух наборов, аналогичных по назначению аргументам <набор1> и <набор2> функции sssetfirst (у примитивов набора включены только ручки, у примитивов набора2 включены ручки и подсвечивание).Функция ssnamex возвращает список, в котором элементами являются описания способа выбора примитивов, попавших в набор. Если аргумент <номер> не задан, то длина возвращаемого списка равна количеству элементов, определяемых аргументом <набор>. Если аргумент <номер> задан и задан корректно, то возвращаемым значением будет список из одного элемента - описания способа выбора примитива с порядковым номером, равным значению аргумента <номер>. Если же аргумент <номер> задан неправильно, то функция ssnamex вернет nil.
Описание способа выбора примитива - это список из трех элементов: (<метод> <примитив> <данные>). Параметр <метод> - целое число, которое соответствует методу выбора функции ssget и может принимать такие значения:
0 - неинтерактивный выбор ("L", "А", "X" и т. п.);
1 - выбор указанием точки;
2 - "W" или "WP";
3 - "С" или "СР";
4 - "F".
Если на месте параметра <метод> стоит отрицательное число, то оно определяет многоугольник выбора (см. описание многоугольника ниже).
Параметр <примитив> описания способа выбора примитива является его именем в том виде, в котором оно выводится функцией entlast. Параметр <данные> может быть либо только числом 0, либо числом 0 и списком, уточняющим выбор, либо числом 0 и номером многоугольника. В уточняющем списке может быть точка, с помощью которой выбран объект. Если использован номер многоугольника (а он должен быть отрицательным: -1 , -2 и т. п.), то далее будет следовать описание многоугольника с соответствующим номером.
Описание многоугольника - это список такого вида: (<номер_многоугольника> <точка1> ... <точкаN>) . Нумерация многоугольников начинается с -1 и наращивается путем добавления -1 к очередному номеру.
Описание точки (<точка1> и т. п.) - это список из трех (или двух) элементов: (<код> <база> [<вектор>] ) . Описание точки зависит от вида, на котором она выбиралась, и фактически представляет собой описание прямой, луча или отрезка. Параметр <код> является кодом описания точки (0 - прямая, 1 - луч, 2 - отрезок), параметр <база> представляет собой начальную точку описания, а необязательный параметр <вектор> - это либо направление, в котором продолжается бесконечная линия (прямая или луч), либо смещение в сторону, характерное для отрезка.
Пример:
Если в набор nab5 включен один объект, который был указан точкой (7.51 16.02) на обычном виде сверху в МСК, то выражение (ssnamex nab5 0) возвращает примерно следующее: ((1 <имя объекта: 14аа560> 0 (0 (7.51 16.02 0.0)))) .
В этом примере возвращенный функцией ssnamex список состоит из одного элемента (списка), в котором присутствуют следующие составные части:
Другие примеры значений, возвращаемых функцией ssnamex:
((0 <Имя объекта: 14ае578> 0)) - один примитив, выбранный неинтерактивным методом (например, "L"); ((3 <Имя объекта: 14ае568> О -1) (3 <Имя объекта: 14ае578> 0 -1) (-1 (0 (-147.787 129.133 0.0)) (0 (-64.2728 129.133 0.0)) (0 (- 64.2728 22.3376 0.0)) (0 (-147.787 22.3376 0.0)))) - два примитива, выбранных секущим прямоугольником с номером -1 (для прямоугольника заданы четыре точки); ((1 <Имя объекта: 14ае560> 0 (0 (74.2672 64.8218 0.0))) (2 <Имя объекта: 14ае570> 0 -1) (2 <Имя объекта: 14ае568> 0 -1) (-1 (0 (-177.446 158.755 0.0)) (0 (40.3151 158.755 0.0)) (0 (40.3151 83.1407 0.0)) (0 (-177.446 83.1407 0.0)))) - три примитива, первый из которых выбран указанием с помощью точки (74.2672 64.8218 0.0), а второй и третий выбраны рамкой, которая фигурирует как многоугольник с номером -1.В этих примерах параметр <вектор> описания точек нигде не использован, т. е. объекты выбирались на виде сверху в МСК.
Наборы - удобный инструмент для выбора нужных примитивов рисунка с заданными свойствами. После формирования набора затем из него с помощью функции ssname (или ssnamex) извлекаются нужные объекты, с которыми далее выполняются необходимые операции (например: удаление, модификация и т. д.).
Помимо примитивов в рисунке всегда присутствует определенный объем неграфической информации: описания блоков, таблицы слоев, таблицы видовых экранов, таблицы типов линий, размерные стили и т. п. Все они хранятся в базе рисунка примерно в том же виде, что и примитивы.
Для доступа к табличным объектам в языке имеются такие функции:
(tbinext <таблица> [<признак>]) - чтение характеристик очередного объекта из таблицы. Допустимые значения параметра <таблица> приведены ниже. Если параметр <признак> задан и отличен от nil, то возвращаются данные первого элемента таблицы. Иначе возвращаются данные объекта, следующего за тем, который был прочитан в предыдущем обращении к функции tbinext с той же таблицей. Если требуемого объекта нет или таблица пуста, то возвращается nil; (tbiobjname <таблица> <заголовок>) - определение объекта таблицы по его заголовку (имени блока, слоя и т. п.). Возвращается имя объекта (аналогично имени примитива) в базе рисунка. Если объект не найден, то возвращается nil. (tbisearch <таблица> <заголовок> [<следующий>]) - получение списка с характеристиками объекта таблицы по его заголовку. Возвращается список, соответствующий найденному объекту (или nil, если объект не обнаружен). Если параметр <следующий> задан и не равен nil, то указатель функции tbinext устанавливается на имя элемента <заголовок>. Следующее обращение к функции tbinext вернет данные об объекте, расположенном в таблице после объекта, использованного в качестве аргумента в функции tbisearch.В качестве допустимых значений параметра <таблица> во всех трех функциях могут фигурировать только следующие текстовые строки:
BLOCK" - таблица описаний блоков;LAYER" - таблица слоев;LTYPE" - таблица типов линий;STYLE" - таблица текстовых стилей;DIMSTYLE" - таблица размерных стилей;UCS " - таблица именованных систем координат;VIEW" - таблица именованных видов;VPORT" - таблица конфигураций видовых экранов;APPID" - таблица имен приложений.Схема использования рассмотренных функций будет ясна из примеров:
(5etq lay1 (tbinext "LAYER" T)) - возвращает список с данными первого слоя рисунка (первым слоем должен быть слой с именем "0"), например: ((0 . "LAYER") (2 . "0") (70 . 0) (62 . 7) (6 . "Continuous")). В этом списке в точечной паре с -кодамиотражаются следующие свойства:
0 - находится имя таблицы, в которой ищется неграфический объект,
2 - имя слоя,
6 - тип линий примитивов слоя по умолчанию (т. е. каким типом отображать объекты с типом линии BYLAYER),
62 - цвет слоя по умолчанию,
70 - состояние слоя по отношению к операциям блокирования, замораживания; нетрудно заметить, что аналогичные -коды используются в списке, возвращаемом функцией entget для примитивов.
(setq lay2 (tbinext "LAYER")) - возвращает список с данными второго слоя рисунка, например: ((0 . "LAYER") (2 . "стена1") (70 . 4) (62 . 40) (6 . "ограждение1"));
(setq lay2name (tbiobjname "LAYER" "Стена1")) - возвращает <Имя объекта: 14аа570>; теперь с помощью функции entget можно получить тот же список, что и lay2 в предыдущем примере.
С помощью этих трех функций можно проанализировать наличие в рисунке таких элементов, как описания блоков, пользовательские системы координат или текстовые стили с определенными именами и выбрать соответствующий вариант работы программы.
Свойствами, аналогичными таблицам, обладают в рисунке словари (dictionaries). К ним относятся, например, словари стилей
(dictadd <словарь> <символ> <новый>) - добавление нового объекта к словарю; (dictnext <словарь> [<признак>]) - чтение очередного символа из словаря (аналогична функции tbinext, но работает со словарями); (dictremove <словарь> <символ>) - удаление символа словаря; (dictrename <словарь> <старое> <новое>) - переименование символа словаря; (dictsearch <словарь> <символ> [<следующий>]) - поиск символа в словаре (аналогично функции tbisearch); (layoutlist) - получение списка имен листов текущего рисунка; (namedobjdict) - получение имени корневого словаря неграфических объектов рисунка; (setview <вид> [<в экран>]) - установка вида в видовом экране; (snvalid <имя>) - проверка имени таблицы символов на недопустимые знаки.К любому примитиву рисунка можно добавлять расширенные данные, т. е. текстовые или числовые данные, которые желательно хранить вместе с геометрией (например, марки материалов, наименования узлов, секций и т. п.). Обычно наличие такой информации позволяет разрабатывать программы связи с базами данных (рассмотрение таких программ не является предметом настоящей книги). Расширенные данные связываются с именем определенного приложения. У одного графического примитива могут быть данные нескольких приложений, которые располагаются последовательно в определенной структуре.
Если расширенные данные присоединены к примитиву, то в базе рисунка они следуют за обычными данными (-коды этих данных находятся в диапазоне от -2 до 239). Извлечь расширенные данные можно с помощью функции entget, при обращении к которой нужно указывать имя приложения, с которым они связаны. В списке, возвращаемом функцией entget, расширенные данные находятся в подсписке, начинающемся с -кода -3 (признак наличия расширенных данных), в котором далее располагаются точечная пара с кодом 1001 (начало расширенных данных и имя приложения, с которым они связываются) и точечные пары с -кодами 1000, 1002-1071. Назначение -кодов расширенных данных описывается в табл. 3.6.
| Код | Назначение |
|---|---|
| 1000 | Строковая константа длиной не более 255 знаков (256-й знак зарезервирован под символ с кодом 0) |
| 1001 | Строковая константа, используемая только для указания имени приложения, длиной не более 31 знака (если код 1001 попадает внутрь списка, организуемого с помощью -КОДОВ 1002, то он интерпретируется как обычная константа, а не имя приложения; см. далее описание -кода 1002). Имя приложения должно состоять только из цифр, латинских букв и символов |
| 1003 | Имя слоя, с которым связываются расширенные данные |
| 1005 | Метка объекта в базе чертежа |
| 1010 | Трехмерная точка (три вещественных числа) |
| 1040 | Вещественное число |
| 1070 | 16-битовое целое число (со знаком или без знака) |
| 1071 | 32-битовое целое число со знаком (длинное целое). Хотя система AutoCAD хранит данные группы с кодом 1071 как длинное целое, возвращает их как вещественные числа. Функциям entmake и entmod в точечной паре с кодом 1071 можно подавать либо целые числа, либо вещественные. ObjectARX трактует данные группы 1071 как длинные целые |
| 1002 | Строка, принимающая значения "{" или "}" и имеющая тот же смысл, что и левая и правая круглые скобки в обозначении списка. С помощью группы с кодом 1002 можно формировать в расширенных данных |
| 1004 | Двоичные данные длиной не более 127 байт. Обрабатываются только в ObjectARX |
| 1011 | Трехмерная точка, интерпретируемая как положение в МСК. Такая точка перемещается, масштабируется, поворачивается и симметрируется одновременно с родительским примитивом рисунка. Если точка попадает в рамку выбора команды РАСТЯНУТЬ (STRETCH), то она подвергается операции растягивания вместе с родительским примитивом |
| 1012 | Трехмерная точка, интерпретируемая как перемещение в МСК. Такая точка не перемещается и не растягивается одновременно с основным примитивом, но участвует вместе с ним в операциях масштабирования, поворота и симметрирования |
| 1013 | Трехмерная точка, интерпретируемая как направление в МСК. Такая точка не масштабируется, не перемещается и не растягивается одновременно с основным примитивом, но участвует вместе с ним в операциях поворота и симметрирования. Вектор с координатами, взятыми из группы с кодом 1013, является нормализованным, т. е. единичной длины |
| 1041 | Вещественное число, интерпретируемое как расстояние. Оно масштабируется одновременно с родительским примитивом |
| 1042 | Вещественное число, интерпретируемое как масштабный коэффициент. Масштабируется одновременно с родительским примитивом |
Как было сказано выше, расширенные данные связываются с именем конкретного приложения. Имена приложений хранятся в рисунке в таблице символов "APPID". Чтобы занести имя приложения в эту таблицу, следует пользоваться функцией rеgарр:
(rеgарр <приложение>)
Параметр <приложение> должен быть текстовой строкой (по возможности нужно выбирать имя приложения таким, чтобы оно не совпадало с именами приложений других разработчиков - иначе это приведет к неправильной работе с расширенными данными). Функция rеgарр возвращает nil в случае ошибки (nil возвращается также, если приложение с таким именем уже регистрировалось).
Функция entmake может создать примитив и сразу присоединить к нему расширенные данные. С помощью функции entmod можно добавить расширенные данные к существующему графическому объекту.
Пример
Предположим, что к последнему существующему примитиву рисунка (пусть им является отрезок) нужно добавить расширенные данные, связанные с приложением "GENHULL":
(setq le (entget (entlast) ) ) - сохраняет в переменной le список последнего примитива, у которого еще нет расширенных данных: ((-1 . <Имя объекта: 14аа578>) (0 . "LINE") (330 . <Имя объекта: 14aa4f8>) (5 . "2F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (100 . "AcDbLine") (10 85.4655 223.335 0.0) (11 187.712 167.209 0.0) (210 0.0 0.0 1.0)) ; (setq edata '((-3 ("GENHULL" (1000 . "Пластмасса") (1070 . 57))))) - сохраняет в переменной edata список с расширенными данными, которые будут добавлены к списку le (добавляются текстовая строка с DXF -кодом 1000 и целое число с DXF -кодом 1070); (setq le2 (append le edata)) - объединяет списки le и edata и формирует новый список le2: ((-1 . <Имя объекта: 14аа578>) (0 . "LINE") (330 . <Имя объекта: 14aa4f8>) (5 . "2F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (100 . "AcDbLine") (10 85.4655 223.335 0.0) (11 187.712 167.209 0.0) (210 0.0 0.0 1.0) (-3 ("GENHULL" (1000 . "Пластмасса") (1070 . 57)))) ; (entmod le2) - модифицирует примитив по новому списку и возвращает то же значение, что и предыдущее выражение; (entget (entlast) '("GENHULL")) - получает список нового последнего примитива вместе с расширенными данными, относящимися к приложению "GENHULL": ((-1 . <Имя объекта: 14аа578>) (0 . "LINE") (330 . <Имя объекта: 14aa4f8>) (5 . "2F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1) (100 . "AcDbLine") (10 85.4655 223.335 0.0) (11 187.712 167.209 0.0) (210 0.0 0.0 1.0) (-3 ("GENHULL" (1000 . "Пластмасса") (1070 . 57)))) .Размер расширенных данных любого примитива не должен превышать 16 килобайт (16383 байта). Поэтому по мере добавления таких данных их размер нужно контролировать. Этой цели служат две функции:
(xdsize <список>) - получает размер в байтах, необходимый для сохранения расширенных данных; аргумент <список> - это список с расширенными данными, начинающийся с DXF -кода -3; (xdroom <примитив>) - возвращает целое число - количество свободных байтов в зоне расширенных данных примитива.Перед записью в зону примитива новой порции расширенных данных нужно проверить, достаточно ли для них места.
Коротко рассмотрим другие функции языка .
Функция alert позволяет вывести на экран диалоговое окно с сообщением системы AutoCAD. Синтаксис функции:
(alert <сообщение>)
Функция возвращает nil. Максимальная длина строки <сообщение> зависит от многих вещей (в частности, от платформы) и может быть вычислена пользователем самостоятельно. В случае превышения допустимой длины AutoCAD обрезает сообщение. При необходимости вывести сообщение в несколько строк нужно использовать знаки конца строки ("\n").
Пример:
(setq lines (strcat "Я вас любил: любовь еще, быть может,\n" "В душе моей угасла не совсем;\nНо пусть она вас больше не тревожит-\n" "Я не хочу печалить вас ничем.")) (alert lines) выводит на экран окно, изображенное на рис. 3.4.
(рис 3.4) Диалоговое окно, вызываемое функцией alert
В данном примере выведены четыре строки, поскольку трижды был использован знак конца строки. Выход из диалогового окна, изображенного на рис.3.5, - щелчок по кнопке ОК.
Рассмотрим несколько полезных геометрических функций.
(inters <точка1> <точка2> <точка3> <точка4> [<признак>]) - если аргумент <признак> отсутствует или задан отличным от nil, функция вычисляет пересечение двух отрезков. Первый имеет концы в точке1 и точке2, а второй - в точкеЗ и точке4. Точки заданы соответствующими аргументами: <точка1>, <точка2>, <точка3> и <точка4>. Если аргумент <признак> задан и равен nil, то функция вычисляет пересечение двух прямых, проходящих через отрезки. Если все аргументы точки являются трехмерными, то функция inters ищет пересечение в трехмерном пространстве. Если хотя бы одна из точек имеет только две координаты, то вычисляется пересечение проекций отрезков на текущую плоскость построений. Точки задаются как списки из двух или трех вещественных чисел; (polar <точка> <угол> <расстояние>) - возвращает координаты точки, которая отстоит от исходной точки, определяемой аргументом <точка> на заданное расстояние с помощью аргумента <расстояние>; вектор, идущий из исходной точки в вычисляемую новую точку, должен образовывать (в проекции на текущую плоскость построений) с осью Х заданный угол, определяемый аргументом <угол>, в радианах; (textbox <список>) - возвращает список из двух точек, являющихся точками диагоналей прямоугольника, описанного вокруг надписи. Надпись задается с помощью аргумента <список>, который должен иметь формат списка текстового примитива (в том виде, в каком его вернула бы функция entget). Если аргумент <список> не содержит каких-либо параметров, то функция textbox при вычислении дополняет его текущими установками рисунка; (osnap <точка> <режим>) - возвращает результат применения к точке, заданной аргументом <точка>, функции объектной привязки с установками режимов, заданными в аргументе <режим>. Режимы привязки указываются с помощью строки, в которой без пробелов, через запятую перечисляются наименования режимов: "_end", "_mid", "_int", "_nea", "_nod" и т. д. На результат операции оказывает влияние значение системной переменной APERTURE .Примеры:
(inters '(2.25 4.50) '(-2.25 6.335) '(1.27 0.50) '(-8.65 -2.30)) - возвращает nil; (inters '(2.25 4.50) '(-2.25 6.335) '(1.27 0.50) '(-8.65 -2.30) nil) - возвращает (7.64593 2.29966); (polar '(16.32 4.782) 0.345 4.79) - возвращает (20.8278 6.40196); (osnap '(16.32 4.782) "_end,_mid") - возвращает координаты точки, уточненной с помощью применяемых одновременно функций объектной привязки к конечной и средней точкам.К полезным функциям, кроме того, относятся функции работы с элементами меню:
menucmd - операции с пунктами меню;menugroup - работа с группой меню.Подробности описания этих функций можно найти в справочной системе AutoCAD.
В языке есть некоторое количество функций для работы с диалоговыми окнами. Функции работы с диалогами - load_dialog, unload_dialog, start_dialog, done_dialog, term_dialog, new dialog.
Функции работы С ПОЛЯМИ - action_tile, get_tile, set_tile, mode tile, get_attr, client_data_tile.
Функции работы с slide_image, start_image, vector image, end_image, dimx_tile, dimy_tile, fill_image.
Функции работы со списками - start_list, end_list, add_list.
К рассматриваемой версии языка в качестве расширения могут быть добавлены более ста функций, реализующих технологию ActiveX и дополняющих возможности пользователя по созданию эффективных программных продуктов на базе системы AutoCAD 2000. Все эти функции начинаются с префиксов vir-, via- и vlax-, и перед первым обращением к любой из них надо выполнить функцию загрузки (без этого они не будут доступны):
(vl-load-com)
Технология ActiveX облегчает и ускоряет доступ к примитивам и их характеристикам. К примитивам рисунка можно прикрепить другие объекты, называемые реакторами. Реакторы отслеживают определенные будущие события (например, перемещение или удаление примитива, открытие, сохранение или закрытие рисунка, вставку блока или внешней ссылки). Как только проверяемое событие происходит, реакторы с помощью специальных средств выполняют запрограммированные операции.
Упражнение
С помощью справочной системы определите назначение функций cons, load, .
Возвращаемое значение - результат вычисления интерпретатором выражения, записанного в процедуре.
Переменная - именованный участок памяти для хранения данных.
Символы - это слова, состоящие из группы буквенно-цифровых знаков и являющиеся именами функций или переменных, используемых для хранения данных пользователя.
Загрузка файла в AutoCAD - операция загрузки файла в программу с помощью функции Load.
Функции присвоения setq - функция, которая присваивает переменной значение выражения.
Функция command - функция , которая имитирует ввод пользователя в командной строке AutoCAD с клавиатуры.
является внутренним языком программы AutoCAD. Процедуры представляют собой набор функций с задаваемыми параметрами и аргументами. Встроенные функции обладают широкими возможностями создания и редактитования чертежных объектов.
AutoLISP ?AutoLISP ?AutoLISP ?Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.