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

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

Как автоматически выставить радиус скругления в зависимости от угла между отрезками

Ответ
Поиск в этой теме
Непрочитано 06.04.2015, 10:55 #1
Как автоматически выставить радиус скругления в зависимости от угла между отрезками
Seryj_Wolk
 
Инженер-электрик
 
Псков
Регистрация: 04.03.2008
Сообщений: 59

Кто может помочь с лиспом по скруглению углов. Нужно чтобы команда автоматически выставляла радиус скругления в зависимости от угла между отрезками. Например при угле от 45 до 90 радиус 1000, при угле от 90 до 120 - 3000 и т.д. Ни у кого нет ничего похожего? Помогите кто чем может, а то я с лиспами вообще не дружу
Просмотров: 5327
 
Непрочитано 06.04.2015, 11:06
#2
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,471


Я могу вот эту ссылку дать http://forum.dwg.ru/showthread.php?t=22894 , может подружитесь с лиспом.
__________________
_бложиг
Boxa вне форума  
 
Автор темы   Непрочитано 17.04.2015, 09:06
#3
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


Народ, ну помогите кто-нибудь
Seryj_Wolk вне форума  
 
Непрочитано 17.04.2015, 09:08
#4
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,471


Ну если очень нужно, а с лиспом не дружится, то сюда http://forum.dwg.ru/forumdisplay.php?f=33
__________________
_бложиг
Boxa вне форума  
 
Непрочитано 17.04.2015, 12:23
#5
Веселин


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


Что делать, если отрезок меньше, чем радиус? Как быть при углах меньше 45, и больше 120 градусов?
Веселин вне форума  
 
Автор темы   Непрочитано 20.04.2015, 14:40
#6
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


Цитата:
Сообщение от Веселин Посмотреть сообщение
Что делать, если отрезок меньше, чем радиус? Как быть при углах меньше 45, и больше 120 градусов?
Ну в самом простом случае выдавать ошибку "Скругляемый отрезок меньше радиуса скругления". При угле от 0 до 45 радиус скругления например 500. От 120 до 180 - 5000. А нельзя так чтобы в лиспе это поправить можно было? Забивать радиус и еще лучше изменять количество разбиений. Наприме 0-45, 45-90, 90-120, и т.д.
Seryj_Wolk вне форума  
 
Непрочитано 27.04.2015, 20:34
1 | #7
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,588


Цитата:
Сообщение от Seryj_Wolk Посмотреть сообщение
Нужно чтобы команда автоматически выставляла радиус скругления в зависимости от угла между отрезками.
Цитата:
Сообщение от Seryj_Wolk Посмотреть сообщение
Ни у кого нет ничего похожего?
Есть. Почти похожее. Чуть подправил, надеюсь, что правильно понял, что нужно. Использованы функции mip:entsel от VVA и RTD (по-моему, от него же).

Код:
[Выделить все]
  ;|
	Команда для сопряжения двух отрезков или двух смежных сегментов одной полилинии с радиусом, 
	зависящим от угла между сопрягаемыми отрезками или сегментами.
	Использованы вспомогательные функции mip:entsel и RTD. 
|;
	
