Gigachat сгенерировал код на Autolisp

Kirill
отредактировано 10 Mar Раздел: Полезные дополнения

Попросил я сгенерировать код на Autolisp чтобы он работал в nanoCAD и он конечно же генерирует ошибки. А их довольно трудно отладить, так как nanoCAD даже не указывает номер строки где была ошибка (как мне не хватает VisualLISP). Не поможете мне немного поправить программу?

Задание:

Необходимо запросить имя файла с расширением CSV и указанием пути его сохранения, а затем открыть его для записи. Необходимо циклично получать данные от пользователя и в конце цикла записывать их в файл одной строкой до тех пор пока первый ввод данных не окажется пустым и затем закрыть файл и завершить работу программы. Во время работы цикла необходимо просить выбрать в текущем чертеже однострочный текст и назвать запрос "введите имя куста". К полученному из чертежа тексту добавить ; и записать в файл. Попросить пользователя выбрать полилинию и назвать запрос "укажите ндс". Проверить количество вершин выбранной полилинии и если их больше 2, то сообщить об ошибке и попросить указать другую полилинию. Попросить пользователя выбрать точку на экране с запросом "укажите начало ндс" . Вычислить какая из точек выбранной ранее полилинии ближе всего к выбранной точке и из этой точки поликлиники нарисовать отрезок длинной 10 единиц вертикально вверх. Записать в файл координату x точки из которой был нарисован отрезок и добавить ; Записать в файл координату y точки из которой был нарисован отрезок и добавить ; Вычислить угол между нарисованным отрезком и выбранной полилинией и записать его в файл добавив ; Запись данных во время одного цикла производить в одну строку файла. Удалить нарисованный отрезок. Запустить следующий цикл.

Результат:

;; Функция для открытия файла CSV и получения имени файла
(defun GetCSVFile ()
(setq fileName (getfiled "Select CSV File to Save Data" "" "csv" 16))
(if (= nil fileName)
(progn
(princ "\nNo file selected. Exiting program.")
(exit)
)
)
(open fileName "w")
)

;; Функция для вычисления расстояния между двумя точками
(defun DistanceBetweenPoints (pt1 pt2)
(sqrt (+ (expt (- (car pt2) (car pt1)) 2) (expt (- (cadr pt2) (cadr pt1)) 2)))
)

;; Функция для нахождения ближайшей точки полилинии к заданной точке
(defun FindClosestVertex (pline pt)
(setq plinePts (vlax-safearray->list (vla-get-coordinates (car pline))))
(setq minDist nil)
(foreach vertex plinePts
(setq dist (DistanceBetweenPoints vertex pt))
(if (or (null minDist) (< dist minDist))
(progn
(setq minDist dist)
(setq closestPt vertex)
)
)
)
closestPt
)

;; Основная функция программы
(defun c:MainProgram (/ csvFile outputString textObj polyline ndsPoint closestPt lineStartAngle lineEndAngle)
(vl-load-com)

;; Открываем файл CSV для записи
(setq csvFile (GetCSVFile))

;; Цикл для ввода данных и выполнения операций
(while t
;; Просим выбрать однострочный текст
(setq textObj (entsel "\nSelect single-line text object: "))
(if (not (and (listp textObj) (= "TEXT" (cdr (assoc 0 (entget (car textObj)))))))
(progn
(princ "\nSelected entity is not a single-line text. Please try again.")
(continue)
)

;; Получаем текст из выбранного объекта
(setq bushName (cdr (assoc 1 (entget (car textObj)))))

;; Добавляем введённый текст в строку вывода
(setq outputString (strcat bushName ";"))

;; Просим выбрать полилинию
(setq polyline (entsel "\nSelect a polyline for NDS: "))
(if (not (listp polyline))
(progn
(princ "\nInvalid selection. Try again.")
(continue)
)
)

;; Проверяем количество вершин полилинии
(setq plinePts (vlax-safearray->list (vla-get-coordinates (car polyline))))
(if (<= (length plinePts) 2)
(progn
(princ "\nPolyline must have more than two vertices. Select another one.")
(continue)
)
)

;; Просим выбрать начальную точку НДС
(setq ndsPoint (getpoint "\nSpecify the start point of NDS: "))

;; Находим ближайшую точку полилинии к указанной точке
(setq closestPt (FindClosestVertex polyline ndsPoint))

;; Рисуем отрезок длиной 10 единиц вверх от ближайшей точки
(command "_line" closestPt (polar closestPt pi/2 10) "")

;; Добавляем координаты начала отрезка в строку вывода
(setq outputString (strcat outputString (rtos (car closestPt)) ";" (rtos (cadr closestPt)) ";"))

;; Вычисляем угол между отрезком и полилинией
(setq lineStartAngle (angle closestPt (caddr plinePts)))
(setq lineEndAngle (angle closestPt (cadddr plinePts)))
(setq angleDiff (abs (- lineStartAngle lineEndAngle)))

;; Добавляем угол в строку вывода
(setq outputString (strcat outputString (rtos angleDiff) ";"))

;; Удаляем нарисованный отрезок
(command "_erase" "_last" "")

;; Записываем строку в файл
(write-line outputString csvFile)

;; Продолжаем цикл
(princ "\nNext iteration...")
)

)

Тэги темы:

Комментарии

    1. Есть VSCode + AutoLispExtension
    2. Надо к ближайшей точке или к ближайшей вершине?
    3. На фига строить отрезок? Его нужность вызывает серьезные сомнения
    4. Общая организация кода вызывает оторопь. Особенно тот факт, что файл на запись открывается, но при этом не закрывается.

  • Я позволил себе поиздеваться над кодом : https://autolisp.ru/2025/03/12/lisp-ai-vs-likeprogrammer/