Тема: Как разбить полилинию на участки различной длины?
есть ли способ разметить полилинию на участки с различной длиной?
Информационный портал для профессионалов в области САПР
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Форумы CADUser → Autodesk → AutoCAD → Как разбить полилинию на участки различной длины?
Чтобы отправить ответ, вы должны войти или зарегистрироваться
есть ли способ разметить полилинию на участки с различной длиной?
_divide, только перед этим через ddptype поставь вид точек (если разбивать точками будешь)
> kpblc
насколько я понял _divide разбивает на заданное количество отрезков одинаковой длины, мне же необходимо разбить на отрезки различной длины. Например чтобы полилинию длиной 100 разбило на участки длиной 10, 20, 45, 15, 10...
Кроме как руками (для прмых кусков) тут тяжело предложить что-то имхо. И непонятно, что делать, если в новой части полилинии участвует вершина. А что делать с дуговыми сегментами?
проще вычертить..
берешь полилинию и последовательно, допустим по горизонтали, откладываешь 10, 20, 45, 15, 10...
в местах стыковки будет срабатывать привязка Endpoint
> kpblc
с дугами сложнее, там еще радиус присутствует...
как сделать дугу, определенного радиуса и определенного размера, и последовательность дуг 10, 20, 45, 15, 10...
В принципе для ортогональных полилиний можно воспользоваться программой, которая описана здесь:
https://www.caduser.ru/forum/topic19844.html
Т.е. можно в начале полилинии нарисовать точку, настроенную на крест, а потом копировать ее с нужным шагом.
> Alena
Не совсем про то, но тем не менее: в случае полилинии с дуговыми сегментами как мерять расстояние? Если по прямой, то все очень просто делается руками. Если по дуге - то надо дополнительные вычисления производить.
И по поводу "прямых" кусков: допустим, длина первого сегмента 100, второго - 150, третьего - 125. Сегменты располагаются под произвольными углами друг к другу в общем случае, но для примера возьмем через 22,5 градуса; первый сегмент - под углом 30 градусов к горизонтали; начало полилинии - в (0,0,0) - чтобы не было совсем все просто. Надо разбить по длинам (начиная с первого): 35, 22, 100, 120, сколько осталось (оставим в стороне пока вопрос о случае, если длины полилинии не хватает на все отрезки).
И в результате: на первом сегменте располагаются 2 точки с координатами соответственно (30.31,17.5) и (49.36,28.5), а вот дальше начинается чехарда. До следующей точки меряем по прямой? Если да, то ее координаты будут (122.46,96.74), а если по полилинии (т.е. дошли до вершины, померяли расстояние, и от нее - дальше), то получается уже что-то около (121.30,95.22). Дальше - больше.
Казалось бы, разница копеечная, но при больших длинах набежит нехилая погрешность, если с этим делом не определиться.
Можете проверить - прав ли я, а то мне уже и самому интересно становится
---
И все это не совсем ИМХО.
> kpblc
если дуговые сегменты и углы полилинии создают такие трудности может есть какой-нибудь способ для прямых участков? Предложенный выше вариант с копированием на заданное расстояние в общем подходит, но уж слишком много копировать прийдется... а как-нибудь автоматизировать этот процесс можно?
Да не трудности это в общем-то, геометрию просто вспоминать надо и применять ее постоянно (если лисп писать) ;) Есть у меня вариант, но он, по-моему, хуже программы Владимира Громова - нарисовать в начале полилинии окружность, задать нужный радиус, из точки пересечения следующую окружность, опять радиус, ну и так далее.
В определенной степени задача упростилась бы, если бы можно было заранеее задать конкретные шаги разбиения для любых линейных полилиний. Скажем, создать список из шагов внутри программы. Но если шаги произвольные и нет регулярности, да еще если сегменты не ортогональны (пусть даже без дуговых сегментов), то задача очень сложная, IMHO, по крайней мере для меня.
> Владимир Громов
шаги разбиения можно задать разве что в виде текстового файла... создавать список внутри программы нет смысла так как они нерегулярны.
В данный момент пока приходится скриптом вычерчивать все точки по прямой обычным копированием а потом уже командой align выравнивать нужные куски по полилинии.Но углов тоже хватает, а на них приходится вымерять расстояния вручную, то поэтому постоянно возникает желание это все как-то автоматизировать...
> Олег
Сделай файл "Чего должно быть" в каде и разошли желающим (мне, кстати, тоже можешь прислать, только на kpblc2000@yandex.ru - gmail не очень дружит чего-то с вложениями) - может, чего путное и получится.
Положить на webfile.ru вряд ли получится - эта зараза последнее время что-то падает.
отсылать там особо нечего, я лучше еще раз попытаюсь максимально точно сформулировать что есть и что должно получится.
Есть ломаная незамкнутая 2D полилиния, без дуговых сегментов и файл с расстояниями между точками.
Должно получится: та же полилиния с расположенными на ней точками, растояния между которыми соответствуют указанным в файле. Для случаев когда вершина угла полилинии находится между точками длина считается по полилинии.
Длина полилинии равна сумме отрезков?... по идее должна быть равна..
Возможно все-таки использовать команду _divide.
Линию длиной 100 разбить на 20 равных участков, по 5 и потом ненужные точки удалить.. Оставить расстояния 10, 20, 45, 15, 10...
Вобщем находить кратное деление, а потом оставлять точки заданных расстояний..
> Alena
Длина полилинии либо равна сумме отрезков, либо больше.
С divide точно не получится - числа 10, 20, 45, 15, 10 я приводил только для примера, а вообще диапазон длин от 1.00 до 12.00. Я так понял что облегчить мою участь может только lisp, которого я не знаю... Поэтому буду надеятся что кого-нибудь эта задачка заинтересует
Непонятна только структура файла из которого беруться расстояния. А если вводить координаты в командной строке то примерно так:
(defun c:pldi (/ actDoc spFlag actSp stFlag poly sumDis nextDis nextPt firPt) (vl-load-com) (setq actDoc(vla-get-ActiveDocument (vlax-get-acad-object)) spFlag(vla-get-ActiveSpace actDoc) ); end setq (if(= 0 spFlag) (setq actSp(vla-get-PaperSpace actDoc)) (setq actSp(vla-get-ModelSpace actDoc)) ); end if (princ "\n*** Select line, polyline or spline *** ") (if (setq poly (ssget "_:S" '((0 . "*LINE")(-4 . "<NOT")(0 . "MLINE")(-4 . "NOT>")))) (progn (setq poly(vlax-ename->vla-object(ssname poly 0)) stFlag T sumDis 0.0 firPt(vla-AddPoint actSp (vlax-3d-point (vlax-curve-getStartPoint poly))) ); end setq (while stFlag (initget 1) (setq nextDis (getint (strcat "\nSpecify distance: ")) sumDis (+ sumDis nextDis) nextPt(vlax-curve-getPointAtDist poly sumDis) ); end setq (if nextPt (vla-AddPoint actSp(vlax-3d-point nextPt)) (progn (princ "\n+++++++++ End of line +++++++++ ") (setq stFlag nil) ); end progn ); end if ); end while ); end progn ); end if (princ) ); end of c:pldi
Это конечно только набросочек...
> Fantomas
Здорово. Размечаются и линейные и криволинейные объекты. Только, если надо принудительно закончить разметку до "исчерпания" размечаемого объекта, получается аварийное завершение команды.
Прошу прощения, сделал только ввод целых чисел. Исправил на вещественные. Чтобы было видно как он отрисовывает точки надо естественно переключить их стиль.
(defun c:pldi (/ actDoc spFlag actSp stFlag poly sumDis nextDis nextPt firPt) (vl-load-com) (setq actDoc(vla-get-ActiveDocument (vlax-get-acad-object)) spFlag(vla-get-ActiveSpace actDoc) ); end setq (if(= 0 spFlag) (setq actSp(vla-get-PaperSpace actDoc)) (setq actSp(vla-get-ModelSpace actDoc)) ); end if (princ "\n*** Select line, polyline or spline *** ") (if (setq poly (ssget "_:S" '((0 . "*LINE")(-4 . "<NOT")(0 . "MLINE")(-4 . "NOT>")))) (progn (setq poly(vlax-ename->vla-object(ssname poly 0)) stFlag T sumDis 0.0 firPt(vla-AddPoint actSp (vlax-3d-point (vlax-curve-getStartPoint poly))) ); end setq (while stFlag (initget 1) (setq nextDis (getreal (strcat "\nSpecify distance: ")) sumDis (+ sumDis nextDis) nextPt(vlax-curve-getPointAtDist poly sumDis) ); end setq (if nextPt (vla-AddPoint actSp(vlax-3d-point nextPt)) (progn (princ "\n+++++++++ End of line +++++++++ ") (setq stFlag nil) ); end progn ); end if ); end while ); end progn ); end if (princ) ); end of c:pldi
получается аварийное завершение команды
Ну *error* то несложно переопределить. А пока нет четкой постановки задачи, то дёргаться нет смысла. Непонятно например что делать с оставшимся кончиком полилинии, нужно ли образмеривать отрезки, какую структуру имеет файл и т. д.
> Fantomas
Как бы, все-таки, закончить команду раньше, чем кончится объект? Можно, конечно, задать расстояние заведомо большее, чем осталось, в противном случае приходится нажимать Esc. Так же играет роль порядок отрисовки объекта (положение начальной точки). Ну, и, конечно, надо иметь в виду, что привязка к точке должна быть "_nod" ("узел"), а то вид точки (скажем, крест) может ввести в заблуждение. В данном случае я говорю от себя, т.е. меня устроила бы и работа программы в текущем виде, без (текстового?) файла со списком расстояний. Но, конечно, слово за автором задачи.
> Fantomas
Что еще интересно. Если мы размечаем дуговой сегмент полилинии, то длина откладывается именно по кривой, а не по хорде. Так может, есть смысл включить в набор объектов, для которых возможно образмеривание, и дугу, IMHO?
Ну, Олег, скажи свое слово.
Думаю что завершать можно если сначала вводить координаты а потом отрисовывать всё вместе. Дугу добавил. С выбором начальной точки тоже вроде проблем нет. Но сейчас нет времени. Работать тоже иногда надо :)
(defun c:pldiv (/ actDoc spFlag actSp stFlag poly sumDis nextDis nextPt firPt Counter disLst notDr) (vl-load-com) (setq actDoc(vla-get-ActiveDocument (vlax-get-acad-object)) spFlag(vla-get-ActiveSpace actDoc) ); end setq (if(= 0 spFlag) (setq actSp(vla-get-PaperSpace actDoc)) (setq actSp(vla-get-ModelSpace actDoc)) ); end if (princ "\n*** Select line, polyline, arc or spline *** ") (if (setq poly (ssget "_:S" '((-4 . "<OR")(0 . "*LINE")(0 . "ARC")(-4 . "OR>") (-4 . "<NOT")(0 . "MLINE")(-4 . "NOT>")))) (progn (setq poly(vlax-ename->vla-object(ssname poly 0)) stFlag T sumDis 0.0 nextDis 0.0 disLst '() Counter 0 ); end setq (while nextDis (setq disLst(append disLst(list nextDis)) nextDis (getreal (strcat "\nSpecify distance or Enter to draw points: ")) ); end setq ); end while (while stFlag (setq sumDis (+ sumDis(nth Counter disLst)) nextPt(vlax-curve-getPointAtDist poly sumDis) ); end setq (if nextPt (vla-AddPoint actSp(vlax-3d-point nextPt)) (setq stFlag nil) ); end if (setq Counter(1+ Counter)) ); end while (if(>(length disLst)Counter) (princ (strcat "\n +++ Insufficient lentgth. "(itoa(-(length disLst)Counter)) " point(s) was not created! ")) ); end if ); end progn ); end if (princ) ); end of c:pldiv
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Форумы CADUser → Autodesk → AutoCAD → Как разбить полилинию на участки различной длины?
Форум работает на PunBB, при поддержке Informer Technologies, Inc