Создание средней (осевой) линии или биссектрисы.
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Создание средней (осевой) линии или биссектрисы.

Создание средней (осевой) линии или биссектрисы.

Ответ
Поиск в этой теме
Непрочитано 02.05.2012, 13:49 #1
Создание средней (осевой) линии или биссектрисы.
Astartes
 
Котло- и реакторостроение
 
Барнаул
Регистрация: 25.02.2010
Сообщений: 824

Приветствую.
Я знаю что есть два лиспа для решения подобной задачи. Это bi_line Александра Ривилиса, и Middle PolyLine (MPL) от VVA.
Оба лиспа работаю хорошо. Спасибо авторам.
Единственная "проблема", для того чтобы построить линию между двумя другими нужно первую и вторую линию выделять по отдельности.
Вопрос можно подработать лисп так, чтобы выделить две линии рамкой, затем Ентер, и средняя линия (биссектриса) готова? Или это невозможно?

Последний раз редактировалось Astartes, 03.05.2012 в 04:54.
Просмотров: 16486
 
Непрочитано 04.05.2012, 10:50
#2
lastloch


 
Регистрация: 23.12.2010
Сообщений: 65


Цитата:
Сообщение от Astartes Посмотреть сообщение
Или это невозможно?
Наверное возможно. Осталось найти эти лиспы.
lastloch вне форума  
 
Непрочитано 04.05.2012, 10:55
#3
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


