ynhh 发表于 2021-12-13 14:38:57

求圆管轴线

求圆管轴线
由直线生成圆管很容易,现反过来,由圆管生成轴线感觉就无法了
只要有圆管轴线上任意两点坐标就可以了
如还能在选择三维圆管的同时,求出圆管外直径和壁厚,那感情更好了。
谢谢




夏生生 发表于 2021-12-13 14:38:58

不敢当,千万别叫大师。两点选择是为了后续建立切面,不只是为了选择图元,3Dsolid麻烦的地方在于几何特征点很难获取,我还是建议采用两点栏选的形式。非要选取的话,要用nentsel,但选择点不对的话,程序一样出错

夏生生 发表于 2021-12-13 23:03:18

本帖最后由 夏生生 于 2021-12-13 23:10 编辑

代码又臭又长:lol

;;;思路是建立两个断面,断面中心连线,
;;;后续可以根据连线再求出连线的垂面,利用垂面建立断面,可以求得直径和壁厚
(defun c:test (/ value2list vxv ANG DOC LST1 LST2 OBJ OBJ1 OBJ2 OBJ3 PT1 PT1A PT2 PT2A PT3 PT3A SS)
(defun value2list (value)
    (setq value      (vl-catch-all-apply
                  (function vlax-safearray->list)
                  (list (vlax-variant-value value))
                )
    )
    (if      (= (type value) (function LIST))
      value
      nil
    )
)
(defun vxv (u v)
    (list
      (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
      (- (* (car v) (caddr u)) (* (car u) (caddr v)))
      (- (* (car u) (cadr v)) (* (car v) (cadr u)))
    )
)
(setq      pt1(getpoint "\n栏选起点:")
      pt2(getpoint pt1 "\n栏选终点:")
      pt3(mapcar '+ pt1 '(0 0 1))
      ang(+ (* 0.5 pi) (angle pt1 pt2))
      pt1a (polar pt1 ang 1)
      pt2a (polar pt2 ang 1)
      pt3a (mapcar '+ pt1a '(0 0 1))
      ss   (ssget "f" (list pt1 pt2) '((0 . "3DSOLID")))
      obj(vlax-ename->vla-object (ssname ss 0))
      pt1(vlax-3d-point pt1)
      pt1a (vlax-3d-point pt1a)
      pt2(vlax-3d-point pt2)
      pt2a (vlax-3d-point pt2a)
      pt3(vlax-3d-point pt3)
      pt3a (vlax-3d-point pt3a)
      doc(vlax-get-property (vlax-get-acad-object) 'activedocument)
      doc(if (= 1 (getvar "cvport"))
               (vlax-get-property doc 'paperspace)
               (vlax-get-property doc 'modelspace)
             )
      obj1 (vla-SectionSolid obj pt1 pt2 pt3)
      obj2 (vla-SectionSolid obj pt1a pt2a pt3a)
      lst1 (value2list (vla-explode obj1))
      lst2 (value2list (vla-explode obj2))
      pt1(vla-get-Center (car lst1))
      pt2(vla-get-Center (car lst2))
      obj3 (vla-addline doc pt1 pt2)
)
(vla-ScaleEntity obj3 pt1 1000)
(foreach n (append (list obj1 obj2) lst1 lst2)
    (vla-delete n)
)
(setq      pt1(value2list pt1)
      pt2(value2list pt2)
      pt3(mapcar '- pt2 pt1) ;_法向量
      pt1a (distance '(0 0 0) pt3) ;_法向量的模
      pt1a (mapcar '(lambda (x) (/ x pt1a)) pt3) ;_单位向量
      pt2a (vl-list* (- (cadr pt1a)) (car pt1a) (cddr pt1a)) ;_pt1a旋转90度
      pt3a (vxv pt1a pt2a) ;_垂面点1
      pt2a (vxv pt1a pt3a) ;_垂面点2
      obj1 (vla-SectionSolid
               obj
               (vlax-3d-point pt1)
               (vlax-3d-point (mapcar '+ pt1 pt3a))
               (vlax-3d-point (mapcar '+ pt1 pt2a))
             )
      lst1 (value2list (vla-explode obj1))
      lst2 (vl-sort (mapcar 'vla-get-Diameter lst1) '>)
)
(vla-delete obj1)
(princ (strcat "\n直径:"
               (rtos (car lst2) 2 2)
               ";壁厚:"
               (rtos (* 0.5 (- (car lst2) (cadr lst2))) 2 2)
         )
)
(princ)
)

ynhh 发表于 2021-12-14 09:29:02

夏生生 发表于 2021-12-13 23:03
代码又臭又长

大师您好:
您的程序经试很好,只是操作时选择两点有时如没与圆管相交时就出错
请你试试能不能改成
选择圆管实体图元的方式
谢谢您的帮助

ynhh 发表于 2021-12-14 10:16:39

夏生生 发表于 2021-12-14 09:42
不敢当,千万别叫大师。两点选择是为了后续建立切面,不只是为了选择图元,3Dsolid麻烦的地方在于几何特征 ...

谢谢夏工。
您写的程序看上去太难以理解,我慢慢消化学习。
再请教个问题:
用section
中的三点方式形成一个面与圆管实体相交后形成两个位于圆管侧壁上的面域,再用这两个面域来取出平行于圆管的长线,线的两端点则是展开图的下料长度。
但有个不太明白的是,圆管一次形成两个面域感觉混乱,怕自动选择错了,不知能不能只形成一个面域?
以您的水平应能搞定这个展开程序的
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=184499&page=1#pid903159
也请您看看


夏生生 发表于 2021-12-14 10:34:53

ynhh 发表于 2021-12-14 10:16
谢谢夏工。
您写的程序看上去太难以理解,我慢慢消化学习。
再请教个问题:


实际上是一个平铺直叙的逻辑
(setq      pt1(getpoint "\n栏选起点:");_栏选起点,切面1第一点pt1
      pt2(getpoint pt1 "\n栏选终点:");_栏选终点,切面1第二点pt2
      pt3(mapcar '+ pt1 '(0 0 1));_切面1第三点pt3,把第一点的z+1(1可以是任意值)
      ang(+ (* 0.5 pi) (angle pt1 pt2));_点1、2角度+90度,为切面2做准备
      pt1a (polar pt1 ang 1);_切面2第一点,pt1顺角度移动1(1可以是任意值)
      pt2a (polar pt2 ang 1);_切面2第二点,pt2顺角度移动1(1可以是任意值)
      pt3a (mapcar '+ pt1a '(0 0 1));_切面2第三点,把pt1a的z+1(1可以是任意值)
      ss   (ssget "f" (list pt1 pt2) '((0 . "3DSOLID")));_选择实体,最好能切到完整截面
      obj(vlax-ename->vla-object (ssname ss 0));_转为obj
      pt1(vlax-3d-point pt1);_转为数组
      pt1a (vlax-3d-point pt1a);_转为数组
      pt2(vlax-3d-point pt2);_转为数组
      pt2a (vlax-3d-point pt2a);_转为数组
      pt3(vlax-3d-point pt3);_转为数组
      pt3a (vlax-3d-point pt3a);_转为数组
      doc(vlax-get-property (vlax-get-acad-object) 'activedocument);_doc
      doc(if (= 1 (getvar "cvport"))
               (vlax-get-property doc 'paperspace)
               (vlax-get-property doc 'modelspace)
             );_space
      obj1 (vla-SectionSolid obj pt1 pt2 pt3);_切第一个面域
      obj2 (vla-SectionSolid obj pt1a pt2a pt3a);_切第二个面域
      lst1 (value2list (vla-explode obj1));_炸开第一个面域
      lst2 (value2list (vla-explode obj2));_炸开第二个面域
      pt1(vla-get-Center (car lst1));_炸开后的图元是椭圆或圆,随便找一个获取其形心
      pt2(vla-get-Center (car lst2));_炸开后的图元是椭圆或圆,随便找一个获取其形心
      obj3 (vla-addline doc pt1 pt2);_形心相连即为中心线
)
(vla-ScaleEntity obj3 pt1 1000);_中心线放大1000倍
(foreach n (append (list obj1 obj2) lst1 lst2)
    (vla-delete n)
);_删除前面操作产生的obj
(setq      pt1(value2list pt1);_数组转点,前面产生的第一个面域的中心
      pt2(value2list pt2);_数组转点,前面产生的第二个面域的中心
      pt3(mapcar '- pt2 pt1) ;_法向量
      pt1a (distance '(0 0 0) pt3) ;_法向量的模
      pt1a (mapcar '(lambda (x) (/ x pt1a)) pt3) ;_单位向量
      pt2a (vl-list* (- (cadr pt1a)) (car pt1a) (cddr pt1a)) ;_pt1a旋转90度
      pt3a (vxv pt1a pt2a) ;_垂面点1
      pt2a (vxv pt1a pt3a) ;_垂面点2
;;;前面的运算都是为了求与管中心线垂直的面,因为第一面域和第二面域都不一定垂直于管中心线
;;;后面的操作和前面的操作基本相同,区别就在于垂直面,我就不注释了
      obj1 (vla-SectionSolid
               obj
               (vlax-3d-point pt1)
               (vlax-3d-point (mapcar '+ pt1 pt3a))
               (vlax-3d-point (mapcar '+ pt1 pt2a))
             )
      lst1 (value2list (vla-explode obj1))
      lst2 (vl-sort (mapcar 'vla-get-Diameter lst1) '>)
)
(vla-delete obj1)

999999 发表于 2022-4-30 09:27:25

这么好的贴子,及大神的耐心回复,顶起来

寒潮大冬瓜 发表于 2024-8-7 20:54:30

很好→很棒!很好~很棒!!很好……很棒!!!
页: [1]
查看完整版本: 求圆管轴线