Две функции - (write-char
7.4. Пример обработки файла
Поставим следующую задачу. Пусть в результате выполнения программы расчета получены координаты некоторого множества точек, которые следует использовать для построения проходящего через них примитива. Структура файла выглядит следующим образом:
¬¬1¬¬¬¬0¬¬¬¬¬0.0000¬¬¬¬¬¬¬0.0000
¬¬2¬¬¬¬5¬¬¬¬¬6.4214¬¬¬¬¬¬¬8.2349
¬¬З¬¬¬10¬¬¬¬¬8.7965¬¬¬¬¬¬26.1500
и так далее. В четырех столбцах файла расположены следующие параметры: порядковый номер строки, значение аргумента (например, указан шаг счета нарастающим итогом), координаты X и Y расчетных точек, символом ¬ обозначены обусловленные форматом вывода незаполненные позиции в строках данных.
Предположим далее, что численные значения координат могут содержать три знака перед десятичной точкой и включать в себя символ отрицательного числа - знак минус. Задача заключается в том, чтобы извлечь значения координат из файла и передать их Автокаду.
Длина строки файла составляет 32 позиции. В соответствии с оговоренным условием значения координат могут занимать 9 позиций. Для перестраховки установим длину читаемых позиций, равной 10 символам (вдруг в файле неожиданно для нас окажется число с четырехзначной целой частью).
С точки зрения составления программы, нам следует выполнить следующие операции: организовать цикл, внутри которого были бы прочитаны значения координат, и присвоить эти значения точкам будущего примитива. В этой связи следует упомянуть о существенном недостатке Автолиспа: в нем отсутствует понятие индексированной переменной, свойственное операторным языкам. Поэтому процесс вычерчивания примитива приходится производить параллельно с извлечением данных, а количество извлекаемых за один прием данных ограничивать (в рассматриваемом примере одной точкой).
Итак, напишем функцию, извлекающую из чертежа координаты точек.
1 (defun pnt ()
2 (setq lin (read-line file1))
3 (setq x1 (atof (substr lin 10 10)))
4 (setq y1 (atof (substr lin 23 10)))
5 (setq pt1 (listx1 y1))
)
Строка 1 устанавливает имя программируемой функции pnt, строка 2 считывает из файла, определенного дескриптором file1, первую строку lin, рассматривая ее как строковую переменную. Далее (строка 3) функция substr считывает информацию, содержащуюся в позициях 10...19 строки lin, функция atof преобразует считанную строковую переменную в числовую, а уже setq приписывает это значение координате x1. Аналогичные действия выполняет строка 4, устанавливая координату y1. Наконец, выделенные координаты приписываются точке pt1 (строка 5).
Если остановиться на вычерчивании за один прием участка полилинии, проходящего через две точки, то соответствующая функция будет выглядеть, например, следующим образом:
(defun otr ()
(command “pline” pt1 “w” “0” “” pt2 “”)
).
Теперь можно написать полностью программу, обрабатывающую файл результатов расчета любой длины.
;;; ==============================================
(defun cdraw ()
;;; ==============================================
;;; подавление вывода текста на экран
(setq svar_old (getvar “cmdecho”))
(setvar “cmdecho” 0)
;;; загрузка штрих-пунктирной линии
(if (tblsearch "ltype" "Acad_ISO04w100")
(princ)
(command "linetype" "load"
"Acad_ISO04w100" "acadiso.lin" "" "")
)
;;; сохранение текущего слоя
(setq lay_old (getvar "clayer"))
;;; создание нового слоя в чертеже
(command "layer" "new" "cam"
"c" "magenta" "cam"
"I" "Acad_ISO04w100" "cam"
"s" "cam" "")
;;; вызов файла и чтение первой строки
(setq get_F (getstring "Введите имя файла:"))
(setq file1 (open (strcat get_F) "r"))
(setq t1 (pnt))
;;; организация цикла счета строк файла
(setq k 0)
(while (read-line file1)
(setq k (+ k 1))
)
(close file1)
;;; чтение файла и обрисовка профиля
(setq file1 (open get_F “г”))
(repeat (- k 1)
(setq t2 (pnt))
(otr)
(setq t1 t2)
)
(close file1)
(command “layer” “s” lay_old)
(setvar “cmdecho” svar_old)
(princ)
)
Разумеется, в текст программы должны быть включены функции, описанные в этом параграфе (имеются в виду функции pnt и otr).
Приведенный пример представляет собой фрагмент программы, используемой для автоматической обрисовки центрового профиля кулачка. Дополнительно реальная программа выполняет операции объединения сегментов полилинии, генерирования типа линии, размещения изображения профиля в нужном месте чертежа и поворота изображения на заданный угол. To обстоятельство, что профиль очерчивается отрезками прямых, не играет существенной роли, так как при малом шаге счета (он в реальной программе принят равным одному угловому градусу, а может быть установлен сколь угодно малым) визуально профиль не отличается от такового, построенного с помощью сплайна.
И последнее замечание. Приведенный фрагмент содержит два цикла: while и repeat. Это сделано лишь для иллюстрации принципов их построения. В реальной программе достаточно одного цикла while.