Функции autolispа


Содержание

Функции autolispа

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

apply function arg &s;rest more-args

В последние годы в ряде реализаций Common Lisp не допускается использовать в качестве аргумента apply старые добрые лямбда-выражения. Однако это ограничение легко обходится — достаточно использовать аббревиатуру

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

Аргументы, передаваемые function образуются из последнего аргумента apply, которые с помощью append дописываются в конец вызова функции. Фактически, создается список аргументов, который и передается функции для обработки. Например:

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

Это может оказаться весьма полезным при использовании режима &allow-other-keys:

funcall fn &rest arguments

Так же, как и в случае apply, обработка лямбда-выражений осуществляется с помощью специальной аббревиатуры #’ , которая представляет собой сокращенное описание вызова function.

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

В этом отношении funcall является отражением реально существующего в Лиспе единства программ и данных — ничто не мешает вам сгенерировать код программы в самой программе и тут же его использовать для получения новых функций. Одним словом, вот она — реальная предпосылка для вполне реального искусственного интеллекта (А заодно и реализационная основа для создания Лисп-вирусов. ).

Константа call-arguments-limit

Последовательные вычисления

Специальная форма progn

Форма progn представляет собой одну из элементарных управляющих структур, предназначенных для формирования так называемых «составных операторов», аналогами которых в процедурных языках программирования являются, например, блоки begin-end.

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

Если последняя форма, входящая в вызов progn возвращает несколько значений, то и сама форма progn возвращает все эти значения. Если внутри блока progn не оказалось ни одной формы, то в качестве результата будет возвращено NIL. Эти правила верны и для неявных вызовов progn.

Функция prog1

Как правило, prog1 используется для оценки значений выражений с побочными эффектами, в которых интерес представляет результат, полученный <\it до того>, как эти побочные эффекты вступят в силу. Например:

изменяет car-часть ячейки x, делая ее равной foo и возвращает прежнее значение car-части x.

Функция prog1 всегда возвращает только одно значение, даже если сама первая форма, являющаяся ее аргументом, формирует сразу несколько. В результате

и могут вести себя по-разному, если x приводит к получению нескольких значений.

Хотя prog1 может принудительно возвращать одно единственное значение, обычно в Common Lisp для этой цели используется функция values.

Функция prog2

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

Функция prog2, как и prog1, всегда возвращает одно значение, даже в том случае, если вторая форма пытается вернуть сразу несколько. В результате и могут вести себя по-разному, если y возвращает несколько значений.

Установление новых связей переменных

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

Специальная форма let

Форма let предназначена для последовательного выполнения нескольких форм, в которых осуществляется связывание заданных переменных с вычисляемыми значениями.

С формальной точки зрения, форма вида

вначале оценивает значения выражений value1, value2, и т.д., и сохраняет полученные результаты. Затем все переменные varj одновременно связываются с соответствующими результатами вычислений; при этом каждое связывание представляет собой лексическую связь, если только иное не оговаривается явно с помощью объявления special.

Затем последовательно вычисляются значения bodyk; при этом игнорируются все полученные значения, кроме последнего (Это означает, что тело let представляет собой неявную конструкцию progn .). Форма let возвращает результат оценки значения bodyn (если тело пусто, что с практической точки зрения просто не имеет смысла, то let возвращает в качестве значения NIL).

Допускается вместо списка ( varj valuej), использовать просто запись varj. В этом случае varj вначале присваивается значение равное NIL. В соответствии с правилами хорошего тона рекомендуется использовать varj только в тех случаях, когда значение этой переменной до своего первого использования будет сохранено, например, с помощью setq. И если для правильной работы алгоритма необходимо, чтобы начальное значение было именно NIL, то рекомендуется откровенно указывать — (varj NIL), если начальное значение должно означать «false,»или (varj ‘()), если начальное значение должно представлять собой пустой список.

Например, фрагмент кода

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

Объявления типов переменных могут располагаться только в начале тела формы let.

Специальная форма let*

Специальная форма let* в целом подобна let, и отличается лишь тем, что связывание переменных осуществляется не одновременно, а последовательно. Это позволяет в выражениях ссылаться на значения переменных, которые уже были вычислены ранее в этой же форме let*.

Иначе говоря, форма

вначале оценивает значение value1, затем связывает с этим значением переменную var1; после этого оценивается значение value2 и результат связывается с var2, затем процесс продолжается.

После этого осуществляется последовательное вычисление выражений bodyj. Все полученные значения кроме последнего (bodyn) отбрасываются (Это означает, что тело let представляет собой неявную конструкцию progn .). Форма let* возвращает результат оценки bodyn (если ни одной формы не вызывалось, let* возвращает NIL).

Допускается вместо списка ( varj valuej), использовать просто запись varj. В этом случае varj вначале присваивается значение равное NIL. В соответствии с правилами хорошего тона рекомендуется использовать varj только в тех случаях, когда значение этой переменной до своего первого использования будет сохранено, например, с помощью setq. И если для правильной работы алгоритма необходимо, чтобы начальное значение было именно NIL, то рекомендуется откровенно указывать — ( varj NIL), если начальное значение должно означать «false,»или ( varj ‘()), если начальное значение должно представлять собой пустой список.

Вначале области тела let* могут помещаться объявления типа переменных.

Специальная форма compiler-let

В тех случаях, когда compiler-let выполняется интерпретатором Лиспа, эта функция ведет себя аналогично let, включая неявные объявления special для связей переменных. Однако если эта форма обрабатывается компилятором, то код для вычисления значений переменных не генерируется. Вместо этого, обработка тела компилятором (включая все расширения макросов в теле) выполняются с использованием специальных переменных, ассоциируемых с используемыми в форме значениями, назначенным введенным переменным. Основное назначение этой формы состоит в упрощении организации взаимодействия между сложными макросами.

В теле этой формы не допускается использование объявлений типа.

Во многих современных реализациях CommonLisp эта форма отсутстствует. Вместо нее рекомендуется использовать macrolet или symbol-macrolet.

Специальная форма progv

Если форма содержит слишком мало значений, то все оставшиеся символы не получают никакого значения; см. makunbound. Если передано слишком много значений, то все лишние игнорируются.

Результатом вызова progv является значение, полученное при оценке последней формы form. Все связи динамических переменных действуют только в пределах формы progv.

Форма progv особенно полезна при написании интерпретаторов на Лиспе и предоставляет программисту удобный механизм для связывания динамических переменных.

Специальная форма flet

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

Можно определить произвольное количество функций. При этом каждое определение по формату подобно форме defun form: вначале задается имя, затем список параметров (который может содержать ключи &optional, &rest, или &key), затем следуют необязательные объявления типов и строки документирования, и наконец, собственно тело функции.

Конструкция labels в основном идентична рассмотренной выше flet. Однако эти конструкции различны с той точки зрения, что имена функций flet влияют только не тело функции, в то время как labels относится к самим определениям этих функций. Это означает, что labels могут использоваться для определения взаимно рекурсивных функций, что невозможно сделать с помощью flet. Именно это различие делает форму labels настолько полезной. Использование flet позволяет локально переопределить имя функции, но новое локальное определение будет ссылаться на глобальное определение; а вот при использовании labels такого эффекта не возникнет. Вот небольшой пример:

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

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

После расширения макроса, определенного с помощью macrolet, мы получим:

Все упоминания x и flag вполне корректно относятся к параметрам функции foo, поскольку эти параметры видимы макровызову во время его расширения.

Специальная форма symbol-macrolet

Появление формы symbol-macrolet отражает интеграцию в CommonLisp объектно-ориентированного расширения CLOS, которое мы рассмотрим отдельно, и уж точно не в этом году. Однако symbol-macrolet может использоваться и независимо от CLOS.

Формы forms выполняются как неявный вызов progn в лексическом окружении, которое приводит к тому, что каждая ссылка на любую переменную var, определенную при вызове symbol-macrolet, заменяется соответствующим ей выражением expansion. Можно считать, что ссылка на переменную var интерпретируется как макровызов без параметров; затем либо оценивается значение expansion либо помещается на место ссылки.

Обратите внимание, что имена, создаваемые таким образом, используют пространство имен переменных, но не функций; поэтому вы можете иметь функцию (или макрос, или специальную форму) и одновременно — переменную с тем же самым именем, и это не приведет ни к каким конфликтам.

Однако это приводит к тому, что результат symbol-macrolet может быть затенен при последующем использовании let или других конструкций, которые осуществляют связывание переменных; symbol-macrolet не выполняет подстановку всех обращений к var вообще, а только тех, которые конструируются как ссылки к переменным в области действия лексической связи var как переменной. Например:

Вам может показаться, что ‘goody просто заменяет все обращения к символу pollyanna, и значением let будет goody; но не все так просто! В случае такого поведения системы мы получили бы:

что синтаксически неверно. Правильная расширенная форма представляет собой:

поскольку смена связи pollyanna формой let затеняет символ из макроопределения.

Расширение expansion, ассоциируемое с каждой переменной var оценивается не во время связывания, но только после того, как будет заменено обращение к var. Макрос setf позволяет использовать этот макрос как место применения нового значения, в качестве которого используется расширение этого макроса; кроме того setq для переменной, которая на самом деле является макро-символом, также интерпретируется как применение setf. Форма возвращает значение последней формы, либо nil, если не было получено никакого значения.

Имейте в виду, что использование объявлений типов declarations перед телом хотя и допускается, но может приводить к неожиданным результатам.

Кондиционалы

Традиционной для Лисп конструкцией, предназначенной для организации условного выполнения функций является, конечно же cond. Однако более удобной и простой является форма if, которая навевает прямые ассоциации с условными операторами в других языках программирования. Поэтому, в целях соблюдения преемственности с Бейсиком и Паскалем мы начнем обсуждение условных операторов именно с этой формы. Кроме того, мы рассмотрим конструкции case и typecase, которые также покажутся начинающим более удобными чем cond.

Специальная форма if

Специальная форма if соответствует конструкции if-then-else, реализованной в большинстве современных языков программирования процедурного типа. Вначале осуществляется оценка значения формы test. Если полученный результат отличен от NIL, выполняется форма then; в противном случае выполняется форма else. Сама форма if возвращает в качестве результата значение выполненной формы.

С точки зрения традиционного Лиспа конструкция if эквивалентна:

но понятно, что if в некоторых случаях более удобна.

Форма else может отсутствовать, в этом случае если значение test равно NIL, то никаких дополнительных действий не выполняется и значение всей формы if становится равным NIL. Если значение, возвращаемое формой ifв этой ситуации имеет для вас значение, то более предпочтительным может быть использование and. Если же возвращаемое значение роли не играет, то более удобным может оказаться when.

Форма when

Форма вида (when test form1 form2 . ) вначале оценивает значение условия test. Если результат равен NIL, то form не выполняется и возвращается NIL. В противном случае формы form образуют неявный progn и оцениваются последовательно, слева направо. Значение последней формы становится значением всей функции.

Обычно when используется для условного формирования тех или иных побочных эффектов, а значение, которое возвращает when, в большинстве случаев не используется. Если же возвращаемое значение представляет для вас практический интерес, то более предпочтительно использовать and или if.

Форма unless

В большинстве случаев эта форма используется ради ее побочных эффектов, и возвращаемое ею значение не используется. Если же результат вычислений имеет практическое значение, то имеет смысл вместо unless использовать if.

Форма cond

Форма cond может иметь произвольное количество (включая нуль)
вариантов, которые представляют собой список форм. Каждый из
вариантов состоит из условия test, за которым следует нуль
или больше следствий consequents.

Выполняется первый вариант, в котором test получает значение, отличное от NIL; все остальные варианты игнорируются, а следствия в выбранном варианте выполняются последовательно, образуя неявный вызов progn.

С формальной точки зрения cond последовательно просматривает варианты слева направо. Для каждого варианта производится оценка условия test. Если результатом является NIL, cond переходит к анализу следующего варианта. В противном случае cdr-часть варианта рассматривается как список форм, подлежащих последовательному исполнению, и они оцениваются слева направо, как неявный progn. После завершения выполнения cond завершает работу, даже не приступая к анализу следующих вариантов.

Если для выбранного cond варианта отсутствовал список следствий, то возвращается результат оценки теста. И наконец, если в ходе проверки не удалось найти ни одного подходящего варианта, то значением cond становится NIL.

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

Согласно правилам хорошего счета рекомендуется всегда помещать в конце формы cond вариант (T NIL).

Форму cond в Лиспе можно сравнить с традиционной расширяемой конструкцией if- then- else, используемой в большинстве языков программирования:

Форма case

Форма case представляет собой кондиционал, который выбирает для выполнения один из вариантов путем сравнения значения формы keyform с различными константами key, которые обычно представляют собой ключевые слова, числа или символы, но можно, вообще говоря, использовать произвольные объекты Лиспа. Формат этой формы следующий:

По своей структуре case во многом похож на cond, да и ведет себя похоже. Однако case отличается в части работы механизма выбора исполняемого варианта.

Первое, что делает case — это оценка значения формы keyform, для получения объекта, который называется ключевым объектом формы. Затем case по очереди рассматривает все варианты. Если при этом ключ key находится в keylist, то есть равен в смысле eql какому либо объекту в keylist данного варианта, то следствия этого варианта оцениваются как неявный progn; case возвращает то, что было возвращено последним следствием либо NIL, если в данном варианте не было ни одного следствия. Если не удается найти ни одного подходящего варианта, то case возвращает NIL.

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

Допускается вместо списка ключей keylist, использовать один из символов — T или otherwise. Вариант, содержащий такой символ, всегда будет выполняться, а поэтому должен быть размещен в самом конце формы (Это единственное исключение из правила, которое гарантирует независимость порядка следования операторов).

В том случае, когда варианту соответствует один единственный ключ, он может записываться вместо списка, состоящего из одного элемента. При этом никакой неоднозначности в интерпретации ключей не возникает. Такой ключ не может иметь значение NIL (которое может быть интерпретировано как () — список без ключей), T, или представлять собой cons-ячейку.

Форма typecase

Форма typecase представляет собой кондиционал, который выбирает один из вариантов в соответствии с типом переданного ему объекта. Форма может быть интерпретирована следующим образом:

По своей структуре typecase во многом схожа с cond или case, и ведет себя почти так же, выбирая и выполняя один из вариантов. Однако, эта форма отличается от упомянутых выше механизмом выбора варианта.

Прежде всего это отличие typecase, состоит в оценке значения формы keyform, которая должна сгенерировать объект, который называется ключевым объектом. Затем typecase последовательно рассматривает каждый из вариантов. При проверке варианта осуществляется сопоставление полученного типа ключевого объекта со спецификатором типа type, который не оценивается при вызове функции и должен представлять собой литеральный спецификатор типа. Выполняется первый вариант, спецификатор типа которого удовлетворяет типу ключевого объекта. Следствия этого варианта выполняются как неявный вызов progn, и typecase возвращает результат оценки последней формы. Если в данном варианте не было описано ни одной формы, либо если не удалось подобрать ни одного варианта, то typecase возвращает NIL.

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

В некоторых реализациях Common Lisp, компилятор может сгенерировать предупреждение, если вариант никогда не может быть выполнен из за его затенения более ранними вариантами.

Функции autolispа

В результате совершенствования AutoLISP появилась интегрированная среда разработки Visual LISP (VLISP), которая включает в себя компилятор, отладчик и ряд других средств, повышающих производительность. В языке появились новые возможности, которые позволяют взаимодействовать с объектами с использованием интерфейса ActiveX. Кроме того, на VLISP с помощью реакторов объектов можно обрабатывать различные события.

В отличие от ObjectARX или VBA, в Visual LISP для каждого чертежа, открытого в многодокументной среде AutoCAD, имеется свое пространство имен и собственная среда. Пространство имен каждого чертежа является изолированным, что позволяет избегать конфликтов имен переменных, процедур AutoLISP среди одновременно открытых чертежей. Например, следующее выражение по-разному устанавливает значение переменной а для различных документов.

В Visual LISP имеется механизм загрузки обозначений и переменных из одного пространства имен в другое. Для получения более подробной информации о пространствах имен см. раздел справки AutoLISP Developer’s Gu > «Справка для разработчиков».

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

Приложения Visual LISP могут загружаться из файлов трех форматов:

  • LSP-файлы (с расширением . lsp)—Текстовый файл ASCII, содержащий код программы AutoLISP.
  • FAS-файлы (с расширением . fas)—двоичная скомпилированная версия одного файла программы LSP.
  • VLX-файлы (с расширением . vlx)—скомпилированный набор одного или нескольких файлов LSP или DCL-файлов.

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

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

О программировании средствами AutoLISP см. раздел справки AutoLISP Developer’s Gu >AutoLISP Reference (Справочник по AutoLISP). Для отображения Справки для разработчиков следует щелкнуть на стрелке раскрывающегося списка, расположенной на панели инструментов «Инфоцентр» справа от кнопки «Справка». В появившемся меню выберите «Дополнительные ресурсы» «Справка для разработчиков». В программах на AutoLISP можно использовать диалоговые окна. Документация о программируемых диалоговых окнах содержится только в документации AutoLISP Developer’s Guide (Руководство по AutoLISP для разработчиков).

Вызов интегрированной среды разработки приложений Visual LISP.

Управляет дополнительным выбором объектов (заменяет или дополняет текущий набор выбранных объектов).

Управляет автоматическим созданием рамки выбора объектов в ответ на запрос «Выберите объекты».

Функции autolispа

AutoLISP ОБ РТЙНЕТБИ: ОБЮЙОБЕН

оЕ ЪОБА, РПЮЕНХ ФБЛ НБМП РПМШЪПЧБФЕМЕК РЙЫХФ РТПЗТБННЩ ОБ СЪЩЛЕ AutoLISP. чПЪНПЦОП, УБНП РПОСФЙЕ РТПЗТБННЙТПЧБОЙС ЧУЕМСЕФ УФТБИ. ч ФП ЦЕ ЧТЕНС ОЕФ ОЙЮЕЗП, УРПУПВОПЗП УТБЧОЙФШУС РП ЬЖЖЕЛФЙЧОПУФЙ У РТПЗТБННЙТПЧБОЙЕН ОПЧЩИ ЛПНБОД. йЪ ЧУЕИ ЙОУФТХНЕОФПЧ РТПЗТБННЙТПЧБОЙС ДМС РПМШЪПЧБФЕМЕК AutoCAD ОБЙВПМЕЕ ДПУФХРЕО AutoLISP. оЕХЦЕМЙ ЛБЦДЩК РПМШЪПЧБФЕМШ AutoCAD ДПМЦЕО ХНЕФШ РТПЗТБННЙТПЧБФШ Ч AutoLISP? с УЮЙФБА, ЮФП ДПМЦЕО, Й ОБ РТПФСЦЕОЙЙ ЬФПК ЗМБЧЩ ЧЩ ХЪОБЕФЕ, РПЮЕНХ.

еУМЙ РЕТУРЕЛФЙЧБ ЪБОСФШУС РТПЗТБННЙТПЧБОЙЕН ЧБУ ОЕНОПЗП РХЗБЕФ, Х НЕОС ДМС ЧБУ ИПТПЫБС ОПЧПУФШ: ЕУМЙ ЧЩ НПЦЕФЕ ТБВПФБФШ Ч AutoCAD, ФП НПЦЕФЕ РТПЗТБННЙТПЧБФШ Ч AutoLISP. юФПВЩ РПЛБЪБФШ, ОБУЛПМШЛП ЬФП МЕЗЛП, ДБЧБКФЕ ОБРЙЫЕН РТПЗТБННХ РТСНП УЕКЮБУ:

1. ч ЛПНБОДОПК УФТПЛЕ AutoCAD ЧЧЕДЙФЕ УМЕДХАЭЕЕ: (defun C:OO()(setvar «osmode» 4143)) 2. хДБМЙФЕ ЧУЕ ХУФБОПЧЛЙ ПВЯЕЛФОПК РТЙЧСЪЛЙ ОБ ЧЛМБДЛЕ Object Snap (пВЯЕЛФОБС РТЙЧСЪЛБ) ДЙБМПЗПЧПЗП ПЛОБ Drafting Settings (тЕЦЙНЩ ТЙУПЧБОЙС). 3. чЧЕДЙФЕ Ч ЛПНБОДОПК УФТПЛЕ OO .

рПЪДТБЧМСА, ЧЩ ФПМШЛП ЮФП ОБРЙУБМЙ РТПЗТБННХ AutoLISP. юФПВЩ ХЧЙДЕФШ, ЛБЛ ПОБ ТБВПФБЕФ, РТПЧЕТШФЕ ЕЭЕ ТБЪ ХУФБОПЧЛЙ ДМС ПВЯЕЛФОПК РТЙЧСЪЛЙ. нЩ УОПЧБ ЧЕТОЕНУС Л ЬФПК РТПЗТБННЕ РПУМЕ ФПЗП, ЛБЛ С ТБУУЛБЦХ ОЕНОПЗП ФЕПТЙЙ. рПУМЕ РТПЮФЕОЙС ДБООПК ЗМБЧЩ ЧЩ ВХДЕФЕ РТЙДХНЩЧБФШ Й УПЪДБЧБФШ ЧУЕЧПЪНПЦОЩЕ ОПЧЩЕ ЖХОЛГЙЙ AutoLISP.

AutoLISP — НПЭОЩК ЙОУФТХНЕОФ, РТЙ РПНПЭЙ ЛПФПТПЗП ЧЩ НПЦЕФЕ ЪБ УЮЙФБООЩЕ НЙОХФЩ РЙУБФШ ОПЧЩЕ РПМШЪПЧБФЕМШУЛЙЕ ЛПНБОДЩ ДМС AutoCAD. оЕУНПФТС ОБ ФП, ЮФП У AutoCAD ЮБУФП ЙУРПМШЪХАФУС ДТХЗЙЕ СЪЩЛЙ РТПЗТБННЙТПЧБОЙС (УБНЩЕ ЙЪЧЕУФОЩЕ ЙЪ ОЙИ Visual Basic for Applications (VBA) Й C++), AutoLISP ПУПВЕООП РПМЕЪЕО ДМС РПМШЪПЧБФЕМЕК AutoCAD, ФБЛ ЛБЛ ПО ПУОПЧЩЧБЕФУС ОБ УПВУФЧЕООЩИ ЛПНБОДБИ AutoCAD. чПЪНПЦОП, ЬФП ОЕ УБНЩК УПЧЕТЫЕООЩК ЙЪ СЪЩЛПЧ РТПЗТБННЙТПЧБОЙС, ОП ЛБЛБС ТБЪОЙГБ, ЕУМЙ ЙН МЕЗЛП РПМШЪПЧБФШУС? с ЪОБЛПН У РТЙЪОБООЩН УРЕГЙБМЙУФПН — РТПЗТБННЙУФПН ОБ VBA, ОП Й ПО РПМШЪХЕФУС СЪЩЛПН AutoLISP ДМС ОЕЛПФПТЩИ РТПЗТБНН, ПФОПУСЭЙИУС Л AutoCAD.

сЪЩЛ РТПЗТБННЙТПЧБОЙС AutoLISP ЧРЕТЧЩЕ РПСЧЙМУС Ч AutoCAD R2.18. еЗП ТБООЕЕ РПСЧМЕОЙЕ — ПДОБ ЙЪ РТЙЮЙО, РП ЛПФПТЩН AutoCAD УФБМ УЕЗПДОС УБНПК ТБУРТПУФТБОЕООПК CAD-РТПЗТБННПК. уХЭЕУФЧПЧБОЙЕ СЪЩЛБ РТПЗТБННЙТПЧБОЙС ДБМП УППВТБЪЙФЕМШОЩН РПМШЪПЧБФЕМСН ЧПЪНПЦОПУФШ УХЭЕУФЧЕООП ХМХЮЫЙФШ AutoCAD РХФЕН ДПВБЧМЕОЙС ОПЧЩИ ЖХОЛГЙК. юБУФП ЬФЙ ЖХОЛГЙЙ Ч РПУМЕДХАЭЙИ ТЕМЙЪБИ УФБОПЧЙМЙУШ ЛПНБОДБНЙ, ОП ДБЦЕ ЕУМЙ ФБЛПЗП ОЕ РТПЙУИПДЙМП, AutoCAD УФБОПЧЙМУС ВПМЕЕ ХДПВОЩН, ЮЕН ЛПОЛХТЙТХАЭЙЕ РТЙМПЦЕОЙС. оЕУНПФТС ОБ РПСЧМЕОЙЕ, ЧРПУМЕДУФЧЙЙ, ДТХЗЙИ СЪЩЛПЧ РТПЗТБННЙТПЧБОЙС, AutoLISP РП-РТЕЦОЕНХ ПУФБЕФУС ЗМБЧОЩН УТЕДУФЧПН ДМС УПЪДБОЙС РПМШЪПЧБФЕМШУЛЙИ ЖХОЛГЙК AutoCAD.

AutoLISP ПФОПУЙФУС Л СЪЩЛХ LISP (List Processing), РПСЧЙЧЫЕНХУС Ч ЛПОГЕ 1950-И ЗПДПЧ. LISP ЮБУФП ХРПНЙОБЕФУС ЛБЛ ЧФПТПК ЙЪ УФБТЕКЫЙИ СЪЩЛПЧ РТПЗТБННЙТПЧБОЙС, ЧУЕ ЕЭЕ ЙУРПМШЪХАЭЙИУС. уБНЩН УФБТЩН ЙЪ УХЭЕУФЧХАЭЙИ УЮЙФБЕФУС Fortran. рПНЙНП ЙУРПМШЪПЧБОЙС Ч AutoCAD, LISP ФБЛЦЕ ЫЙТПЛП РТЙНЕОСЕФУС Ч РТПЗТБННЙТПЧБОЙЙ ЙУЛХУУФЧЕООПЗП ЙОФЕММЕЛФБ.

Visual LISP (VLISP ЙМЙ VLIDE) РПСЧЙМУС Ч AutoCAD 2000 Ч ЛБЮЕУФЧЕ ПУОПЧОПЗП УТЕДУФЧБ РТПЗТБННЙТПЧБОЙС AutoLISP. ч ОЕН РТЙУХФУФЧХЕФ ТБЪЧЙФБС УТЕДБ РТПЗТБННЙТПЧБОЙС У ЙОУФТХНЕОФБНЙ РПЙУЛБ ПЫЙВПЛ Й ЛПНРЙМСФПТПН, Б ФБЛЦЕ У ОБВПТПН ОПЧЩИ ЖХОЛГЙК, ЧЛМАЮБС ЙЪЧЕУФОЩЕ ЛБЛ ТЕБЛФПТЩ. оЕУНПФТС ОБ ФП, ЮФП С РТЕДУФБЧМСА ОЕЛПФПТЩЕ ЧПЪНПЦОПУФЙ ТЕДБЛФПТБ Visual LISP Ч ЬФПК ЛОЙЗЕ, С ОЕ НПЗХ ПУЧЕФЙФШ ЕЗП ДПУФБФПЮОП РПМОП. еУМЙ ЧЩ УФПМЛОЕФЕУШ УП УЛТЩФПК ПЫЙВЛПК Ч AutoLISP, ЧЩ УНПЦЕФЕ ХЪОБФШ П УРЕГЙБМШОЩИ ЧПЪНПЦОПУФСИ ТЕДБЛФЙТПЧБОЙС Ч Visual LISP Й ВПМШЫПН ОБВПТЕ ЕЗП ЖХОЛГЙК Ч УРТБЧПЮОПК УЙУФЕНЕ AutoCAD ЙМЙ РТЙ РПНПЭЙ ЧБЫЕК МАВЙНПК РПЙУЛПЧПК УЙУФЕНЩ УУЩМПЛ.


    чЩ НПЦЕФЕ РПМХЮЙФШ ДПУФХР Л ДПЛХНЕОФБГЙЙ ПВ AutoLISP, Visual LISP Й ЖПТНБФЕ Drawing Exchange File (DXF), ЕУМЙ Ч НЕОА AutoCAD ЧЩВЕТЕФЕ Help | Additional Resources | Developer Help (уРТБЧЛБ | дПРПМОЙФЕМШОЩЕ ТЕУХТУЩ | дПЛХНЕОФБГЙС ДМС ТБЪТБВПФЮЙЛПЧ).