Выделяй сколько угодно линий, средняя линия строится по первой и последней. Предполагается, что они сонаправлены.
Код:
[Выделить все]
 (defun c:bissa    (/ x00 x01 x02 x03)
  (princ "\nВыберите линии...")
  (while (not (setq x00 (ssget '((0 . "line"))))) (princ "\nНичего не выбрано!\nВыберите линии..."))
  (setq x01 (list))
  (foreach auxi     (list 0 (1- (sslength x00)))
    (setq x01 (append x01 (list (cdr (assoc 10 (setq x02 (entget (ssname x00 auxi))))) (cdr (assoc 11 x02))))))
  (setq x00 nil)
  (entmake
    (list '(0 . "LINE")
      '(100 . "AcDbLine")
      (cons 10 (setq x03 (polar (setq x00 (car x01)) (angle x00 (setq x02 (caddr x01))) (/ (distance x00 x02) 2))))
      (cons 11 (polar x03
               (/ (+ (angle x00 (setq x00 (cadr x01))) (angle x02 (setq x02 (cadddr x01)))) 2)
               (/ (distance x00 x02) 2)))))
  (princ))

Последний раз редактировалось ciril, 04.05.2012 в 12:24.
ciril вне форума  
 
Автор темы   Непрочитано 05.05.2012, 06:19
#4
Astartes

Котло- и реакторостроение
 
Регистрация: 25.02.2010
Барнаул
Сообщений: 824


lastloch, Я почему-то думал, что эти лиспы популярны и все ими пользуются. ))
Выкладываю.

Есть еще один лист Axis_Den, от Дениса Флюстикова. Он делает осевые линии и для окружностей и для линий. Причем окружности можно выбрать рамкой и осевые отрисуются на всех окружностях разом, а линии так же приходится выделять по одной.

Cirik
Спасибо. Только непонятно, средняя линия отрисовывается определенной величины. В указанных мной лиспах, линия отрисовывается той же величины что основные линии.
И ваш лисп работает только для параллельных линий, для линий идущих под углом друг к другу он не работает.
Вложения
Тип файла: zip Archive.zip (37.7 Кб, 164 просмотров)

Последний раз редактировалось Astartes, 05.05.2012 в 06:38.
Astartes вне форума  
 
Непрочитано 05.05.2012, 11:00
#5
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


добавь после (setq x00 nil)
Код:
[Выделить все]
 (and (> (distance (car x01) (caddr x01)) (distance (cadr x01) (cadddr x01))) (setq x01 (reverse x01)))
если две линии разной длины, то какова должна быть длина итоговой линии?
и чего надо-то - биссектрису угла или среднюю линию между двумя отрезками?
ciril вне форума  
 
Автор темы   Непрочитано 05.05.2012, 12:10
#6
Astartes

Котло- и реакторостроение
 
Регистрация: 25.02.2010
Барнаул
Сообщений: 824


ciril, Добавил, ничего не поменялось.
Цитата:
Сообщение от ciril Посмотреть сообщение
и чего надо-то - биссектрису угла или среднюю линию между двумя отрезками?
Лиспы открывали что я в архиве приложил?
Лисп bi_line отрисовывает все как нужно (и паралельные и под углом). Единственное что хотелось бы, это добавить возможность выбирать обе линии рамкой, как это сделано в вашем лиспе. Объединить, так сказать.
Astartes вне форума  
 
Непрочитано 05.05.2012, 12:40
#7
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


не люблю я править чужой код объединил
Код:
[Выделить все]
 (defun C:BI_LINE  (/ x00 en1 en2 e1 e2 p1 p2 p11 p12 p21 p22 tmp d1 d2 _bm)
  (setvar "CMDECHO" 0)
  (princ "\nВыберите отрезки...")
  (while (not (setq x00 (ssget '((0 . "line"))))) (princ "\nНичечго не выбрано!\nВыберите отрезки..."))
  (redraw (setq en1 (ssname x00 0)) 3)
  (redraw (setq en2 (ssname x00 (1- (sslength x00)))) 3)
  (setq x00 nil)
  (setq _bm (getvar "BLIPMODE"))
  (setvar "BLIPMODE" 0)
  (setq	p11 (cdr (assoc 10 (setq e1 (entget en1))))
	p12 (cdr (assoc 11 e1))
	p21 (cdr (assoc 10 (setq e2 (entget en2))))
	p22 (cdr (assoc 11 e2)))
  (if (> (+ (distance p11 p21) (distance p12 p22)) (+ (distance p11 p22) (distance p12 p21)))
    (progn				; меняем местами начало и конец второго отрезка
      (setq tmp	(list p21 p22)
	    p21	(cadr tmp)
	    p22	(car tmp))))
  (cond	;;отрезки пересекаются
	((setq p1 (inters p11 p12 p21 p22 T))
	 (setq d1 (max (distance p1 p11) (distance p1 p21)))
	 (setq d2 (max (distance p1 p12) (distance p1 p22)))
	 (setq p11 (polar p1 (angle p1 p11) d1))
	 (setq p12 (polar p1 (angle p1 p12) d2))
	 (setq p21 (polar p1 (angle p1 p21) d1))
	 (setq p22 (polar p1 (angle p1 p22) d2)))
	;; пересекаются прямые, на которых лежат отрезки
	((setq p1 (inters p11 p12 p21 p22 nil))
	 (if (> (distance p1 p11) (distance p1 p12))
	   (progn (setq	tmp (list p11 p12)
			p11 (cadr tmp)
			p12 (car tmp))
		  (setq	tmp (list p21 p22)
			p21 (cadr tmp)
			p22 (car tmp))))
	 ;; (if (progn
	 (setq d1 (min (distance p1 p11) (distance p1 p21)))
	 (setq d2 (max (distance p1 p12) (distance p1 p22)))
	 (setq p11 (polar p1 (angle p1 p11) d1))
	 (setq p12 (polar p1 (angle p1 p12) d2))
	 (setq p21 (polar p1 (angle p1 p21) d1))
	 (setq p22 (polar p1 (angle p1 p22) d2))))
  ;; (cond
  (setq p1 (mapcar '* '(0.5 0.5 0.5) (mapcar '+ p11 p21)))
  (setq p2 (mapcar '* '(0.5 0.5 0.5) (mapcar '+ p12 p22)))
  (command "_.LINE" "_none" (trans p1 0 1) "_none" (trans p2 0 1) "")
  (setvar "BLIPMODE" _bm)
  (redraw en1 4)
  (redraw en2 4)
  (princ))
ciril вне форума  
 
Автор темы   Непрочитано 05.05.2012, 13:08
#8
Astartes

Котло- и реакторостроение
 
Регистрация: 25.02.2010
Барнаул
Сообщений: 824


ciril, Вот! Спасибо большое, теперь как надо.
Ну и раз уж так. Как сделать, чтобы полученная линия автоматом переходила на определенный слой. Как это сделать я знаю, нужно добавить такую строчку (vl-cmdf "_-LAYER" "_M" "Осевая" ""). Тогда у этой линии будет параметры присвоенные слою "Осевая". А хотелось бы чтобы линия получалась в текущем слое, цвет - по слою, тип линии - ACAD_ISO04W100, вес линии - 0,2мм.
Astartes вне форума  
 
Непрочитано 05.05.2012, 14:03
#9
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


замени строку (command... на
Код:
[Выделить все]
 (or (entmake (list '(0 . "LINE")
		     '(6 . "ACAD_ISO04W100")
		     '(370 . 20)
		     (cons 10 (trans p1 0 1))
		     (cons 11 (trans p2 0 1))))
      (prompt "\nОтрезок не создан!")
      (exit))
с цветом установленным по умолчанию для вновь создаваемых примитивов, с цветом по слою позже, рабочий день заканчивается
ciril вне форума  
 
Непрочитано 05.05.2012, 14:13
#10
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от ciril Посмотреть сообщение
Код:
[Выделить все]
 (or (entmake (list '(0 . "LINE")
	     '(6 . "ACAD_ISO04W100")
	     '(370 . 20)
	     (cons 10 (trans p1 0 1))
	     (cons 11 (trans p2 0 1))))
     (prompt "\nОтрезок не создан!")
     (exit))
нафига такое счастье?
gomer вне форума  
 
Автор темы   Непрочитано 10.05.2012, 05:25
#11
Astartes

Котло- и реакторостроение
 
Регистрация: 25.02.2010
Барнаул
Сообщений: 824


ciril, Спасибо, отлично все работает.

gomer, Что не так?
Astartes вне форума  
 
Непрочитано 10.05.2012, 10:15
#12
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


Цитата:
Сообщение от gomer Посмотреть сообщение
нафига такое счастье?
ну а вдруг отрезок не будет создан, а вот и оповещение
ciril вне форума  
 
Непрочитано 10.05.2012, 19:07
#13
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от ciril Посмотреть сообщение
ну а вдруг отрезок не будет создан, а вот и оповещение
А чего он не создан?
рисование отрезка - заключительный этап программы... (exit) тут не особо-то и нужен
но больше всего я не могу понять почему происходит таки прерывание по (exit)
gomer вне форума  
 
Автор темы   Непрочитано 11.05.2012, 12:01
#14
Astartes

Котло- и реакторостроение
 
Регистрация: 25.02.2010
Барнаул
Сообщений: 824


ciril, Еще пара вопросов.
Можно ли среднюю линию(дугу) между дугами сделать? Лиспы которые я выкладывал не могут этого сделать. Разве что Плтулс может, если дуги в полилинии конвертировать. Есть какая-то сложность с дугами, не знаете?
Можно ли еще немного модернизировать лисп, чтобы после отрисовки средней линии, команда не прерывалась, а предлагала выбрать следующие две линии? Это конечно больше блажь, вызов предыдущей команды правым кликом сделать несложно, но всеже. ))

Последний раз редактировалось Astartes, 11.05.2012 в 12:47.
Astartes вне форума  
 
Непрочитано 11.05.2012, 12:05
#15
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


gomer, вообще, конечно, согласен, перестраховался, хотя с другой стороны... у меня при отсутствии в чертеже заданного типа линии отрезок создается не всегда (Civil2012)
Astartes, вот так запрашивает продолжение и немного переписал код, так мне больше нравится
Код:
[Выделить все]
 (defun C:BI_LINE  (/ x00 en1 en2 e1 e2 p1 p2 p11 p12 p21 p22 tmp d1 d2 _bm _cm)
  (setq _cm (getvar "CMDECHO")
        _bm (getvar "BLIPMODE"))
  (setvar "BLIPMODE" (setvar "CMDECHO" 0))
  (while (not (eq "Нет" (progn (initget "Да Нет") (getkword "\nПродожить? [Да/Нет] <Да>: "))))
    (princ "\nВыберите отрезки...")
    (while (not (setq x00 (ssget '((0 . "line"))))) (princ "\nНичего не выбрано!\nВыберите отрезки..."))
    (redraw (setq en1 (ssname x00 0)) 3)
    (redraw (setq en2 (ssname x00 (1- (sslength x00)))) 3)
    (setq x00 nil)
    (setq p11 (cdr (assoc 10 (setq e1 (entget en1))))
          p12 (cdr (assoc 11 e1))
          p21 (cdr (assoc 10 (setq e2 (entget en2))))
          p22 (cdr (assoc 11 e2)))
    (if (> (+ (distance p11 p21) (distance p12 p22)) (+ (distance p11 p22) (distance p12 p21)))
      (setq tmp p21
            p21 p22
            p22 tmp))
    (cond ;;отрезки пересекаются
          ((setq p1 (inters p11 p12 p21 p22 T))
           (setq d1  (max (distance p1 p11) (distance p1 p21))
                 d2  (max (distance p1 p12) (distance p1 p22))
                 p11 (polar p1 (angle p1 p11) d1)
                 p12 (polar p1 (angle p1 p12) d2)
                 p21 (polar p1 (angle p1 p21) d1)
                 p22 (polar p1 (angle p1 p22) d2)))
          ;; пересекаются прямые, на которых лежат отрезки
          ((setq p1 (inters p11 p12 p21 p22 nil))
           (if (> (distance p1 p11) (distance p1 p12))
             (setq tmp p11
                   p11 p12
                   p12 tmp
                   tmp p21
                   p21 p22
                   p22 tmp))
           (setq d1  (min (distance p1 p11) (distance p1 p21))
                 d2  (max (distance p1 p12) (distance p1 p22))
                 p11 (polar p1 (angle p1 p11) d1)
                 p12 (polar p1 (angle p1 p12) d2)
                 p21 (polar p1 (angle p1 p21) d1)
                 p22 (polar p1 (angle p1 p22) d2))))
    (or (entmake (list '(0 . "LINE")
                       '(6 . "ACAD_ISO04W100")
                       '(370 . 20)
                       (cons 10 (trans (mapcar '* '(0.5 0.5 0.5) (mapcar '+ p11 p21)) 0 1))
                       (cons 11 (trans (mapcar '* '(0.5 0.5 0.5) (mapcar '+ p12 p22)) 0 1))))
        (princ "\nОтрезок не создан!"))
    (redraw en1 4)
    (redraw en2 4))
  (setvar "BLIPMODE" _bm)
  (setvar "CMDECHO" _cm)
  (princ))
с дугами - подумаю, слабо представляю себе среднюю между двух дуг
навскидку, вот так для сонаправленных, одинаково выпуклых дуг:
Код:
[Выделить все]
 (defun c:bi_arc  (/ x00 x01 x02)
  (princ "\nВыберите дуги...")
  (while (not (setq x00 (ssget '((0 . "arc"))))) (princ "\nДуги не выбраны!\nВыберите дуги..."))
  (setq x01 (entget (ssname x00 0))
        x02 (entget (ssname x00 (1- (sslength x00))))
        x00 nil)
   (or (entmake
        (list '(0 . "ARC")              
              '(6 . "ACAD_ISO04W100")
              '(370 . 20)
              (cons 10
                    (trans (mapcar '* '(0.5 0.5 0.5) (mapcar '+ (cdr (assoc 10 x01)) (cdr (assoc 10 x02)))) 0 1))
              (cons 40 (/ (+ (cdr (assoc 40 x01)) (cdr (assoc 40 x02))) 2))
              (cons 50 (/ (+ (cdr (assoc 50 x01)) (cdr (assoc 50 x02))) 2))
              (cons 51 (/ (+ (cdr (assoc 51 x01)) (cdr (assoc 51 x02))) 2))))
      (princ "\nДуга не создана!"))
  (princ))

Последний раз редактировалось ciril, 11.05.2012 в 14:02.
ciril вне форума  
 
Непрочитано 12.05.2012, 10:55
#16
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Если дуги имеют разные радиусы, то средняя линия уже не дуга...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 12.05.2012, 11:46
#17
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


Astartes, я за такое не возьмусь
ciril вне форума  
 
Автор темы   Непрочитано 12.05.2012, 12:02
#18
Astartes

Котло- и реакторостроение
 
Регистрация: 25.02.2010
Барнаул
Сообщений: 824


ciril, Спасибо за проделанную работу.
Есть пара вопросов. По поводу первого лиспа. Там появляется запрос "продолжать или нет", причем он появляется даже перед тем как я выбрал первые линии. Без запроса не обойтись?
Просто тогда пропадает смысл в модернизации лиспа.
Попробую объяснить. Вот я вызвал лисп, выделил 2 линии, получил среднюю линию, команда закончилась. Правая кнопка мыши (повтор предыдущей команды у меня) и все по новой.
Если воспользоваться модернизированным лиспом, то получается даже на один клик мышки больше. Вызов команды, ответ на запрос "продолжить или нет" (правый клик, получается лишний) выбор отрезков и опять ответ на запрос (правый клик, в данном случае на продолжение команды, а в первом случае на повтор команды, что в моем понимании одинаково).
Я представлял себе так. Для примера команда оффсет(подобие). Там после создания подобия, команда не прервется и можно выбрать следующий объект для подобия, без лишних запросов.

По поводу дуг, да вы правильно поняли, лисп работает хорошо. Теперь вопрос, можно ли его объеденить с лиспом для линий?

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


Странно, как вы прочитали мой комментарий, я же его еще не отправлял. ))
Понял, спасибо еще раз за проделанную работу.
Вложения
Тип файла: dwg
DWG 2007
Труба.dwg (90.0 Кб, 2517 просмотров)

Последний раз редактировалось Astartes, 12.05.2012 в 12:15.
Astartes вне форума  
 
Непрочитано 12.05.2012, 12:12
#19
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


Не, это был комментарий к посту #16 Посмотрел чертеж, понял, наконец, что нужно Объединю чуть позже.
ciril вне форума  
 
Непрочитано 14.05.2012, 11:20
#20
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


Вот так
Код:
[Выделить все]
(defun C:BI_LINE  (/ x00 en1 en2 e1 e2 p1 p2 p11 p12 p21 p22 tmp d1 d2 _bm _cm)
  (setq _cm (getvar "CMDECHO")
        _bm (getvar "BLIPMODE"))
  (setvar "CMDECHO" 1)
  (setvar "BLIPMODE" 0)
  (while (progn (princ "\nВыберите дуги или отрезки...")
                (setq x00 (ssget '((-4 . "<or") (0 . "line") (0 . "arc") (-4 . "or>")))))
    (redraw (setq en1 (ssname x00 0)) 3)
    (redraw (setq en2 (ssname x00 (1- (sslength x00)))) 3)
    (setq x00 nil
          e1  (entget en1)
          e2  (entget en2))
    (if (and (eq "LINE" (cdr (assoc 0 e1))) (eq "LINE" (cdr (assoc 0 e2))))
      (progn (setq p11 (cdr (assoc 10 e1))
                   p12 (cdr (assoc 11 e1))
                   p21 (cdr (assoc 10 e2))
                   p22 (cdr (assoc 11 e2)))
             (if (> (+ (distance p11 p21) (distance p12 p22)) (+ (distance p11 p22) (distance p12 p21)))
               (setq tmp p21
                     p21 p22
                     p22 tmp))
             (cond ;;отрезки пересекаются
                   ((setq p1 (inters p11 p12 p21 p22 T))
                    (setq d1  (max (distance p1 p11) (distance p1 p21))
                          d2  (max (distance p1 p12) (distance p1 p22))
                          p11 (polar p1 (angle p1 p11) d1)
                          p12 (polar p1 (angle p1 p12) d2)
                          p21 (polar p1 (angle p1 p21) d1)
                          p22 (polar p1 (angle p1 p22) d2)))
                   ;; пересекаются прямые, на которых лежат отрезки
                   ((setq p1 (inters p11 p12 p21 p22 nil))
                    (if (> (distance p1 p11) (distance p1 p12))
                      (setq tmp p11
                            p11 p12
                            p12 tmp
                            tmp p21
                            p21 p22
                            p22 tmp))
                    (setq d1  (min (distance p1 p11) (distance p1 p21))
                          d2  (max (distance p1 p12) (distance p1 p22))
                          p11 (polar p1 (angle p1 p11) d1)
                          p12 (polar p1 (angle p1 p12) d2)
                          p21 (polar p1 (angle p1 p21) d1)
                          p22 (polar p1 (angle p1 p22) d2))))
             (or (entmake (list '(0 . "LINE")
                                '(6 . "ACAD_ISO04W100")
                                '(370 . 20)
                                (cons 10 (trans (mapcar '* '(0.5 0.5 0.5) (mapcar '+ p11 p21)) 0 1))
                                (cons 11 (trans (mapcar '* '(0.5 0.5 0.5) (mapcar '+ p12 p22)) 0 1))))
                 (princ "\nОтрезок не создан!")))
      (or (entmake
            (list '(0 . "ARC")
                  '(6 . "ACAD_ISO04W100")
                  '(370 . 20)
                  (cons 10
                        (trans (mapcar '* '(0.5 0.5 0.5) (mapcar '+ (cdr (assoc 10 e1)) (cdr (assoc 10 e2)))) 0 1))
                  (cons 40 (/ (+ (cdr (assoc 40 e1)) (cdr (assoc 40 e2))) 2))
                  (cons 50 (/ (+ (cdr (assoc 50 e1)) (cdr (assoc 50 e2))) 2))
                  (cons 51 (/ (+ (cdr (assoc 51 e1)) (cdr (assoc 51 e2))) 2))))
          (princ "\nДуга не создана!")))
    (redraw en1 4)
    (redraw en2 4))
  (setvar "BLIPMODE" _bm)
  (setvar "CMDECHO" _cm)
  (princ))
ciril вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Создание средней (осевой) линии или биссектрисы.



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание нового типа линий Apelsinov AutoCAD 915 08.07.2022 12:36
Создание линии типа "_______текст_______ " с возможностью изменение текста xabraxabra AutoCAD 18 03.10.2011 02:35
LISP Создание осевой линии для 3Dsolids nem LISP 7 19.10.2010 12:42