(defun C:TEST ( / *error* oldCMDECHO en1 pt1 en2 pt2 pt1+ pt2+ inters-pt ang)
(vl-load-com)
	(defun *error* (msg) 
		(if oldCMDECHO (setvar "CMDECHO" oldCMDECHO))
	)
	(setq oldCMDECHO (getvar "CMDECHO"))
	(setvar "CMDECHO" 0)
	(setq en1 (mip:entsel "\nУкажите первый отрезок или сегмент полилинии: " '("LINE" "LWPOLYLINE") nil))
	(if en1 
		(progn
			(setq pt1 (vlax-curve-getClosestPointTo en1 (getvar "LASTPOINT"))) ;;точка на первом отрезке (сегменте)
			(setq en2 (mip:entsel "\nУкажите второй отрезок или сегмент полилинии: " '("LINE" "LWPOLYLINE") nil))
			(if en2 
				(progn
					(setq pt2 (vlax-curve-getClosestPointTo en2 (getvar "LASTPOINT")) ;;точка на втором отрезке (сегменте)
						  pt1+ (vlax-curve-getPointAtParam en1 (+ 0.001 (vlax-curve-getParamAtPoint en1 pt1))) ;;вторая точка на первом отрезке (сегменте)
						  pt2+ (vlax-curve-getPointAtParam en2 (+ 0.001 (vlax-curve-getParamAtPoint en2 pt2))) ;;вторая точка на втором отрезке (сегменте)
						  inters-pt (inters pt1 pt1+ pt2 pt2+ nil) ;; точка пересечения отрезков (сегментов)
					)
					(if inters-pt
						(setq ang 
								(abs 
									(- 
										(atoi (rtos (RTD (angle inters-pt pt1)) 2 0)) 
										(atoi (rtos (RTD (angle inters-pt pt2)) 2 0))
									)
								) ;; угол между отрезками (сегментами)
						)
						(princ "\nВыбранные отрезки или сегменты параллельны и не могут быть сопряжены")
					)
					(if (and ang (> ang 180)) (setq ang (- 360 ang))) ;; если расчитанный угол больше 180, то вычитаем его из 360
					
					;;; далее описаны граничные значения углов, при которых выбирается соответствующий радиус скругления
					(cond 
					  (	(and (> ang 0)(<= ang 45))
						(setvar "FILLETRAD" 500)
					  )
					  (	(and (> ang 45)(<= ang 90))
						(setvar "FILLETRAD" 1000)
					  )
					  (	(and (> ang 90)(<= ang 120))
						(setvar "FILLETRAD" 3000)
					  )
					  (	(and (> ang 120)(< ang 180))
						(setvar "FILLETRAD" 5000)
					  )
					)
					(if ang
						(if (vl-cmdf "_.FILLET" "_Multiple" pt1 pt2 "")
							(princ (strcat "\nСегменты сопряжены. Угол: " (rtos ang 2 0) ", радиус: " (rtos (getvar "FILLETRAD") 2 0)))
						)
					)
				)
				(princ "\nОтменено")
			)
		)
		(princ "\nОтменено")
	)
	(setvar "CMDECHO" oldCMDECHO)
	(princ)
)	
	;; Описание вспомогательных функций	
	
	(defun mip:entsel (promt filter entlist / key n newentlist ent_point promt)
	;;;Функция mip:entsel
	;;;Еденичный выбор объекта, замена функции entsel
	;;;Возвращает entity name выбранного примитива или nil, точку указания запоминает в переменной LASTPOINT
	;;;Параметры:
	;;;promt - предложение выбрать объект (string)
	;;;filter - фильтр объектов для выбора вида '("LINE" "LWPOLYLINE")
	;;;entlist - список примитивов которые не надо выбирать (либо список entity name, либо PICKSET)
	;;;
	;;;Примеры:
	;;;(mip:entsel "\nВыберите объекты" '("LINE" "LWPOLYLINE") nil)
	;;;(mip:entsel "\nВыберите объекты" nil nil)
	;;;(setq aa nil) (mip:entsel "\nВыберите объекты" '("LINE" "LWPOLYLINE") (while (setq a (car (entsel))) (setq aa (append aa (list a)))))
	;;;(mip:entsel "\nВыберите объекты" '("LINE" "LWPOLYLINE") (ssget))
	  (setq key T n 0 newentlist nil)
	  (if (eq (type entlist) 'PICKSET)
		(progn
			(while (setq a (ssname entlist n)) (setq newentlist (append newentlist (list a)) n (1+ n)))
			(setq entlist newentlist)
		);progn
	   );if
		(while key
			(if (or (setq ent_point (entsel promt)) (= (getvar "ERRNO") 7))
			(if (or (eq (type ent_point) 'LIST) (not ent_point))
			  (if ent_point
				(if (member (setq ent (car ent_point)) entlist)
				  (princ "\nПримитив уже выбран")
				  (if filter
					  (if (not (member (cdr (assoc 0 (entget ent))) filter))
					(progn (setq str "\nНеверный выбор, выберите: ")
					  (princ (substr (setq str (foreach n filter (setq str (strcat str n ", ")))) 1 (- (strlen str) 2)))
					);progn
					(setq key nil)
					  );if
					(setq key nil)
				);if
				);if
				(setq key T)
			  );if
				(setq key nil)
			);if
		  (setq key nil)
			);if
		 );while
	  (if (eq (type ent_point) 'LIST)
		(progn (setvar "LASTPOINT" (cadr ent_point)) ent)
		ent_point
	  );if
	);defun
	(defun RTD (a)(/ (* a 180.0) pi)) ;;функция переводит радианы в градусы
	(princ "\nКоманда \"TEST\" загружена")
	(princ)
Бегло протестировал, вроде всё работает. Надо только разобраться, в граничных значениях, где больше, где меньше, а где больше или равно. И
Цитата:
Сообщение от Seryj_Wolk Посмотреть сообщение
в лиспе это поправить

Последний раз редактировалось skkkk, 22.05.2015 в 16:11.
skkkk на форуме  
 
Автор темы   Непрочитано 30.04.2015, 13:05
#8
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


skkkk
Большое спасибо!!!! Будет свободная минутка потестирую и отпишусь о результате
Seryj_Wolk вне форума  
 
Автор темы   Непрочитано 19.05.2015, 09:37
#9
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


Цитата:
Сообщение от skkkk Посмотреть сообщение
Есть. Почти похожее. Чуть подправил, надеюсь, что правильно понял, что нужно. Использованы функции mip:entsel от VVA и RTD (по-моему, от него же).
Проверил. Вроде все работает. Еще раз большое спасибо. Облегчил ты мне жизнь.
Только есть небольшой ньюанс. Если я сопрягаю непрерывную полилинию, то все отлично. А если я сопрягаю отдельные куски полилинии или отрезки, то происходит следующее. После ввода команды нужно указать первый сегмент отрезка или полилинии. Указываю. Затем второй. Указываю. По идее должны были сопречься два элемента, но вместо этого выдает что "Сегменты сопряжены" и висит указание "Выберите второй объект или нажмите клавишу Shift при выборе, чтобы создать угол:". Приходится опять выбирать первый элемент и только после этого элементы сопрягаются. Если полилиния одна, то такого нет. После указания второго сегмента сразу происходит сопряжение. Можно это как-то поправить?

Последний раз редактировалось Seryj_Wolk, 19.05.2015 в 10:34.
Seryj_Wolk вне форума  
 
Непрочитано 19.05.2015, 12:31
1 | #10
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,588


Цитата:
Сообщение от Seryj_Wolk Посмотреть сообщение
но вместо этого выдает что "Сегменты сопряжены" и висит указание "Выберите второй объект или нажмите клавишу Shift при выборе, чтобы создать угол:"
Тестировал я, как уже говорил, бегло, и ожидал в принципе, некоторых бяк, но тот момент, что сопрягаться должны как цельные многосегментные полилинии, так и раздельные полилинии и отрезки, я продумал сразу (по приглашениям программы даже это понятно) и у меня при тесте срабатывали все случаи и под всеми углами 100%. Сейчас проверил еще раз: у меня работает и в том, и в другом случае. И пока мыслей нет, что может быть не так. Для того, чтобы мне легче было понять и воспроизвести ошибку, для начала приложи файл с примером, попробую на нем, там посмотрим. Думаю, какая-то переменная воду мутит.
skkkk на форуме  
 
Автор темы   Непрочитано 19.05.2015, 13:16
#11
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


Цитата:
Сообщение от skkkk Посмотреть сообщение
Тестировал я, как уже говорил, бегло, и ожидал в принципе, некоторых бяк, но тот момент, что сопрягаться должны как цельные многосегментные полилинии, так и раздельные полилинии и отрезки, я продумал сразу (по приглашениям программы даже это понятно) и у меня при тесте срабатывали все случаи и под всеми углами 100%. Сейчас проверил еще раз: у меня работает и в том, и в другом случае. И пока мыслей нет, что может быть не так. Для того, чтобы мне легче было понять и воспроизвести ошибку, для начала приложи файл с примером, попробую на нем, там посмотрим. Думаю, какая-то переменная воду мутит.
На вскидку попробовал несколько файлов наугад. Везде такая ерунда. Может это из-за автокада моего? Вот например файлик
Вложения
Тип файла: dwg
DWG 2007
Пример.dwg (519.6 Кб, 1305 просмотров)
Seryj_Wolk вне форума  
 
Непрочитано 20.05.2015, 18:34
1 | #12
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,588


Seryj_Wolk, обновил в #7.
skkkk на форуме  
 
Автор темы   Непрочитано 21.05.2015, 08:54
#13
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


skkkk,
Без изменений, так же как и раньше было
Seryj_Wolk вне форума  
 
Непрочитано 21.05.2015, 11:25
1 | #14
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,588


Самое интересное, что у меня и на твоем файле сразу работало. Я там нашел пару ошибок, добавил (vl-load-com), думал, может, дело в нем. Тестировал еще и на 2015-м у коллеги, без него не работало, с ним - все четко. Значит, без изменений...
Тогда поехали дальше. Какая версия Автокада? Есть ли дополнения какие, может, реакторы?
Далее я бы сравнил переменные. Для этого набираешь в командной строке _sysvdlg, там есть кнопка SaveAs. Сохрани в текстовый файл и приложи к посту. Дальше посмотрим.

Уважаемые форумчане, прошу, у кого есть возможность, проверить работу программы на версиях ниже 2011-й, а еще лучше, до 2008, поскольку у Серого Волка формат файла 2007. И подтвердить или опровергнуть ошибку, описанную им в #9.
skkkk на форуме  
 
Автор темы   Непрочитано 21.05.2015, 14:27
#15
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


AutoCAD 2007 A.54.0 (UNICODE)
Без всяких дополнений. Ничего кроме небольших лиспов не прикручено.
Неизвестная команда "SYSVDLG". Для вызова справки нажмите F1.
Seryj_Wolk вне форума  
 
Непрочитано 22.05.2015, 16:11
1 | #16
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,588


Цитата:
Сообщение от Seryj_Wolk Посмотреть сообщение
Неизвестная команда "SYSVDLG"
Стало быть, и без ExpressTools.
Впрочем, есть еще предположение, что используемая в коде команда _.FILLET имеет в 2007-м несколько иное поведение, поэтому срабатывает не так, как в 2011-м и 2015-м. Проверить не могу. Какие запросы в 2007-м у этой команды?
Основываясь на этом предположении, исправил код в #7, может, так сработает?
skkkk на форуме  
 
Автор темы   Непрочитано 22.05.2015, 16:31
#17
Seryj_Wolk

Инженер-электрик
 
Регистрация: 04.03.2008
Псков
Сообщений: 59


Цитата:
Сообщение от skkkk Посмотреть сообщение
Стало быть, и без ExpressTools.
Впрочем, есть еще предположение, что используемая в коде команда _.FILLET имеет в 2007-м несколько иное поведение, поэтому срабатывает не так, как в 2011-м и 2015-м. Проверить не могу. Какие запросы в 2007-м у этой команды?
Основываясь на этом предположении, исправил код в #7, может, так сработает?
без изменений
Seryj_Wolk вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как автоматически выставить радиус скругления в зависимости от угла между отрезками

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разработка ПОС, искусство проектирования Tyhig Технология и организация строительства 117 25.11.2021 17:38
Какой язык перспективен для инженера-конструктора с условием The_Mercy_Seat Программирование 705 17.03.2021 14:19
Revit Structure для конструктора (проблемы проектирования) professor_off Revit 5168 26.08.2015 16:48
Как отразить звуки от распахнутого окна квартиры? trel Архитектура 44 18.06.2015 06:11
Определение угла между отрезками Mazai Программирование 2 07.04.2008 12:27