рПУЛПМШЛХ ОЕЛПФПТЩЕ ЛПНБОДЩ Й НОПЗЙЕ ЙОУФТХНЕОФЩ Express Tools ОБРЙУБОЩ ОБ СЪЩЛЕ AutoLISP, ВПМШЫЙОУФЧП ЙЪ ОБУ РПУФПСООП РПМШЪХАФУС LISP-РТПЗТБННБНЙ, ОЕ ДПЗБДЩЧБСУШ ПВ ЬФПН. ч ДЙТЕЛФПТЙЙ C:\Program Files\AutoCAD 2007\Express УПДЕТЦБФУС 70 РТПЗТБНН ОБ AutoLISP, ЧЛМАЮБС УМЕДХАЭЙЕ РТПЗТБННЩ, ОБУФПМШЛП РПМЕЪОЩЕ, ЮФП ЧЩ НПЦЕФЕ УЮЙФБФШ ЙИ УПВУФЧЕООЩНЙ ЛПНБОДБНЙ AutoCAD:

  • aliasedit.lsp
  • aspace.lsp
  • attout.lsp
  • breakl.lsp
  • bscale.lsp
  • burst.lsp
  • dimassoc.lsp
  • flatten.lsp
  • layoutmerge.lsp
  • lman.lsp
  • overkill.lsp
  • saveall.lsp
  • tcase.lsp
  • textmask.lsp
  • txtexp.lsp

    рПЙУЛ РТПЗТБНН ОБ AutoLISP

    чЩ НПЦЕФЕ ОБКФЙ ДТХЗЙЕ РТПЗТБННЩ ОБ СЪЩЛЕ AutoLISP ОБ НОПЗПЮЙУМЕООЩИ йОФЕТОЕФ-УБКФБИ, Ч ЛОЙЗБИ, ЦХТОБМБИ, Б ФБЛЦЕ Ч ЛПНРШАФЕТБИ ЧБЫЙИ ДТХЪЕК Й ЛПММЕЗ. ч ЛБЮЕУФЧЕ ЪБНЕЮБФЕМШОПЗП ОБЮБМБ НПЦЕФЕ РПУЕФЙФШ УБКФ НЕЦДХОБТПДОПК ЗТХРРЩ РПМШЪПЧБФЕМЕК Autodesk User Group International РП БДТЕУХ www.AUGI.com. дТХЗЙЕ УБКФЩ РПСЧМСАФУС Й ЙУЮЕЪБАФ, РПЬФПНХ С ОЕ ВХДХ ЙИ ЪДЕУШ РЕТЕЮЙУМСФШ. ч ТЕЪХМШФБФЕ РПЙУЛБ Ч ЙОФЕТОЕФ ЧЩ ОБКДЕФЕ НЙММЙПОЩ РТПЗТБНН ОБ УПФОСИ ФЩУСЮ УБКФПЧ. нОПЗЙЕ ЙЪ ЬФЙИ РТПЗТБНН ВЕУРМБФОЩ, AutoLISP-РТПЗТБННЙУФЩ ЭЕДТП ДЕМСФУС ТЕЪХМШФБФБНЙ УЧПЕК ТБВПФЩ. (оЕ ЪБВЩЧБКФЕ ПВ ЬФПН, ЛПЗДБ УБНЙ ОБХЮЙФЕУШ РЙУБФШ РПМЕЪОЩЕ РТПЗТБННЩ.) рТПЧЕТСКФЕ ЙОЖПТНБГЙА ПВ БЧФПТУЛЙИ РТБЧБИ ДМС ЛБЦДПК РТПЗТБННЩ, Й ЧЩ ПВСЪБФЕМШОП ОБКДЕФЕ ФТЕВПЧБОЙС БЧФПТБ. оЕ ЪБВЩЧБКФЕ, РТПЗТБННЩ ОБ AutoLISP СЧМСАФУС ЙОФЕММЕЛФХБМШОПК УПВУФЧЕООПУФША ЙИ БЧФПТПЧ.

    рТПЗТБННЩ ОБ AutoLISP ВЩЧБАФ ЛБЛ РТПУФЩЕ, ФБЛ Й УМПЦОЩЕ, Й ЧУЕ ПОЙ ФТЕВХАФ ИПТПЫЕЗП ЪОБОЙС ЛПНБОД AutoCAD. чЩ ХЦЕ ЪОБЛПНЩ УП УФТХЛФХТПК ЛПНБОД AutoCAD, РПЬФПНХ ЗПФПЧЩ ОБЮБФШ РТПЗТБННЙТПЧБФШ Ч AutoLISP.

    оБРЙУБОЙЕ РТПЗТБНН AutoLISP

    с ОБЪЧБМ ЬФХ ЗМБЧХ «AutoLISP ОБ РТЙНЕТБИ», РПФПНХ ЮФП ДМС ФПЗП, ЮФПВЩ РПЛБЪБФШ ЛМАЮЕЧЩЕ УЧПКУФЧБ РТПЗТБННЙТПЧБОЙС, С ПРЕТЙТХА РТЙНЕТБНЙ ЛПДПЧ. ьФБ ЗМБЧБ ОЕ РТЕДОБЪОБЮЕОБ ДМС ПРЩФОЩИ РТПЗТБННЙУФПЧ, ПОБ ОБРЙУБОБ ДМС РПМШЪПЧБФЕМЕК AutoCAD. лПЗДБ С ЧРЕТЧЩЕ ТЕЫЙМ РПРТПВПЧБФШ AutoLISP, УУЩМЛБ, Л ЛПФПТПК С ПВТБФЙМУС, ОБЮЙОБМБУШ У ТБУУХЦДЕОЙК ПВ БФПНБИ, УРЙУЛБИ, МСНВДБ-ЧЩТБЦЕОЙСИ, ЖХОЛГЙСИ CONS Й MAPCAR , У РТЙНЕТБНЙ ДМЙОПК Ч ПДОХ УФТПЛХ, ЛПФПТЩЕ ДМС НЕОС ОЙЮЕЗП ОЕ ЪОБЮЙМЙ. х НЕОС ВЩМБ ПРТЕДЕМЕООБС ГЕМШ — ОБРЙУБФШ ЛПНБОДХ, ЛПФПТБС ВЩ БЧФПНБФЙЮЕУЛЙ РПНЕЭБМБ ПДЙО ЮЕТФЕЦ Ч ДТХЗПК. с ОЕ УНПЗ ТЕЫЙФШ ЪБДБЮХ ДП ФЕИ РПТ, РПЛБ ОЕ ТБУУНПФТЕМ УХЭЕУФЧХАЭЙЕ РТПЗТБННЩ Й ОЕ РПОСМ, ЛБЛ ПОЙ ТБВПФБАФ. чУРПНЙОБС П УПВУФЧЕООПН ПРЩФЕ, С УПВЙТБАУШ РТЙЧЕУФЙ ЧБН РТЙНЕТЩ РТПЗТБНН Й ПВЯСУОЙФШ, ЛБЛ ПОЙ ТБВПФБАФ. чУЕ ЮФП ПФ ЧБУ ФТЕВХЕФУС — ЧЧЕУФЙ ЙИ ВЕЪ ПЫЙВПЛ, РПРТПВПЧБФШ Й РТПЮЙФБФШ РПСУОЕОЙС. ьФП ФБЛ РТПУФП.

    нПС РЕТЧБС РТПЗТБННБ AutoLISP

      чРЕТЧЩЕ С РТЕРПДБЧБМ ПУОПЧЩ ТБВПФЩ Ч AutoCAD Ч 1989 ЗПДХ. с У УБНПЗП ОБЮБМБ ЪОБМ, ЮФП НОЕ РТЙДЕФУС ПГЕОЙЧБФШ ТБВПФЩ УФХДЕОФПЧ Ч ЬМЕЛФТПООПН ЧЙДЕ, ЮФПВЩ РТПЧЕТЙФШ ФПЮОПУФШ ЗЕПНЕФТЙЙ, РПЬФПНХ ЛБЦДХА ОЕДЕМА С ЪБЗТХЦБМ ЧУЕ ЮЕТФЕЦЙ. лПНБОДБНЙ DIST (дйуф) Й >DEFUN Й ЧЩРПМОСФШ ЛПНБОДЩ AutoCAD ЙЪ РТПЗТБННЩ AutoLISP. оП НПС РТПЗТБННБ ОЕ ТБВПФБМБ. рПУМЕ ЮБУПЧ ВЕЪХУРЕЫОЩИ РПРЩФПЛ С ПФЛТЩМ ЧУЕ РТПЗТБННЩ AutoLISP, ЛПФПТЩЕ УНПЗ ОБКФЙ, Ч ОБДЕЦДЕ, ЮФП ЛБЛБС-МЙВП ЙЪ ОЙИ ЙНЕЕФ ДЕМП У ЖБКМБНЙ ЮЕТФЕЦЕК. й С ПВОБТХЦЙМ ЙОФЕТЕУОХА ДЕФБМШ: ЕУМЙ Ч РТПЗТБННЕ ЙНЕЕФУС УУЩМЛБ ОБ ЙНС ЖБКМБ, Ч РХФЙ ЖБКМБ ЙНС ЖБКМБ Й РБРЛЙ ТБЪДЕМСАФУС ДЧПКОПК ПВТБФОПК ОБЛМПООПК ЮЕТФПК. оЕХЦЕМЙ ЙЪ-ЪБ ЬФПЗП С ОЕ НПЗ ЧУФБЧЙФШ ЮЕТФЕЦ? оЕХЦЕМЙ ЧУЕ ФБЛ РТПУФП?
      уТБЪХ УЛБЦХ: ДБ. с ВЩМ РПТБЦЕО! рТПЧЕТЛБ ЮЕТФЕЦЕК ДМС ФТЕИ ЛМБУУПЧ ОБЮЙОБАЭЙИ РЕТЕУФБМБ ВЩФШ РТПВМЕНПК РПУМЕ ФПЗП, ЛБЛ С ДПВБЧЙМ ЕЭЕ ЖХОЛГЙК Ч РТПЗТБННХ РТПЧЕТЛЙ. уФХДЕОФЩ ЧПЧТЕНС РПМХЮБМЙ УЧПЙ ТБВПФЩ, Б Х НЕОС ПУФБЧБМПУШ ВПМШЫЕ УЧПВПДОПЗП ЧТЕНЕОЙ, ЛПФПТПЕ С НПЗ РПФТБФЙФШ ОБ РПЧЩЫЕОЙЕ ЛБЮЕУФЧБ ПВХЮЕОЙС. дМС НЕОС AutoLISP — ЬФП, РТЕЦДЕ ЧУЕЗП, ЧПЪНПЦОПУФШ ЪБОЙНБФШУС ВПМЕЕ ЙОФЕТЕУОПК ТБВПФПК.

    с ИПЮХ, ЮФПВЩ ЧЩ ОБЮБМЙ РЙУБФШ РТПЗТБННЩ, ОП РТЙ ЬФПН ЙЪВЕЦБМЙ ОЕЛПФПТЩИ ТБУРТПУФТБОЕООЩИ ПЫЙВПЛ. дМС ЬФПЗП ЧЩ ДПМЦОЩ ЙНЕФШ РТЕДУФБЧМЕОЙЕ П УФТХЛФХТЕ РТПЗТБНН AutoLISP. ч РТПЗТБННЙТПЧБОЙЙ УФТХЛФХТБ РТПЗТБННЩ ОЕ НЕОЕЕ ЧБЦОБ, ЮЕН ЗТБННБФЙЛБ СЪЩЛБ.

  • лБЦДБС РТПЗТБННБ УПДЕТЦЙФ ПДОХ ЙМЙ ОЕУЛПМШЛП ЖХОЛГЙК AutoLISP, ФБЛЙИ ЛБЛ DEFUN , GETPOINT , + Й – .
  • йНС ЛБЦДПК ЖХОЛГЙЙ РТЕДЧБТСЕФУС ПФЛТЩЧБАЭЕК УЛПВЛПК.
  • лБЦДПК ПФЛТЩЧБАЭЕК УЛПВЛЕ ДПМЦОБ УППФЧЕФУФЧПЧБФШ ЪБЛТЩЧБАЭБС УЛПВЛБ.
  • рТПВЕМЩ Й ЛБЧЩЮЛЙ ЙУРПМШЪХАФУС ДМС ТБЪДЕМЕОЙС ЛПНРПОЕОФПЧ ЧОХФТЙ УЛПВПЛ.
  • еУМЙ ОЕПВИПДЙНЩ БТЗХНЕОФЩ, ПОЙ ХЛБЪЩЧБАФУС РПУМЕ ЙНЕОЙ ЖХОЛГЙЙ.

    тБУУНПФТЙН Ч ЛБЮЕУФЧЕ РТЙНЕТБ ЧЩЮЙУМЙФЕМШОХА ЖХОЛГЙА. рПУЛПМШЛХ ЖХОЛГЙС ДЕМЕОЙС Ч AutoLISP ПВПЪОБЮБЕФУС ОБЛМПООПК ЮЕТФПК, УЙОФБЛУЙУ ДМС ДЕМЕОЙС ПДОПЗП ЮЙУМБ ОБ ДТХЗПЕ ЧЩЗМСДЙФ УМЕДХАЭЙН ПВТБЪПН: (/ 4.0 2) .

    ъБ ПФЛТЩЧБАЭЕК УЛПВЛПК УМЕДХЕФ ЖХОЛГЙС / , ЪБ ОЕК, РП ЛТБКОЕК НЕТЕ, ПДЙО РТПВЕМ, ЪБ ЛПФПТЩН, Ч УЧПА ПЮЕТЕДШ, ДЧБ БТЗХНЕОФБ, ТБЪДЕМЕООЩИ РТПВЕМБНЙ — ЮЙУМЙФЕМШ 4.0 Й ДЕМЙФЕМШ 2, ЪБ ОЙНЙ УМЕДХЕФ ЪБЛТЩЧБАЭБС УЛПВЛБ. ьФБ ЖХОЛГЙС НПЦЕФ ВЩФШ РЕТЕЧЕДЕОБ ЛБЛ «ТБЪДЕМЙФШ 4.0 ОБ 2». дТХЗЙЕ ЖХОЛГЙЙ, ФБЛЙЕ ЛБЛ (* 4.0 2) , (+ 4.0 2) Й (- 4.0 2) ЙНЕАФ БОБМПЗЙЮОЩК ЖПТНБФ. ьФБ УФТХЛФХТБ ПФМЙЮБЕФУС ПФ ФПК, Л ЛПФПТПК ЧЩ РТЙЧЩЛМЙ, ЙЪХЮБС НБФЕНБФЙЛХ. оЕ РЩФБКФЕУШ ЙУРПМШЪПЧБФШ (2 + 2) , ФБЛБС ЖХОЛГЙС ОЕ ВХДЕФ ТБВПФБФШ, ФБЛ ЛБЛ РЕТЧЩК ЬМЕНЕОФ Ч УЛПВЛБИ — ГЕМПЕ ЮЙУМП, Б ОЕ ЖХОЛГЙС.

    чЧПД РТПЗТБНН Ч AutoCAD

    чЩ НПЦЕФЕ РТЙДХНБФШ МАВХА РТПЗТБННХ, ОП ДП ФЕИ РПТ, РПЛБ ЧЩ ОЕ ЧЧЕДЕФЕ ЕЕ Ч AutoCAD, ЧБЫБ РТПЗТБННБ ВХДЕФ ВЕУРПМЕЪОПК. л УПЦБМЕОЙА, ОЕФ УРПУПВБ ОБРТСНХА ЪБЗТХЪЙФШ ЧБЫЙ НЩУМЙ Ч AutoCAD, РПЬФПНХ РТЙДЕФУС ЧПУРПМШЪПЧБФШУС ЛМБЧЙБФХТПК. еУФШ ОЕУЛПМШЛП УРПУПВПЧ ЪБУФБЧЙФШ AutoCAD ЧЩРПМОЙФШ РТПЗТБННХ ОБ СЪЩЛЕ AutoLISP:

  • чЧЕУФЙ РТПЗТБННХ Ч ЛПНБОДОПК УФТПЛЕ.
  • ъБЗТХЪЙФШ ФЕЛУФПЧЩК ЖБКМ, УПДЕТЦБЭЙК ЛПД AutoLISP.
  • йУРПМШЪПЧБФШ ЖХОЛГЙА ЪБЗТХЪЛЙ Ч ТЕДБЛФПТЕ Visual LISP.

    чЧПД Ч ЛПНБОДОПК УФТПЛЕ ПВЩЮОП РТЙНЕОСЕФУС ФПМШЛП ДМС ФЕУФЙТПЧБОЙС ЛПТПФЛЙИ УФТПЛ ЛПДБ. фЕН ОЕ НЕОЕЕ С ЮБУФП РЙЫХ ФБЛЙН УРПУПВПН ПЮЕОШ ЛПТПФЛЙЕ РТПЗТБННЩ, ПУПВЕООП ЛПЗДБ ИПЮХ УДЕМБФШ ЮФП-ФП УРЕГЙЖЙЮЕУЛПЕ ДМС ПРТЕДЕМЕООПЗП ЮЕТФЕЦБ Й ОЕ ЧЙЦХ УНЩУМБ УПИТБОСФШ РТПЗТБННХ. оЕДБЧОП С ФБЛЙН УРПУПВПН УПЪДБЧБМ РПМЙМЙОЙЙ Ч ЧЙДЕ ПЛТХЦОПУФЕК. оЕ ДХНБА, ЮФП НОЕ ЕЭЕ ТБЪ РТЙДЕФУС ЪБОЙНБФШУС ФЕН ЦЕ, РПЬФПНХ С РТПУФП ЧЧЕМ РТПЗТБННХ Ч ЛПНБОДОПК УФТПЛЕ. лПЗДБ С ЪБЛПОЮЙМ УЕБОУ ТБВПФЩ Ч AutoCAD, РТПЗТБННБ ФБЛЦЕ ЪБЧЕТЫЙМБ ТБВПФХ.

    ъБЗМБЧОЩЕ ЙМЙ УФТПЮОЩЕ?

      ч AutoLISP ТЕЗЙУФТ ЙНЕЕФ ЪОБЮЕОЙЕ ФПМШЛП Ч ОЕУЛПМШЛЙИ УМХЮБСИ.
    • лПЗДБ ЧЩ РПНЕЭБЕФЕ ХРТБЧМСАЭЙК УЙНЧПМ, ФБЛПК ЛБЛ УЙНЧПМ, ПВПЪОБЮБАЭЙК ОБЮБМП УФТПЛЙ, Ч ЛБЧЩЮЛБИ, ОБРТЙНЕТ, Ч РПДУЛБЪЛЕ ПО ДПМЦЕО ВЩФШ УФТПЮОЩН: «\nSelect point: «.
    • лПЗДБ Ч РТПГЕДХТЕ ПФЛТЩФЙС ЖБКМБ ЧЩ ХЛБЪЩЧБЕФЕ, ЮФП ИПФЙФЕ УДЕМБФШ (ЮЙФБФШ, ОБРЙУБФШ ЙМЙ ДПРПМОЙФШ), ЧЩ ДПМЦОЩ ФБЛЦЕ РПМШЪПЧБФШУС УФТПЮОЩНЙ УЙНЧПМБНЙ, ОБРТЙНЕТ: (open «C:\\file.dwg» «r») .
      дТХЗЙНЙ УМПЧБНЙ, ЧЩ УБНЙ ТЕЫБЕФЕ, ЙУРПМШЪПЧБФШ ЪБЗМБЧОЩЕ ЙМЙ УФТПЮОЩЕ УЙНЧПМЩ. зМБЧОПЕ, ВХДШФЕ РПУМЕДПЧБФЕМШОЩ, ЮФПВЩ ЧРПУМЕДУФЧЙЙ ОЕ ЪБРХФБФШУС УБНПНХ.

    дБЧБКФЕ Ч РЕТЧХА ПЮЕТЕДШ ТБУУНПФТЙН РТПГЕДХТХ ЧЧПДБ Ч ЛПНБОДОПК УФТПЛЕ.

    чЧПД Ч ЛПНБОДОПК УФТПЛЕ

    чЕТОЕНУС Л РТПЗТБННЕ, ТБУУНПФТЕООПК ЧП ЧУФХРМЕОЙЙ Л ЬФПК ЗМБЧЕ. юФПВЩ ЧЧЕУФЙ ЬФХ РТПЗТБННХ ОБ AutoLISP Ч ЛПНБОДОПК УФТПЛЕ, ЧЩ РТПДЕМБМЙ УМЕДХАЭЕЕ:

  • оБВТБМЙ Ч ЛПНБОДОПК УФТПЛЕ (defun C: OO()(setvar «osmode» 4143)) . еУМЙ ЧЩ ОЕ ДПРХУФЙМЙ ПЫЙВПЛ, Ч ЛПНБОДОПК УФТПЛЕ РПСЧЙМБУШ РПДУЛБЪЛБ C:OO .
  • юФПВЩ РПЧЕТЙФШ РТПЗТБННХ, ЧЩ ПЮЙУФЙМЙ УХЭЕУФЧХАЭЙЕ ОБУФТПКЛЙ ПВЯЕЛФОПК РТЙЧСЪЛЙ.
  • юФПВЩ РТЙНЕОЙФШ ОПЧХА, УПЪДБООХА ЧБНЙ ЛПНБОДХ, ЧЩ ОБВТБМЙ пп Ч ЛПНБОДОПК УФТПЛЕ. ч ПФЧЕФ ЧЩ ДПМЦОЩ ВЩМЙ РПМХЮЙФШ 4143.
  • лПЗДБ ЧЩ УОПЧБ РТПЧЕТЙМЙ ОБУФТПКЛЙ ПВЯЕЛФОПК РТЙЧСЪЛЙ, ЧЩ ДПМЦОЩ ВЩМЙ ХЧЙДЕФШ УМЕДХАЭЙЕ ХУФБОПЧЛЙ ДМС ПВЯЕЛФОПК РТЙЧСЪЛЙ: End (лпо), Mid (ует), Cen (гео), Nod (хъе), Int (фчу), Ext (ртп).

    чЩ ФПМШЛП ЮФП ПРЙУБМЙ ОПЧХА ЛПНБОДХ AutoCAD РПД ЙНЕОЕН OO. лПЗДБ ЧЩ ЕЕ ЧЧПДЙФЕ, ЪОБЮЕОЙЕ УЙУФЕНОПК РЕТЕНЕООПК OSMODE, ЛПФПТБС ХРТБЧМСЕФ ПВЯЕЛФОПК РТЙЧСЪЛПК, НЕОСЕФУС ОБ 4143. ьФП НПЕ УФБОДБТФОПЕ ЪОБЮЕОЙЕ ДМС ЬФПК РЕТЕНЕООПК. нОЕ ОТБЧЙФУС ЬФБ ЛПНБОДБ, РПФПНХ ЮФП С ЮБУФП ЙЪНЕОСА ХУФБОПЧЛЙ РТЙЧСЪЛЙ ДМС ОЕУЛПМШЛЙИ ПРЕТБГЙК У ЛБЛЙН-МЙВП ПВЯЕЛФПН. лПЗДБ С ИПЮХ ЧЕТОХФШ УЧПЙ ПВЩЮОЩЕ ОБУФТПКЛЙ, ОБНОПЗП ВЩУФТЕЕ ЧЧЕУФЙ OO, ЮЕН ПФЛТЩЧБФШ ДЙБМПЗПЧПЕ ПЛОП Drafting Settings (тЕЦЙНЩ ТЙУПЧБОЙС).

      уЙУФЕНОЩЕ РЕТЕНЕООЩЕ Ч AutoCAD (ЙОПЗДБ ЙИ ЙНЕОХАФ setvars) ХРТБЧМСАФ НОПЗЙНЙ БУРЕЛФБНЙ РТПЗТБННЩ. ъОБЮЕОЙС ЧУЕИ УЙУФЕНОЩИ РЕТЕНЕООЩИ AutoCAD (Б ЙИ Ч AutoCAD 2007 ПЛПМП 550) НПЦОП ХЧЙДЕФШ РТЙ РПНПЭЙ ЖХОЛГЙЙ GETVAR Ч AutoLISP. ъОБЮЕОЙС НОПЗЙИ РЕТЕНЕООЩИ ФБЛЦЕ НПЦОП ЙЪНЕОЙФШ ЖХОЛГЙЕК SETVAR . л ФБЛЙН УЙУФЕНОЩН РЕТЕНЕООЩН, ОБРТЙНЕТ, ПФОПУЙФУС OSMODE. юЕН МХЮЫЕ ЧЩ ЪОБЛПНЩ У УЙУФЕНОЩНЙ РЕТЕНЕООЩНЙ, ФЕН ЬЖЖЕЛФЙЧОЕЕ УНПЦЕФЕ РПМШЪПЧБФШУС AutoLISP. чЩ НПЦЕФЕ ХЧЙДЕФШ ЧУЕ РЕТЕНЕООЩЕ, ЕУМЙ ЧЧЕДЕФЕ Ч ЛПНБОДОПК УФТПЛЕ _setvar ? * ЙМЙ ПВТБФЙФЕУШ Л УРТБЧПЮОПК УЙУФЕНЕ AutoCAD, ЮФПВЩ РПМХЮЙФШ УРЙУПЛ РЕТЕНЕООЩИ Ч БМЖБЧЙФОПН РПТСДЛЕ.

    уХЭЕУФЧХЕФ ФПМШЛП ПДОБ РТПВМЕНБ. ьФБ ПФМЙЮОБС ЛПНБОДБ ИТБОЙФУС Ч ПРЕТБФЙЧОПК РБНСФЙ, РПЬФПНХ ЧЩ ОЕ УНПЦЕФЕ ЕК ЧПУРПМШЪПЧБФШУС, ЕУМЙ ПФЛТПЕФЕ ДТХЗПК ЮЕТФЕЦ, Й ПОБ РТПРБДЕФ, ЛПЗДБ ЧЩ ЪБЛТПЕФЕ ФЕЛХЭЙК ЖБКМ ЮЕТФЕЦБ. еУМЙ ЧЩ ИПФЙФЕ ЕЭЕ ТБЪ ЧПУРПМШЪПЧБФШУС ЬФПК ЛПНБОДПК, ЧЩ ДПМЦОЩ ЕЕ УПИТБОЙФШ.

    Функции autolispа

    Глава 12. AutoLISP в среде Visual LISP.

    Мы уже рассмотрели некоторые функции-AutoLISP, встроенные в систему AutoCAD (setq, load, command). В этом разделе освещаются остальные функции.

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

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

    Вопросы создания функций пользователя рассмотрены в разд. 12.5, а особенности работы с объектами рисунка AutoCAD — в разд. 12.6.


    Полный перечень функций AutoLISP (в алфавитном порядке) приведен в приложении 8.

    К арифметическим относятся следующие функции (вместе с описанием функций приводится их синтаксис):

    • (+ [ [ . [ ] . ] ]) — сложение любого количества чисел;
    • (- [ [ . [ ] . ]]) — вычитание из первого числа суммы любого количества чисел;
    • (* [ [ . [ ] . ]]) — перемножение любого количества чисел;
    • (/ [ [ . [ ] . ]]) -деление первого числа на произведение любого количества чисел;
    • (1+ ) — увеличение числа на 1;
    • (1- ) — уменьшение числа на 1;
    • (

    ) — дополнение числа до — 1;

  • (abs ) — абсолютная величина числа.
  • Все арифметические функции допускают работу с аргументами целого или вещественного типа. Если все аргументы целые, то возвращается целое значение. Если хотя бы один аргумент вещественный, то результатом будет вещественное число. Некоторые арифметические функции допускают вызов без аргументов — в этом случае возвращается 0 (целое число).

    (+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.

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

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

    • (= [ . [ ]. ]) — проверка на равенство любого количества аргументов (рекомендуется использовать для чисел или строк);
    • (/= [ . [ ]. ]) — проверка на неравенство любого количества аргументов (рекомендуется использовать для чисел или строк);
    • ( [ . [ ]. ]) — проверка на возрастание любого количества аргументов, слева направо (для чисел или строк);
    • (> [ . [ ]. ]) -Проверка на убывание любого количества аргументов, слева направо (для чисел или строк);
    • ( [ . [ ]. ]) — Проверка на неубывание любого количества аргументов, слева направо (для чисел или строк);
    • (>= [ . [ ]. ]) — Проверка на не возрастание любого количества аргументов, слева направо (для чисел или строк).

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

    (> 2 2 30) — возвращает nil ;

    (>= «qa» «q») — возвращает T.

    Следующие функции выполняют логические операции:

    • (and [ [ . [ ]. ]]) — операция логического «и» для любого количества аргументов (все, что отлично от nil, рассматривается как т);
    • (or [ [ . [ ]. ]]) — операция ло-гического «или» для любого количества аргументов (все, что отлично от 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:

    Типы аргументов: любые.

    Возвращаемое значение: вычисленное значение , если значение отлично от nil (nil в логических операциях используется как «ложь»); или значение , если значение равно nil (когда опущено, тогда вместо возвращается 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 ( — возвращает строку «а опущено);

    (if nil «Point») — возвращает nil (т. к. всегда ложно).

    Если функция if используется для выполнения по условию не одного выражения, а нескольких, то эти выражения следует объединить с помощью функции рrоgп (иначе будет синтаксическая ошибка, вызванная неправильным количеством аргументов при обращении к функции if):

    Функция объединяет несколько (не менее двух!) выражении в одно, когда по синтаксису языка AutoLISP может использоваться только одно (как в функции if).

    Типы аргументов: любые.

    Рассмотрим использование функции progn на таком примере. Пусть при выполнении условия (> а b) нужно выполнить выражения (setq с -1), (setq d (-cab)) и (* d b) , а при невыполнении условия — выполнить выражения (setq с 2), (setq d (* а Ь) ) И (* d с).

    Листинг 12.4. Пример совместного использования функций if и progn

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

    Условная операция типа case с любым количеством условий осуществляется с помощью функции cond:

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

    Возвращаемое значение функции cond — последнее вычисленное выражение. Если вычисляемое выражение отсутствует (не задано в списке), то возвращается результат вычисления последнего аргумента . Если аргументы функции cond не заданы, то возвращается nil.

    (cond) — возвращает nil ;

    (cond (14)) — возвращает 14 .

    Впрочем, использование функции cond с неполным количеством аргументов не имеет особого смысла.

    Рассмотрим задачу: переменной mycolor нужно присвоить текстовое значение с наименованием одного из основных цветов AutoCAD («красный», «желтый», «зеленый», «голубой», «синий») в зависимости от текущего значения переменной сс, которая принимает значения 1, 2, 3, 4, 5. В случае если значение переменной ее оказалось отличным от перечисленных, то переменной mycolor нужно присвоить «» (пустая строка).

    Листинг 12.5. Пример 1 использования функции cond

    (setq mycolor (cond

    Функция setq присваивает переменной mycolor результат вычисления функции cond. Значение, возвращаемое функцией cond, вычисляется по следующей схеме. Сначала рассматривается список, заданный в качестве первого аргумента- ((= cc 1) «красный») — и проверяется условие, являющееся первым элементом этого списка. Если оказалось, что значение переменной cc равно 1 и, значит, первое условие возвращает «истину», то дальнейшее рассмотрение аргументов функции cond не выполняется, а в качестве возвращаемого значения принимается «красный». Если первое условие не вычислилось как «истина», то проверяется второе условие и т. д. В качестве последнего, шестого, условия стоит т (т. е. «истина» при любых значениях), поэтому, если значение переменной cc не совпало с 1, 2, 3, 4, 5, то в качестве возвращаемого значения функции cond будет принято «» (пустая строка).

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

    Листинг 12.6. Пример 2 использования функции cond

    ((= cc 1) (setq abc «красный»)

    (command «_PLINE» «-50,120.45» «97.66,23.124» «45.7,800» «_С»)

    ((= cc 2) (setq abc «желтый»)

    (command «_CIRCLE» «-50,120.45» «100»)

    В этом примере функция 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 — см. разд. 12.3). Однако в данном примере функция 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 проверяет равенство двух аргументов (аналогична функции =):

    Типы аргументов: любые.

    Тип возвращаемого значения: логическое (т, если значения аргументов совпали, и nil, если не совпали).

    (eq -10.0 -10) — возвращает т ;

    (eq о 3) — возвращает nil ;

    (eq «abc» «АBC») — возвращает nil .

    Функция equal проверяет равенство двух объектов (для чисел и списков из числовых величин равенство проверяется в пределах допуска):

    Типы аргументов: любые.

    Тип возвращаемого значения: логическое (т, если абсолютная величина разности аргументов не превосходит значение аргумента , и 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: значение , когда последнее вычисленное значение аргумента отлично от nil. При неудачном задании цикл, организуемый с помощью функции while, может оказаться бесконечным.

    Рассмотрим следующий пример. Пусть надо вычислить значение n! (факториал), т. е. произведение целых чисел от 1 до n. В данном разделе восклицательный знак используется как знак функции факториала.

    Листинг 12.7. Пример использовании функции while (вычисление факториала)

    (setq i 1 factorial 1)

    (setq factorial (* factorial i))

    Рассмотрим работу примера, когда число n равно 11 (т. е. вычисляется 11!).

    В программе используются переменные i (это переменная, являющаяся счетчиком цикла) и factorial (переменная, которая накапливает произведение чисел, формирующее факториал). Перед входом в цикл они получают начальные значения — соответственно, 1 и 1 (по определению 1! считается равным 1).

    Функция while проверяет условие (

    Далее снова передается управление на вход в цикл (уже при i=2). Проверка условия опять дает результат «истина», поэтому i получает значение 3 (2+1), a factorial — 6 (2*3). И так далее, пока i не станет равным n (11) и программа покинет цикл, не выполняя внутренних операций. Результат: при n=11 factorial=39, 916,800 (запятые разделяют триады цифр).

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

    Типы аргументов: — целое число (имеют смысл только положительные числа), — любое выражение. После аргумента могут идти другие выражения, которые нужно выполнить внутри цикла.

    Возвращаемое значение — значение последнего вычисленного выражения. Если аргумент имеет нулевое или отрицательное значение, или после аргумента не заданы выражения, то функция repeat возвращает nil.

    Переработаем предыдущий пример (см. листинг 12.7) — вместо while воспользуемся функцией repeat.

    Листинг 12.8. Пример использования функции repeat (вычисление факториала) I

    (setq i 1 factorial 1)

    (setq factorial (* factorial i))

    Поскольку входные значения i=1 и factorial = l! =1, то остается умножить factorial на 2, 3, . , n. Количество таких умножении равно n-1, что на языке AutoLISP записывается как (i- n). Остальное работает как в предыдущем примере.

    К основным вычислительным функциям относятся следующие функции:

    • (fix ) — усечение числа до целого (отбрасывается дробная часть);
    • (rem [ [ . [ ] . ]]) — получение остатка от деления аргументов на , затем остатка от деления результата на аргумент и т. д.;
    • (mах [ [ . [ ] . ]]) — определение максимального из чисел;
    • (min [ [ . [ ] . ]]) — определение минимального из чисел;
    • (gcd ) — вычисление наибольшего общего делителя для двух положительных целых чисел;
    • (angle ) — вычисление угла, в радианах, между осью Х текущей системы координат и вектором, идущим из точки заданной аргументом в точку заданную аргументом ;
    • (distance ) — вычисление расстояния между двумя точками, заданными аргументами и ;
    • (sqrt ) — вычисление квадратного корня;
    • (sin ) — вычисление синуса угла;
    • (cos ) — вычисление косинуса угла;
    • (atan [ ]) — вычисление арктангенса; если второй аргумент опущен, то вычисляется арктангенс от первого аргумента ; если заданы оба аргумента, то вычисляется арктангенс частного от деления первого аргумента на второй / ; если аргумент равен нулю, то возвращается угол +pi/2 или -pi/2 (знак выбирается по знаку аргумента );
    • (ехр ) — вычисление натурального антилогарифма- результата возведения в степень постоянной е (2.71828);
    • (expt ) — возведение числа в степень;
    • (log ) — вычисление натурального логарифма.

    (fix -10.083) — возвращает -10;

    (fix 40.45) — возвращает 40;

    (rem 14 2) — возвращает о (результат целый, т. к. оба аргумента целые);

    (rem 12.9 3.5) — возвращает 2.4;

    (max 7 3.4 2.0092) — возвращает 7.о (результат вещественный, поскольку есть вещественные аргументы);

    (min 7 3.4 2.0092) — возвращает 2.0092;

    (gcd 42 12) — возвращает б;

    (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 [ [ . [ ]. ]]) — вычисление побито вого «и» для списка целых чисел;
    • (logior [ [ . [ ]. ]]) — вычисление побито-вого «или» для списка целых чисел;
    • (lsh [ [ ] ]) — вычисление побитового сдвига целого числа;
    • (Boole [ . ] ]) — универсальная побитовая булева функция.

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

    Функция logand (побитовое «и») работает следующим образом. Каждое целое число может быть представлено в двоичном виде (иначе говоря, в виде суммы степеней числа 2, в которой перед степенью 2 стоит множитель 0 или 1; показатель степени в данной сумме может быть от 0 до 30). Например:

    5 = 1*2^0 + 0*2^1 + 1*2^2 = 101 2 , 3 = 1*2^0 + 1*2^1 + 0*2^2 = 11 2

    31-й (старший) разряд в таком представлении отводится под знак (минусу соответствует 1, плюсу соответствует 0). После перевода всех чисел в двоичное представление, выполняется поразрядная (побитовая) операция «и» по следующему правилу:

    (logand 0 0)= (logand 1 0)= (logand 0 1)= 0; (logand 1 1) = 1.

    Если аргументы не заданы, то возвращается 0. Если задан только один аргумент, то возвращается .

    (logand 3 5) — возвращает 1.

    Функция logior (побитовое «или») работает по следующему правилу:

    (logior 1 0)= (logior 0 1)= (logior 1 1)= 1; (logior 0 0) = 0.

    Если аргументы не заданы, то возвращается 0. Если задан только один аргумент, то возвращается .

    (logior 3 5) — возвращает 7;

    (logior 2) — возвращает 2.

    Побитовый сдвиг (функция lsh ) выполняется для двоичного представления чисел (по поводу двоичного представления см. функцию logand ). Побитовый сдвиг выполняется влево, если аргумент положителен, и вправо, если — отрицателен. Целые числа могут иметь не более чем 32 бита (нумерация битов от 0 для младшего разряда до 31 — этот разряд является знаковым), поэтому если старшие разряды при сдвиге влево выходят за 31-й разряд, то они теряются. При сдвиге вправо младшие разряды теряются.

    Если аргументы не заданы, то возвращается о. Если задан только один аргумент или аргумент равен о, то возвращается .

    (lsh 2 l) — возвращает 4;

    (lsh 3 30) — возвращает -1073741824.

    В функции Boole аргумент должен иметь значение от 0 до 15, что соответствует 16-ти вариантам булевых функции. Остальные аргументы — произвольные целые числа.

    Номер любой булевой функции (они все двуместные, т. е. имеют два аргумента, каждый из которых может быть 0 или 1) кодируется следующим образом: если функция для пары (1 1) возвращает 1, то к ее номеру добавляется 1=2^0; если функция для (1 0) возвращает 1, то добавляется 2=2^1; если функция для (0 1) возвращает 1, то добавляется 4=2^2; если функция для (0 0) возвращает 1, то добавляется 8=2^3. При таком кодировании рассмотренные выше функции logand и logior получат номера 1 и 7.

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

    Если заданы только два аргумента ( и ), то возвращается .

    (Boole 15 -3 45) возвращает — l;

    (Boole 8 16 17) — возвращает — 18.

    Функция type позволяет определять тип символа AutoLISP:

    Тип аргумента: (имя функции или переменной).

    Если аргумент не является именем функции или переменной с присвоенным значением, то возвращается nil. Другие варианты возвращаемого значения:

    • ENAME — имя примитива AutoCAD;
    • EXRXSUBR — имя приложения ObjectARX;
    • FILE — указатель (дескриптор) файла;
    • INT — целое число;
    • LIST — список;
    • PAGETB — таблица диспетчера страничной организации памяти;
    • PICKSET — набор выбора;
    • REAL — вещественное число;
    • SAFEARRAY — безопасный массив;
    • STR — строка;
    • SUBR — встроенная функция AutoLISP;
    • SYM символ;
    • VARIANT — вариант;
    • USUBR — пользовательская функция AutoLISP;
    • VLA-объект — объект Visual LISP, использующий технологию ActiveX.

    Некоторые из перечисленных вариантов возвращаемого значения доступны только при использовании других средств разработки приложений. Типы данных, доступные в Visual LISP, приведены в разд. 12.2.

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

    Функция rtos, преобразующая вещественное число в строку, имеет следующие аргументы:

    • — вещественное или целое число;
    • — целое (номер режима представления вещественных чисел);
    • — количество десятичных знаков в представлении вещественных чисел.

    Аргументы и имеют тот же смысл и принимают те же значения, что и системные переменные LUNITS и LUPREC. Если аргументы и опущены, то в качестве их значений принимаются текущие значения LUNITS и LUPREC. На форму возвращаемого значения может оказывать влияние системная переменная UNITMODE.

    Допустимые значения аргумента :

    • 1 — научный;
    • 2 — десятичный;
    • 3 — инженерный (футы и дюймы);
    • 4 — архитектурный (футы и дюймы);
    • 5 — дробный.

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

    (rtos 10.9453 1 3) — возвращает «1.095Е+01»;

    (rtos 10.9453 2 3) — возвращает «10.945».

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

    Аргументы функции angtof: строка, представление > — целое число. Значения аргумента соответствуют значениям системной переменной AUNITS. Если аргумент опущен, то в качестве его значения принимается текущее значение переменной AUNITS.

    Допустимые значения аргумента :

    • 1 — градусы;
    • 2 градусы, минуты, секунды;
    • 3 — грады;
    • 4 — радианы;
    • 5 — топографические единицы.

    Возвращается вещественное значение угла в радианах, для которого аргумент является строковым представлением (возможно, в другом формате представления углов). Если аргумент задан в неправильном формате, то возвращается 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 является обратной по отношению к функции rtos .

    Аргументы: — строка, представляющая число в одном из форматов; — целое число, значения которого соответствуют значениям системной переменной LUNITS (см. описание функции rtos). Если аргумент опущен, то в качестве его значения принимается текущее значение системной переменной LUNITS.

    Возвращаемое значение: вещественное число. Если аргумент имеет неправильную структуру, то возвращается nil.

    (distof «l» 2) — возвращает 1.0;

    (distof «1.0945E+01» l) — возвращает 10.945.

    Функция trans преобразует координаты точки из одной системы координат (СК) в другую. Аргументы функции:

    • — точка (список из двух или трех чисел, соответствующий двумерной или трехмерной точке);
    • — код СК, в которой аргументом задана точка (т. е. СК, из которой нужно преобразовать точку), может быть целым числом или именем примитива AutoCAD;
    • — код СК, в которую нужно преобразовать точку, заданную аргументом , может быть целым числом или именем примитива AutoCAD;
    • — необязательный аргумент, если он задан и отличен от nil (например, т), то меняет интерпретацию аргумента . В этом случае список из двух или трех чисел рассматривается не как координаты точки, а как координаты вектора перемещения.

    Аргументы и могут принимать следующие значения:

    • имя примитива (в том виде, в каком оно возвращается функциями ssname, entsel, nentsel, entnext, entlast);
    • трехмерный вектор выдавливания (вектор нормали к плоскости);
    • цифровой код от 0 до 3 (объясняется ниже).


    Цифровой код системы координат может принимать такие значения:

    • 0 — мировая СК (МСК);
    • 1 — текущая СК (ТСК);
    • 2 — экранная СК (ЭСК);
    • 3 — экранная СК листа (ЭСКЛ).

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

    Коды 0 и l могут использоваться в аргументах и в любых сочетаниях. Это означает, что если = 0, то аргумент может быть или любым цифровым кодом (от 0 до 3), или именем примитива, или вектором выдавливания; аналогично: если = о, то аргумент может быть или любым цифровым кодом (от 0 до 3), или именем примитива, или вектором выдавливания.

    Цифровой код 2 сочетается с разными вариантами, но его интерпретация зависит от цифрового кода другой СК. Если вторая СК имеет код 0 или l, то первая СК (с кодом 2) является ЭСК текущего видового экрана. Если вторая СК имеет код з, то первая СК (с кодом 2) является ЭСК текущего видового экрана в пространстве модели.

    Цифровой код 3 (ЭСКЛ) используется только в паре с цифровым кодом 2 другой СК (разобран в предыдущем абзаце).

    Имя примитива в качестве аргумента используется в том случае. когда координаты точки, хранящейся вместе с примитивом (например, начальная или конечная точки отрезка, центр окружности, вершина полилинии и т. п.), нужно пересчитать из системы координат объекта (СКО) в другую СК. В некоторых операциях (например, при работе с функцией entmake) возникает необходимость пересчитать точку в СКО — здесь имя примитива будет фигурировать в качестве аргумента .

    Некоторые объекты (например, трехмерные полилинии) не имеют особой СКО и хранят свои данные в МСК.

    Свои преимущества имеет и способ, когда трехмерный вектор выдавливания применяется в качестве аргументов или (например, при проектировании объекта на плоскость с известным вектором нормали). Этот способ не может использоваться для тех объектов, у которых в качестве СКО фигурирует МСК.

    Возвращаемым значением функции trans является список из трех координат точки (или вектора перемещения) в новой СК. Если значения аргументов и заданы противоречиво, то возвращается nil (например, если функция trans вызывается с цифровым кодом СК, равным 3, из пространства модели, а не из пространства листа).

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

    Если задан аргумент и его значение отлично от nil (т. е. аргумент интерпретируется не как точка, а как вектор перемещения), то добавляемая координата Z получает значение 0. Если признак не задан или равен nil, то значение координаты Z зависит от аргумента и выбирается по табл. 12.1.

    Таблица 12.1. Выбор функцией trans координаты Z для двумерной точки

    Значение Z

    Текущий уровень (значение системной переменной ELEVATION)

    В проекции на текущую плоскость построений (т. е. плоскость ТСК + текущий уровень)

    В проекции на текущую плоскость построений (т. е. плоскость ТСК + текущий уровень)

    Рассмотрим пример. Предположим, в качестве ТСК выбрана система координат, у которой оси параллельны осям МСК, а начало находится в точке 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 [ [ . [ ] . ]]) — конкатенация (сцепление)строк;
    • (strlen [ [ . [ ] . ]]) — вычисляет суммарную длину всех строк-аргументов (длина строки — это количество буквенно-цифровых знаков в строке);
    • (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;

    (strien «Петербург») — возвращает 9;

    (substr «Happy New Year» 7 3) — возвращает «New»;

    (substr «Happy New Year» 7) — возвращает «New Year».

    Функция wcmatch проверяет строку на соответствие образцу (шаблону):

    Аргументы: — строка, структуру которой нужно проверить; — особая строка, определяющая требования к проверяемой структуре. Аргумент может содержать как обычные алфавитно-цифровые знаки, так и специальные групповые знаки (wild-card-characters), рассматриваемые в табл. 12.2. Можно в строке, определенной аргументом , задать сразу несколько шаблонов, на соответствие каждому из которых аргумент будет проверен; шаблоны должны разделяться с помощью запятой.

    Таблица 12.2. Специальные знаки, которые можно использовать в образце

    Назначение

    Заменяет одну любую цифру

    Заменяет одну букву

    . (точка)

    Заменяет любой символ, не являющийся ни буквой, ни цифрой

    Заменяет любую последовательность любых символов, даже пустую; может использоваться в любом месте аргумента

    Заменяет ровно один любой символ

    Если стоит в начале образца, заданного аргументом , то означает «все, кроме определенного аргументом «

    Заменяет любой из символов, перечисленных в скобках

    Заменяет любой символ, кроме перечисленных в скобках

    Между двумя однотипными знаками указывает на диапазон

    , (запятая)

    Разделяет два шаблона

    ‘ (обратный апостроф)

    Превращает специальный знак в обычный

    В квадратных скобках любой знак рассматривается не как специальный, поэтому его не надо предварять обратным апострофом. Символ «\» является служебным, поэтому его использование отвечает правилам, изложенным в разд. 12.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») — возвращает Т.

    Функции autolispа

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

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

    В конце концов, несмотря на важность макросов ( The Lisp Way! ), вся реальная функциональность обеспечивается функциями. Макросы выполняются во время компиляции и создают код программы. После того, как все макросы будут раскрыты, этот код полностью будет состоять из обращения к функциям и специальным операторам. Я не упоминаю, что макросы сами являются функциями, которые используются для генерации кода, а не для выполнения действий в программе.1)

    Определение новых функций

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

    В качестве имени может использоваться любой символ.2) Как правило, имена функций содержат только буквы, цифры и знак минус, но, кроме того, разрешено использование других символов, и они используются в определенных случаях. Например, функции, которые преобразуют значения из одного типа в другой, иногда используют символ -> в имени. Или функция, которая преобразует строку в виджет, может быть названа string->widget . Наиболее важное соглашение по именованию, затронутое в главе 2, заключается в том, что лучше создавать составные имена, используя знак минус вместо подчеркивания или использования заглавных букв внутри имени. Так что frob-widget лучше соответствует стилю Lisp, чем frob_widget или frobWidget .

    Список параметров функции определяет переменные, которые будут использоваться для хранения аргументов, переданных при вызове функции.3) Если функция не принимает аргументов, то список пуст и записывается как () . Различают обязательные, необязательные, множественные, и именованные (keyword) параметры. Эти вопросы будут обсуждаться подробнее в следующем разделе.

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

    Тело DEFUN состоит из любого числа выражений Lisp. При вызове функции они вычисляются по порядку, и результат вычисления последнего выражения возвращается, как значение функции. Для возврата из любой точки функции может использоваться специальный оператор RETURN-FROM , что я продемонстрирую через некоторое время.

    В главе 2 мы написали функцию hello-world , которая выглядела вот так:

    Теперь вы можете проанализировать части этой функции. Она называется hello-world , список параметров пуст, потому что она не принимает аргументов, в ней нет строки документации, и ее тело состоит из одного выражения:

    Вот пример немного более сложной функции:

    Эта функция называется verbose-sum , получает два аргумента, которые связываются с параметрами x и y , имеет строку документации, и ее тело состоит из двух выражений. Значение, возвращенное вызовом функции + , становится значением функции verbose-sum .

    Списки параметров функций

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

    Основное назначение списков параметров – объявление переменных, которые будут использоваться для хранения аргументов, переданных функции. Когда список параметров является простым списком имен переменных, как в verbose-sum , то параметры называются обязательными. Когда функция вызывается, она должна получить ровно по одному аргументу для каждого из обязательных параметров. Каждый параметр связывается с соответствующим аргументом. Если функция вызывается с меньшим или большим количеством аргументов, чем требуется, то Lisp сообщит об ошибке.

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

    Необязательные параметры

    В то время как многие функции, подобно verbose-sum , нуждаются только в обязательных параметрах, не все функции являются настолько простыми. Иногда функции должны иметь параметр, который будет использоваться только при некоторых вызовах, поскольку он имеет «правильное» значение по умолчанию. Таким примером может быть функция, которая создает структуру данных, которая будет при необходимости расти. Поскольку, структура данных может расти, то не имеет значения, по большей части, какой начальный размер она имеет. Но пользователь функции, который имеет понятие о том, сколько данных будет помещено в данную структуру, может улучшить производительность программы путем указания нужного начального размера этой структуры. Однако, большинство пользователей данной функции, скорее всего, позволят выбрать наиболее подходящий размер автоматически. В Common Lisp вы можете предоставить этим пользователям одинаковые возможности с помощью необязательных параметров; пользователи, которые не хотят устанавливать значение сами, получат разумное значение по умолчанию, а остальные пользователи смогут подставить нужное значение.5)

    Для определения функции с необязательными параметрами после списка обязательных параметров поместите символ &optional , за которым перечислите имена необязательных параметров. Простой пример использования выглядит так:

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

    Lisp все равно будет проверять количество аргументов, переданных функции (в нашем случае это число от 2 до 4-х, включительно), и будет выдавать ошибку, если функция вызвана с лишними аргументами, или их, наоборот, не достает.

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

    Эта функция требует указания одного аргумента, который будет присвоен параметру a . Второй параметр – b , получит либо значение второго аргумента, если он указан, либо число 10.

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

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

    Иногда полезно будет знать, было ли значение необязательного параметра задано пользователем, или использовалось значение по умолчанию. Вместо того, чтобы писать код, который проверяет, является ли переданное значение равным значению по умолчанию (это все равно не будет работать, поскольку пользователь может явно задать значение, равное значению по умолчанию), вы можете добавить еще одно имя переменной к списку параметров после выражения для значения по умолчанию. Указанная переменная будет иметь истинное значение, если пользователь задал значение для аргумента, и NIL в противном случае. По соглашению, эти переменные называются также как и параметры, но с добавлением » -supplied-p » к концу имени. Например:

    Выполнение этого кода приведет к следующим результатам:

    Остаточные (Rest) параметры

    Необязательные параметры применяются только тогда, когда у вас есть отдельные параметры, для которых пользователь может указывать или не указывать значения. Но некоторые функции могут требовать изменяемого количества аргументов. Некоторые встроенные функции, которые вы уже видели, работают именно так. Функция FORMAT имеет два обязательных аргумента – поток вывода и управляющую строку. Но кроме этого, он требует переменное количество аргументов, зависящее от того, сколько значений он должен вставить в управляющую строку. Функция + также получает переменное количество аргументов – нет никаких причин ограничиваться складыванием только двух чисел, эта функция может вычислять сумму любого количества значений. (Она даже может работать вообще без аргументов, возвращая значение 0 .) Следующие примеры являются допустимыми вызовами этих двух функций:

    Очевидно, что вы можете написать функцию с переменным числом аргументов, просто описывая множество необязательных параметров. Но это будет невероятно мучительно – простое написание списка параметров может быть не очень хорошим делом, и это не связывает все параметры с их использованием в теле функции. Для того, чтобы сделать это правильно, вы должны иметь число необязательных параметров равным максимальному допустимому количеству аргументов при вызове функций. Это число зависит от реализации, но гарантируется, что оно будет равно минимум 50 . В текущих реализациях оно варьируется от 4,096 до 536,870,911 .6) Хех! Этот мозгодробительный подход явно не является хорошим стилем написания программ.

    Вместо этого, Lisp позволяет вам указать параметр, который примет все аргументы (этот параметр указывается после символа &rest ). Если функция имеет параметр &rest (остаточный параметр), то любые аргументы, оставшиеся после связывания обязательных и необязательных параметров, будут собраны в список, который станет значением остаточного параметра &rest . Таким образом, список параметров для функций FORMAT и + будут выглядеть примерно так:

    Именованные параметры

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

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

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

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

    Когда функция вызывается, каждый именованный параметр связывается со значением, которое указано после ключевого слова, имеющего то же имя, что и параметр. Вернемся к главе 4, в которой указывалось, что ключевые слова – это имена, которые начинаются с двоеточия, и которые автоматически определяются как константы, вычисляемые сами в себя FIXME (self-evaluating).

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

    Также как и для необязательных параметров, для именованных параметров можно задавать выражение для вычисления значения по умолчанию и имя supplied-p -переменной. И для необязательных, и для именованных параметров, значение по умолчанию может ссылаться на параметры, указанные ранее в списке.

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

    позволяет пользователю вызывать функцию вот так:

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

    Совместное использование разных типов параметров

    Использование всех четырех типов параметров в одной функции хотя и является вполне возможным, но применяется редко. Когда используется более одного типа параметров, они должны быть объявлены в порядке, который мы уже обсуждали – сначала указываются имена требуемых параметров, затем — необязательных, потом — остаточных ( &rest ), и в заключение — именованных параметров. Но обычно в функциях, которые используют несколько типов параметров, комбинируют требуемые параметры с одним из других видов параметров, или возможно комбинируют необязательные и остаточные параметры. Два других сочетания – необязательных или остаточных параметров с именованными параметрами, могут привести к очень удивительному поведению функции.

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

    Если она вызывается вот так, то все нормально:

    И вот так, все работает нормально:

    Но в этом случае, она выдает ошибку:

    Это происходит потому, что имя параметра :z берется как значение для необязательного параметра y , оставляя для обработки только аргумент 3 . При этом, Lisp ожидает, что в этом месте встретится либо пара имя/значение, либо не будет ничего, и одиночное значение приведет к выдаче ошибки. Будет даже хуже, если функция будет иметь два необязательных параметра, так что использование функции как в последнем примере, приведет к тому, что значения :z и 3 будут присвоены двум необязательным параметрам, а именованный параметр z получит значение по умолчанию – NIL , без всякого указания, что что-то произошло неправильно.

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

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

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

    Возврат значений из функции

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

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

    Вы увидите в главе 20 что RETURN-FROM в самом деле не привязана к функциям; она используется для возврата из блока кода, определенного с помощью оператора BLOCK . Однако, DEFUN автоматически помещает тело функции в блок кода с тем же именем, что и имя функции. Так что, вычисление RETURN-FROM с именем функции и значением, которое вы хотите возвратить, приведет к немедленному выходу из функции с возвратом указанного значения. RETURN-FROM является специальным оператором, чьим первым аргументом является имя блока из которого необходимо выполнить возврат. Это имя не вычисляется, так что нет нужды его экранировать.

    Следующая функция использует вложенные циклы для нахождения первой пары чисел, каждое из которых меньше чем 10 , и чье произведение больше заданного аргумента, и она использует RETURN-FROM для возврата первой найденной пары чисел:

    Надо отметить, что необходимость указания имени функции из которой вы хотите вернуться, является не особо удобной – если вы измените имя функции, то вам нужно будет также изменить имя, использованное в операторе RETURN-FROM .8) Но следует отметить, что явное использование RETURN-FROM в Lisp происходит значительно реже, чем использование выражения return в C-подобных языках, поскольку все выражения Lisp, включая управляющие конструкции, такие как условные выражения и циклы, вычисляются в значения. Так что это не представляет особой сложности на практике.

    Функции как данные, или Функции высшего порядка

    В то время как основной способ использования функций – это вызов их с указанием имени, существуют ситуации, когда было бы полезно рассматривать функции как данные. Например, вы можете передать одну функцию в качестве аргумента другой функции, вы можете написать общую функцию сортировки, и предоставить пользователю возможность указания функции для сравнения двух элементов. Так что один и тот же алгоритм может использоваться с разными функциями сравнения. Аналогично, обратные вызовы (callbacks) и FIXME hooks зависят от возможности хранения ссылок на исполняемый код, который можно выполнить позже. Поскольку функции уже являются стандартным способом представления частей кода, имеет смысл разрешить рассмотрение функций как данных.9)

    В Lisp функции являются просто другим типом объектов. Когда вы определяете функцию с помощью DEFUN , вы в действительности делаете две вещи: создаёте новый объект-функцию, и даёте ему имя. Кроме того, имеется возможность, как вы увидели в главе 3, использовать LAMBDA для создания функции без имени. Действительное представление объекта-функции, независимо от того, именованный он или нет, является неопределенным – в компилируемых вариантах Lisp, они вероятно состоят в основном из машинного кода. Единственными вещами которые вам надо знать – как получить эти объекты, и как выполнять их, если вы их получили.

    Специальный оператор FUNCTION обеспечивает механизм получения объекта-функции. Он принимает единственный аргумент и возвращает функцию с этим именем. Имя не экранируется. Так что, если вы определили функцию foo , например вот так:

    вы можете получить объект-функцию следующим образом:10)

    В действительности, вы уже использовали FUNCTION , но это было замаскировано. Синтаксис # ‘, который вы использовали в главе 3, является синтаксической оберткой для FUNCTION , точно также как и ‘ является оберткой для QUOTE .11) Так что вы можете получить объект-функцию вот так:

    После того, как вы получили объект-функцию, есть только одна вещь, которую вы можете сделать с ней – выполнить ее. Common Lisp предоставляет две функции для выполнения функции через объект-функцию: FUNCALL и APPLY .12) Они отличаются тем, как они получают аргументы, которые будут переданы вызываемой функции.

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

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

    Следующая функция демонстрирует более реалистичное использование FUNCALL . Она принимает объект-функцию в качестве аргумента, и рисует простую текстовую диаграмму значений возвращенных функцией, вызываемой для значений от min до max с шагом step .

    Выражение FUNCALL вычисляет значение функции для каждого значения i . Внутрениий цикл использует это значение для определения того, сколько раз напечатать знак «звездочка».

    Заметьте, что вы не используете FUNCTION или # ‘ для получения значения fn ; вы хотите, чтобы оно интерпретировалось как переменная, поскольку значение этой переменной является объектом-функцией. Вы можете вызвать plot с любой функцией, которая берет один числовой аргумент, например, со встроенной функцией EXP , которая возвращает значение e , возведенное в степень переданного аргумента.

    Однако FUNCALL не особо полезен, когда список аргументов становится известен только во время выполнения. Например, для работы с функцией plot в других случаях, представьте, что вы получили список, содержащий объект-функцию, минимальное и максимальное значения, а также шаг изменения значений. Другими словами, список содержит значения, которые вы хотите передать как аргументы для plot . Предположим, что этот список находится в переменной plot-data . Вы можете вызвать plot с этими значениями вот так вот:

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

    Это как раз тот случай, когда на помощь приходит APPLY . Подобно FUNCALL , ее первым аргументом является объект-функция. Но после первого аргумента, вместо перечисления отдельных аргументов, она принимает список. Затем APPLY применяет функцию к значениям в списке. Это позволяет вам переписать предыдущий код следующим образом:

    Кроме того, APPLY может также принимать «свободные» аргументы, также как и обычные аргументы в списке. Таким образом, если plot-data содержит только значения для min , max и step , то вы все равно можете использовать APPLY для отображения функции EXP используя следующее выражение:

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

    Анонимные функции

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

    Когда кажется, что определение новых функций с помощью DEFUN является излишним, вы можете создать «анонимную» функцию, используя выражение LAMBDA . Как обсуждалось в главе 3, LAMBDA -выражение выглядит примерно так:

    Можно представить себе, что LAMBDA -выражения – это специальный вид имен функций, где само имя напрямую описывает что эта функция делает. Это объясняет, почему вы можете использовать LAMBDA -выражение вместо имени функции с # ‘.

    Вы даже можете использовать LAMBDA -выражение как «имя» функции в выражениях, вызывающих функцию. Если вы хотите, то вы можете переписать предыдущий пример с FUNCALL в следующем виде.

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

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

    которую затем передать plot .

    Но легче и более понятно написать вот так:

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

    Язык программирования lisp: функции, синтаксис, среда разработки

    Более сорока лет назад разработан и внедрен в использование для выполнения целей искусственного интеллекта язык программирования LISP (ЛИСП), позднее ставший популярным среди пользователей ПО AutoCAD. Он создан для символьных вычислений. С течением времени был преобразован, чтобы соответствовать новым потребностям ИИ.

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

    Это imperative language (императивный), действия которого описывают выполнение алгоритма, отличается от других, декларативных, предполагающих определение ограничений и соотношений в предметной сфере поставленной цели. По сравнению с другими подобными разработками С++ и FORTRAN, ЛИСП наделен большей функциональностью. Его популярность обусловлена большими возможностями для программирования в сочетании с мощным набором:

    Это средства построения данных структур обозначения высокого уровня.

    Конструкция

    LISP синтаксис и семантика, разработанные программистами, обусловлены теорией рекурсивных функций. Символьные, s-выражения, являются элементами предложений, сочетаний. В них представлены софты и файлы. Они могут отображаться в виде списка (list) или атомов (atom).

    Во втором варианте включены числовые комбинации, цифры, буквы латинского алфавита и знаки: *, -, +, /,@, %, , &, _, ,

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

    Составляющими одних перечислений могут служить другие, более мелкие, подпункты. Символьные структуры разной формы и уровня сложности можно создавать благодаря произвольной углубленности и вложенности. Существует пустая строка, она обозначается – () и называется «nill». При возведении информационной структуры, а также при способе управления ею, она играет особенную роль, представляясь одновременно и атомом, и списком.

    Язык LISP относится к языкам программирования, которые используются для создания дополнительных загрузок к ПО по проектированию и моделированию. Для их использования необязательно хорошо разбираться в компьютере на уровне профессионала.

    После изучения основных принципов работы в таких пакетах, как AutoCAD или ZWCAD 2020 Professional, который является аналогом ACAD, появляется необходимость упростить выполнение длительных рутинных операций или полностью избавиться от них. Для этого дополнения и нужны. Если они написаны на ЛИСПе, скрипты называются LISP-приложения. Каждое из них представляет собой текстовый файл с определенным встроенным кодом для выполнения команды и подсказками от производителя. Определитесь с нужными для работы свойствами, выбирайте надстройку, скачивайте ее и загружайте в «ЗВКАД» или другую платформу. Рассмотрим возможности одного такого модуля на образце скрипта «Выравнивание текстов».

    Примеры программ на ЛИСПе (lisp) для Автокада

    Приложение форматирует страницу горизонтально и вертикально по заданной точке. Это полезная возможность, непредусмотренная в основном ПО. Файл с расширением *.lsp открывается двумя кликами левой кнопки мыши. В окне появится «блокнот».

    Чтобы сгладить и уподобить несколько напечатанных строк в готовом чертеже, обычно приходится выполнять однообразные действия много раз. Со скачанным скриптом это выполняется одной командой (в примере указана Z-TEXT-ALIGN).

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

    • для инженерного проектирования в строительстве;
    • коммунальных структур, занимающихся планированием и укладкой сетей;
    • ЛИСПы Автокада для геодезистов.

    Как загрузить вспомогательную часть в ПО

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

    Помимо файлов lisp также поддерживается загрузка форматов:

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

    Обратите внимание: при скачивании архивированного лисп-приложения, распакуйте его, чтобы на ПК фрагмент сохранился перед загрузкой.

    Этапы установки LISP (их можно отследить по истории):

    1. Перейдите по пути «Управление» – «Приложения» – «Загрузить».
    2. В командной строке основного ПО введите «_appload».
    3. В окне «Загрузка/Выгрузка» найдите файл с одним из вышеперечисленных расширений и кликните «Загрузить».
    4. Процедура завершена. Переходите к тестированию и написанию кода.

    Важно: при каждом запуске базовой утилиты нажмите кнопку «Добавить» в разделе «Добавить в автозагрузку». Если этого не сделать, то будет выполнен единоразовый вход в модуль, который не сохраняется с закрытием софта.

    Команды LISP-программы для Автокада (Autocad)

    В главном ПО их посмотреть невозможно, поэтому нужно обратиться к исходному файлу дополнения. Он открывается в «Блокноте», вверху которого находится название команды для запуска лиспа и вся необходимая информация для работы от его создателей. В примере указано z-text-align, что и нужно ввести в командную строку, чтобы вызвать нужный инструмент.

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

    Обратите внимание: в случае отсутствия подобной подсказки, ищите ее в коде – в строке «defun c: z-text-align».

    Вложения, написанные на диалекте, разработаны только для внедрения в полную версию ACAD и в схожие программы, например, ZWCAD 2020 Professional, NanoCAD, они не подгружаются. Для них существуют другие приложения.

    Список функций лисп (LISP) – языка программирования для Autocad

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

    Варианты, производимые этим оператором:

    • с префиксом «С:» (circle) – команда на выполнение s-выражения в сфере деятельности;
    • без приставки – их вычисления используются в теле программы-дополнения.

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

    Есть участок кода: (setq gh (+ 4 5)), где setq – одна из прописанных единиц. Она объявляет вариацию gh. В скобках знак + тоже опция, числа 4 и 5 – данные, которые были введены в систему. Значение выражения в gh сохранится, то есть 4+5 =9, gh=9. При заданном условии (setqhj (* gh 2), в результат hj сохраняется 18 – gh = 9, 9 умножить на 2 равно 18.

    Синтаксис отличен от привычной большинству математики. Его порядок представлен сначала задачей, а потом переменными. В школьном счете это выглядит, как (3+2), а здесь (+ 3 2), однако, смысл одинаковый.

    Список функций lisp, работа которых является основой дополнительных приложений:

    • для преобразования данных (float);
    • вычислений (fix);
    • организации циклов (if);
    • логические (and, nul,=, , or и другие);
    • арифметические (+, -,

    При помощи этого программного диалекта создают новые уравнения 3-х классов:

    Язык, который не позволяет этого – бесполезен. Часто используется LISP в геодезии, инженерии и строительстве, применяя надстройку «Автокада».

    С помощью ЛИСП изучают рекурсивную функцию, используя такую возможность, как «трассировка». Это основной и весьма эффективный способ организации вычислений, повторяющихся несколько раз.

    На входе в эту ячейку печатают значения входящих параметров, а на выходе появляются результаты, полученные в ходе операции. Для этого есть специальная опция класса FSURB, называемая TRACE. При ее успешном завершении, возвращается наименование задачи. При неудачном – возврат «NIil».

    Пример включения рассматриваемой возможности SUMLIST и произведения математических манипуляций, суммирования элементов списка (1 2 3 4 5):

    Обратите внимание на то, что ответ на поставленную задачку ведется в ином порядке – от последнего к первому.

    Используемые только для AutoCAD (Автокад) LISP программы, устанавливаются исключительно на полноценную версию и не подходят по списку функций и команд для работы в пакетах типа Autodesk LT, Electrical, Mechanical. Исключений немного, ими выступают специальные разработки типа LT Extender, с типом расширения *.arx, *.lsp.


    АВТОЛИСП —
    язык графического программирования в системе AutoCAD

    1.1. Программы и программирование

    1.2. Псевдокод — средство разработки алгоритмов

    2.1. Назначение и возможности языка Автолисп

    2.2. Основные понятия языка Автолисп

    2.3. Разработка простейших программ на языке Автолисп

    2.4. Построение параметризованных изображений

    2.5. Использование программ на языке Автолисп при работе в системе AutoCAD

    3.1. Функции для работы с числами 1 +, 1-, REM, GCD, MIN, MAX

    3.2. Функции для проверки условий BOUNDP, MINUSP, NUMBERP, NULL, ZEROP, EQUAL

    3.3. Функции для работы с текстами STRLEN, STRCAT, SUBSTR

    3.4. Функции для изменения типа данных ANGTOS, ASCII, ATOP, ATOI, CHR, FIX, FLOAT, ITON, RTOS, TRANS

    3.5. Программирование управляющих структур. Функции COND, PROGN, REPEAT

    3.6. Функции для работы с файлами OPEN,CLOSE

    3.7. Ввод и вывод данных

    4.1. Списки и их применение. Точечные пары

    4.2. Создание списков. Функции LIST, CONS, APPEND, REVERSE

    4.3. Выделение элементов списков. Функции типа CAR и CDR. Функции LAST, MEMBER, NTH, ASSOC

    4.4. Анализ списков. Функции LISTP, ATOM, EQ

    4.5. Работа со списками. Функции APPLY, FOREACH,MAPCAR

    5.1. Специфика языка Автолисп как части системы AutoCAD

    5.2. Объектная привязка с помощью функции OSNAP

    5.3. Воздействие на экран. Функции GRAPHSCR, TEXTSCR, GRCLEAR, REDRAW, MENUCMD

    5.4. Работа с системными переменными и сим вольными таблицами. Функции GETVAR и SETVAR

    5.5. Формирование и анализ наборов примитивов. Функции типа SS

    5.6. Работа с примитивами. Функции ENTNEXT, ENTLAST, ENTSEL, ENTDEL. Операция REDRAW над примитивом

    5.7. Работа с данными примитивов и модификация примитивов. Функции ENTGET, ENTMOD, ENTUPD

    ВВЕДЕНИЕ

    Система AutoCAD — это наиболее распространенная в настоящее время система для ПЭВМ, ориентированная на автоматизированное проектирование в машиностроении, а также в строительстве. По данным на 1991 г. в мире имелось около 500 тыс. зарегистрированных копий AutoCAD. Можно утверждать, что на каждом предприятии, где имеются ПЭВМ, совместимые с семейством IBM PC, и где стоят задачи автоматизации конструкторских работ AutoCAD используется или осваивается.

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

    Любой графический редактор позволяет скомпоновать чертеж на экране графического дисплея с помощью устройств ввода ЭВМ и вывести его на бумажный носитель. Однако конструктор, освоивший графический редактор, обнаружит, что выигрыш во времени по сравнению с традиционным способом незначителен, а иногда его и вовсе нет. Экспертные оценки дают следующие цифры: от уменьшения времени на 20% до его увеличения в 2-3 раза! В каждом конкретном случае эффект сокращения времени сильно зависит от характера чертежа.

    Перечислим возможные источники, обеспечивающие сокращение времени.

    1. Полуавтоматические простановка размеров и, главным образом, штриховка, нанесение условных обозначений, построение рамки и штампа.

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

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

    Конструктор, освоивший графический редактор ACAD и убедившийся на практике, что эффект от автоматизации чертежных работ незначителен, может обнаружить, что система AutoCAD предоставляет гораздо более эффектные возможности, чем возможности графического редактора. Оказывается, чертежи можно получать безо всякий затрат времени и усилий на «рисование». Чертеж, который в ручном варианте или с помощью графического редактора

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

    Для создания программ, выпускающих чертежи, в системе AutoCAD имеется мощное средство — язык AutoLISP (далее будем писать русский вариант названия — Автолисп). Но чтобы использовать богатые возможности Автолиспа, нужно научиться программировать на этом языке. Конструктору, ранее не знакомому с программированием, освоить язык графического программирования Автолисп сложнее, чем язык графического редактирования (или, как говорят, «электронный кульман»). Однако, практика показывает, что это вполне по силам конструктору.

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

    Материал книги построен так, чтобы разделить этот шаг на «две ступеньки».

    Гл. 1 и 2 дают начальное представление о специфике программирования как области деятельности; знакомят с псевдокодом — средством описания алгоритмов; дают начальные сведения о языке Автолисп, достаточные для решения многих задач, например такой, как построение параметризуемых чертежей (наиболее «массовая» задача для Автолиспа).

    Гл. 3-5 содержат систематизированное изложение функций языка Автолисп и практически исчерпывающий материал о том, что следует знать конструктору об Автолиспе.

    Изложение сопровождается примерами программ, которые подробно обсуждаются. Разумеется, чтобы освоить язык, необходимо на нем «говорить», т.е. самому писать и отлаживать программы на Автолиспе. Поэтому изучение этой книги должно сопровождаться выполнением практических заданий.

    Книга позволит научиться программировать на Автолиспе. При написании практических программ следует использовать фирменную документацию по Автолиспу для имеющейся у пользователя версии AutoCAD.

    1. ПОНЯТИЕ О ПРОГРАММИРОВАНИИ. РАЗРАБОТКА АЛГОРИТМОВ ПРОГРАММ НА ПСЕВДОКОДЕ

    1.1 Программы и программирование

    Рассмотрим, что такое программа (и, в частности, графическая программа, формирующая изображение), отталкиваясь от графического редактирования — же знакомого способа формирования изображения. Этот способ заключается в следующем: конструктор определяет характер очередного действия; конструктор вводит соответствующую команду в ЭВМ; программа ACAD интерпретирует эту команду, т.е. разворачивает ее в последовательность команд процессора ЭВМ; затем эта последовательность команд выполняется; результат выполнения отображается на экране.

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

    В ACAD имеются средства создания сценариев. Сценарий — это тоже последовательность команд графического редактора, но составленная заранее и записанная в виде файла на магнитном диске. Преимущество сценария в том, что его можно использовать многократно. Однако, составить сценарий значительно сложнее, чем работать на «электронном кульмане», так как он записывается на бумаге без мгновенного отображения на экране. Такая работа «вслепую» приведет к тому, что в сценарии могут остаться ошибки, которые после запуска сценария придется отыскивать в его тексте и исправлять.

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

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

    Такие возможности характерны для любого языка программирования. К ним относятся: обращение из программы к подпрограммам (в сценарии аналогичный эффект может быть достигнут запуском из сценария других сценариев, а также командой INSERT — ВСТАВЬ); компактная запись повторяющихся последовательностей действий — циклов (в сценарии некоторым подобием цикла может служить команда ARRAY — МАССИВ);

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

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

    Определим несколько понятий, связанных с созданием и использованием программ.

    Язык программирования, на котором человек пишет программу, — это не тот язык, который непосредственно воспринимается процессором ЭВМ. Поэтому перед выполнением программы она должна быть переведена на язык команд ЭВМ. Такой перевод осуществляется специальной программой — транслятором. Существуют два вида транслятора: интерпретатор и компилятор.

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

    Компилятор позволяет разделить во времени процесс трансляции и процесс выполнения программы. Если программа, предназначенная для интерпретации, хранится только в одном виде — в том, который создал человек на языке программирования, то при использовании компилятора дело обстоит сложнее. Учтем, что программа может собираться из отдельных, относительно самостоятельных (возможно даже разработанных ранее для других программ) «строительных блоков», которые называются модулями. В связи с этим программа, написанная человеком, может подвергнуться следующим превращениям: из исходных модулей, т.е. модулей, написанных на языке программирования, транслятор формирует объектные модули;

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

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

    Таким образом, программа на магнитном диске может хранится в виде:

    набора исходных модулей, удобного для внесения изменений в программу;

    набора объектных модулей, удобного для построения новых программ;

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

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

    Технология программирования существенно отличается от технологии создания чертежа с помощью «электронного кульмана» и включает следующие этапы: постановку задачи, разработку алгоритма, написание программы, ввод программы в ЭВМ, отладку программы.

    Постановка задачи заключается в четком определении всех деталей и особенностей задачи, которая должна быть решена на ЭВМ: входных и выходных данных, формул, условий, правил выбора вариантов и т.д. [1]. Например, если создается программа для семейства чертежей, то постановка задачи может включать такие работы, как:

    подбор чертежей всех деталей данного семейства; составление на их основе чертежа комплексной детали;

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

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

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

    разделение текстовой части чертежа на постоянную и переменную части, определение правил ввода переменных частей текста и связывания постоянных и переменных частей;

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

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

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

    Алгоритм — это подробная схема программы. Можно даже считать, что алгоритм это уже программа, но написанная на языке, недостаточно формализованном для того, чтобы ее мог обработать транслятор. Более подробно разработка алгоритмов рассмотрена в п.1.2.

    Написание программы — это перевод алгоритма на язык программирования. Программа записывается на бумаге и тщательно проверяется. Ввод программы в ЭВМ осуществляется, как правило, с клавиатуры при использовании программы — редактора текста (программы типа Norton Editor, Lexicon, WordStar и др.). В результате создается файл на магнитном диске. (Если предполагается использование компилятора, то этот файл или набор файлов является исходным модулем или набором исходных модулей программы.)

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

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

    принимает сообщения программы и вводит в программу данные.

    1.2. Псевдокод — средство разработки алгоритмов

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

    Итак, основное противоречие, которое должен разрешить разработчик алгоритма — это противоречие между объективной сложностью задачи и требованием простоты алгоритма. Сложность задачи может привести к тому, что алгоритм станет, во-первых, длинным, а во-вторых, запутанным: с множеством условий, выборов, разветвляющихся и пересекающихся цепочек действий. Разрешить это противоречие можно методом последовательной детализации алгоритма «сверху-вниз». Такой же метод используется и при проектировании технических объектов, когда, например, сначала прорабатывается общий вид объекта, затем — узлы, далее -детали.

    Для записи алгоритмов естественный язык, как правило, оказывается неудобным, поэтому используются специальные средства. Наиболее, распространенными являются блок-схемы, HIPO-диаграммы, псевдокод [1-3].

    В этом параграфе рассматривается псевдокод, т.к. описание алгоритма на псевдокоде в наибольшей степени приближается к тексту программы на языке программирования. Ряд языков программирования, в том числе Автолисп, имеют в составе своих средств полные аналоги конструкций псевдокода. Таким образом, изучение псевдокода — наиболее простой путь к изучению языка программирования для начинающего. (Собственно, само название «псевдо-код» является синонимом названия «почти программа».)

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

    алгоритм на псевдокоде делится на сегменты, каждый сегмент соответствует относительно самостоятельной законченной функции и может детализироваться в последующих сегментах: таким образом обеспечивается последовательная детализация алгоритма «сверху-вниз», а каждый сегмент в отдельности удовлетворяет критерию понятности;

    правила псевдокода предусматривают удобную организацию управляющих структур типа «Принятие решения», «Цикл», что устраняет «запутанность» и повышает понятность сегментов;

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

    Поясним назначение конструкций типа «Принятие решения» и «Цикл». Наиболее простым и понятным описанием действий программы является последовательная цепочка обозначений простых действий. Но такие «линейные» программы получаются редко. Например, если приходится выбирать конфигурацию конкретной детали из комплексной детали, то это означает ветвление программы. «Принятие решения» — это процедура проверки выполнения какого-либо условия или комплекса условий и выбора направления («ветви») дальнейших действий.

    Если в программе требуется много раз подряд выполнить одну и ту же последовательность действий, но каждый раз с новыми данными или с несколько изменившимися; условиями, то такая процедура называется циклом. Однократное выполнение последовательности действий называется шагом цикла. Для каждого цикла должно существовать условие окончания или выхода из цикла. Например, количество шагов цикла может быть известно заранее. В других случаях это условие формируется и проверяется на каждом шаге цикла. Пример — формирование детали типа «вал», имеющей несколько ступеней: в этом случае можно описать последовательность действий по изображению на чертеже одной ступени и повторить эту последовательность в цикле.

    Основные правила псевдокода сводятся к следующему.

    1. Описание действий на псевдокоде разделяется на сегменты. Каждый сегмент содержит описание законченной функции. Желательно, чтобы сегмент был обозрим (т.е. занимал не более одной страницы) и чтобы для его понимания не требовалось привлекать другие сегменты. Сегмент имеет вид:

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

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

    2а. Структура ЕСЛИ-ТО-ИНАЧЕ используется, если нужно описать проверку выполнения условия и выбор одного из двух действий в зависимости от выполнения или невыполнения данного условия. Структура оформляется следующим образом:

    ЕСЛИ Обозначение условия ТО

    Обозначение действий А

    Обозначение действий В

    Структура ЕСЛИ-ТО-ИНАЧЕ подразумевает, следующее. Проводится проверка обозначенного условия. Если оно выполняется, то выполняются «Действия А». Если условия не выполняются, то выполняются «Действия В». Вторая часть структуры (после слова ИНАЧЕ) может быть опущена. В этом случае, если условие не выполняется, то не выполняются никакие действия.

    ЕСЛИ габаритный размер L >100 TO

    Выбрать масштаб 1:10

    Выбрать масштаб 1:5

    2.б Структура ВЫБОР используется, если существует N вариантов действий, причем выбор варианта зависит от значения некоторой переменной (т.е. в отличие от предыдущей структуры структура ВЫБОР реализует многопозиционный переключатель). Структура оформляется следующим образом:

    ВЫБОР Обозначение переменной ИЗ

    СЛУЧАЙ 1 (Значение переменной 1)

    Обозначение действий А

    СЛУЧАЙ 2 (Значение переменной 2)

    Обозначение действий В

    СЛУЧАЙ N (Значение переменной N)

    Обозначение действий Z

    Структура ВЫБОР подразумевает следующее. Имеется некоторая «переменная», которая может принимать несколько значений, и для каждого значения имеется свой вариант действий. Проводится проверка значения переменной. Далее ищется вариант действий — «случай», соответствующий данному значению переменной. Если такой случай найден, то выполняются действия, соответствующему этому случаю. Прочие действия, описанные в структуре ВЫБОР, не выполняются.

    ВЫБОР по типу детали ИЗ

    СЛУЧАЙ 1 (тип детали = вал)

    Сформировать чертеж вала

    СЛУЧАЙ 2 (тип детали = фланец)

    Сформировать чертеж фланца

    СЛУЧАЙ 3 (тип детали = колесо)

    Сформировать чертеж колеса

    2в. Структура ПОКА-ЦИКЛ используется, если последовательность действий требуется повторять многократно, т.е. в цикле. Действия в цикле повторяются до тех пор, пока выполняется некоторое условие. Причем цикл начинается с проверки условия, и если оно перед началом цикла не выполняется, то действия в цикле не выполняются ни разу. Структура оформляется следующим образом:

    ПОКА Обозначение условия ЦИКЛ

    2г. Структура ЦИКЛ ДО используется для тех же целей, что и предыдущая структура. Отличие состоит в том, что

    действия в цикле повторяются до тех пор, пока не будет достигнуто выполнение условия;

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

    Структура оформляется следующим образом :

    ЦИКЛ ДО Обозначение условия

    Отметим, что любой из этих двух структур было бы достаточно для описания любого цикла. Однако, в одних случаях удобнее оказывается ПОКА-ЦИКЛ, в других — ЦИКЛ ДО.

    Пример построения цикла:

    Ввести количество ступеней вала N

    ЦИКЛ ДО обработки последней ступени (I=N)

    Ввести параметры очередной 1-й ступени

    Сформировать изображение 1-й ступени

    Увеличить I на единицу

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

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

    За. Каждое обозначение действия в последовательности должно начинаться с новой строки.

    3б. Каждое последующее обозначение действия должно начинаться с той же позиции, что и предыдущее обозначение.

    Зв. В сегменте описание функции должно смещаться на три позиции вправо относительно наименования функции (и слова КОНЕЦ), как показано выше.

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

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

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

    Пример фрагмента алгоритма, содержащего два последовательных сегмента:

    Разработать чертеж детали.

    Выдать на экран перечень групповых деталей.

    Выбрать тип групповой детали (действие конструктора)

    ВЫБОР по типу детали ИЗ

    СЛУЧАЙ 1 (тип детали — тело вращения)

    Выдать на экран перечень деталей ТВ

    Выдать подтип детали из перечня

    ВЫБОР по подтипу детали ИЗ

    СЛУЧАЙ 1 (подтип — вал)

    Сформировать чертеж вала

    СЛУЧАЙ 2 (подтип — фланец)

    Сформировать чертеж фланца

    СЛУЧАЙ 2 (тип детали — корпус)

    СЛУЧАЙ 3 (тип детали — плоская)

    Проектировать плоскую деталь

    ВСЕ ВЫБОР Сформировать рамку и штамп

    Сформировать чертеж вала

    Ввести количество ступеней вала N (действие конструктора)

    ПОКА не сформирована последняя ступень (I>N) ЦИКЛ

    Ввести параметры 1-й ступени (действие конструктора)

    Сформировать изображение 1-й ступени

    Увеличить I на единицу

    Ввести указание о наличии отверстия (действие конструктора)

    ЕСЛИ отверстие имеется ТО

    Сформировать изображение отверстия

    Указать базу для простановки размеров (действие конструктора)

    Проставить размеры ступеней вала у

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

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

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

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

    Отметим в заключение, что структуре ЕС-ЛИ-ТО-ИНАЧЕ в Автолиспе соответствует функция IF, структуре ВЫБОР — функция COND, структуре ПОКА-ЦИКЛ — функция WHILE.

    2.1. Назначение и возможности языка Автолисп

    Графический язык программирования Автолисп является расширением языка программирования Лисп. Лисп — это язык высокого уровня, ориентированный на обработку списков, который выбран в качестве базового потому, что графические примитивы (начиная, с точки), блоки, наборы примитивов и блоков удобно представляются в виде списков.

    В составе системы AutoCAD поставляется интерпретатор с языка Автолисп (входящий в модуль ADE-3). Если при генерации AutoCAD интерпретатор Автолиспа был подключен, то он загружается в оперативную память после запуска графического редактора ACAD и доступен в течение всего сеанса работы с ACAD. Таким образом, графический редактор ACAD и интер-претататор Автолиспа представляют собой единую систему: любая функция Автолиспа может быть вызвана из графического редактора и любая команда редактора может быть использована в программе на Автолиспе.

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

    1. Программирование чертежей с параметризацией. Создается программа, позволяющая при каждом обращении к ней формировать новый чертеж, отличающийся от предыдущих 26 чертежей, построенных этой же программой, размерами, а также, возможно, и топологией: могут появиться новые элементы обогащения, сечения, измениться текстовая часть чертежа и т.д. Время получения чертежа с помощью такой программы может быть в десятки раз меньше времени, необходимого для его создания с помощью редактора ACAD, и, что не менее важно, получить чертеж сможет любой конструктор, не знакомый ни с командами ACAD, ни с Автолиспом.

    2. Создание и использование графических баз данных. Если накоплено большое количество чертежных файлов, программ на Автолиспе, соответствующих чертежным фрагментам, деталям, узлам, то их можно в некотором смысле считать графической базой данных. Программы на Автолиспе в сочетании с пользовательскими меню могут организовывать просмотр, поиск, подключение к объектам их частей и т.п. Тогда работа конструктора в системе AutoCAD будет сводиться к поиску нужных объектов (сборочных единиц, деталей) или частей чертежа, обращению к соответствующим Лисп-программам и ответам на вопросы этих программ.

    Отметим одно очень важное обстоятельство: хранение графических данных в виде набора программ на Автолиспе дает возможность в десятки и сотни раз сократить требуемую память на магнитном диске по сравнению с памятью, необходимой для хранения чертежных файлов ACAD, так как, во-первых, одна программа позволяет получить не один, а множество чертежей, во-вторых, текст программы на Автолиспе занимает на порядок меньше памяти, чем DWG-файл, который может быть получен в результате работы этой программы.

    3. Анализ и (или) автоматическое преобразование изображений. Программа на Автолиспе может воспринимать чертеж на экране, построенный с помощью графического редактора и обсчитывать его; например, могут быть решены такие задачи: обнаружение пересечений трубопроводов, разведенных в пространстве; подсчет суммарной длины трасс; расчет центра масс и моментов инерции; выдача на печать спецификации по сборочному чертежу и т.п.

    Программа также может быстро осуществить преобразование изображения, на которое при работе в графическом редакторе пришлось бы затратить значительное время, например: заменить все вставки одного типа на вставки другого типа из какого-либо чертежного файла; перенести все объекты с одного слоя на другой слой; повернуть все блоки на заданный угол — каждый относительно своей базовой точки и т.п.

    4. Расширение системы команд графического редактора ACAD и построение на основе универсального редактора специализированных САПР, имеющих гораздо более простой и естественный для пользователей язык, ориентированный на конкретную предметную область. В этом случае хорошим дополнением к Автолиспу является возможность создания пользовательских меню.

    В языке Автолисп (версия 10) определены около 150 различных операций, которые называются встроенными функциями.

    По назначению их можно подразделить на функции:

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

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

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

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

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

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

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

    Далее перечислены функции, определяющие специфику языка Автолисп, т.е. функции, связанные с графикой и работой в среде графического редактора ACAD:

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

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

    для выделения примитивов построенного на экране чертежа и наборов примитивов, выделения и изменения характеристик примитивов и блоков, анализа и измнения системных переменных и содержимого символьных таблиц ACAD;

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

    Из всего многообразия функций Автолиспа в этой главе рассмотрены 37, среди них — наиболее часто употребимые представители различных классов функций (но не всех). Знания этих функций в совокупности со знанием команд ACAD достаточно для программирования несложных параметризованных чертежей.

    2.2. Основные понятия языка Автолисп

    Соглашения по форме записи правил языка. В дальнейшем изложении приведены правила построения выражений языка Автолисп. Введем некоторые «правила описания этих правил», а именно поясним смысл символов ::=;

    (угловые скобки); [] (квадратные скобки); . (многоточие). Все эти символы не встречаются в выражениях Автолиспа, и поэтому их можно использовать для записи правил Автолиспа.


    ::= — означает «это есть»;

    — означает, что на данное место можно подставить любой объект

    [(объект >] — означает, что объект может присутствовать, а может и не

    присутствовать в данном выражении;

    . — означает, что объектов данного класса может быть несколько.

    Использование таких обозначений поясним на понятном всем примере: сформулируем правило обычной записи целых чисел в виде:

    Программа. Программа на языке Автолисп представляет собой построенный с помощью любого редактора текстов с соблюдением правил языка текстовый файл, который хранится на магнитном диске под определенным именем. Он может быть загружен в ОЗУ в ходе сеанса графического диалога в системе ACAD и может быть выполнен путем соответствующего ответа на подсказку ACAD

    COMMAND: (в русской версии — Команда)

    Программа — это последовательность функций Автолиспа и функций, определенных самим программистом.

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

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

    Здесь +/- означает плюс или минус. Целые -числа могут задаваться в пределах от -32768 до 32767. Целое число без знака — от 0 до 65535.

    Здесь точка отделяет целую часть от дробной части.

    Для чисел с большими порядками удобна запись

    Здесь «Е» означает «10 в степени», а показатель степени ставите^ после Е.

    В Автолиспе определена также константа, обозначаемая PI и имеющая значение 3.1415926.

    Длина текстовой константы не более 100 знаков. Если в тексте встречается знак «\»,то он должен быть удвоен (т.е. вместо «\» должно быть записано «\\». Это связано с тем, что символ «\» используется для ввода управляющих символов: \n — перевод строки, \r — возврат каретки, \t — табуляция.

    Переменные формируются из любого количества символов, кроме знаков ().,»:’ пробел, перевод строки. Первым символом должна быть буква. Переменная, так же как и в математике, — это объект, имеющий имя и значение. Имя служит для обозначения объекта. Правила записи переменных, приведенные выше, это, по сути дела, правила записи имен. Конкретное значение переменная приобретает в процессе выполнения программы, например, переменная, имеющая имя XI, может последовательно принимать значения 10, 12.3, «НАЧАЛО», NIL .

    Помимо перечисленных атомов определен еще «пустой атом», обозначаемый как NIL, что означает «ничего», т.е. атом, не имеющий никакого значения.

    Примеры правильной записи данных:

    0.0 целые константы;

    -12.34Е8 действительные константы;

    «\nУкажите точку» текстовые константы;

    CROSS_POINT_2 переменные (имена переменных);

    Примеры неправильной записи данных:

    -100000 — целая константа за пределами допустимых значений;

    .25 — действительная константа без целой части;

    25. — действительная константа без дробной части;

    «AB\CD» — управляющий символ «\С» не определен, символ

    «\» должен повторяться дважды;

    «ABCD — отсутствуют закрывающие кавычки;

    АВCD — такая запись возможна (см. ниже), но это уже не имя переменной, т.к.

    внутри имеется пробел.

    Составной элемент программы на Автолиспе, состоящий из атомов или других списков, отделенных друг От друга пробелами, называется списком. Он всегда заключается в скобки,таким образом:

    Как следует из приведенной записи, возможен список и без элементов, т,е. список вида (). Такой список имеет значение NIL.

    Примеры правильной записи списков:

    (Al Bl Cl) — атомами являются переменные;

    («А» «В» «С») — атомами являются текстовые константы;

    (А 10.0 20.0 NIL) — «смешанный» список: второй и третий

    атомы — действительные числа, последний — пусто.

    Примеры неправильной записи списков:

    А В С — отсутствуют скобки;

    (А (В С) — число закрывающих скобок меньше числа открывающих — наиболее распространенная ошибка при написании программ на Автолиспе.

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

    Здесь — это символическое имя. Каждая функция имеет свое, связанное с ней имя.

    Аргументы функции — это выражения, построенные по правилам Автолиспа, в том числе другие функции. Для каждой конкретной функции характерны определенное количество, типы и порядок следования аргументов.

    Здесь COS — имя функции для вычисления косинуса;

    — аргумент, который может быть действительной константой или целой константой или переменной.

    Здесь знак «+» — имя функции для вычисления суммы;

    В этом примере функция сложения производит суммирование трех слагаемых, обозначенных именами А, В, С, и возвращает результат, имеющий форму числа и равный сумме А+В+С. Этот результат используется программой, а именно — подставляется в качестве аргумента в функцию COS. В свою очередь, функция COS возвращает свой результат (новое число), который тоже может быть использован. В дальнейшем в книге при описании каждой конкретной функции будут приведены ее имя, характеристика аргументов и возвращаемое значение.

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

    первая — встроенные функции Автолиспа, т.е. те функции, имена которых и правила работы с которыми изложены в соответствующем фирменном руководстве по Автолиспу;

    вторая — функции, которые Вы сами придумали и описали в своей программе средствами Автолиспа;

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

    Описание новой функции в программе должно предшествовать обращению к этой функции. Описание новой функции в Автолиспе -это тоже функция, имеющая имя DEFUN:

    Здесь — это имя, которое Вы придумали для новой функции. Список аргументов — это список имен, обозначающих те данные, которые будут посылаться в функцию перед ее выполнением. Локальные переменные — это переменные, определение которых действует только внутри описываемой функции (т.е. Вы можете одним и тем же именем обозначать совершенно разные данные в разных функциях, и это не приведет ни к каким конфликтам, если эти имена определены Вами как локальные) . Как аргументы, так и локальные переменные могут и отсутствовать, но скобки () после имени функции обязательны.

    — это любая запись, выполненная по правилам Автолиспа. Именно выражение показывает, какие действия должна выполнять описываемая функция.

    Значение, возвращаемое функцией DEFUN — это имя описанной функции, т.е. после выполнения функции DEFUN можно в любом месте программы обращаться к описанной новой функции по ее имени. Примером использовав ния функции DEFUN является приведенная ни-\ же простая программа на Автолиспе.

    ;Программа 1. Вычисление суммы SIN(A) + COS(A)

    (DEFUN SINCOS (A) ; имя функции и список

    ( + (SIN A) (COS А)); выражение: SIN(A) + COS(A)

    ) ;конец программы — закрывающая скобка»)»

    Программа 1 состоит из единственной функции DEFUN. Эта функция описывает придуманную нами функцию, которую мы назвали SINCOS.

    Функция SINCOS имеет один аргумент, который мы обозначили именем А. Выражение Автолиспа в составе функции показывает, что должна делать данная функция. Любой текст от знака»;» до конца строки — комментарий для читателя.

    Текст Программы 1 можно набрать в сеансе работы с ACAD в ответ на приглашение COMMAND:. Этот текст будет обработан интерпретатором Автолиспа. В результате такой обработки, т.е. в результате выполнения функции DEFUN, будет возвращено имя функции SINCOS, а значит эта функция в дальнейшем может быть выполнена.

    Для выполнения функции SINCOS можно в ответ на очередное приглашение ACAD набрать строку

    Тем самым интерпретатору Автолиспа будет задана новая программа, состоящая из од-. ной функции SINCOS с определенным значением аргумента, в нашем случае равным нулю. Эта функция возвращает ‘ число, равное SIN(0)+COS(0), в нашем случае 1.0. Это число будет отображено на экране дисплея.

    Подробнее об использовании программ Автолиспа в среде ACAD — см. в п. 2.5.

    2.3. Разработка простейших программ на языке Автолисп

    Программирование вычислений. Математические функции. Для программирования вычислений можно использовать следующие функции:

    + (сложение);- (вычитание);* (умножение);/(деление);ЕХРТ (возведение в степень);

    ABS (определение модуля числа);

    SORT (квадратный корень);

    LOG (натуральный логарифм);

    и некоторые другие (см. п. 3.1.).

    Аргументы этих функций -. целые или действительные числа. Углы выражаются в радианах. Функции «+»,»-«, «*»,»/» могут иметь два аргумента и более, при этом у функции «-» первый аргумент обозначает уменьшаемое, остальное -вычитаемое, у функции «/» первый аргумент -делимое, остальные — делители. Функция ЕХРТ должна иметь два аргумента (первый — основание, второй — показатель степени), остальные функции должны иметь один аргумент.

    Тип возвращаемого значения зависит от функции и типов аргументов. Функции SIN, COS, ATAN, SORT, EXP, LOG всегда возвращают действительные числа.

    Использование команд ACAD в Автолиспе. Функция COMMAND. Любая команда графического редактора ACAD может быть включена в программу на Автолиспе, что позволяет строить изображения из программы автоматически или с участием пользователя. Это делается с помощью функции COMMAND, имеющей вид

    Здесь — имя требуемой команды, определенной в данной версии ACAD.

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

    Слово PAUSE в качестве аргумента обозначает переключение в режим графического диалога, т.е. после чтения PAUSE команда ожидает одного аргумента (опцию, точку и др.) с клавиатуры, от «мыши» и тд., в точности так, как если бы команда выполнялась просто в ACAD.

    Дополнительные сведения о функции COMMAND:

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

    (COMMAND «») соответствует вводу пробела с клавиатуры;

    (COMMAND) равносильно нажатию клавиши CTRL/C.

    (COMMAND «LINE» «1,1» «10,10» «»)

    ; Эта функция строит линию по точкам 1,1 и 10,10

    (COMMAND «CIRCLE» «2P» «10,10» «20,20»)

    ; Строится окружность по точкам на концах диаметра

    (COMMAND «CIRCLE» «10,10» PAUSE «LINE» «10,10» «10,5»)

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

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

    Обратите внимание на то, как вводятся координаты точки в функции COMMAND: координаты X и Y отделяются запятой, и все эти заключается в кавычки.

    (COMMAND «CIRCLE» PC R)

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

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

    Использование переменных. Функция SETQ. Функции GET.

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

    Функция действует следующим образом: выполняются действия, задаваемые выражением 1, и результат, возвращаемый этим выражением, становится текущим значением переменной 1. Если имеются другие «пары», то с ними функция поступает аналогично. Функция SETQ возвращает значение последнего выражения.

    (SETQ А 10.0) ; записывает 10 в А

    (SETQ В (+ 123)) ; записывает в В результат сложения

    (SETQ A 1 В 2 С 3) ; записывает 1 в А, 2 в В, 3 в С,

    ; возвращает значение 3

    (SETQ D (SETQ А 1 В 2 С 3)) ; записывает 3 в D

    Любую из этих функций вы можете набрать в ответ на приглашение ACAD.

    Для ввода значений переменных пользователем служат функции типа GET. К ним относятся:

    GETINT — ввод целого числа;

    GETREAL — ввод вещественного числа;

    GETSTRING — ввод строки текста;

    GETPOINT — ввод точки;

    GETDIST — ввод расстояния;

    GETANGLE — ввод угла

    и некоторые другие функции. .

    Работу функций GETINT, GETREAL, GETSTRING рассмотрим на примере функции GETINT, которая в общем виде выглядит так:

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

    Аналогично записываются и действуют функции GETREAL и GETSTRING.

    Функция создает паузу и ожидает ввода точки. Точка может быть введена путем указания на экране или путем набора ее координат на клавиатуре в виде X, Y. Функция возвращает координаты точки (в виде списка — см. п. 2.4.). Аргумент имеет тот же смысл, что и для функций GETINT. Если задан аргумент , то при перемещении курсора на экране будет отображаться «резиновая линия» от данной «опорной» точки до текущего положения курсора.

    Функция создает паузу и ожидает ввода расстояния. Расстояние может быть указано тремя способами:

    как действительное число с клавиатуры;

    путем указания двух точек (будет определено расстояние между точками);

    путем указания второй точки при наличии аргумента .

    В двух последних случаях между первой точкой и текущим положением курсора рисуется «резиновая линия».

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

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

    ; Программа 2 . Построение окружности

    (SETQ PC (GETPOINT «\nВведите центр:»))

    (SETQ R (OETDIST PC «\nВведите радиус:»))

    (COMMAND «CIRCLE» PC: R)

    ; Окружность появляется на экране

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

    ; Программа 3. Построение окружности

    (DEFUN OKR 0 ; Имя описываемой функции

    (SETQ PC (GETPOItff «\nВведите центр:»))

    (SETQ R (GETDIST PC «\nВведите радиус:»))

    (COMMAND «CIRCLE» PC R)

    Такую программу можно записать на диск, затем в любое время вызвать с диска (подробнее об этом см. в п, 2.5) и запустить на выполнение, набрав (OKR) в ответ на приглашение ACAD. (Напомним, символ «\n» в тексте подсказок означает «перевод строки»).

    2.4. Построение параметризованных изображений

    Функции QUOTE, POLAR, ANGLE, DISTANCE, INTERS. Приведенные ранее простые примеры не демонстрируют все преимущества программирования на Автолиспе по сравнению с использованием редактора ACAD, В этом параграфе рассмотрена программа, иллюстрирующая принцип построения параметризуемых изображений. Для такого построения требуется задавать геометрические объекты «внутри программы», т.е. без участия пользователя.

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

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

    (QUOTE А) -возвращает А

    (QUOTE (А В С )) — возвращает (А В С)

    QUOTE (1.0 1.0)) — возвращает (1.0 1.0)

    В тексте программы, создаваемой в виде файла, символ QUOTE, как правило, заменяют эквивалентным обозначением ’ , т.е. (QUOTE A) то же самое, что ‘А. Но непосредственно в ответ на приглашение ACAD можно набирать только текст в форме (QUOTE. ).

    Геометрическая точка в программе может быть задана пятью способами.

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

    Второй — непосредственное указание координат точки в виде списка из двух (двухмерная точка) или трех (трехмерная точка) элементов с помощью функции QUOTE.

    (QUOTE (1.0 1.0)) — точка с координатами 1,1;

    ‘(1.0 1.0) — аналогично;

    ‘(1.0 2.0 3.0) — точка в трехмерном пространстве с координатами X=1,Y=2,2=3.

    Третий способ — задание точки нерез’другую точку, угол и расстояние с помощью функции POLAR:

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

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

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

    Функция INTERS находит точку пересечения двух отрезков — отрезка от к с отрезком от к -и возвращает найденную точку. -любое выражение Автолиспа. Если равен NIL, то будет определена точка пересечения линий бесконечной длины, наложенных на заданные отрезки. Если имеет любое значение, отличное от NIL, или если аргумент вообще отсутствует, то ищется точка пересечения только внутри отрезков. Если точка пересечения в этой ситуации не найдена, то функция INTERS возвращает NIL.

    Для геометрических построений могут оказаться полезными функции ANGLE и DISTANCE.

    Функция возвращает действительное число, / равное углу в радианах, образованному прямой, проходящей через и , с осьюХ.

    Функция возвращает действительное число, равное расстоянию между и . ‘

    Принцип построения параметризованных изображений иллюстрирует Программа 4, позволяющая построить квадрат с задаваемой стороной и вписанную в него окружность. Аналогично можно строить и более сложные изображения: для получения нового изображения с помощью программы пользователь задает новые значения параметров (точки, расстояния, числа и др.). Из этих данных в программе могут быть получены другие переменные данные с помощью математических функций, функции POLAR и т.п. Переменные данные будут использованы в качестве аргументов команд ACAD посредством функции COMMAND.

    ; Программа 4. Квадрат с вписанной окружностью

    (DEPUN CQUADR ( ) ; заголовок описываемойфункции

    ; Зададим начальную точку — левый нижний угол квадрата:(SETQ PI (GETPOINT «\nНач. точка:»))

    ; Зададим длину квадрата:

    (SETQ L (GETDIST «\nДлина стороны:»))

    ; определим три оставшиеся вершины квадрата:

    (SETQ Р2 (POLAR PI 0.0 L))

    (SETQ P3 (POLAR P2 (/ PI 2) L)) ; угол = PI/2

    (SETQ P4 (POLAR P3 PI L)); угол = PI

    ; Построим квадрат на экране:

    (COMMAND «LINE» PI P2 P3 P4 «С»)

    ; (Здесь «С» задает опцию «Замыкание»)

    ;Определим радиус окружности:

    ; Определим центр окружности РС:

    (SETQ PR (POLAR PI 0.0 R)) ;PR — точка касания

    ; на нижней стороне

    (SETQ PC (POLAR PR (/ PI 2) R))

    ; Построим окружность на экране:

    (COMMAND «CIRCLE» PC R)

    ) ; Конец описания функции QUADR

    Обратите внимание на несколько необычное имя функции — C:QUADR. Символы «С:» имеют определенный смысл, который будет разъяснен в разделе 2.5.

    Подпрограммы, ветвления и циклы. Логические функции. Функции WHILE и IF. В любом языке программирования есть средства для создания подпрограмм, циклов, ветвлений в программах в зависимости от результатов проверки условий. Такие средства есть и в Автолиспе.

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

    Для этих целей в Автолиспе служит уже известная функция DEFUN. Описание некоторой функции с помощью DEFUN и можно считать подпрограммой, а обращение к описанной ранее функции — вызовом подпрограммы. При обращении на место символических аргументов в описании функции подставляются истинные значения этих переменных. Например, описанная в Программе 1 функция SINCOS(A) может рассматриваться как подпрограмма. А строка (SINCOS 0.0), встречающаяся в какой-либо программе, является обращением к этой подпрограмме, причем аргумент А принимает значение 0.

    Ветвления в программе организуются с помощью функции IF:

    Здесь — такое выражение Автолиспа, которое среди прочих значений может в какой-то ситуации получить значение NIL.

    Функция IF вычисляет значение условия и, если оно не NIL, то выполняет , иначе — выполняет , если она присутствует. Функция IF возвращает результат выполнения функции. Таким образом, функция IF соответствует управляющей структуре псевдокода ЕСЛИ-ТО-ИНАЧЕ.

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

    / = (не равно) = (больше или равно)

    которые позволяют выполнять сравнение чисел или текстов, а также функции AND, OR, NOT, обеспечивающие возможность строить сложные условия из простых.

    Все эти функции могут возвращать одно из двух значений: NIL («нет», условие не выполняется) или Т («да», условие выполняется).

    Например, функция» =» имеет вид:

    Здесь в качестве атомов могут стоять либо числа (как целые, так и вещественные), либо текстовые данные. Функция возвращает Т, если все атомы равны между собой, иначе — NIL.

    Функция «/=» определена только, для двух атомов.

    Если каждый предыдущий атом меньше последующего, то возвращается Т, иначе — NIL.

    Аналогично определяются остальные функции сравнения. Для текстовых констант понятие «меньше» означает следующее: сравнение производится по первой несовпадающей букве. «Меньшей» считается тот символ, ASCII-код ко- . торого меньше. Для букв алфавита коды нарастают в алфавитном порядке (отдельно для заглавных, отдельно для строчных букв).

    Функции AND, OR, NOT являются функциями алгебры логики.

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

    Выполняется операция логического ‘ИЛИ’. Возвращается Т, если хотя бы одно выражение имеет значение Т, иначе — NIL.

    Выполняется логическая функция ‘НЕ’. Если выражение имеет значение NIL, то возвращается Т, во всех остальных случаях возвращается NIL.

    Пусть имеются следующие значения:

    ( = А 5) возвращает Т


    Приведенная ниже Программа 5 иллюстрирует ветвление по условию с использованием функции IF.

    ; Программа 5. Вычисление тангенса

    (DEFUN TAN (A / S С) ; Заголовок функции

    ; А — аргумент функции — угол, S, С — локальные переменные

    (IP (/ = С 0.0) (/ S С) «бесконечность»)

    Здесь, если С не равно нулю, вычисляется тангенс (и значение тангенса будет возвращено функцией). Если же С равно нулю, то. тангенс не вычисляется, а функция возвращает строку «бесконечность» — это слово и появится на экране.

    Цикл в Автолиспе организуется с помощью функции WHILE.

    Здесь — это выражение, которое в некоторых ситуациях может принимать значение NIL.

    Функция WHILE вычисляет значение условия и, если оно не NIL, вычисляет выражения, затем снова условие и т.д. Это продолжается, пока условие не станет равно NIL. Затем WHILE возвращает последнее значение последнего выражения. Таким образом, функция WHILE соответствует структуре псевдокода ПОКА-ЦИКЛ.

    Приведенная ниже Программа 6 иллюстрирует использование цикла, позволяющего компактно записать построение сложного изображения: строится семейство из 20 квадратов, каждый из которых повернут на угол 0.1*Р1 относительно предыдущего и имеет периметр в 0.9 раз меньше предыдущего. Для построения 20 замкнутых линий имеется всего одна команда LINE

    ; Программа 6. Построение семейства квадратов:

    ; Получение исходных данных (описание функции)

    (DEPUN ID ( ); Заголовок функции

    (SETQ PI (GETPOINT «\n Нач. точка:»))

    (SETQ L (GETDIST P1 «\n Нач. длина:»))

    ; Построение одного квадрата:

    (DEFUN QUADR (L A /P2 R3 й4); Заголовок функции

    ; Здесь P2, РЗ, Р4 объявлены как локальные

    (SETQ P2 (POLAR PI A L))

    (SETQ РЗ (POLAR P2 (+ А (/ PI 2)) L))

    (SETQ P4 (POLAR РЗ (+ A PI) L))

    (COMMAND «LINE» PI P2 P3 P4 «C»)

    ; Построение семейства квадратов:

    (DEFUN QN ( ) ; Заголовок функции

    (SETQ В 0.0) ; Задан начальный угол В=0

    (ID) ; Выполнена функция ID

    ; Выполним функцию QUADR с

    ; параметрами L, В:

    ; Увеличим угол на 0.1 PI

    (SETQ В (+В (* PI 0.1)))

    ; Изменим L в 0.9 раз:

    Результат выполнения .Программы 5 показан на рис.1. В предыдущих примерах каждая программа содержала по одному описанию функции. Пример Программы 6 демонстрирует, что такое соответствие не обязательно. Программа может содержать несколько описаний функций (несколько функций DEFUN).

    Рис. 1. Результат двухкратного выполнения Программы 6 с разными исходными данными

    Каждое описание функции — это функциональный модуль, который можно использовать отдельно, в частности в других программах. Обратите внимание на передачу данных при вызове функции. В заголовке функции QUADR описано два аргумента: L, А. При обращении в функцию QUADR передаются значения параметров: L и В. Это следует понимать так, что в момент обращения к QUADR:

    А становится равно В;

    L (которое будет работать внутри QUADR) становится равным L (которое существовало

    Следовательно, А и В, L и L — это разные данные, и не имеет значения, выбраны для их обозначения разные имена (как А и В) или одинаковые (как L). Изменения, которые происходят с В и L внутри функции, никак не отражаются на значениях А и L в остальной программе.

    В Приложении приведена Программа и для построения чертежа детали — вала с произвольным количеством ступеней. На примере этой программы модно видеть, как для построения чертежа могут использоваться функции, рассмотренные в данной главе:, DEFUN, COMMAND, POLAR, IF, WHILE, функции типа GET. Программа 13, так же как Программа 6, иллюстрирует общую схему построения программ для получения параметризованных чертежей:

    ввод исходных данных (в том числе — базовой точки);

    определение точек внутри программы с помощью функции POLAR с использованием введенных данных;

    построение примитивов на экране с помощью функции COMMAND по определенным точкам.

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

    2.5. Использование программ на языке Автолисп при работе в системе AutoCAD

    До сих пор рассматривался вопрос о том, как писать программы на Автолиспе, но, по существу, не затрагивался вопрос о том, как их применять. Для использования Автолиспа в сеансе работы с графическим редактором ACAD необходимы следующие условия.

    Используемая версия AutoCAD должна иметь модуль ADE-3. При настройке системы AutoCAD Автолисп должен быть подключен. При Выполнении этих условий Вы можете обращаться к Автолиспу, т.е. выполнять функции Автолиспа в любой момент, когда редактор выдает подсказку COMMAND: (КОМАНДА:).

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

    Непосредственный ввод программы с клавиатуры. В ответ на приглашение COMMAND: можно ввести первую функцию программы (набрать ее текст на клавиатуре), и она будет выполнена, в ответ на следующее приглашение -следующую функцию и тд. Изображение будет строиться постепенно, как при работе с редактором ACAD. Значение, возвращаемое каждой функцией, будет выдаваться на экран ( в нижнюю строку).

    Итак, любой текст, начинающийся с символа «(«, редактор ACAD воспринимает как функцию Автолиспа и передает интерпретатору Автолиспа. Именно такой способ упоминался в п.2.4. Очевидно, что он неудобен, так как при каждом повторном выполнении программу нужно вновь полностью набирать.

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

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

    До того, как решено выполнить данную программу, ее следует загрузить в ОЗУ с помощью функции Автолиспа LOAD. Функция имеет вид:

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

    Теперь в ответ на подсказку COMMAND: в любой момент можно ввести строку с именем любой функции программы, определенной в программе с помощью DEFUN, заключив это имя в скобки. Если требуется, то после имени функции указываются ее аргументы. Например, текст Программы 1 (см. п.2.3) можно набрать в текстовом редакторе и записать на диск под именем SC.LSP. В сеансе работы с ACAD в ответ на COMMAND: ввести строку:

    На экране появится имя загруженной функции — SINCOS.

    После этого на любой запрос COMMAND:

    можно набрать ответ:

    В результате этого Программа 1 будет выполнена (с аргументами 0, Tt и др.). Аналогично можно подготовить, загрузить и выполнить другие программы,

    Программа 3 вызывается Строкой (OKR)

    Программа 5 вызывается строкой (TAN значение угла)

    Программа 6 вызывается строкой (QN)

    Оформление программы как готовой команды ACAD. Программу можно оформить так, чтобы после загрузки файла с этой программой, ее можно было вызывать по имени точно так же, как вызываются команды ACAD (т.е. без скобок).

    Для этого имя главной функции в программе (последней, которая описана через DEFUN) нужно начать с символов «С:». Например, в Программе. 4 (см. п.2.4) описана функция C:QUADR. Такую программу можно вызвать на выполнение, набрав строку QUADR. Таким образом, можно оформлять только функции, не имеющие аргументов. —

    Аналогично оформлена головная функция C:VAL в Программе 13 (см. Приложение). Таким образом, программу можно вызвать командой VAL.

    Автоматическая загрузка программ. Может возникнуть желание обойтись без команды LOAD и загружать программу автоматически. Это можно сделать, если добавить текст программы в файл ACAD.LSP. Такой файл будет загружен в ОЗУ при вызове редактора ACAD.

    3.1. Функции для работы с числами 1+, 1-, REM, GCD, MIN, MAX

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

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

    Функция возвращает наибольший общий делитель двух целых чисел.

    Функция делит на и т.д. и возвращает остаток от деления.

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

    3.2. Функции для проверки условий BOUNDP, MINUSP, NUMBERP, NULL, ZEROP, EQUAL

    Наряду с функциями для проверки условий, описанными в п.2.4 (типа =, /=, > и т.п.), имеются следующие функции.

    Функция возвращает Т, если имеет какое-либо значение, кроме NIL. Если равен NIL, то возвращается NIL.

    Функция возвращает Т, если имеет значение NIL, иначе возвращается NIL. Примеры:

    Пусть (SETQ А 2) Тогда (BOUNDP А) — > Т

    (SETQ В NIL) (BOUNDP В) — > NIL

    (SETQ С В) (BOUNDP D) — > не определено

    (SETQ D ‘( )) (NULL A) — > NIL

    Функция возвращает Т, если -число (целое или действительное). Для остальных типов элементов возвращается NIL.

    Если аргументом функции является отрицательное число, то возвращается Т, если число неотрицательное, то NIL. Если аргумент не является числом, то функция не определена (интерпретатор Автолиспа выдает сообщение об ошибке).

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

    Функция возвращает Т, если оба выражения равны между собой, иначе — NIL. Эту функцию можно применять во всех случаях, где используется функция =, однако возможности EQUAL шире:

    аргументами EQUAL могут быть не только атомы, но и более сложные конструкции — списки, например, геометрические точки, заданные списками координат;

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

    (SETQ A (GETREAL)) ; Вводится число 3.14

    (EQUAL A PI O.I) ; Возвращает Т, т.к. различия

    ; 3.14 и PI лежат в поле допуска.

    Функции EQ и ATOM для анализа списков рассмотрены в п.4.4.

    3.3. Функции для работы с текстами STRLEN, STRCAT, SUBSTR

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

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

    Функция возвращает строку, образующуюся в результате «сцепления» строк — аргументов.

    Функция возвращает строку текста, являющуюся частью , заданной в качестве аргумента (выделяет подстроку). Здесь — количество символов в выделяемой подстроке; если оно не задано, то подстрока продолжается до конца строки.

    Пусть задано: Тогда

    (SETQ A «ABCD») (STRLEN A) — > 4

    (SETQ В «CDEFG») (STRCAT А В) — > «ABCDCDEFG»

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

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

    3.4. Функции для изменения типа данных ANGTOS, ASCII.ATOF, ATOI, CHR, FIX, FLOAT, ITOA, RTOS, TRANS

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

    Функция преобразует , выраженный в виде действительного числа в радианах, в форму текстовой строка-Аргумент указывает, в каком формате должен бь^ть представлен угол:

    4 — топографические единицы («N», «W»,

    Аргумент — это целое число, задающее число знаков после запятой. Если аргументы не указаны, то используются значения переменных ACAD: AUNITS и AUPREC. Если значение угла отрицательное, то выполняется преобразование в эквивалентный положительный угол в пределах 0. 2П.

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

    Функция преобразует текстовую переменную следующим образом: выделяет первый символ и возвращает соответствующий ему ASCII-код (т.е. целое число).

    Функция может оказаться полезной, если при вводе текста с клавиатуры нажимают на «несимвольные» клавиши, такие, как Enter. Сигналы от таких клавиш могут быть отслежены в программе только по их кодам.

    Функция выполняет преобразование, обратное ASCII: преобразует

    (ASCII «A») — > 65 (CHR 65) — > «А»

    (ASCII «В») — > 66 (CHR 66) — > «В»

    (ASCII «ABBA») -> 65 (CHR 27) -> эквивалентно нажатию клавиши ESC

    Функции осуществляют преобразование аргумента, имеющего тип строки текста, в соответственно действительное и целое числа. При этом содержание должно допускать такое преобразование (например, не содержать в своем составе букв, кроме «Е»).

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

    (ATOF «123.7») 123.700000

    (ATOF «123») 123.000000

    (ATOF «1.2E-3») 0.001200

    (ATOI «A2») не определено

    Функции осуществляют преобразование из соответственно целого или действительного числа в текст.

    Аргумент может иметь значение от 1 до 5 и задавать форму представления действительного числа в виде:

    3-5 — см. в «Руководстве по программированию» (Автолисп, версия 10. Autodesk Ltd.,1989).

    Аргумент задает число знаков после запятой. Если режим и точность не указаны, то используются значения системных переменных ACAD: LUNITS и LUPREC.

    С помощью этих функций можно использовать числовые значения, формируемые программой, для выдачи на экран сообщений пользователю. Например, в функции ID (см. Приложение) (ITOA i) позволяет включать в строку сообщения переменную i — номер ступени вала.

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

    3.5. Программирование управляющих структур. Функции COND, PROGN, REPEAT

    Развитой язык программирования должен обеспечивать реализацию управляющих структур типа «ветвление» и «цикл». Такие структуры реализуются на Автолиспе с помощью функций IF и WHILE (см. п.2.4). Функции, рассмотренные ниже, расширяют возможности программирования управляющих структур.

    Функция COND реализует управляющую структуру ВЫБОР из нескольких вариантов действий и позволяет заменить использование многократно вложенных IF.

    Здесь -любая последовательность функций Автолиспа.

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

    (COND (( > А 0) (SETQ В «PLUS»))

    ((= А 0) (SETQ В «ZERO»))

    Если перед выполнением этой функции в переменную А было записано положительное число, то в результате вычисления функции в В будет записан текст «PLUS», функция возвратит «PLUS». Аналогично отработаются случаи, когда окажется, что А=0 и А

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

    Функция PROGN объединяет последовательность функций в «макрофункцию». PROGN возвращает значение последней функции в последовательности.

    (PROGN (SETQ В (/1 А))

    Здесь, если А>0, вычисляются В и С (и возвращается значение С), иначе возвращается текст «А

    (SETQ STR «МАТЕРИАЛ:»)

    (REPEAT 3 (SETQ S (GETSTRING))

    (SETQ STR (STRCAT STR S))

    Здесь трижды с клавиатуры вводятся текстовые строки, которые «сцепляются» с начальной строкой «МАТЕРИАЛ».

    Циклическая обработка списков может также быть организована с помощью функций FOREACH и MAPCAR (см. п.4.5).

    3.6. Функции для работы с файлами OPEN,CLOSE

    В Автолиспе имеются возможности для обмена данными между программами через магнитные носители, при этом могут быть использованы данные не только из различных программ на Автолиспе, но и из программ на других языках. Например, расчетная программа на языке ФОРТРАН (Паскаль, С и др.) может записать свои результаты на диск, а программа на Автолиспе прочитает эти данные и использует как параметры для построения чертежа.

    Файл с данными можно также использовать для «пакетного ввода» исходных данных в программу, вместо организации ввода в режиме диалога. Это целесообразно, когда при каждом запуске программы вводится большой объем данных, изменяющихся незначительно. Тогда проще отредактировать текстовый файл, чем заново набирать эти данные. Операции ввода-вывода с использованием файлов рассмотрены в п.3.7.

    Перед тем как начать работу с файлом, его нужно открыть с помощью функции OPEN:

    Здесь — обозначение открываемого файла в среде MS-DOS (имя.расширение). При необходимости указывается префикс.

    Значение может быть символами «г», или «w», или «а», где:

    «r» — существующий файл открывается для чтения; если такого файла нет, то функция вернет NIL;

    «w» — файл открывается для записи; если файла с таким именем нет, то создается новый файл с указанным именем; если такой файл уже существует, то он заменяется новым файлом с тем же именем;

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

    Функция OPEN всегда используется в сочетании с функцией SETQ, так как OPEN возвращает условное имя файла, используемое внутри программы, которое будем называть дескриптором файла. (Дескриптор файла и имя файла, известное операционной системе, — это два разных понятия.) Дескриптор файла необходимо записать с помощью SETQ в какую-либо переменную, эту переменную затем придется использовать в операциях ввода-вывода.

    Таким образом, строка

    (SETQ F1 (OPEN «/K1/FILE1.DAT» «r»))

    означает, что на рабочем диске в подкаталоге К1 ищется файл FILE1 с расширением DAT, этот файл открывается для чтения, значение дескриптора файла присваивается переменной Fl. Обратите внимание на то, что в текстовых константах Автолиспа символ «/» используется там, где по правилам MS-DOS должен стоять символ «\». Это вызвано тем, что символ «\» в Автолиспе используется для ввода управляющих символов.

    После того как работа с данным файлом закончена, его следует закрыть с помощью функции CLOSE:

    например, файл F1 должен быть закрыт так:

    Итак, любой вид работы с файлом должен ткрываться» функцией OPEN и «закрываться» функцией CLOSE. Например, пусть в програм-е предусмотрены сброс промежуточных данных на магнитный диск, а затем использование их данных в следующей части программы. го может быть организовано следующим образом:

    (SETQ F (OPEN «FD.DAT» «w»))

    (В том числе операции записи в файл)

    (SETQ F (OPEN «FD.DAT» «r»))

    (В том числе операции чтения из файла)

    В Автолиспе имеется также функция NDFILE для поиска файла по имени: она возвращает полное имя с префиксом каталога:

    3.7. Ввод и вывод данных

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

    Ввод данных пользователем. Функции типа GET, READ. Функция INITGET. Пользователь может ввести в программу числа, символы и строки символов, в том числе ключевые слова, сигналы с функциональной клавиатуры, геометрические данные. Ввод чисел производится с помощью функций GETINT и GETREAL (см. п.2.3). Для ввода строк символов могут быть использованы функции:

    Обе эти функции создают паузу и ждут строку, набранную на клавиатуре. Но GETSTRING обладает более богатыми возможностями:

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

    на экран может выдаваться подсказка.

    Функция READ-CHAR работает следующим образом. Если на клавиатуре не был набран никакой текст, то эта функция создает паузу для набора текста, заканчивающегося нажатием ENTER. После этого функция возвращает ASCII-код первой из нажатых клавиш. Каждое последующее обращение к READ-CHAR «сканирует» текст, включая клавишу ENTER (код 10). Например, пусть в программе имеются последовательно пять обращений к READ-CHAR. Тогда возможен следующий обмен данными:

    Пользователь набирает QQW

    READ-CHAR-I срабатывает и возвращает 81 (код Q)

    READ-CHAR-II возвращает 81

    READ-CHAR-III возвращает 87 (код W)

    READ-CHAR-IV возвращает 10

    Функцию READ-CHAR можно использовать в тех случаях, когда необходимо проверить код нажатой клавиши, не связанный с каким-либо символом. Например, в функции RZM (см. Приложение) таким образом проверяется, была ли нажата клавиша Enter (как утвердительный ответ на вопрос программы), код этой клавиши 10. Эта проверка осуществляется, как

    Геометрические данные вводятся с помощью функций, описанных в п.2.3: GETDIST, GETANGLE, GETPOINT. Первые две возвращают числа, третья — точку в виде списка координат. Помимо них для получения точки можно использовать:

    а для ввода угла

    Функция GETCORNER отличается от GETPOINT только тем, что при движении курсора рисуется не «резиновая линия», а прямоугольник от базовой точки.

    Функция GETORIENT работает так же, как GETANGLE, если в ходе сеанса работы действует выбор нуля и направления отсчета по умолчанию (рис. 2а). Если же с помощью системных переменных ACAD эти величины изменяются, то значения, возвращаемые GETANGLE и GETORIENT,-He совпадают (см. рис.2 и табл.1).

    Как следует из рис.2 и табл.1, GETORIENT воспринимает задание и «нулевой оси», и направления угла, a GETANGLE — только направления. Поэтому GETANGLE можно использовать при повороте вставляемого блока, так как угол, равный 0, всегда будет давать 0. А GETORIENT можно использовать для введения таких углов, как угол базовой линии для команды TEXT.

    Имеется возможность модифицировать условия работы функций GET с помощью функции INITGET:

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

    Рис.2. Иллюстрация различий между функциями GETANGLE и GETORIENT:

    а — направления для отсчета углов по умолчанию;

    б — направления, заданные с помощью системных переменных;

    в — интерпретация углов функцией GETANGLE в условиях рис.26;

    г — интерпретация углов функцией GETORIENT в условиях рис.26.

    Таблица 1. Значения, возвращаемые функциями, при задании аргументов (в градусах) в условиях рис. 26.

    Значение (GETANGLE A) (GETORIENT A)

    180 3.14159 4.71239

    -90 1.5708 3.14159

    — это целое число, которое может принимать любое из значений, указанных в табл.2, или любую сумму этих значений.

    Таблица 2. Управляющий признак INITGET

    1 Запрещен пустой ввод (т.е. )

    2 Запрещен ввод нуля

    4 Запрещен ввод отрицательных чисел

    8 Не контролируются лимиты, даже если LIMCHECK включено

    16 Возвращаются трехмерные точки

    32 Для «резиновой линии» или рамки применяется пунктир

    Условия, заданные функцией INITGET, действуют на ближайшую функцию типа GET. «Запрет» функции INITGET действует так, что при его нарушении пользователем функция GET срабатывает повторно до тех пор, пока не будут введены приемлемые данные. С такой целью функция INITGET используется в функции C:VAL (см. Приложение), что гарантирует правильный ввод числа ступеней вала.

    Значение признака, задаваемого функцией INITGET, должно соответствовать назначению последующей функции GET (табл.3).

    Таблица 3. Функции GET, для которых имеют смысл управляющие признаки

    Аргумент в функции INITGET имеет форму текстовой константы. А по содержанию — это список ключевых слов, которые может ввести пользователь в ответ на функцию GET. Список ключевых слов строится по следующим правилам:

    ключевые слова в списке разделяются пробелами;


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

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

    Ключевые слова, разрешенные функцией INITGET, могут вводиться пользователем с клавиатуры в ответ на функцию GET. Такое слово будет возвращено функцией GET в виде строки текста (вне зависимости от назначения функции, т.е. от того, какие данные она формирует обычно). Это позволяет пользователю управлять работой программы (ввести «команду») в любой точке, где ему предлагается ввести данные с помощью GET-функции.

    (INITGET 7 «REZba FASKA 1,FAS1 FASKA2,FAS2»)

    Пусть первая встретившаяся после INITGET функция типа GET имеет вид:

    (SETQ A (GETINIT «\nNOMER/REZba/PASl/FAS2»))

    Тогда пользователь может ввести следующие данные с клавиатуры: положительное целое число (так как в INITGET записано 7=1+2+4); строки REZBA, REZ, FASKA1, FAS1, FASKA2, FAS2. Любой другой ввод будетвосприниматься как неправильный, и GETINT будет снова запрашивать данные. Отметим, что работа организуется именно функцией INITGET, a текст в функции GETINT служит только подсказкой пользователю.

    Знакомство с INITGET позволяет понять ункцию GETKWORD:

    Функция запрашивает ключевое слово у пользователя и возвращает введенное ключевое в виде строки текста. Применение GETKWORD имеет смысл, если перед этим (ючевые слова были определены функцией INITGET.

    С помощью сочетания функций INITGET, GETKWORD и COND удобно организовывать ветвления в программе, управляемые пользователем.

    Вывод данных на экран. Функции типа HNT и WRITE, функция PROMT. Управление выводом . Программа в процессе работы может выдавать на экран символы, строки текста, а также значения любых выражений Автолиспа том числе числа и списки). Во многих случаях один и тот же результат может быть получен различными функциями.

    Функции различаются оформлением результата и возвращаемым в программу значением. Рассмотрим эти функции.

    Печатает символ, ASCII-код которого задан иым числом, и возвращает этот код.

    Печатает текст (без кавычек) и возвращает текст в форме текстовой константы (в качках).

    Печатает и возвращает значение выражения (если — текст, то он выдается в кавычках).

    Функция PRIN1 (так же как PRINC и PRINT) без аргументов может быть использована для «тихого завершения» программы, так как эти функции в отсутствие аргумента ничего не возвращают. Такой прием использован в Программе 13 (см. последнюю строку программы в Приложении). Без этой строки программа выдала бы в строку подсказки значение, возвращенное функцией COMMAND, т.е. NIL.

    Печатает и возвращает значение выражения (текст печатается без кавычек).

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

    Печатает текст и возвращает NIL.

    (WRITE-CHAR 88) Печатает Х Возвращает 88 (код X)

    (WRITE-LINE «ABCD») ABCD «ABCD»

    (PRIN1 «ABCD») «ABCD» «ABCD»

    (PRIN1′(А В С)) (А В С) (А В С)

    (PRINC «ABCD») ABCD «ABCD»

    (PRINT «ABCD») «ABCD» «ABCD»

    (PROMPT «ABCD») ABCD NIL

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

    \n — перевод строки;

    \г — возврат к началу строки;

    Печать с новой строки обеспечивается также функцией PRINT. Для перевода строки служит и функция TERPRI, которая возвращает NIL.

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

    Здесь буквой «Ф» для краткости обозначен дескриптор файла, заданный в SETQ с помощью функции OPEN для данного файла.

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

    Функция READ-LINE считывает очередную запись и воспринимает ее как строку текста (возвращая эту строку). Функция READ-CHAR воспринимает очередной символ из считанной записи, а если такого символа нет, то считывает новую запись и воспринимает первый символ (возвращая ASCII-код, т.е. число).

    Таким образом, читать из файла можно только текст.

    С помощью функций типа WRITE и PRINT можно выдавать данные на устройство печати. Для этого в функции OPEN в качестве имени файла необходимо указать логическое имя устройства печати.

    Использование возможностей ввода и вывода в Автолиспе иллюстрирует Программа 7. Она позволяет считывать текстовые данные из файла и включать строки текста в чертеж по желанию пользователя. Одна запись файла соответствует одной строке текста. Все строки располагаются одна под другой [7].

    Алгоритм, реализуемый Программой 7:

    Ввести имя файла, содержащего текст

    Ввести начальную точку для первой строки текста

    Считать первую запись файла

    Разместить первую строку текста на экране

    ПОКА очередная запись файла существует ЦИКЛ

    Считать очередную запись файла

    Выдать текст очередной строки для просмотра

    Ввести сигнал пользователя

    ЕСЛИ сигнал =»Да» ТО

    Разместить очередную строку текста на экране

    ; Программа 7: Чтение текста из файла и размещение в чертеже

    (DEFUN С: TXTIN (/bn pn f st)

    (SETQ fn (GETSTRING «\nИмя файла:»)

    pn (GETPOINT «\n Нач. точка:»)

    (COMMAND «TEXT» pn «.2» «» st)

    (WHILE (SETQ st (READ-LINE 0)

    (COMMAND «TEXT» «» st)

    Примечание. В этой программе сигналом ”Да» считается нажатие на клавишу Enter AСП-код клавиши равен 10). Любой другой ответ воспринимается как «Нет».

    Приведенную программу можно использовать для усовершенствования Программы 13 (см. Приложение). Для этого в конец программы (перед строкой (PRIN1)) следует вставить строки:

    (LOAD «TXTIN») TXTIN

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

    4.1. Списки и их применение. Точечные пары

    Любой, кто знаком с языками программирования, такими, как Бэйсик, Паскаль, С, Фортран, заметит в Автолиспе ряд отличий от этих зыков, в частности, отсутствие такого важного способа организации данных, как массивы (переменные с индексами), обеспечивающего компактную запись повторяющихся действий с помощью циклов. Подобные задачи решаются в Автолиспе с помощью списков.

    Как уже известно (п.2.4), геометрические точки представляются в Автолиспе в форме тисков из двух или трех координат. В дальнейшем (см. гл.5) будет показано, что примитивы CAD также представляются в виде сложных тисковых структур. Таким образом, для понимания специфики Автолиспа и его возможностей по обработке геометрических и графических данных ACAD, необходимо изучить функции работы со списками.

    Как указывалось в п.2.2, список — это объект формы:

    где — это список или атом.

    Особым случаем списка является точечная паpa:

    При хранении точечных пар требуется меньше места в памяти, чем при хранении обычных списков. Точечная пара может быть сформирована функцией CONS (см. ниже). Некоторые функции обработки списков не могут работать с точечными парами. Если точечная пара выдается на экран, то между атомами Автолисп печатает точку. Об использовании точечных пар будет сказано в п. 5.7.

    4.2. Создание списков. Функции LIST, CONS, APPEND, REVERSE

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

    Список можно сформировать и путем указания примитива на экране, «развернуть» его функцией ENTGET (см. гл.5). Кроме того, имеются функции, позволяющие конструировать списки из данных, определенных ранее в программе.

    Функция LIST формирует список из любого числа элементов (атомов или списков) и возвращает список.

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

    Таким образом, если функция LIST формирует новый список, то CONS — расширяет существующий. Однако, возможно использование CONS и в следующей форме:

    В этом случае создается точечная пара.

    Функция APPEND соединяет несколько списков в один общий список. Отличие APPEND от LIST поясняется примерами, приведенными ниже.

    Функция REVERSE возвращает список с элементами, расставленными в обратном порядке.

    (SETQ F (LIST А В)) создает в F список ((1.0 2.0)(С D Е))

    (SETQ G (LIST ‘X В)) создает в G список Х (С D Е))

    (SETQ G (CONS ‘X В)) создает (X С D E)

    (SETQ G (CONS ‘(X) В)) создает ((X) С D Е)

    (SETQ G (CONS 34)) создает точечную пару (3.4)

    (SETQ H (APPEND А В)) создает (1.0 2.0 С D Е),

    т.е. происходит слияние списков в отличие от функции LIST, формирующей «список списков».

    (SETQ H (APPEND ‘(X) В)) создает (X С D Е) — в отличие от функции CONS с такими же аргументами

    (SETQ H (APPEND ‘X В)) — ошибка, аргументы должны быть списками

    (SETQ В (REVERSE В)) создает в В (Е D С).

    4.3. Выделение элементов списков. Функции типа CAR и CDR. Функции LAST, MEMBER, NTH, ASSOC

    Любая структура данных имеет смысл тогда, когда возможен доступ к отдельным элементам этой структуры. При работе со списками необходимо выделять элементы и другие части списков. Например, если необходимо изменить координату Х точки, заданной как (LIST X У), то элемент Х предварительно следует извлечь из списка:

    Функция возвращает первый элемент списка. Если список пуст, то возвращается NIL.

    Функция возвращает новый список, отличающийся отсутствием первого элемента (обрезает список спереди). Если список пуст, возвращается NIL. Если представлен как точечная пара, то CDR возвращает второй элемент как атом, а не как список.

    В Автолиспе определены функции, обеспечивающие последовательное выполнение CAR и (или) -CDR вплоть до четырех уровней вложенности: CAAR, CADR, CDDR, CADAR и т.д.

    (CAAR X) возвращает А как (CAR (CAR X))

    (CDAR X) возвращает (В) как (CDR (CAR X))

    (CADAR X) возвращает В как (CAR (CDR (CAR X))) и т.п.

    Функции типа CAR и CDR часто используются для выделения координат точек (CAR -для X, CADR — для У, CADDR — для Z).

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

    Функция просматривает и ищет в нем заданный . Если найден, то возвращается список от до конца исходного . Иначе возвращается NIL.

    Функция возвращает элемент , имеющий заданный . должен иметь целое неотрицательное значение. Примем во внимание, что первый элемент списка имеет номер 0. Если превышает число элементов в -1, то возвращается NIL.

    (LAST А) возвращает (D E)

    (MEMBER ‘С А) возвращает (С (D Е))

    (NTH О А) возвращает В

    (NTH 2 А) возвращает (D Е)

    (NTH 3 А) возвращает NIL

    Функция ASSOC обеспечивает «ассоциативный поиск» в структурированном списке, т.е. в списке, элементы которого являются списками, эти списки построены по схеме:

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

    (SETQ DETAL ‘((КОД 123456) (КОДМ 001234) (М 1.45)))

    (ASSOC ‘КОДМ DETAL) возвращает (КОДМ 001234)

    (Теперь с помощью функции CADR можно «отрезать» ключевой элемент КОДМ и выделить значение 001234.)

    Функция SUBST дополняет функцию ASSOC, позволяя заменять элементы в списке.

    Производится просмотр списка, и каждый найденный заменяется на . Возвращается обновленный список.

    4.4. Анализ списков. Функции LISTP, ATOM, EQ

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

    Функция возвращает Т, если является списком, иначе — NIL.

    Функция, обратная к LISTP, т.е. возвращает Т, если является атомом.

    Функция проверяет идентичность двух выражений, которые, как правило, являются списками. Списки считаются идентичными, если они связаны друг с другом через SETQ. Если два списка идентичны (EQ), то они всегда равны (EQUAL). Если же два списка равны, то они необязательно идентичны.

    Пусть (SETQ X ‘(А В С)) (SETQ Y X)

    (EQUAL X Y) дает Т

    (EQUAL X ‘(А В С)) дает Т

    (EQ X ‘(А В С)) дает NIL

    4.5. Работа со списками. Функции APPLY, FOREACH, MAPCAR

    Как отмечалось в п.4.1, имеются возможности компактной записи некоторых действий с помощью списков. Для этого можно использовать функции APPLY, FOREACH, MAPCAR.

    Таким образом выполняется какая-либо функция Автолиспа, имя которой указано и которая может иметь несколько аргументов. Эти аргументы задаются . Например,

    (APPLY ‘+'(12 3)) эквивалентно (+123)

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

    (FOREACH 1(123) (SETQ Е ( + Е I)))

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

    (SETQ S (MAPCAR’ + ‘(10 20 30) ‘(1 2 3)))

    Формируется S в виде списка (11 22 33), каждый элемент которого есть результат применения функции «+» к паре аргументов, взятых из двух списков.

    4.6. Примеры

    Из рассмотренных в данной главе функций работы со списками при программировании геометрических построений на Автолиспе, наверное, чаще всего используются функции LIST (для получения геометрической точки из отдельных координат), а также CAR и CADR (для выделения координат точки). Такое использование иллюстрируется следующей простой функцией:

    ; Программа 8. Получение трехмерной точки

    ; по заданной двухмерной точке и координате Z

    (LIST (CAR p) (CADR p) z)

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

    Программа 9 составлена в предположении, что есть некоторый список, являющийся схемой описания какого-либо объекта, т.е. перечнем ключевых слов. Например, описание сотрудников может представлять следующая схема:

    («фамилия» «имя» «отчество» «год рождения». )

    Программа 9 содержит две функции. Функция «Синтез» позволяет построить на основе схемы описание конкретного объекта, также имеющее форму списка. Каждый элемент этого списка является списком вида:

    Например, описание объекта может выглядеть так:

    ((«фамилия» «Попов») («имя» «Иван»). )

    Функция «Анализ» позволяет найти любой элемент описания объекта по ключевому слову и при необходимости изменить значение этого элемента.

    Алгоритм, реализуемый Программой 9:

    (Аргумент функции — список Схема)

    Сформировать пустой список Объект (LIST)

    ПОКА имеются элементы в списке Схема ЦИКЛ

    Выдать ключевое слово и ввести значение ключевого слова

    Сформировать субсписок из ключевого слова и его значения

    Добавить субсписок в Объект (CONS)

    Реверсировать список Объект

    Выдать запрос и ввести ключевое слово

    ЕСЛИ введено не Пусто ТО

    Найти значение по ключу (ASSOC) и выдать его

    Выдать запрос и ввести новое значение

    ЕСЛИ введено не Пусто ТО

    Сформировать новый субсписок (LIST)

    Подставить новый субсписок в Объект (SUBST)

    ; Программа 9: Пример работы со списками

    (DEFUN SINTEZ (Схема)

    (FOREACH Ключ Схема

    (PRINC (STRCAT «\n Введите значение»

    (SETQ Значение (GETSTRING))

    (SETQ Элемент (LIST Ключ Значение))

    (SETQ Объект (CONS Элемент Объект))

    (SETQ Объект (REVERSE Объект))

    (SETQ Ключ (GETSTRING «\n Введите ключевое слово (или Enter)»))

    (IF (/= (ASCII Ключ) 10)

    (SETQ Элемент (ASSOC Ключ Объект))

    (SETQ Значение (CADR Элемент))

    (PRINC (STRCAT Ключ «=» Значение))

    (SETQ Новое_значение (GETSTRING

    «\n Введите новое значение (или Enter)»))

    (IF (/= (ASCII Новое_значение) 10)

    (SETQ Новый_элемёнт (LIST Ключ

    Объект (SUBST Новый_элемент

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

    Рассмотрим, как используются функции работы со списками в Программе 13.

    При построении первой ступени формируется список sp, состоящий из одного элемента -списка точек р2 и рЗ:

    (SETQ sp (LIST (LIST p2 p3)))

    При построении каждой следующей ступени в этот список добавляется новая пара точек:

    (SETQ sp (CONS (LIST p2 p3) sp))

    Обратим внимание на то, что новая пара добавляется в начало списка, т.е. порядок следования пар точек в списке обратен порядку построения ступеней вала.

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

    т.е. на каждом шаге цикла выбирается очередной элемент списка sp и записывается в рр.

    Верхняя и нижняя точки для простановки размера выделяются из рр следующим образом:

    (SETQ p1 (CAR рр) p2 (CADR рр))

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

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

    список sp «переворачивается»:

    (SETQ sp (REVERSE sp))

    первая пара точек выделяется:

    (SETQ рр (NTH 0 sp))

    вторая (нижняя) точка из пары выделяется:

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

    На примере Программы 13 можно также видеть, как функции LIST, CAR и CADR используются для внутрипрограммного построения точек. Например,

    (SETQ p3 (LIST (- (CAR p1) 10) (CADR p1)))

    определяет точку p3, координата Х которой смещена на десять единиц влево по отношению к точке р1. Аналогичный результат был бы получен с помощью (POLAR pi PI 10).

    5.1. Специфика языка Автолисп как части системы AutoCAD

    Помимо возможностей Автолиспа, свойственных и другим языкам программирования, а также возможностей по обработке списков, двойственных версиям языка Лисп, в Автолиспе имеются и специфические возможности, связанные с тем, что программа на Автолиспе работает в среде, созданной системой AutoCAD. Эта среда характеризуется:

    определенными параметрами (системными переменными AutoCAD);

    определенной организацией экрана (графического или текстового);

    наличием изображения (чертежа), построенного на графическом экране и состоящего из примитивов и блоков;

    определенной организацией данных об изображении в памяти ЭВМ — наличием графической базы данных чертежа, в которой содержатся описания примитивов и блоков, значения системных переменных, таблицы слоев, типов линий и т.д.

    Программа на Автолиспе может воспринимать особенности этой среды и оказывать влияние на нее.

    5.2. Объектная привязка с помощью функции OSNAP



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

    Предполагается, что на чертеже имеется объект, проходящий через заданную .

    Аргумент — это строка текста, характеризующая режим привязки точно так же, как для команды OSNAP. Например:

    «CEN» — центр окружности или дуги;

    «BND» — конечная точка отрезка, дуги;

    «INS» — базовая точка блока и др.

    Если точка, соответствующая заданному режиму, не найдена, то возвращается NIL.

    5.3. Воздействие на экран. Функции GRAPHSCR, TEXTSCR, GRCLEAR, REDRAW, MENUCMD

    В ходе выполнения программа может влиять на состояние экрана.

    С помощью этих функций можно переключать экран с текстового на графический и обратно.

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

    Функция очищает поле чертежа графического экрана.

    Функция позволяет восстановить картину, стертую с помощью GCLEAR. Кроме того, EDRAW может применяться для перерисовывания текущего экрана и выполнять ту же роль, что и команда графического редактора REDRAW.

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

    Аргумент имеет следующий вид:

    Для экранного меню — S (другиe типы см. в «Руководстве пользователя»(АВТОКАД, версия 10. Autodesk Ltd., 1989)).

    Таким образом (MENUCMD «S = S3 «) будет лзывать на экран раздел меню S3. Применение этой функции предполагает знание структуры файла меню, который используется в процессе работы данной программы (например, стандартного файла меню ACAD.MNU).

    Все перечисленные здесь функции возвращают NIL.

    5.4. Работа с системными переменными и символьными таблицами. Функции GETVAR и SETVAR

    Тем, кто полностью освоил графический редактор ACAD, известно, что при вызове ACAD устанавливаются по умолчанию значения множества системных переменных, влияющих на режим работы с редактором. В ходе графического диалога эти значения можно переустанавливать командой SETVAR. Полный список системных переменных, их типов и значений приведен в «Руководстве пользователя».

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

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

    Следует иметь в виду, что некоторые системные переменные определены только для гения (см. «Руководство пользователя»). Такие переменные нельзя переустановить. Примеры:

    (SETQ A (GETVAR «ANOBASE»))

    возвращается и записывается в А действительное число, определяющее направление угла 0 в этом чертеже.

    (SETVAR «CMDECHO» 0)

    задается значение 0 для переменной CMDECHO, что приведет к исчезновению «эха» выполняемых команд.

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

    В ходе работы с редактором ACAD создаются также символьные таблицы LNTYPE, LAYER другие, определяющие типы линий, слои, ви-ы, блоки, гарнитуры шрифтов. Данные из этих таблиц могут быть прочитаны с помощью функций TBLNEXT,TBLSEARCH, описанных в «Руководстве по программированию».

    5.5. Формирование и анализ наборов примитивов. Функции типа SS

    Программы на Автолиспе могут работать с бъектами специальных типов — графическими бъектами. К таким объектам относятся:

    примитивы ACAD, имеющиеся на экране в процессе работы программы;

    совокупности таких примитивов, называемые в Автолиспе наборами.

    Графические объекты могут быть «введены в программу», т.е. возможно именование этих объектов с помощью имен переменных, так же как именование чисел, строк текстов, точек. После этого можно оперировать с этими объектами, обращаясь к ним по именам. В том числе можно анализировать и изменять характеристики этих объектов, что приводит к изменению изображения на экране.

    Для лучшего представления о том, как происходит работа с примитивами и наборами, полезно понять следующее. При выделении каким-либо способом примитива или набора из базы данных Автолисп формирует внутрипрограммное имя этого объекта (примитива или набора). На самом деле — это не имя, а ссылка на объект, но для программиста это не имеет значения. Программист поступает следующим образом: он записывает это «имя» в какую-либо переменную с помощью SETQ. Затем эта переменная может быть использована для любого указания на объект. Например, она может быть подставлена в качестве аргумента в команду, требующую указания примитива или группы примитивов. Далее такая технология будет проиллюстрирована на примере.

    Основное средство определения наборов примитивов — функция SSGET.

    Функция возвращает определение (внутрипрограммное имя) выбранного примитива или отбора (совокупности примитивов), которое может быть «записано» в неременную Автолиспа (с помощью SETQ);

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

    Возможны следующие значения режима:

    «Р», в русском варианте «Т» — выбирается текущий набор;

    «L», русское «П» — выбирается последний сформированный на чертеже примитив;

    «W», русское «Р» — выбираются примитивы, попавшие в рамку с углами в и ;

    «С», русское «С» — выбираются примитивы, пересекаемые рамкой. Кроме этих возможны еще две конструкции:

    Здесь выбираются примитивы, проходящие через .

    Здесь — список, элементами которого являются одна или несколько точечных пар. Каждая точечная пара строится по следующей форме:

    ( . ) Здесь — одно из принятых в Автолиспе чисел, показывающих, по какому признаку выбираются примитивы, например;

    0 — примитивы одного типа;

    2 — примитивы, входящие в один блок (INSERT) ;

    6 — по типу линии;

    7 — по гарнитуре шрифта;

    8 — по имени слоя;

    62 — по цвету и др.

    вернет набор, включающий все примитивы, находящиеся на слое, именованном как «SLI»;

    (SSGET «X» ‘((0. «LINE») (62 .1)))

    вернет набор, состоящий из всех линий красного цвета (1 — номер красного цвета).

    Выполнение последовательности функций

    (SETQ sdel (SSGET «X» ‘((6 . «CENTER»))))

    (COMMAND «ERASE» sdel)

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

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

    Функция SSLENGTH возвращает целую величину, представляющую число примитивов в наборе. Таким образом, программа может «узнать», сколько объектов было выделено пользователем. По известному числу примитивов можно организовать цикл по обработке последовательно каждого примитива.

    Здесь и далее — это имя переменной набора, т.е. переменной, определенной ранее следующим образом:

    Функция SSNAME возвращает внутрипрог-раммное имя примитива из , идущего под соответствующим номером.

    Здесь — целая величина. Первый по порядку примитив имеет номер 0. Если меньше 0 или больше максимального номера примитива в наборе, то возвращается NIL. Таким образом, конструкция вида

    позволяет выделить примитив из , записав его имя в .

    Функция SSMEMB проверяет, входит ли в . Если да, то возвращается имя примитива, если нет, — то NIL.

    Здесь и далее — имя переменной, значение которой записано с помощью SETQ, например, путем применения функции SSNAME.

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

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

    (SETQ S (SSADD р1))

    Эта конструкция формирует новый набор, состоящий из одного примитива. Предполагается, что pi — переменная, в которую ранее было записано имя примитива. Имя созданного набора записывается в переменную S, которую теперь можно использовать для указания на набор.

    Функция удаляет из , если он там присутствовал, иначе — ничего не меняется. Возвращается имя набора.

    Пример работы с набором:

    ; Здесь образуется пауза, в ходе которой пользователь

    ; укажет несколько объектов на экране (примитивов).

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

    ; набор. Формируется внутрипрограммное имя

    ;этого набора, которое возвращается функцией SSGET в переменную SS

    ;Теперь в программе данный набор можно обозначить как SS.

    (SETQ L (SSLENGTH SS))

    ;Определено количество примитивов в наборе SS и записано в L.

    (SETQ SL (SSNAME SS (1-L)))

    ;Выделен последний примитив в наборе SS, его внутрипрограммное

    ;имя возвращено функцией SSNAME в переменную SL

    (SETQ SN (SSADD SL))

    ;Создан новый набор, содержащий последний

    ;примитив из набора SS. Имя нового набора записано в переменную SN.

    (SETQ SS (SSDEL SL SS))

    ;Из SS удален последний элемент. Получавшийся в результате набор будет ;также назван SS.

    (COMMAND «ERASE» SS)

    ;Набор SS удаляется с экрана, т.е. стираются все примитивы, ранее ; помеченные пользователем, кроме последнего (SL).

    5.6. Работа с примитивами. Функции ENTNEXT, ENTLAST, ENTSEL, ENTDEL. Операция REDRAW над примитивом

    Примитивы в ACAD могут быть простыми (линия, окружность, строки текста. ) или составными (полилинии, вставки блоков). Составные примитивы делятся на субпримитивы.

    Например, для полилинии субпримитивами являются вершины, для вставки блоков — атрибуты. С помощью функций типа SS, рассмотренных в п.5.5, могут быть получены либо наборы примитивов, либо примитивы (простые или составные), но не субпримитивы. Функции, рассматриваемые в данном параграфе, позволяют работать с примитивами и субпримитивами.

    Функция возвращает внутрипрограммное имя примитива или субпримитива:

    если не указан, то возвращается первый из примитивов чертежа (неудаленных);

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

    если указан составной примитив; то ENTNEXT возвращает первый субпримитив указанного примитива;

    если указан субпримитив, то ENTNEXT возвращает субпримитив, принадлежащий тому же примитиву, что и указанный, и следующий за указанным;

    если запрашиваемый объект отсутствует, то возвращается NIL.

    Функция возвращает внутрипрограммное имя последнего примитива на чертеже (неудаленного). Субпримитив с помощью ENLAST не выделяется.

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

    Функция возвращает результат в виде списка из двух элементов:

    первый элемент — внутрипрограммное имя примитива;

    второй элемент — точка, в которой было проведено указание, эта точка возвращается в виде списка координат.

    Возвращаемый результат может быть «записан в переменную» с помощью SETQ. Эта переменная впоследствии может быть задана в ответ на любую команду ACAD (в функции COMMAND), требующую выбрать объект и учитывающую точку указания. Кроме того, результат, записанный в данную переменную, может быть «разложен .на составные части»: (CAR ) возвращает имя примитива, (CADR ) вернет точку указания.

    Удаление, восстановление и обновление примитивов:

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

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

    Функция возобновляет изображение примитива после очистки экрана функцией GRCLEAR. Таким образом, рассмотренная в п.5.3 функция REDRAW может также управлять изображением примитива:

    Действие REDRAW зависит от значения аргумента : 1 — примитив перерисовывается; 2 — примитив стирается; 3 — примитив подсвечивается; 4 — подсветка примитива отменяется.

    5.7. Работа с данными примитивов и модификация примитивов. Функции ENTGET, ENTMOD, ENTUPD

    Каждый примитив с точки зрения системы AutoCAD представляет собой достаточно сложную совокупность данных. Представление об этих данных дают правила расположения данных в DXF-файле, который является текстовым описанием чертежа (см. «Руководство пользователя»).

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

    Таким образом, программа на Автолиспе может анализировать и видоизменять чертеж, построенный, например, в режиме диалога с редактором ACAD.

    Формирование списка данных примитива:

    Функция формирует и возвращает список, содержащий данные о примитиве.

    Структура списка напоминает перечень данных о примитиве в DXF-файле и зависит от типа примитива и от того, насколько характеристики примитива соответствуют умолчанию.

    Правила построения списка:

    каждый элемент списка является списком (будем называть его субсписком);

    большинство субсписков имеют вид точечных пар (кроме субсписков, описывающих точки);

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

    первый субсписок имеет вид (-1 . имя-примитива);

    второй: (0. тип-примитива);

    третий: (8. имя-слоя);

    далее следуют некоторые атрибуты примитива в том случае, если их значения отличаются от значений по умолчанию, набор этих атрибутов зависит от версии ACAD, примером может служить (62. код-цвета);

    далее следуют характеристики примитива, состав которых зависит от типа примитива.

    Например, для отрезка прямой (тип = «LINE»):

    Для окружности (тип = «CIRCLE»):

    Для дуги (тип = «ARC»):

    Пример списка, возвращаемого функцией ENTGET для окружности, находящейся на слое «О», синего цвета (номер цвета — 5) с центром в точке (2 2 0) и с радиусом 1.5, изображенной пунктирной линией («DASHED»):

    (10 2.0 2.0 0.0) (40. 1.5)

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

    (SETQ PR (ENTNEXT))

    ; Выделяется первый примитив в базе данных,

    ; имя которого возвращается в PR

    (SETQ SPR (ENTGET PR))

    ;Формируется список из данных, описывающих примитив PR, этот список ;возвращается в SPR

    ; Здесь следуют операции над списком SPR

    ; по изменению каких-либо данных в этом списке

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

    На применение ENTMODE накладываются некоторые ограничения:

    не может быть изменен тип примитива;

    такие атрибуты как Тип линии (и некоторые другие), могут принимать только те значения, которые к данному моменту определены в сеансе работы с ACAD;

    однако слой может быть задан и новый, отсутствовавший к данному моменту.

    Функция ENTMODE может выполняться над примитивом или субпримитивом. Если ENTMODE выполняется над субпримитивом, то видимого изменения на экране не происходит. 122

    С помощью этой функции можно изменить изображение примитива после того, как изменены субприпримитивы этого примитива с помощью ENTMODE.

    Однократное изменение сложного примитива происходит гораздо быстрее, чем его многократная перерисовка после изменения каждого субпримитива.

    5.8. Примеры

    Приведенные ниже примеры демонстрируют различные применения функций для работы с примитивами и наборами. Каждая из этих программ — не только иллюстрация, но и практически полезная функция, которая может пригодиться конструктору, работающему с редактором AC AD. Эти программы иллюстрируют возможности расширения системы AutoCAD с помощью Автолиспа.

    ; Программа 10: Удаление предпоследнего элемента

    (SETQ secondlast (ENTDEL (ENTLAST)))

    Известно, что в редакторе ACAD имеется команда ERASE («СОТРИ»), которая позволяет стереть последний элемент чертежа или элемент, указываемый конструктором. Однако, оба эти способа могут оказаться неудобными в следующей ситуации: конструктор создает сложный насыщенный чертеж и ему не сразу удается правильно построить нужный элемент. Конструктор хотел бы повторить попытку, но при этом сохранить неправильный элемент в качестве «отправной точки», а после удачного построения — стереть этот элемент. Имея описанную выше функцию, он сможет это сделать, подав команду ERASE2.

    Программа» 10 решает задачу просто и изящно:

    стирается последний примитив (но его имя записывается в переменную secondlast);

    стирается примитив, ставший последним, т.е. бывший предпоследний;

    путем повторного применения функции ENTDEL по отношению к примитиву secondlast стертый последний элемент восстанавливается на экране.

    Программа 11, приведенная ниже, дает возможность значительно упростить решение задачи, нередко встречающейся на практике при конструировании сложных объектов, — перенесение всех примитивов, находящихся на одном слое, на другой слой [6].

    Средства ACAD позволяют решить такую задачу только с помощью метода последовательного указания всех переносимых примитивов -долгого и неудобного.

    Алгоритм, реализуемый Программой 11:

    Установить переменную found в NIL (found «NIL свидетельствует о том, что на слое не найдено ни одного примитива).

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

    Выдать сообщение о том, что поиск начался.

    Записать в entn имя первого примитива чертежа

    ПОКА entn существует ЦИКЛ

    Получить в cnt список, соответствующий entn

    ЕСЛИ имя слоя в списке ent совпадает с именем

    старого слоя ТО

    Заменить слой примитива новым слоем

    Установить found =t (примитив найден)

    Записать в entn имя очередного примитива

    ЕСЛИ founds NIL (примитив отсутствует) ТО

    Выдать сообщение об отсутствии примитивов

    ; Программа 11 Перенос примитивов с одного слоя

    (DEPUN C:CNGLAY (/cmd entn ent)

    (SETVAR «CMDECHO» 0)

    (SETQ oldlyr (STRCASE (GETSTRINO

    «\n Введите старое имя слоя:»))

    newlyr (STRCASE (OETSTRING

    «\n Введите новое имя слоя:»)))

    (PRINC «\n Ведется поиск примитивов на слое»)

    (SETQ entn (ENTNEXT))

    (SETQ ent (ENTGET entn))

    (IF ( = (CDR (ASSOC 8 ent) oldlyr)

    (COMMAND «CHANGE» entn»»

    (SETQ entn (ENTNEXT entn))

    (PRINC (STRCAT «\n На слое» oldlyr» нет примитивов»))

    (SETVAR «CMDECHO» 1)

    Возможно, два ключевых действия нуждаются в комментариях.

    1. Функция (ASSOC 8 ent) выполняет ассоциативный поиск в списке ent, являющемся описанием примитива в базе данных чертежа. Это описание, как указывалось, само состоит из списков — точечных пар, среди которых обязательно имеется пара вида (8.имя_слоя). Этот подсписок и выделяется из общего списка ent с помощью ASSOC. Функция CDR «обрезает» этот подсписок, сохраняя вторую его часть -имя слоя.

    2. Аргументы команды CHANGE («Изменить») перечисляются в соответствии с тем, как происходили бЫ ответы на вопросы этой команды в диалоге 1: ACAD:

    entn — имя примитива в ответ на запрос объекта;

    » » указывает, что выбор объектов закончен;

    «p» указывает на то, что нужно изменить одно из свойств объекта;

    «LA» говорит о том^что этим свойством является слой;

    newlyr указывает новое имя слоя;

    » » соответствует нажатию ENTER,завершающему выполнение команды.

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

    1. Используются локальные переменные.

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

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

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


    Рассматриваемая далее программа 12, составленная на базе программы, приведенной в работе [5], может оказаться полезной для тех, кто решает задачи разводки коммуникаций, например трубопроводов в пространстве, где важным критерием является суммарная длина трасс. Предлагаемая программа позволяет вычислять суммарную длину всех полилиний, имеющихся в чертеже. (Если изменить вид «фильтра» в функции SSGET, то можно просчитывать полилинии, обладающие каким-либо общим свойством, например, находящиеся на заданном слое). Для понимания программы необходимо иметь представление о том, как устроен в базе данных список, соответствующий полилинии, которая является сложным примитивом, содержащим в качестве субпримитивов вершины полилинии. Достаточно знать следующее.

    1. В набор, образуемый с помощью SSGET, попадают только основные примитивы. Тип примитива для полилинии — POLYLINE.

    2. Для того чтобы попасть на первую вершину полилинии, нужно применить функцию ENTNEXT, где аргументом является имя основного примитива (типа PLINE). Субпримитив вершины полилинии имеет тип VERTEX. Субсписок, содержащий координаты вершин, имеет код 10.

    3. Для перемещения к следующей вершине также используется ENTNEXT, где аргументом является имя субпримйтива — предыдущей вершины.

    4. Признаком окончания списка для полилинии служит примитив типа SEQEND.

    Алгоритм, реализуемый Программой 12:

    Записать 0 в суммарную длину трасс tsum

    Составить набор sspline, содержащий все полилинии чертежа

    Определить число полилиний в наборе — ssl

    Записать номер первой полилинии 0 в num

    Получить имя очередной полилинии npline по ее номеру в

    Получить имя первого субпримитива en

    Записать в pi nil

    Получить е1 — список для примитива en

    ПОКА тип en равен VERTEX ЦИКЛ (т.е. субпримитив есть вершина)

    Записать в р1 точку — вершину

    Найти расстояние от р1 до точки — вершины и прибавить

    это расстояние к tsum

    Записать в р1 точку — вершину

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

    Получить el — список для примитива en

    Увеличить пит на единицу

    Выдать значение суммарной длины трасс tsum

    ; Программа 12: Определение суммарной длины

    (DEFUN LTRASS (/sspline ssl num npline pi en el tsum)

    (SETQ sspline (SSGET «X» ‘((0. “POLYLINE»))))

    (SETQ ssl (SSLENGTH sspline))

    (SETQ p1 (CDR (ASSOC 10 el)))

    (SETQ tsum (+ tsum (DISTANCE p1

    (SETQ p1 (CDR (ASSOC 10 el))))))

    (SETQ en (ENTNEXT en))

    (SETQ el (ENTGET en))

    (PROMPT “\n Общая длина трасс =»)

    В этой книге описаны основные функции языка Автолисп для AutoCAD версии 10. Знания этих функций достаточно для решения большинства практических задач: построения чертежей типовых деталей и узлов, расчетно-графических задач, работы с файлами, анализа и преобразования изображений, расширения системы команд графического редактора ACAD. Некоторые функции (около 20) остались за рамками описания, в том числе функции, связанные с распределением оперативной памяти, отладкой программ и др.

    Все возможности языка Автолисп сохранились в последней версии системы AutoCAD (версия 11, русскоязычная, поставляется с конца 1991 г). Помимо этого, в версии 11 имеется возможность графического программирования с использованием языка С. Для выполнения программ, написанных на языке С, необходим интерпретатор Автолиспа.

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

    Наряду с программированием на Автолиспе существует и другой способ получения модели семейства чертежей, отличающихся значениями размеров, — метод параметризации. Этот метод реализован в таких системах, как PARACAD, SYNTHESIS, CUSP, p-Design, и других, работающих совместно с системой AutoCAD. Модель формируется с помощью системы параметризации в режиме графического редактирования, т.е. значительно удобнее и быстрее, чем программирование. Однако круг задач, решаемых с помощью системы параметризации, значительно уже, чем круг задач, для решения которых используется Автолисп, и ограничен получением чертежей, различающихся только размерами. Например, чертеж вала с произвольным количеством ступеней, приведенный в Приложении, нельзя получить методом параметризации.

    Пример программы на языке Автолисп для получения семейства чертежей

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

    При составлении программы принимались следующие решения:

    масштаб изображения 1:1;

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

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

    контур создается полилинией шириной 0.5, что позволяет’ получать на изображении различную толщину для контурных и прочих линий;

    диаметры проставляются так, что размерная линия отстоит на 10 см от правой границы данной ступени, следовательно, при слишком малой длине ступени размерный текст может наложиться на линию контура;

    в связи с этим пользователю предоставлена возможность выбора способа простановки диаметров: автоматически или «вручную» с помощью команд ACAD.

    ; Программа 13. Формирование изображения вала

    ; с заданным числом ступеней

    (DEFUN ID ( ) ; Функция для ввода исходных данных

    (SETQ d (GETDIST (STRCAT «\nВведите диаметр ступени» (ITОА i) » d = «))

    1 (GETDIST «\nВведите длину ступени 1= «))

    (DEFUN STO ( ) ;Функция для изображения первой

    (SETQ p1 (POLAR bp (/ PI 2) (/ d 2))

    p3 (POLAR p2 (* 1.5 PI) d)

    p4 (POLAR p3 PI 1)

    pl (POLAR bp 0 1) ;pl — базовая точка для новой ступени

    (COMMAND «PLINE» p1 «W» 0.5 0.5 p2 p3 p4 «С»)

    (SETQ sp (LIST (LIST p2 p3))); подготовка списка

    ; пар точек для простановки диаметров

    (DEPUN ST1 ( ) ; Функция для изображения ступени

    ; с меньшим диаметром

    (SETQ p1 (POLAR pl (/ PI 2) (/ d 2))

    p4 (POLAR p3 PI 1)

    (COMMAND «PLINE» p1 «W» 05 05 p2 p3 p4″ «)

    (SETQ sp (CONS (LIST p2 p3) sp)) ; дополнение

    (DEFUN ST2 ( ) ; Функция для изображения ступени

    ; с большим диаметром

    (SETQ p1 (POLAR pl (/ PI 2) (/ d0 2))

    p2 (POLAR p1 (/ PI 2) (/ d 2))

    p4 (POLAR p3(* 1.5 PI) d)

    p5 (POLAR p4 PI 1)

    p6 (POLAR pl (‘1.5 PI) (/ d0 2))

    (COMMAND «PLINE» p1 «W» 0.5 0.5 p2 p3 p4 p5p6″ «)

    (SETQ sp (CONS (LIST p3 p4) sp))

    (DEFUN RZM ( ) ; Функция для простановки размеров

    (PROMPT «\nНужно ли проставлять диаметры? «)

    (IF ( = (READ-CHAR) 10) ; В случае ответа

    (FOREACH рр sp ; Цикл по элементам

    ; списка sp — парам точек

    ; Выделение первой точки

    ; Выделение второй точки

    рЗ (LIST (- (CAR p1) 10) (CADR p1))

    ; Точка для размерной линии

    (COMMAND «DIM1» «VER» p1 p2 рЗ

    (SETQ pr (GETPOINT «\nУкажите точку для простановки первого размера»)

    ; Реверсирование списка точек

    ; Выделение первой пары точек из списка

    ; Выделение второй (нижней) точки из пары

    (COMMAND «DIM» «HOR» bp p1 pr» «)

    ;Простановка длины первой ступени

    (SETQ sp (CDR sp)) ; Удаление первой пары точек

    (FOREACH рр sp ;Цикл по оставшемуся списку пар

    (SETQ p1 (CADR рр))

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

    ; Завершение команды DIM — аналог Ctrl/C

    (DEFUN C:VAL ( ) ; Головная функция — построение

    (SETVAR «CMDECHO» 0) ;Отмена эха команд

    (SETVAR «BLIPMODE» 0)

    ;Отмена маркировки точек примитивов

    (SETQ bp (GETPOINT «\nУкажите базовую точку»))

    ;3апрет на ввод неположительных чисел и пробела

    (SETQ n (GETINT «\nВведите число ступеней вала n = «))

    (SETQ i 1) ; i — номер ступени

    (ID) ; Ввод исходных данных для

    (STO) ; Изображение первой ступени

    (ID); Ввод исходных данных для i-й ступени

    (ST1) ;Изображение ступени с меньшим диаметром

    (ST2) ;Изображение ступени с большим диаметром

    AutoLISP / VisualLISP

    В предыдущей части уже были рассмотрены некоторые особенности работы vla-функций применительно к графической составляющей dwg-файла. Но были рассмотрены далеко не все вопросы. В частности, не было освещено «создание примитива через ActiveX без явного указания необязательных настроек». И никак не был затронут вопрос о модификации созданного примитива (точнее, удобства и очевидности изменения).

    Начнем, пожалуй, с «настроек по умолчанию». Если в DXF Reference напрямую указываются необязательные параметры (то есть принимаемые текущими), то при работе через ActiveX ситуация иная: указываются только необходимые для создания примитива параметры. Все остальное необходимо задавать отдельными вызовами соответствующих функций. К таким параметрам можно отнести, например, цвет примитива (принимается текущий); тип линии примитива; слой примитива и т.п.
    Создадим и активируем пользовательскую систему координат, ось Z которой непараллельна мировой и запустим следующие коды:

    Обратите внимание, что в первом случае окружность создается в мировой системе координат, а вторая — в текущей. При этом координаты центра у них не совпадают. Поигравшись с trans, можно добиться полного соответствия результатов vla- и ent-функций. Но пока разговор немного не об этом.

    Разберемся с модификацией примитивов.

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

    Сначала разберем вариант внесения изменений в ename-представление примитива:

    Преобразуем его в список:

    Ненужные и некритичные элементы списка удалены.
    Последовательность изменения такова: сначала надо изменить список; потом — модифицировать примитив; потом — обновить его графическое представление. Для этого обычно используются соответственно subst, entmod, entupd. Допустим, мы хотим изменить значение 210 группы на ‘(-1.0 0.0 0.0). Сначала проверим работу subst:

    Получилось? Получилось (еще бы!). Теперь обновляем примитив:

    Активируем AutoCAD и наблюдаем за изменениями примитива. Казалось бы, достаточно просто. Но не без некоторых подводных камней.
    Например, в примитиве могут повторяться ключи точечных пар (пример можно посмотреть чуть выше — в частности, это группы 100), и использованный assoc вернет «не то». Можете попробовать, используя представленный механизм, заменить координаты второй (или n-дцатой) вершины обычной полилинии. Кроме того, некоторые точечные пары могут вообще отсутствовать при создании примитива (например, пара 370 — вес линии; или группа 3 в многосточном тексте), и в таком случае приходится ее принудительно добавлять. Внесение же изменений, например, в трехмерную полилинию для неподготовленного человека сродни шаманству.

    Теперь возьмемся за изменение vla-представления.
    Отменим только что сделанные изменения и вернемся в VLIDE:

    Результат немногим более информативен, чем показанный ранее (entget (entlast)). Посмотрим свойства и методы vla-примитива:

    Здесь сначала показываются доступные свойства примитива; следом идут его методы. Мы пока будем работать именно со свойствами, а методы оставим «на потом, если руки дойдут. И если кому-то понадобится».
    Внесение изменений в vla-представления отличается от изменений ename-представлений. И отличия тут достаточно серьезные.
    Прежде чем мы продолжим, следует напомнить, что при работе через ActiveX есть непреложное правило: первым аргументом функции обязательно идет указатель на объект, с которым выполняется работа. Без этого дальнейшее движение невозможно. Дополнительные данные по работе с ActiveX внутри VisualLISP можно посмотреть здесь.

    Итак, отличия.
    Во-первых, существует два варианта задания / чтения свойств: сокращенная и полная. У каждой есть свой плюс и свой минус. Сокращенная короче; полная — устойчивее.
    Во-вторых, обновление большинства примитивов (спасибо Евгению Елпанову) при работе через ActiveX происходит после выхода из функции, в которой выполнялось изменение свойства примитива. То есть если написать код вида:

    ( defun test ( / ent )
    ( setq ent ( vlax — ename -> vla — object ( car ( entsel ) ) ) )
    ( test1 )
    ( test2 )
    ) ;_ end of defun

    ( defun test1 ( )
    ( vla — put — color ent 1 )
    ) ;_ end of defun

    ( defun test2 ( )
    ( vla — put — lineweight ent aclnwt211 )
    ) ;_ end of defun

    то обновление примитива будет выполнено 3 раза: первый раз при выходе из test1, второй — при выходе из test2, третий — при выходе из test. При работе, например, с большими и насыщенными блоками, бездумное использование подобного подхода породит приличные проблемы с быстродействием готового кода. Особняком здесь стоят таблицы AutoCAD, но разговор о них впереди.
    При «разборе» ename-представлений мы рассматривали изменений нормали объекта (группа 210). В vla-представлении это Normal. Проверим свойство Normal у пока неизмененного объекта (проверку будем выполнять в сокращенной и в полной форме):

    И списком здесь, казалось бы, и не пахнет.
    Ну, на самом деле не совсем так. Точнее, совсем не так. Это просто ActiveX-представление списка (так называемый variant). Его можно преобразовать в обычный список:

    Но нам-то надо наоборот: готовый список (точнее, трехмерные координаты точки) преобразовать во что-то «этакое».
    Именно для списков из 3 чисел Autodesk внедрила функцию (vlax-3d-point). Вот ее-то и используем:

    И все бы хорошо, да вот незадача — координаты центра окружности в мировой системе координат при изменении через entmod меняются, а при vlax-put-property — нет. И это только потому, что для окружности в ename=представлении в группе 10 хранятся координаты в системе координат объекта (OCS). Мы же не трогали группу 10? Не трогали. Вот и получаем «ускакавший» примитив.
    И если бы это был один примитив с подобным поведением! Так ведь нет — для примитива POINT (точка) координаты (кстати, тоже группа 10) хранятся в мировой системе координат; для LINE (отрезки) — тоже мировая; для TEXT (текста) — в OCS и т.д.
    Поэтому при работе через ename приходится постоянно отслеживать — какой примитив и как меняется.

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

    LISP. Атом первый

    Привет, Хабр!
    LISP заинтересовал меня уже давно, но, к сожалению, активно использовать свои знания и стремления на практике шанса не было. Скоро новый учебный год, а значит у меня опять будет возможность изучать и, уже второй год, преподавать студентам LISP. Еще одной проблемой, кроме традиционного отсутствия интереса к сложным вещам, кажется отсутствие литературы. Да и вообще, тема LISP-а в интернете, а тем более в рунете освещена слабо. Вот и на Хабре публикаций довольно мало.

    Надеюсь, эта статья понравится общественности и откроет серию, повествующую об одном из наиболее интересных и наименее понятных (хотя до brainfuck и далеко) языков программирования – LISP. Ведь, как это не банально, еще один язык — еще одна жизнь

    Начнем с базовых понятий LISP-а – атомов и списков. Немного позже, если будет интересно, в приквеле «Атоме нулевом» можно будет более подробно поговорить о философии и причинах возникновения LISP, а так же о современных направлениях его использования.

    Краткая история

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

    Чем же отличается LISP от традиционных языков программирования? Рассмотрим ключевые особенности:

    • Формы представления программ и обрабатываемых данных в LISP идентичны и являются списочными структурами. В связи с этим открывается несколько интересных возможностей – например, обработка программой других программ. Не говоря уже об универсальности, расширяемости и масштабируемости самого синтаксиса. Ядро LISP, написанное на LISP, занимает менее 200 строк, а интерпретатор ПРОЛОГа – чуть более 50 строк.
    • Реализация списков позволяет не задумываться об управлении памятью, резервировании и освобождение ячеек происходит динамически. Таким образом можно говорить о появлении сборщика мусора уже в первых версиях LISP.
      LISP не является строго типизированным языком программирования. Сегодня это мало кого удивит, однако стоит напомнить, что на начальным этапах данная концепция противостояла строготипизированному Фортрану.
    • Префиксная нотация дает широкие возможности для синтаксического анализа выражений, а так же обеспечивает возможность использования единого списочного контекста для программ и данных.
    • Использование огромного количества скобок. Именно поэтому наряду с традиционной расшифровкой LISP (LISt Processing) существует и Lots of Idiotic Silly Parentheses.
    • Не следует забывать про существования LISP-машин – вычислительных машин, архитектура которых оптимизирована для эффективного выполнения программ на языке LISP. LISP-машины не слишком распространены, по некоторым данным их количество во всем мире не превышает 10000. (Насколько мне известно, в Украине нет ни одной. Лично я видел за свою жизнь лишь одну – в Бухарестском университете, активно используемые на лабораторных работах студентами). LISP-машины исследовательского центра Xerox стали прародителями некоторых распространенных идей и технологий: сборка мусора, лазерная печать, многооконные системы и т.д.). Надеюсь, у меня появится шанс поговорить об этом подробнее в одном из следующих выпусков.

    Типы данных

    Традиционно в LISP рассматривают два типа атомов: символы и числа. Символы могут обозначать числа, строки, сложные структуры, функции и другие объекты. Ограничения на имена символов зависят от используемого диалекта, но большинство из них не накладывает практически никаких ограничений на используемые в именах символы. Кроме того, опять же в большинстве диалектов, имена символов не зависят от регистра.
    Некоторые символы имеют специальное назначение – это константы, встроенные функции, T (true, истина) и NIL (false, ложь).

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

    Например, точечными парами являются выражения:

    Атомы и точечные пары объединяют под общим названием S-выражения (S-expression, symbolic expression). Особым видом S-выражения является список, выражаемый следующим образом:

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

    Крылья, ноги… Главное хвост

    И голова и хвост являются ключевыми понятиями в списочном контексте LISP. Первый элемент списка именуется головой списка, все остальные элементы – хвостом. Для работы с головой и хвостом существует набор базовых функций, рассмотренный немного ниже.
    Пустой список эквивалентен паре пустых скобок:
    NIL ().
    Непустой список, состоящий из элементов a1, a2, a3… в соответствии с правилами записи S-выражений может быть записан следующим образом:

    В LISP список можно записать и последовательностью элементов, заключенных в скобки и разделенных пробелами. По большему счету, список – это многоуровневая структура данных, для которой архиважна последовательность открывающих и закрывающих скобок.
    Элементами списка могут быть атомы и списки, в том числе и пустой список. Например, () – пустой список, а (NIL) – список, состоящий из одного элемента NIL – что эквивалентно (()).
    Следует понимать, что обычный синтаксис S-выражений может использоваться наравне со списочным синтаксисом, например, следующие выражение эквивалентны:

    (a.(b.nil)), (a b.nil), (a b nil), (a b)

    Если кому-нибудь интересно – можно будет рассказать и о внутреннем представлении списков в памяти. Это вполне самостоятельная и по интересу и по объему тема.

    Основные функции и предикаты

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

    Традиционном к базовым функциям относят QUOTE, CAR, CDR, CONS, ATOM, EQ.

    Функция QUOTE

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

    (+ 5 10) -> 15 ; происходит вычисления выражения 5+10 и вывод результата
    (quote (+ 5 10)) -> (+5 10) ; вычисление блокируется

    Функцию QUOTE можно записать и короче:

    ‘(+ 5 10) -> (+ 5 10) ; ‘ – равноценно quote

    Функция CAR

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

    car (список) -> S-выражение.

    (car ‘(a b c)) -> a
    (car ‘(a)) -> a
    (car ‘a) -> ERROR: a is not a list
    (car ‘(nil)) -> nil
    (car nil) -> nil
    (car ‘(nil a)) -> nil

    Для удобство головой пустого списка считается NIL.

    Фунция CDR

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

    cdr (список) -> список

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

    (cdr ‘(a b c)) -> (b c)
    (cdr ‘(a)) -> nil
    (cdr ‘a) -> ERROR: a is not a list
    (cdr ‘(a (b c))) -> ((b c))
    (cdr ‘(nil a)) -> (a)
    (cdr ()) -> nil

    Функции CAR и CDR реализованы во всех диалектах LISP, но в некоторых для них созданы и синонимы: FIRST и REST, HEAD и TAIL).

    Функция CONS

    Предназначена для создания нового списка из переданных ей в качестве аргументов головы и хвоста:
    cons (s-выражение, список) -> список

    (cons ‘a ‘(b c)) -> (a b c)
    (cons ‘a nil) -> (a)
    (cons nil ‘(b c)) ->(nil b c)
    (cons nil nil) ->(nil)
    (cons ‘(a b) ‘(c)) ->((a b) c)

    Фактически функция CONS является антиподом функций CAR и CDR:

    (cons (car ‘(a b c)) (cdr ‘(a b c))) -> (a b c)

    Функция ATOM

    ATOM и EQ являются предикатами – т.е. функциями, проверяющих соответствие аргумента некоторому свойству и возвращающими T или NIL в зависимости от успешности проверки.

    Предикат ATOM проверяет, является ли объект, переданный в качестве аргумента, атомом:

    atom (S-выражение)

    (atom ‘a) -> t
    (atom ‘(a b c)) -> nil
    (atom ()) -> t ;Т.к. пустой список равен nil, а следовательно атомарен

    Функция EQ

    Предикат, проверяющий идентичность двух символов.

    eq (атом, атом)

    (eq ‘a ‘b) -> nil
    (eq ‘a ‘a) -> t
    (eq ‘a (car ‘(a b)) -> t
    (eq () nil) -> t

    Следует помнить, что предикат EQ применим лишь к атомарным аргументам и не может быть использован для списков. Так же не следует использовать EQ при сравнении чисел.

    Более общим по сравнению с EQ является предикат EQL, позволяющий сравнивать однотипный числа:

    (eq 1.0 1.0) -> nil
    (eql 1.0 1.0) -> t

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

    (eql 1 1.0) -> nil
    (= 1 1.0) -> t

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

    (equal ‘a ‘a) -> t
    (equal ‘(a b) ‘(a b)) -> t

    Наиболее общим предикатом является EQUALP, позволяющий сравнивать произвольные объекты.

    Функция NULL

    NULL проверяет, является ли объект, переданный в качестве аргумента, пустым списком:

    (null ‘()) -> t
    (null ‘(a b c)) -> nil
    (null nil) -> t
    (null t) -> nil

    Судя по двум последним примером, можно сделать вывод, что функцию NULL можно использовать и как логическое отрицание. Для этих же целей в LISP существует и предикат NOT.

    Что дальше?

    Надеюсь, что смог заинтересовать. В следующий раз я планирую рассказать о существующих диалектах LISP (хотя на первых порах достаточно будет университетского XLisp), менее часто используемых базовых функциях, сворачивании CAR и CDR в что-то вроде CAAAADDAAR и определении собственных функций. Позже — рекурсия, управляющие структуры, область действия, ввод-вывод. Еще позже — если не надоем — о функционалах, макросах, свойствах символов и замыканиях. Ну и конечно, о том, о чем попросит общественность.
    До встречи!

    Функции autolispа

    В результате совершенствования AutoLISP появилась интегрированная среда разработки Visual LISP (VLISP), которая включает в себя компилятор, отладчик и ряд других средств, повышающих производительность. В языке появились новые возможности, которые позволяют взаимодействовать с объектами с использованием интерфейса ActiveX. Кроме того, на VLISP с помощью реакторов объектов можно обрабатывать различные события.

    В отличие от ObjectARX или VBA, в Visual LISP для каждого чертежа, открытого в многодокументной среде AutoCAD, имеется свое пространство имен и собственная среда. Пространство имен каждого чертежа является изолированным, что позволяет избегать конфликтов имен переменных, процедур AutoLISP среди одновременно открытых чертежей. Например, следующее выражение по-разному устанавливает значение переменной а для различных документов.

    В Visual LISP имеется механизм загрузки обозначений и переменных из одного пространства имен в другое. Для получения более подробной информации о пространствах имен см. раздел справки AutoLISP Developer’s Gu > «Справка для разработчиков».

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

    Приложения Visual LISP могут загружаться из файлов трех форматов:

    • LSP-файлы (с расширением . lsp)—Текстовый файл ASCII, содержащий код программы AutoLISP.
    • FAS-файлы (с расширением . fas)—двоичная скомпилированная версия одного файла программы LSP.
    • VLX-файлы (с расширением . vlx)—скомпилированный набор одного или нескольких файлов LSP или DCL-файлов.

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

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

    О программировании средствами AutoLISP см. раздел справки AutoLISP Developer’s Gu >AutoLISP Reference (Справочник по AutoLISP). Для отображения Справки для разработчиков следует щелкнуть на стрелке раскрывающегося списка, расположенной на панели инструментов «Инфоцентр» справа от кнопки «Справка». В появившемся меню выберите «Дополнительные ресурсы» «Справка для разработчиков». В программах на AutoLISP можно использовать диалоговые окна. Документация о программируемых диалоговых окнах содержится только в документации AutoLISP Developer’s Guide (Руководство по AutoLISP для разработчиков).

    Вызов интегрированной среды разработки приложений Visual LISP.

    Управляет дополнительным выбором объектов (заменяет или дополняет текущий набор выбранных объектов).

    Управляет автоматическим созданием рамки выбора объектов в ответ на запрос «Выберите объекты».

    Илон Маск рекомендует:  Direct draw термины и концепции
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL