明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 436|回复: 16

[提问] 画相切圆弧

[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式
50明经币
本帖最后由 sunny_8848 于 2025-4-18 14:52 编辑

要求见图。
情形①已知两个圆半径(125),两圆圆心间距是(127),两圆心连线偏移(133),画圆与两小圆及上述偏移出来的直线相切,修剪后得到4段圆弧。
情形②已知两个圆半径(125),两圆圆心间距是(127),与上述两个圆相切的第三个圆半径(370),画出第三个相切圆,上下两段圆弧顶点间距(266)修剪后得到4段圆弧。
情形③已知两个圆半径(125),两圆圆心间距是(127),画与上述两个圆相切的第三个圆,其切点与圆心连线与竖直轴向夹角为14,修剪后得到4段圆弧。
请帮忙写一个lsp文件,上述圆半径等参数在命令行输入。
其实就是几个条件组合,满足3个条件就行。小圆半径和两圆心间距肯定是已知的,有时知道夹角,有时知道大圆半径370,有时知道上下两段圆弧距离是266而已





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

最佳答案

查看完整内容

更新了一下,采用算点法,避免了原来的视口问题,最好用这个 采用作图法,容易出现视口问题,也就是图元在视口外的时候捕捉不到点 (以下为正确示例) 用算点算的,公式推错了,这个代码就作为错误示例放在这里吧,警示后人 (以下为错误示例)
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层
本帖最后由 夏生生 于 2025-4-19 12:21 编辑

更新了一下,采用算点法,避免了原来的视口问题,最好用这个
  1. (defun c:tt  (/  xty-tan  xty-acos ang dis1 dis2 m pt pt1  pt2 pt3  pt4 pt5  pt6 pt7  pt8 pta  r1 r2)
  2. (defun  xty-tan   (ang)
  3.   ((lambda (x)
  4.     (if  (equal 0. x 1e-14)
  5.      nil
  6.      (/ (sin ang) x)))        (cos ang)))
  7. (defun  xty-acos  (num)
  8.   (if (zerop num)
  9.    (* pi 0.5)
  10.    (atan (sqrt (- 1.0 (* num num))) num)))
  11. (setq ***tt-r1***    (if ***tt-r1***
  12.            ***tt-r1***
  13.            125)
  14.        ***tt-dis1***  (if ***tt-dis1***
  15.            ***tt-dis1***
  16.            127)
  17.        ***tt-r2***    (if ***tt-r2***
  18.            ***tt-r2***
  19.            370)
  20.        ***tt-ang***   (if ***tt-ang***
  21.            ***tt-ang***
  22.            14)
  23.        ***tt-dis2***  (if ***tt-dis2***
  24.            ***tt-dis2***
  25.            133)
  26.        pt        '(0 0 0)
  27.        pta        (getpoint "\n插入点:")
  28.        r1        (getreal
  29.            (strcat "\n两圆半径<" (rtos ***tt-r1*** 2 3) ">:"))
  30.        r1        (if r1
  31.            (setq ***tt-r1*** r1)
  32.            ***tt-r1***)
  33.        dis1        (getreal
  34.            (strcat "\n两圆心距:<" (rtos ***tt-dis1*** 2 3) ">:"))
  35.        dis1        (if dis1
  36.            (setq ***tt-dis1*** dis1)
  37.            ***tt-dis1***)
  38.        dis1        (* 0.5 dis1)
  39.        ***tt-kword*** (if ***tt-kword***
  40.            ***tt-kword***
  41.            "Off"))
  42. (initget "Off Ang Rad")
  43. (setq m (getkword
  44.     (strcat "\n已知条件[偏线距(Off)/夹角(Ang)/半径(Rad)]<"
  45.       ***tt-kword***
  46.       ">")))
  47. (if (null m)
  48.   (setq m ***tt-kword***))
  49. (setq ***tt-kword*** m)
  50. (cond
  51.   ((eq m "Ang")
  52.    (setq ang  (getreal
  53.          (strcat "\n夹角(角度)<" (rtos ***tt-ang*** 2 3) ">:"))
  54.    ang  (if ang
  55.          (setq ***tt-ang*** ang)
  56.          ***tt-ang***)
  57.    ang  (* pi (/ ang 180.))
  58.    dis2 (+ r1 (* (xty-tan (* 0.5 ang)) dis1))))
  59.   ((eq m "Off")
  60.    (setq dis2 (getreal
  61.          (strcat "\n偏线距<" (rtos ***tt-dis2*** 2 3) ">:"))
  62.    dis2 (if dis2
  63.          (setq ***tt-dis2*** dis2)
  64.          ***tt-dis2***)
  65.    ang  (* 2 (atan (- dis2 r1) dis1))))
  66.   ((eq m "Rad")
  67.    (setq r2   (getreal
  68.          (strcat "\n外接圆半径<" (rtos ***tt-r2*** 2 3) ">:"))
  69.    r2   (if r2
  70.          (setq ***tt-r2*** r2)
  71.          ***tt-r2***)
  72.    ang  (- (* 0.5 pi) (xty-acos (/ dis1 (- r2 r1))))
  73.    dis2 (- r2 (* (cos ang) (- r2 r1)))))
  74.   )
  75. (setq pt1 (polar pt pi dis1)
  76.        pt1 (polar pt1 (+ (* 0.5 pi) ang) r1)
  77.        pt1 (mapcar '+ pt1 pta))
  78. (setq pt2 (polar pt pi (+ r1 dis1))
  79.        pt2 (mapcar '+ pt2 pta))
  80. (setq pt3 (polar pt pi dis1)
  81.        pt3 (polar pt3 (- (* 1.5 pi) ang) r1)
  82.        pt3 (mapcar '+ pt3 pta))
  83. (setq pt4 (polar pt (* 1.5 pi) dis2)
  84.        pt4 (mapcar '+ pt4 pta))
  85. (setq pt5 (polar pt 0 dis1)
  86.        pt5 (polar pt5 (+ (* 1.5 pi) ang) r1)
  87.        pt5 (mapcar '+ pt5 pta))
  88. (setq pt6 (polar pt 0 (+ r1 dis1))
  89.        pt6 (mapcar '+ pt6 pta))
  90. (setq pt7 (polar pt 0 dis1)
  91.        pt7 (polar pt7 (- (* 0.5 pi) ang) r1)
  92.        pt7 (mapcar '+ pt7 pta))
  93. (setq pt8 (polar pt (* 0.5 pi) dis2)
  94.        pt8 (mapcar '+ pt8 pta))
  95. (vl-cmdf "arc" "none" pt1 "none" pt2 "none" pt3)
  96. (vl-cmdf "arc" "none" pt3 "none" pt4 "none" pt5)
  97. (vl-cmdf "arc" "none" pt5 "none" pt6 "none" pt7)
  98. (vl-cmdf "arc" "none" pt7 "none" pt8 "none" pt1)
  99. ;;; (vl-cmdf "pline" "none" pt1 "a" "s" "none" pt2    "none" pt3 "s" "none" pt4 "none" pt5 "s" "none"    pt6 "none"pt7"cl");_如采用lwpline将pt8可以注释掉

  100. (princ))

采用作图法,容易出现视口问题,也就是图元在视口外的时候捕捉不到点
(以下为正确示例)

  1. (defun c:tt  (/  xty-tan xty-acos ang dis1 dis2 en1 en2 en3 en4 m  pt pt1 pt2 pt3 pt4 pt5 pt6 pt7 pt8 pta r1 r2)
  2. (defun  xty-tan   (ang)
  3.   ((lambda (x)
  4.     (if  (equal 0. x 1e-14)
  5.      nil
  6.      (/ (sin ang) x)))        (cos ang)))
  7. (defun  xty-acos  (num)
  8.   (if (zerop num)
  9.    (* pi 0.5)
  10.    (atan (sqrt (- 1.0 (* num num))) num)))
  11. (setq pt        '(0 0 0)
  12.        pta        (getpoint "\n插入点:")
  13.        r1        (getreal "\n两圆半径:")
  14.        dis1        (* 0.5 (getreal "\n两圆心距:"))
  15.        ***tt-kword*** (if ***tt-kword***
  16.            ***tt-kword***
  17.            "Off"))
  18. (vl-cmdf "circle" "none" (polar pt pi dis1) r1)
  19. (setq en1 (vlax-ename->vla-object (entlast)))
  20. (vl-cmdf "circle" "none" (polar pt 0 dis1) r1)
  21. (setq en2 (vlax-ename->vla-object (entlast)))
  22. (vl-cmdf "zoom"
  23.     "w"
  24.     (list (* 3 (- 0 r1 dis1)) (* 3 (- 0 r1 dis1)))
  25.     (list (* 3 (+ r1 dis1)) (* 3 (+ r1 dis1))))
  26. (initget "Off Ang Rad")
  27. (setq m (getkword
  28.     (strcat "\n已知条件[偏线距(Off)/夹角(Ang)/半径(Rad)]<"
  29.       ***tt-kword***
  30.       ">")))
  31. (if (null m)
  32.   (setq m ***tt-kword***))
  33. (setq ***tt-kword*** m)
  34. (cond ((eq m "Off")
  35.   (setq dis2 (getreal "\n偏线距:")))
  36.        ((eq m "Ang")
  37.   (setq ang  (getreal "\n夹角(角度):")
  38.         ang  (* pi (/ ang 180.))
  39.         dis2 (+ (* r1 (cos ang))
  40.           (* (+ (* r1 (sin ang)) dis1) (xty-tan (* 0.5 ang))))))
  41.        ((eq m "Rad")
  42.   (setq r2   (getreal "\n外接圆半径:")
  43.         ang  (- (* 0.5 pi) (xty-acos (/ dis1 (- r2 r1))))
  44.         dis2 (+ (* r1 (cos ang))
  45.           (* (+ (* r1 (sin ang)) dis1) (xty-tan (* 0.5 ang)))))))
  46. (vl-cmdf "line"
  47.     "none"
  48.     (mapcar '+ pt (list (- dis1) dis2 0))
  49.     "none"
  50.     (mapcar '+ pt (list dis1 dis2 0))
  51.     "")
  52. (setq en3 (vlax-ename->vla-object (entlast)))
  53. (setq pt7 (list 0 dis2 0)
  54.        pt4 (list 0 (- dis2) 0)
  55.        pt2 (list (- 0 r1 dis1) 0 0)
  56.        pt6 (list (+ r1 dis1) 0 0))
  57. (vl-cmdf "circle" "3p" "tan" pt2 "tan" pt6 "tan" pt7)
  58. (setq en4 (vlax-ename->vla-object (entlast)))
  59. (setq pt1 (vlax-safearray->list
  60.       (vlax-variant-value  (vla-intersectwith en1 en4 acExtendBoth))))
  61. (setq pt7 (vlax-safearray->list
  62.       (vlax-variant-value  (vla-intersectwith en2 en4 acExtendBoth))))
  63. (setq pt8 (vlax-safearray->list
  64.       (vlax-variant-value  (vla-intersectwith en3 en4 acExtendBoth))))
  65. (setq pt3 (list (car pt1) (- (cadr pt1)) (caddr pt1)))
  66. (setq pt5 (list (car pt7) (- (cadr pt7)) (caddr pt7)))
  67. (setq pt1 (mapcar '+ pt1 pta))
  68. (setq pt2 (mapcar '+ pt2 pta))
  69. (setq pt3 (mapcar '+ pt3 pta))
  70. (setq pt4 (mapcar '+ pt4 pta))
  71. (setq pt5 (mapcar '+ pt5 pta))
  72. (setq pt6 (mapcar '+ pt6 pta))
  73. (setq pt7 (mapcar '+ pt7 pta))
  74. (setq pt8 (mapcar '+ pt8 pta))
  75. (foreach n (list en1 en2 en3 en4) (vla-delete n))
  76. (vl-cmdf "arc" "none" pt1 "none" pt2 "none" pt3)
  77. (vl-cmdf "arc" "none" pt3 "none" pt4 "none" pt5)
  78. (vl-cmdf "arc" "none" pt5 "none" pt6 "none" pt7)
  79. (vl-cmdf "arc" "none" pt7 "none" pt8 "none" pt1)
  80. (vl-cmdf "zoom" "p")
  81. (princ))

用算点算的,公式推错了,这个代码就作为错误示例放在这里吧,警示后人
(以下为错误示例)

  1. (defun c:tt  (/        xty-acos ang dis1 dis2 m pt pt1 pt2 pt3 pt4 pt5 pt6 pt7 pt8 pta r1 r2)
  2. (defun        xty-acos  (num)
  3.   (if (zerop num)
  4.    (* pi 0.5)
  5.    (atan (sqrt (- 1.0 (* num num))) num)))
  6. (setq pt              '(0 0 0)
  7.        pta              (getpoint "\n插入点:")
  8.        r1              (getreal "\n两圆半径:")
  9.        dis1              (* 0.5 (getreal "\n两圆心距:"))
  10.        ***tt-kword*** (if ***tt-kword***
  11.                        ***tt-kword***
  12.                        "Off"))
  13. (initget "Off Ang Rad")
  14. (setq m (getkword
  15.           (strcat "\n已知条件[偏线距(Off)/夹角(Ang)/半径(Rad)]<"
  16.                   ***tt-kword***
  17.                   ">")))
  18. (if (null m)
  19.   (setq m ***tt-kword***))
  20. (setq ***tt-kword*** m)
  21. (cond ((eq m "Ang")
  22.         (setq ang  (getreal "\n夹角(角度):")
  23.               ang  (* pi (/ ang 180.))
  24.               dis2 (+ r1 (* 0.5 dis1 (sin (* 0.5 ang))))))
  25.        ((eq m "Off")
  26.         (setq dis2 (getreal "\n偏线距:")
  27.               ang  (- (* 0.5 pi) (xty-acos (/ (* 2. (- dis2 r1)) dis1)))))
  28.        ((eq m "Rad")
  29.         (setq r2   (getreal "\n外接圆半径:")
  30.               ang  (- (* 0.5 pi) (xty-acos (/ dis1 (- r2 r1))))
  31.               dis2 (+ r1 (* 0.5 dis1 (sin (* 0.5 ang)))))))
  32. (setq pt1 (polar pt pi dis1)
  33.        pt1 (polar pt1 (+ (* 0.5 pi) ang) r1)
  34.        pt1(mapcar'+ pt1 pta))
  35. (setq pt2 (polar pt pi (+ r1 dis1))pt2(mapcar'+ pt2 pta))
  36. (setq pt3 (polar pt pi dis1)
  37.        pt3 (polar pt3 (- (* 1.5 pi) ang) r1)pt3(mapcar'+ pt3 pta))
  38. (setq pt4 (polar pt (* 1.5 pi) dis2)pt4(mapcar'+ pt4 pta))
  39. (setq pt5 (polar pt 0 dis1)
  40.        pt5 (polar pt5 (+ (* 1.5 pi) ang) r1)pt5(mapcar'+ pt5 pta))
  41. (setq pt6 (polar pt 0 (+ r1 dis1))pt6(mapcar'+ pt6 pta))
  42. (setq pt7 (polar pt 0 dis1)
  43.        pt7 (polar pt7 (- (* 0.5 pi) ang) r1)pt7(mapcar'+ pt7 pta))
  44. (setq pt8 (polar pt (* 0.5 pi) dis2)pt8(mapcar'+ pt8 pta))
  45. (vl-cmdf"arc""none" pt1 "none"pt2 "none"pt3)
  46. (vl-cmdf"arc""none" pt3 "none"pt4 "none"pt5)
  47. (vl-cmdf"arc""none" pt5 "none"pt6 "none"pt7)
  48. (vl-cmdf"arc""none" pt7 "none"pt8 "none"pt1)
  49. (princ))
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层
  1. (setq pt1 (getpoint))
  2. (setq pt2 (getpoint pt1))
  3. (setq line1 (vla-addline (vla-get-ModelSpace (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))
  4.               (VLAX-3D-POINT pt1) (VLAX-3D-POINT pt2)))
  5. (setq minr (getdist pt2))
  6. (setq circle1 (vla-addcircle (vla-get-ModelSpace (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))
  7.                 (VLAX-3D-POINT pt1) minr))
  8. (setq circle2 (vla-addcircle (vla-get-ModelSpace (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))
  9.                 (VLAX-3D-POINT pt2) minr))
  10. (setq ang12 (angle pt1 pt2))
  11. (setq dist12 (distance pt1 pt2))
  12. (setq ptm (polar pt1 ang12 (* 0.5 dist12)))
  13. (setq pianju (getdist ptm))
  14. (setq maxr (/ (+ (* pianju pianju) (* -1 minr minr) (* 0.25 dist12 dist12)) (* 2 (- pianju minr))))
  15. (setq ptc1 (polar ptm (+ ang12 (* 0.5 pi)) (- maxr pianju)))
  16. (setq ptc2 (polar ptm (- ang12 (* 0.5 pi)) (- maxr pianju)))
  17. (setq arc1 (vla-addarc (vla-get-ModelSpace (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))
  18.                 (VLAX-3D-POINT ptc1) maxr (angle ptc1 pt1) (angle ptc1 pt2)))
  19. (setq arc2 (vla-addarc (vla-get-ModelSpace (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))
  20.                 (VLAX-3D-POINT ptc2) maxr (angle ptc2 pt2) (angle ptc2 pt1)))
  21. (setq arc3 (vla-addarc (vla-get-ModelSpace (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))
  22.                 (VLAX-3D-POINT pt1) minr (angle ptc2 pt1) (angle ptc1 pt1)))
  23. (setq arc4 (vla-addarc (vla-get-ModelSpace (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))
  24.                 (VLAX-3D-POINT pt2) minr (angle ptc1 pt2) (angle ptc2 pt2)))
  25. (vla-delete line1)
  26. (vla-delete circle1)
  27. (vla-delete circle2)

评分

参与人数 1明经币 +1 金钱 +5 收起 理由
sunny_8848 + 1 + 5 谢谢帮助(金钱不够了)

查看全部评分

回复

使用道具 举报

 楼主| 发表于 3 天前 | 显示全部楼层

谢谢帮忙,上述代码在已知两圆半径、两圆心间距及第3个圆顶点间距的这种效果挺好的。能麻烦您增加下已知两圆半径和两圆心间距,然后是第三个相切圆半径或切线与垂直轴夹角这两种情形吗
回复

使用道具 举报

 楼主| 发表于 3 天前 | 显示全部楼层
夏生生 发表于 2025-4-18 11:59
用算点算的,由于算了角度,所以有时候误差不小,最好是用画法

谢谢帮忙。画图思路就是我想要的,只是输入第三个圆的半径或切线角度时,得到的圆和第一种方法有点差别,能麻烦您完善下吗
回复

使用道具 举报

发表于 3 天前 来自手机 | 显示全部楼层
sunny_8848 发表于 2025-4-18 13:11
谢谢帮忙。画图思路就是我想要的,只是输入第三个圆的半径或切线角度时,得到的圆和第一种方法有点差别, ...

有角度计算,必然误差大,无法避免的,你自己的三个已知数,相互反算就对不上,可以按计算器试试
回复

使用道具 举报

 楼主| 发表于 3 天前 | 显示全部楼层
我找到偏差大的原因了,您是按切点与小圆圆心连线算角度,实际应该是切点与大圆圆心连线的角度。

本帖子中包含更多资源

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

x
回复

使用道具 举报

 楼主| 发表于 3 天前 | 显示全部楼层
夏生生 发表于 2025-4-18 13:56
有角度计算,必然误差大,无法避免的,你自己的三个已知数,相互反算就对不上,可以按计算器试试

我的参数是用约束求出的,不知道是否约束错了。麻烦您再看看,我感觉是角度那里的计算,您是采用切点与小圆圆心连线,实际我是需要切点与大圆的连线与垂直轴的夹角
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层
sunny_8848 发表于 2025-4-18 14:52
我的参数是用约束求出的,不知道是否约束错了。麻烦您再看看,我感觉是角度那里的计算,您是采用切点与小 ...

(setq ang  (* (getreal "\n夹角(角度):") 2)
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层
sunny_8848 发表于 2025-4-18 14:52
我的参数是用约束求出的,不知道是否约束错了。麻烦您再看看,我感觉是角度那里的计算,您是采用切点与小 ...

在四楼改了,试一下,如果您自己能推出2和3的公式可以用错误示例去改
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-21 18:02 , Processed in 0.222060 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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