找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 681|回复: 3

[试用]:求过一点并且与两直线相切的圆(源码)

[复制链接]

已领礼包: 3个

财富等级: 恭喜发财

发表于 2005-6-4 14:15:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
求过一点并且与两直线相切的圆
这里使用了一个明经上mccad写的一个曲线相交求交点的函数,在下面可以下载到的。因为是别人写的,我没有公布源码,请见谅。


  1. ;;By Xiao_longxin
  2. ;;e1_star  e1_end 第一条直线起、点
  3. ;;e2_star  e2_end 第二条直线起、点
  4. ;;pt 要求的相切圆上的一点

  5. ;;返回:
  6. ;;((圆心坐标) 半径 (圆心坐标) 半径)

  7. (defun errexit (s)
  8.   (princ "\nError:  ")
  9.   (princ s)
  10. )

  11. (defun onepo_twoline_qieyuan (           e1_star    e1_end
  12.                                 e2_star           e2_end     pt /
  13.                                 oldcmdecho oldosmode setp ang1
  14.                                 ang1_cz           ang2              ang2_cz
  15.                                 ang           ang2_      ang1_
  16.                                 e1_e2 e1_e2_gx              pt_e1
  17.                                 pt_e2           jd              p1
  18.                                 p2           p3              dist
  19.                                 dist1           dist2      p4
  20.                                 cr_list           cr_pt      cr_r
  21.                                 ent           pfx              pfx_cz
  22.                                 jd_list           e1              e2
  23.                                )

  24.   ;;(setq e1_star (getpoint))
  25.   ;;(setq e1_end (getpoint))
  26.   ;;(setq e2_star (getpoint))
  27.   ;;(setq e2_end (getpoint))
  28.   ;;(setq pt (getpoint))
  29.   ;;(command "point" pt)
  30.   ;;(command "pline" e1_star e1_end "")
  31.   ;;(command "pline" e2_star e2_end "")

  32.   (setq oldcmdecho (getvar "cmdecho"))
  33.   (setvar "cmdecho" 0)
  34.   (setq oldosmode (getvar "osmode"))
  35.   (setvar "osmode" 0)
  36.   (setq setp 0.000000005)                ;设置允许的误差

  37.   (setq ang1 (angle e1_star e1_end))        ;直线1的方位角
  38.   (setq ang1_cz (+ ang1 (/ pi 2)))
  39.   (setq ang2 (angle e2_star e2_end))        ;直线2的方位角
  40.   (setq ang2_cz (+ ang2 (/ pi 2)))
  41.    
  42.   (setq ang (angle e1_star e2_end))


  43.                                         ;分别判断2条直线之间是否平行
  44.   (if (or (< (abs (- ang1 ang2)) setp)
  45.           (and (< (abs (- ang1 ang2)) (+ pi setp))
  46.                                         ;2条直线平行允许有一定的误差
  47.                (> (abs (- ang1 ang2)) (- pi setp))
  48.           )
  49.       )
  50.     (setq e1_e2 t)
  51.     (setq e1_e2 nil)
  52.   )

  53.    
  54.   ;;判断e1 e2是否是同一条直线
  55.   (if (and e1_e2
  56.            (or (< (abs (- ang1 ang)) setp)
  57.                (and (< (abs (- ang1 ang)) (+ pi setp))
  58.                                         ;2条直线平行允许有一定的误差
  59.                     (> (abs (- ang1 ang)) (- pi setp))
  60.                )
  61.            )
  62.       )
  63.     (setq e1_e2_gx t)
  64.     (setq e1_e2_gx nil)
  65.   )

  66.   ;;求p1点与直线的垂距,以此判断是否在直线上
  67.   (setq p1 (polar pt ang1_cz 100))
  68.   (setq p1 (inters e1_star e1_end p1 pt nil))
  69.   (setq ang1_ (angle p1 pt))
  70.   (setq dist1 (distance p1 pt))
  71.   (if (< dist1 0.0001)
  72.     (setq pt_e1 t)
  73.     (setq pt_e1 nil)
  74.   )
  75.   ;;求p2点与直线的垂距,以此判断是否在直线上
  76.   (setq p2 (polar pt ang2_cz 100))
  77.   (setq p2 (inters e2_star e2_end p2 pt nil))
  78.   (setq dist2 (distance p2 pt))
  79.   (setq ang2_ (angle p2 pt))
  80.   (if (< dist2 0.0001)
  81.     (setq pt_e2 t)
  82.     (setq pt_e2 nil)
  83.   )

  84.   (cond
  85.     ((and (and (< (abs (- ang1_ ang2_)) 0.000000001) e1_e2)
  86.           (not e1_e2_gx)
  87.      )                                        ;点在两平行线的一边
  88.      (prompt "\n点在两平行线的一边,没有切圆")
  89.      (setq cr_list nil)
  90.     )
  91.     ((and e1_e2_gx (or pt_e1 pt_e2))        ;两线共一且点在线上
  92.      (prompt "\n两线共一且点在线上,没有切圆")
  93.      (setq cr_list nil)
  94.     )
  95.     ((and e1_e2_gx (and (not pt_e1) (not pt_e2))) ;两线共线且点不在线上
  96.      (setq cr_r (/ dist1 2))
  97.      (setq cr_pt (polar p1 ang1_ cr_r))
  98.      ;;(command "._circle" cr_pt cr_r)
  99.      (setvar "cmdecho" oldcmdecho)
  100.      (setvar "osmode" oldosmode)
  101.      (setq cr_list (list cr_pt cr_r))
  102.     )
  103.     (e1_e2                                ;两线平行
  104.      (if (or pt_e1 pt_e2)                ;且有点在线上
  105.        (progn
  106.          (setq p1 (polar pt ang1_cz 100))
  107.          (setq p2 (inters e2_star e2_end pt p1 nil))
  108.          (setq p1 (inters e1_star e1_end pt p1 nil))
  109.          (setq cr_r (/ (distance p1 p2) 2))
  110.          (setq cr_pt (polar p1 (angle p1 p2) cr_r))
  111.          ;;(command "._circle" cr_pt cr_r)
  112.          (setvar "cmdecho" oldcmdecho)
  113.          (setvar "osmode" oldosmode)
  114.          (setq cr_list (list cr_pt cr_r))
  115.        )
  116.        (progn                                ;点不在线上
  117.          (setq p1 (polar e1_star ang1_cz 100))
  118.          (setq p1 (inters e2_star e2_end e1_star p1 nil))
  119.          (setq cr_r (/ (distance p1 e1_star) 2))
  120.          (setq p2 (polar e1_star (angle e1_star p1) cr_r))
  121.          (setq p1 (polar p2 ang1 100))
  122.          (setq p3 (polar pt ang1_cz 100))
  123.          (setq p3 (inters p1 p2 p3 pt nil))
  124.          (setq dist (distance p3 pt))
  125.          (setq dist (sqrt (- (* cr_r cr_r) (* dist dist))))
  126.          (setq cr_pt (polar p3 ang1 dist))
  127.          ;;(command "._circle" cr_pt cr_r)
  128.          (setq cr_list (list cr_pt cr_r))
  129.          (setq cr_pt (polar p3 (+ pi ang1) dist))
  130.          ;;(command "._circle" cr_pt cr_r)
  131.          (setvar "cmdecho" oldcmdecho)
  132.          (setvar "osmode" oldosmode)
  133.          (setq cr_list (append cr_list (list cr_pt cr_r)))
  134.        )
  135.      )
  136.     )                                        ;end 两线平行
  137.     (t                                        ;两线不平行
  138.      (setq jd (inters e1_star e1_end e2_star e2_end nil))
  139.      (setq dist (distance pt jd))
  140.      (cond
  141.        ((< dist 0.0001)                        ;两线不平行且点在线e1、e2交点上
  142.         (prompt "\n点在两线的交点上,没有切圆")
  143.         (setq cr_list nil)
  144.        )
  145.        (pt_e1                                ;两线不平行且点在线e1上
  146.         (setq p1 (polar pt ang1_cz 100))
  147.         (setq p2 (polar jd ang2 dist))
  148.         (setq p3 (polar p2 ang2_cz 100))
  149.         (setq cr_pt (inters p1 pt p2 p3 nil))
  150.         (setq cr_r (distance cr_pt pt))
  151.         ;;(command "._circle" cr_pt pt)
  152.         (setq cr_list (list cr_pt cr_r))
  153.         (setq p2 (polar jd (+ pi ang2) dist))
  154.         (setq p3 (polar p2 ang2_cz 100))
  155.         (setq cr_pt (inters p1 pt p2 p3 nil))
  156.         (setq cr_r (distance cr_pt pt))
  157.         ;;(command "._circle" cr_pt pt)
  158.         (setvar "cmdecho" oldcmdecho)
  159.         (setvar "osmode" oldosmode)
  160.         (setq cr_list (append cr_list (list cr_pt cr_r)))
  161.        )
  162.        (pt_e2                                ;两线不平行且点在线e2上
  163.         (setq p1 (polar pt ang2_cz 100))
  164.         (setq p2 (polar jd ang1 dist))
  165.         (setq p3 (polar p2 ang1_cz 100))
  166.         (setq cr_pt (inters p1 pt p2 p3 nil))
  167.         (setq cr_r (distance cr_pt pt))
  168.         ;;(command "._circle" cr_pt pt)
  169.         (setq cr_list (list cr_pt cr_r))
  170.         (setq p2 (polar jd (+ pi ang1) dist))
  171.         (setq p3 (polar p2 ang1_cz 100))
  172.         (setq cr_pt (inters p1 pt p2 p3 nil))
  173.         (setq cr_r (distance cr_pt pt))
  174.         ;;(command "._circle" cr_pt pt)
  175.         (setvar "cmdecho" oldcmdecho)
  176.         (setvar "osmode" oldosmode)
  177.         (setq cr_list (append cr_list (list cr_pt cr_r)))
  178.        )
  179.        (t                                ;两线不平行且点不在线上
  180.         (setq ang1 (angle jd p1))
  181.         (setq ang2 (angle jd p2))
  182.         (setq pfx (rem (/ (+ ang1 ang2 (* 4 pi)) 2) (* 2 pi)))
  183.         (if (not (inters p1 p2 jd pt))
  184.           (setq pfx (+ pfx (/ pi 2)))
  185.         )                                ;求得角平分线
  186.         (setq p4 (polar jd pfx 100))        ;求得角平分线上一点
  187.         (setq pfx_cz (+ pfx (/ pi 2)))
  188.         ;;求得过pt点与角平分线的垂足点
  189.         (setq p3 (polar pt pfx_cz 100))
  190.         (setq p3 (inters jd p4 pt p3 nil))
  191.         (setq pfx (angle jd p3))

  192.         (if (< (abs (- dist1 dist2)) 0.00001)
  193.           (progn                        ;如果pt在角平分线上
  194.             (setq p1 (polar pt pfx_cz 100))
  195.             (setq p1 (inters jd e1_star pt p1 nil))
  196.             (setq ang1 (angle p1 jd)
  197.                   ang2 (angle p1 pt)
  198.             )
  199.             (setq ang (rem (/ (+ ang1 ang2 (* 4 pi)) 2) (* 2 pi)))
  200.             (setq p3 (polar p1 ang 100))
  201.             (setq cr_pt (inters jd pt p1 p3 nil))
  202.             (setq cr_r (distance cr_pt pt))
  203.             ;;(command "._circle" cr_pt pt)
  204.             (setq cr_list (list cr_pt cr_r))
  205.             (setq ang (rem (/ (+ ang1 ang2 (* 5 pi)) 2) (* 2 pi)))
  206.             (setq p3 (polar p1 ang 100))
  207.             (setq cr_pt (inters jd pt p1 p3 nil))
  208.             (setq cr_r (distance cr_pt pt))
  209.             ;;(command "._circle" cr_pt pt)
  210.             (setvar "cmdecho" oldcmdecho)
  211.             (setvar "osmode" oldosmode)
  212.             (setq cr_list (append cr_list (list cr_pt cr_r)))
  213.           )
  214.           (progn                        ;如果pt点不在角平分线上
  215.             (setq dist1 (/ (distance p3 jd) 6))
  216.             (setq p4 (polar jd pfx dist1))
  217.             ;;在jd与pt在角平分线上的垂足的1/4处取一点
  218.             (setq p2 (polar p4 ang1_cz 100))
  219.             (setq p1 (inters jd p1 p4 p2 nil))
  220.             (setq dist1 (distance p4 p1))
  221.             (command "._circle" p4 dist1)
  222.             (setq e1 (entlast))
  223.             (command "._pline" jd pt "")
  224.             (setq e2 (entlast))
  225.             (if        (setq jd_list (GetInterPointlist e1 e2)) ;如果圆与pt_jd
  226.               (progn
  227.                 (entdel e1)
  228.                 (entdel e2)
  229.                 (setq p1 (nth 0 jd_list))
  230.                 (setq p2 (nth 1 jd_list))
  231.                 (setq ang (angle p1 p4))
  232.                 (setq p3 (polar pt ang 100))
  233.                 (setq cr_pt (inters jd p4 pt p3 nil))
  234.                 (setq cr_r (distance cr_pt pt))
  235.                 ;;(command "._circle" cr_pt pt)
  236.                 (setq cr_list (list cr_pt cr_r))
  237.                 (setq ang (angle p2 p4))
  238.                 (setq p3 (polar pt ang 100))
  239.                 (setq cr_pt (inters jd p4 pt p3 nil))
  240.                 (setq cr_r (distance cr_pt pt))
  241.                 ;;(command "._circle" cr_pt pt)
  242.                 (setvar "cmdecho" oldcmdecho)
  243.                 (setvar "osmode" oldosmode)
  244.                 (setq cr_list (append cr_list (list cr_pt cr_r)))
  245.               )
  246.               (progn
  247.                 (setvar "cmdecho" oldcmdecho)
  248.                 (setvar "osmode" oldosmode)
  249.                 (setq cr_list nil)
  250.               )
  251.             )
  252.           )
  253.         )
  254.        )
  255.      )
  256.     )                                        ;end 两线不平行
  257.   )

  258. )


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2005-6-4 15:00:39 | 显示全部楼层
“直接法”:
[php](command"circle" "3p" pause "tan" pause "tan" pause)[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-6-8 11:03:04 | 显示全部楼层
好阿!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

发表于 2005-12-26 07:36:48 | 显示全部楼层
最初由 xyp1964 发布
[B]“直接法”:
[php](command"circle" "3p" pause "tan" pause "tan" pause)[/php] [/B]


确实直接!但是,如果点在角平分线上,应该有两个解.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2025-9-29 01:14 , Processed in 0.304086 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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