LINUX.ORG.RU

AutoLISP неадекватная работа с программой.

 , autolisp,


0

2

Уже несколько месяцев не могу нормально отдебажить код. Понимаю что это мало относится к линуксу, но все таки это Development. Суть в том, что если вводить команду по одной, бережно проверяя перед этим значения переменных то все работает. А как только начинаешь выполнять по несколько команд, сразу возникают непонятные вычисления, координаты вдруг летят непонятно куда, линии чертятся совсем не по программе, а как то рандомно. Возможно ошибка в синтаксисе, уже не знаю что делать убил на это часов наверное не менее 20. Пытался убирать лишние пробелы, табуляцию, иногда выдает рабочий вариант, но как только снова начинаю запускать, оно опять все криво выполняет. http://pastebin.com/HMmeeR6A

Для запуска использую такие параметры
(conserve 1000,2000,100,200,50,10)
Когда кусками код запускал делал так
(setq x 1000 y 2000 a 100 b 200 c 50 max 10)
Переменная max лишняя, хотел сначала реализовать работу, а потом чтобы уже максимальное можно было задать. Логика работы - 2д комната со столами, x и y задают ширину и длинну комнаты, a и b соответствующие параметры столов. с - расстояние между столами. Программа чертит комнату, расчитывает кол-во столов для заданной конфигурации и чертит их. Можете чем нибудь помочь?

★★

Странный этот ваш autolisp какой-то, ну да ладно!

По моему, у вас ошибка в алгоритме. Вы дважды считаете зазор между столами (с): первый раз при задании нижнего левого угла

(setq p1 (list (+ x1 (NTH 0  a1)) (+ y1 (last a1))))
, а второй раз, когда задаете шаг до следующего стола:
(setq cols (+ cols 1) x1(+ v x1))
Напомню, что a1 определена как (list c c), а v как (+ a c)

По вертикали у вас такая же петрушка.

delete83 ★★
()
Ответ на: комментарий от delete83

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

delete83 ★★
()
Ответ на: комментарий от delete83

Ну 2 цикла это по вертикали и горизонтали. А насчет зазора - там в первом куске это вычисление первой точки. Там вычисляются 4 точки, а далее рисуются линии. Вы запускали этот код в автокаде? по идее должен работать в любом. И перегруженности нет, просто там одна точки состоях их двух координат и они записываются в список. А далее я уже орудую этими списками у меня сдвиг по x и по y. Код вроде верный и если все пройти по одной строчке все ок. Даже бывает беру цикл после пары итераций и о чудо он все заполняет как надо! Но как только я все обнуляю и запускаю код опять все сначала.

Bupyc ★★
() автор топика
Ответ на: комментарий от delete83

a1 это точна начальная. a1 a2 a3 a4 это 4 точки стола. они имеют x и y v это сдвиг по x он состоит из длинны а + промежуток c w тоже самое только для y

Bupyc ★★
() автор топика
Ответ на: комментарий от delete83

А вычислять заранее это вы предлагаете мне сделать двумерный массив списков? У каждого стола 4 координаты. Там x и y.

Bupyc ★★
() автор топика
Ответ на: комментарий от Bupyc

У меня нет автокада. Только SBCL, но он ругается на переменные. Не могу разобраться, что его не устраивает. За алгоритм извиняюсь. Действительно, везде шаги правильно заданы. Это я невнимательно посчитал. Про два цикла замечание в силе. Можно сделать в один цикл.

Не надо массивов! Зачем? Что мешает вычислить координаты трех оставшихся вершин по первой вершине? В функцию для отрисовки передаются четыре аргумента: (x y a b), где x и y - координаты начальной точки, а a и b - ширина и высота прямоугольника.

delete83 ★★
()

Disclaimer: Я не знаю autolisp.

Выражение "(+ y1 (last a1))" мне выглядит странно, т.к. в CL last возвращает не сам последний элемент, а последнюю cons-ячейку, т.е. список из последнего элемента.

dmitry_vk ★★★
()
Ответ на: комментарий от dmitry_vk

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

delete83 ★★
()

Вот это упорство! O_O

Тебе, кажется, правильно про last говорят. Я глянул в интернете по AutoLISP: last возвращает не последнее значение, а список из последнего значения. Замени его хотя бы на (nth 1 a<n>). Проверь-ка это сначала.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

А, нет, нифига. У них вообще что-то странное тут в описании. Они так возвращаемое значение просто обозначают в скобочках. Ерунда какая-то.

Вот из какого=то тьюториала:

Last

Will return the last element of a list :

	(last '("M20" "M24" "M30"))

Would return :

	("M30")

Length

This returns an integer indicating the number of elements in a list :

	(length '("M20" "M24" "M30"))

Would return :

	(3)

(3) тоже списком, хотя integer. Наверное, все-таки я ошибся. у них такие обозначения. Но все равно проверь.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

Я уже глянул в другой документации. Там без всяких скобочек:

(last (list 1 2 3)) return 3
(last (list 1 2 (list 3 4))) return (3 4)

delete83 ★★
()

Есть какой-нибудь вариант попробовать autolisp, не качая AutoCAD размером 1GB?

delete83 ★★
()

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

dmitry_vk ★★★
()

Не похоже на твою проблему?

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Problem-with-t...

В первом же совете, который человеку помог говорится:

Without evaluating the code in detail, the first question that comes to mind is: do you have running Object Snap on? That could easily cause the problem you describe.

Ответ:

Thank you soo much, Osnam was switched on and I never expected it can influence the code. It works now,

Zubok ★★★★★
()
Ответ на: комментарий от delete83

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

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Поподробнее? Я нашел процедуру для задержки и сделал после каждого прохода задержку 3 секунды. Автокад стал зависать, но при этом хоть рисует.

Bupyc ★★
() автор топика
Ответ на: комментарий от Bupyc

Попробдробнее что? Там же написано, что надо попробовать сделать. Погугли OSNAP и как отключить. Если не поможет, то надо искать. Если, например, у тебя включен режим ORTHO, а ты мышкой рисуешь наклонную линию, то она у тебя наклонной рисуется? Нет, даже если ты захочешь. Вот и тут - каждая линия хочет отрисоваться в своей правильной позиции, но автокад ее заставляет рисоваться в соответсвии с текущим режимом.

Я нашел процедуру для задержки и сделал после каждого прохода задержку 3 секунды. Автокад стал зависать, но при этом хоть рисует.

Это какой-то ад. Слишком быстро AutoLISP выпоняется - процессор не успевает и путается. Мегаязык :)

Zubok ★★★★★
()

Попробуй для начала использовать в качестве локальных переменных локальные переменные: все setq замени на let.

vahtu
()
Ответ на: комментарий от vahtu

Попробуй для начала использовать в качестве локальных переменных локальные переменные: все setq замени на let.

Там нет let :)

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)

Вот, кстати, кусок кода, в котором текущий режим osmode сохраняется, выключается, а потом восстанаваливается. Между этими событиями происходит отрисовка. Попробуй сделать также и расскажи, что получилось.

Zubok ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.