明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2057|回复: 9

快速改变夹角

[复制链接]
发表于 2014-6-20 19:35 | 显示全部楼层 |阅读模式
5明经币
我有一个关于直线快速旋转(改变夹角)的想法,用lisp完成行么?就是两条直线,相交的,运行命令后,选择第一条直线(固定不动的),选择第二条直线(需要旋转的),然后显示:当前角度为xx度,请输入新角度,输入新角度后,就让第二条直线绕交点旋转使两线的角度等于输入的角度.

最佳答案

发表于 2014-6-20 19:35 | 显示全部楼层
  1. ;;取组码值
  2. (defun sk_dxf(ent code)(cdr(assoc code(entget ent))))
  3. ;;选择函数
  4. (defun sk_sel01(str filter / ent loop)
  5.   (setq loop t
  6.         str (if (= (type str) 'STR) str "")
  7.         filter(if (= (type filter) 'LIST) (mapcar 'strcase filter)  nil)
  8.         )        
  9.   (while loop
  10.     (if(setq ent(entsel str))
  11.       (if (member (strcase (sk_dxf (car ent) 0)) filter)
  12.       (setq loop nil)
  13.       )
  14.       (setq loop nil)
  15.     )
  16.     )
  17.   (if ent ent)
  18.   )
  19. ;;取拾取点附近直线或轻多段线两端点
  20. (defun sk_nearest(ent / en end_pt index index+ lst obj p0 p1 p3 p4)
  21.   (setq en(car ent)
  22.         p0(cadr ent)
  23.         )
  24.   (cond
  25.     ((= (sk_dxf en 0) "LINE")
  26.      (setq p1(vlax-curve-getClosestPointTo en p0))
  27.      (setq lst(list en p1 (sk_dxf en 10)(sk_dxf en 11)))
  28.      )
  29.     ((= (sk_dxf en 0) "LWPOLYLINE")
  30.      (setq p1(vlax-curve-getClosestPointTo en p0)
  31.            obj(vlax-ename->vla-object en)
  32.            end_pt(sk_dxf en 90)
  33.            index(fix(vlax-curve-getParamAtPoint obj p1))
  34.            p3(vlax-curve-getPointAtParam obj index)
  35.            index+(1+ index)
  36.            )
  37.      (if (and (=(sk_dxf en 70) 1)(> index+ end_pt))
  38.        (setq p4 (vlax-curve-getPointAtParam obj 0))
  39.        (setq p4 (vlax-curve-getPointAtParam obj index+))              
  40.        )
  41.      (vlax-release-object obj)
  42.      (setq lst(list en p1 p3 p4))     
  43.      )
  44.     )
  45.   )
  46. ;;;两线角度函数
  47. ;;;Two line angle
  48. ;;<a href=\"http://bbs.mjtd.com/forum.php?mod=viewthread&tid=16602&page=1&authorid=250774\" target=\"_blank\">http://bbs.mjtd.com/forum.php?mo ... amp;authorid=250774</a>
  49. ;;code by qjchen
  50. (defun q:geo:2line:ang2(p1 p2 p3 p4)
  51.   ((lambda(x) (atan (sqrt (abs (- 1.0 (* x x)))) x))
  52.      (/ (apply '+ (mapcar '* (mapcar '- p2 p1) (mapcar '- p4 p3))) (distance p1 p2) (distance p3 p4))
  53.   )
  54. )
  55. ;;三点判断顺逆时针
  56. ;;http://bbs.mjtd.com/forum.php?mo ... &authorid=43121
  57. ;;copy by edata@mjtd
  58. (defun sk_ang_3pt(p1 p2 p3 / a b c d p1x p1y p2x p2y p3x p3y)
  59.   (setq p1x(car p1)
  60.         p1y(cadr p1)
  61.         p2x(car p2)
  62.         p2y(cadr p2)
  63.         p3x(car p3)
  64.         p3y(cadr p3)
  65.         )
  66.   (setq a(- p3y p1y)
  67.         b(- p1x p3x)
  68.         c(-(* -1.0 a p1x)(* b p1y))
  69.         d(-(* -1.0 a p2x)(* b p2y))
  70.         )
  71.   (cond
  72.     ((= d c)0)     
  73.     ((> d c)-1)
  74.     (t 1)
  75.     )
  76.   )

  77. ;;主程序
  78. (defun c:tt(/ ang1 ang2 ang3 ang4 en2 ent1 ent2 ipt lst1 lst2 obj2 p1 p2 p3 p4 pt1 pt2 px1 px2 x y)
  79.   (if(and (setq ent1(sk_sel01 "\n选择第一条线" '("line" "lwpolyline")))
  80.           (list (redraw (car ent1) 3))
  81.           (setq ent2(sk_sel01 "\n选择第二条线" '("line" "lwpolyline")))
  82.           (list (redraw (car ent2) 3))
  83.           )
  84.     (progn
  85.       (setq lst1(sk_nearest ent1)
  86.             lst2(sk_nearest ent2)
  87.             )
  88.       (mapcar '(lambda(x y)(set (read x) y))(List "en1" "pt1" "p1" "p2")lst1)
  89.       (mapcar '(lambda(x y)(set (read x) y))(List "en2" "pt2" "p3" "p4")lst2)
  90.       (if(and pt1 pt2 p1 p2 p3 p4 (setq ipt(inters p1 p2 p3 p4 nil)))
  91.         (progn
  92.           (setq ang1(angle ipt pt1)
  93.                 px1(polar ipt ang1 1)
  94.                 ang2(angle ipt pt2)
  95.                 px2(polar ipt ang2 1)               
  96.                 ang3(q:geo:2line:ang2 ipt px1 ipt px2)
  97.                 obj2(vlax-ename->vla-object en2)
  98.                 )
  99.           (if (setq ang4(getangle (strcat "\n输入新的角度<当前:"(angtos ang3 0 4)">:" )))
  100.             (vla-Rotate obj2 (vlax-3d-point ipt) (if(=(sk_ang_3pt ipt px1 px2)1)(- ang4 ang3)(- ang3 ang4) ))
  101.             )
  102.           (vlax-release-object obj2)
  103.           )
  104.         (prompt "\n确认两条线是否有交点.")
  105.         )      
  106.       )   
  107.     )
  108.   (and ent1(redraw (car ent1) 4))
  109.   (and ent2(redraw (car ent2) 4))
  110.   (princ)
  111.   )

点评

e大,谢谢!非常好!无限感激!  发表于 2014-6-21 17:19
测试正确,极好  发表于 2014-6-21 12:27

评分

参与人数 2明经币 +2 收起 理由
清风明月名字 + 1 赞一个!
lucas_3333 + 1 赞一个!

查看全部评分

回复

使用道具 举报

发表于 2014-6-20 19:49 来自手机 | 显示全部楼层
仅仅是直线?
回复

使用道具 举报

 楼主| 发表于 2014-6-20 19:54 | 显示全部楼层
本帖最后由 lucas_3333 于 2014-6-20 19:57 编辑
edata 发表于 2014-6-20 19:49
仅仅是直线?

如果加上PL线,行吗?如果算上PL线,那也只能是针对两个点的PL线吧
回复

使用道具 举报

发表于 2014-6-20 19:59 来自手机 | 显示全部楼层
都是可以的。
直线边,无凸度。
回复

使用道具 举报

 楼主| 发表于 2014-6-20 20:05 | 显示全部楼层
edata 发表于 2014-6-20 19:59
都是可以的。
直线边,无凸度。

嗯,那样更好,谢谢e大
回复

使用道具 举报

发表于 2014-6-20 23:18 | 显示全部楼层
----------------
  1. ;;取组码值
  2. (defun sk_dxf(ent code)(cdr(assoc code(entget ent))))
  3. ;;选择函数
  4. (defun sk_sel01(str filter / ent loop)
  5.   (setq loop t
  6.         str (if (= (type str) 'STR) str "")
  7.         filter(if (= (type filter) 'LIST) (mapcar 'strcase filter)  nil)
  8.         )       
  9.   (while loop
  10.     (if(setq ent(entsel str))
  11.       (if (member (strcase (sk_dxf (car ent) 0)) filter)
  12.       (setq loop nil)
  13.       )
  14.       (setq loop nil)
  15.     )
  16.     )
  17.   (if ent ent)
  18.   )
  19. ;;取拾取点附近直线或轻多段线两端点
  20. (defun sk_nearest(ent / en end_pt index index+ lst obj p0 p1 p3 p4)
  21.   (setq en(car ent)
  22.         p0(cadr ent)
  23.         )
  24.   (cond
  25.     ((= (sk_dxf en 0) "LINE")
  26.      (setq p1(vlax-curve-getClosestPointTo en p0))
  27.      (setq lst(list en p1 (sk_dxf en 10)(sk_dxf en 11)))
  28.      )
  29.     ((= (sk_dxf en 0) "LWPOLYLINE")
  30.      (setq p1(vlax-curve-getClosestPointTo en p0)
  31.            obj(vlax-ename->vla-object en)
  32.            end_pt(sk_dxf en 90)
  33.            index(fix(vlax-curve-getParamAtPoint obj p1))
  34.            p3(vlax-curve-getPointAtParam obj index)
  35.            index+(1+ index)
  36.            )
  37.      (if (and (=(sk_dxf en 70) 1)(> index+ end_pt))
  38.        (setq p4 (vlax-curve-getPointAtParam obj 0))
  39.        (setq p4 (vlax-curve-getPointAtParam obj index+))              
  40.        )
  41.      (vlax-release-object obj)
  42.      (setq lst(list en p1 p3 p4))     
  43.      )
  44.     )
  45.   )
  46. ;;;两线角度函数
  47. ;;;Two line angle
  48. ;;http://bbs.mjtd.com/forum.php?mo ... amp;authorid=250774
  49. ;;code by qjchen
  50. (defun q:geo:2line:ang2(p1 p2 p3 p4)
  51.   ((lambda(x) (atan (sqrt (abs (- 1.0 (* x x)))) x))
  52.      (/ (apply '+ (mapcar '* (mapcar '- p2 p1) (mapcar '- p4 p3))) (distance p1 p2) (distance p3 p4))
  53.   )
  54. )
  55. ;;主程序
  56. (defun c:tt(/ ang1 ang2 ang3 ang4 en2 ent1 ent2 ipt lst1 lst2 obj2 p1 p2 p3 p4 pt1 pt2 px1 px2 x y)
  57.   (if(and (setq ent1(sk_sel01 "\n选择第一条线" '("line" "lwpolyline")))
  58.           (list (redraw (car ent1) 3))
  59.           (setq ent2(sk_sel01 "\n选择第二条线" '("line" "lwpolyline")))
  60.           (list (redraw (car ent2) 3))
  61.           )
  62.     (progn
  63.       (setq lst1(sk_nearest ent1)
  64.             lst2(sk_nearest ent2)
  65.             )
  66.       (mapcar '(lambda(x y)(set (read x) y))(List "en1" "pt1" "p1" "p2")lst1)
  67.       (mapcar '(lambda(x y)(set (read x) y))(List "en2" "pt2" "p3" "p4")lst2)
  68.       (if(and pt1 pt2 p1 p2 p3 p4 (setq ipt(inters p1 p2 p3 p4 nil)))
  69.         (progn
  70.           (setq ang1(angle ipt pt1)
  71.                 px1(polar ipt ang1 1)
  72.                 ang2(angle ipt pt2)
  73.                 px2(polar ipt ang2 1)       
  74.                 ang3(q:geo:2line:ang2 ipt px1 ipt px2)
  75.                 obj2(vlax-ename->vla-object en2)
  76.                 )
  77.           (if (setq ang4(getangle (strcat "\n输入新的角度<当前:"(angtos ang3 0 4)">:" )))
  78.             (vla-Rotate obj2 (vlax-3d-point ipt) (- ang4 ang3))
  79.             )
  80.           (vlax-release-object obj2)
  81.           )
  82.         (prompt "\n确认两条线是否有交点.")
  83.         )      
  84.       )   
  85.     )
  86.   (and ent1(redraw (car ent1) 4))
  87.   (and ent2(redraw (car ent2) 4))
  88.   (princ)
  89.   )
回复

使用道具 举报

 楼主| 发表于 2014-6-21 10:03 | 显示全部楼层
edata 发表于 2014-6-20 23:18
----------------

谢谢e大,

下图中,如果选择左边的线为第一条线,右边的为第二条线,就可以正确更改
如果选择右边的线为第一条线,左边的为第二条线,这样改角度就总是不对了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复

使用道具 举报

 楼主| 发表于 2014-6-21 11:35 | 显示全部楼层
edata 发表于 2014-6-21 11:32

谢谢e大,这会儿要出去,晚些再测试,谢谢
回复

使用道具 举报

发表于 2015-11-16 18:30 | 显示全部楼层
CAD2007   怎么用啊?  命令TT
只显示第一条线,,选择第二条线   ,,,,命令结束了   麻烦给我一个QQ252113063
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-20 18:33 , Processed in 1.871517 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表