明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: nonsmall

【求助】怎样求得直线和椭圆的交点

  [复制链接]
 楼主| 发表于 2007-8-5 16:36 | 显示全部楼层

9楼的办法就是计算麻烦点,不过转换程序倒不麻烦。谢谢先。

发表于 2007-8-16 10:20 | 显示全部楼层
本帖最后由 作者 于 2007-8-16 10:28:01 编辑

有一个简单的方法:将直线作为边界来剪切椭圆,然后检查椭圆是否发生了改变(如起点及终点角度是否与原来不一样),如果改变了,说明有交点,然后再undo回去.也可以将椭圆作为边界来剪切直线,然后检查直线长度是否发生了变化.

  但这种方法检查不出相切的情况

 楼主| 发表于 2007-8-16 18:00 | 显示全部楼层

方法倒是挺独特的,但是如果线和椭圆只有一个交点的情况就不行了(不相切但穿过一条边)

发表于 2007-8-17 01:18 | 显示全部楼层
我数学不行,关注一下:)
发表于 2007-8-17 12:06 | 显示全部楼层
买了cad(就算它是盗版的),那它就是被用来干活啊!
如果求交点还要自己算,那还用它作甚?!

下面代码,没有使用vl系列函数。
  1. ;;;======================================
  2. ;;;函数名:JD
  3. ;;;功能:求一直线与其它图元的交叉点坐标。
  4. ;;;编写时间:2006-09-28
  5. ;;;======================================
  6. (defun C:jd (/)
  7. ;;;1、提示用户选取对象
  8.   (while
  9.     (= (setq el (entsel "\n请点选直线对象: "))
  10.        nil
  11.     )
  12.   )
  13.   (princ "\n****请选择待求交点的对象**** ")
  14.   (while (= (setq s1 (ssget)) nil)
  15.     (princ "\n**未选择对象,请选择待求交点的对象** ")
  16.   )
  17. ;;;2、记录直线起终点坐标
  18.   (setq    ob_line    (car el) ;_获取对象名
  19.     ent    (entget ob_line)
  20.     pt0_old    (cdr (assoc '10 ent))
  21.     pt1_old    (cdr (assoc '11 ent))
  22.     QD    (list ob_line pt0_old)    ;生成双元表,
  23.     ZD    (list ob_line pt1_old)    ;为执行trim或extend准备响应对象
  24.   )
  25. ;;;3、试着将直线缩短至不与任何选取的对象相交
  26.   (setq b1 0) ;_初始化标记。0表示继续;1表示结束
  27.   (while (= b1 0)
  28.     (command "_trim" s1 "" QD "")
  29.     (command "_trim" s1 "" ZD "")
  30.     (setq ent (entget ob_line)
  31.       pt0 (cdr (assoc '10 ent))
  32.       pt1 (cdr (assoc '11 ent))
  33.     )
  34.     (IF    (AND (equal PT0 PT0_OLD) (equal PT1 PT1_OLD))
  35.       (progn                ;如果起终点未变化,表示已修剪至最短,则:
  36.     (command "_scale" ob_line "" pt0 0.9) ;对直线对象缩放,
  37.     (command "_scale" ob_line "" pt1 0.9) ;以脱离目标对象
  38.     (setq ent     (entget ob_line)    ;重新获取其中点坐标
  39.           pt0_old (cdr (assoc '10 ent))
  40.           pt1_old (cdr (assoc '11 ent))
  41.     )
  42.     (setq b1 1)
  43.       )
  44.       (progn                ;否则:
  45.     (setq pt0_old pt0
  46.           pt1_old pt1
  47.     )
  48.       )
  49.     ) ;_结束IF
  50.     (setq QD (list ob_line pt0_old)
  51.       ZD (list ob_line pt1_old)
  52.     )
  53.   ) ;_结束while
  54. ;;;4、利用延伸命令,循环探测直线起终点是否改变
  55.   (setq list_jd '())            ;建立空表,用于存放交点位置
  56.   ;;先延伸直线起点方向
  57.   (setq b1 0)
  58.   (while (= b1 0)
  59.     (command "_extend" s1 "" QD "")
  60.     (setq ent (entget ob_line)
  61.       pt0 (cdr (assoc '10 ent))
  62.     )
  63.     ;;判断直线起点是否变化
  64.     (IF    (equal PT0 PT0_OLD)
  65.       (setq b1 1)
  66.       (setq list_jd (cons pt0 list_jd)
  67.         pt0_old pt0
  68.         QD        (list ob_line pt0_old)
  69.       )
  70.     ) ;_结束IF
  71.   ) ;_结束while
  72.   ;;延伸直线终点方向
  73.   (setq b1 0)
  74.   (while (= b1 0)
  75.     (command "_extend" s1 "" ZD "")
  76.     (setq ent (entget ob_line)
  77.       pt1 (cdr (assoc '11 ent))
  78.     )
  79.     ;;判断直线终点是否变化
  80.     (IF    (equal PT1 PT1_OLD)
  81.       (setq b1 1)
  82.       (setq list_jd (append list_jd (list pt1))
  83.         pt1_old pt1
  84.         ZD        (list ob_line pt1_old)
  85.       )
  86.     )                    ;结束IF
  87.   ) ;_结束while
  88. ;;;5、结果显示输出
  89.   (setq i 0)
  90.   (princ "\n直线与其它所选对象的交点坐标如下:")
  91.   (repeat (length list_jd)        ;重复次数为表中成员数。
  92.     (print (nth i list_jd))        ;打印当前成员后换行 。
  93.     (setq i (1+ i))            ;计数器加1。
  94.   )
  95.   (princ "\n命令成功完成!")
  96.   (princ)
  97. )
发表于 2007-8-17 13:03 | 显示全部楼层
估计不愿意用vl的更不愿意用comand了
 楼主| 发表于 2007-8-18 17:42 | 显示全部楼层

晕晕中

汗!

办法真是千奇百怪又好玩.

但,如果线的端点正好在椭圆上延伸就不好使了吧?

发表于 2007-8-18 17:53 | 显示全部楼层

尽管这个题可以用各种方法,用vla-intersectwith最简单,核心代码仅仅几行。用Command的方法可以完成。但耗时多。

我上面提供了用计算几何方式的做法,经测试,编译后其速度比用vla-intersectwith快5-10倍。

虽然用计算几何的步骤麻烦,但如果是大量运算的话,其优势体现出来了。

不过每个方法都有优缺点。不知道楼主究竟是在什么情况下要求这个算法?

本帖子中包含更多资源

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

x
发表于 2007-8-19 03:23 | 显示全部楼层
不错,编译后好像更明显.比用vla快一倍
发表于 2007-8-19 06:45 | 显示全部楼层
反了吧?

命令: test
请选择椭圆:
请选择直线:
It spent 27.991 seconds to run this routine.

It spent 15.692 seconds to run Intersect routine.
  1. (Defun C:Test (/ ent1 lst1 ent2 lst2 obj1 obj2 t0 pts)
  2.   (if (And (Setq Ent1 (Car (Entsel "\n请选择椭圆:")))
  3.        (Setq Lst1 (Entget Ent1))
  4.        (= (Cdr (Assoc 0 Lst1)) "ELLIPSE")
  5.        (Setq Ent2 (Car (Entsel "\n请选择直线:")))
  6.        (Setq Lst2 (Entget Ent2))
  7.        (= (Cdr (Assoc 0 Lst2)) "LINE")
  8.       )
  9.     (Progn
  10.       (Setq Obj1 (Vlax-Ename->vla-Object Ent1)
  11.         Obj2 (Vlax-Ename->vla-Object Ent2)
  12.       )
  13.       ;;用计算几何法求
  14.       (Setq T0 (Getvar "TDUSRTIMER"))
  15.       (Repeat 100000
  16.     (Setq Pts (Get-Intersect-Ellipse-And-Line))
  17.       )
  18.       (Princ "\nIt spent ")
  19.       (Princ (* (- (Getvar "TDUSRTIMER") T0) 86400))
  20.       (Princ " seconds to run this routine.\n")
  21.       ;;用VBA法求
  22.       (Setq T0 (Getvar "TDUSRTIMER"))
  23.       (Repeat 100000
  24.     (setq pts (Get-Intersect-Ellipse-And-Line-1))
  25.       )
  26.       (Princ "\nIt spent ")
  27.       (Princ (* (- (Getvar "TDUSRTIMER") T0) 86400))
  28.       (Princ " seconds to run Intersect routine.\n")
  29.     )
  30.   )
  31.   (Princ)
  32. )
  33. ;;;Intersectwith方式
  34. (Defun Get-Intersect-Ellipse-And-Line-1    (/ pts ptl)
  35.   (if (Setq pts (vlax-invoke obj1 'Intersectwith Obj2 Acextendnone))
  36.     (while pts
  37.       (setq ptl    (cons (list (car pts) (cadr pts) (caddr pts)) ptl)
  38.         pts    (cdddr pts)
  39.       )
  40.     )
  41.   )
  42. )
  43. ;;;计算几何方式
  44. (Defun Get-Intersect-Ellipse-And-Line (/   Cen P0x P0y Rat R   An1 SSS
  45.                        CCC Stp Edp Pm  LL  P1  P2  P3
  46.                        P4  P5  X1  Y1  X2  Y2  A   B
  47.                        C   D   E   An
  48.                       )
  49.   (Get-Ellipse-Parameters Lst1)        ;椭圆的参数
  50.   (Get-Line-Parameters Lst2)        ;线段的参数
  51.   (Setq    P1 (Transfer Stp)        ;变换线段起点
  52.     P2 (Transfer Edp)        ;变换线段终点
  53.     X1 (Car P1)
  54.     Y1 (Cadr P1)
  55.     X2 (Car P2)
  56.     Y2 (Cadr P2)
  57.     A  (- Y1 Y2)            ;直线方程系数A
  58.     B  (- X2 X1)            ;直线方程系数B
  59.     C  (- (* Y2 X1) (* Y1 X2))    ;直线方程系数C
  60.     D  (/ C (Sqrt (+ (* A A) (* B B))))
  61.   )                    ;中心到直线距离
  62. &#160; (if (< (Abs D) (+ R 1e-8))&#160;&#160; &#160;&#160;&#160; &#160;;如果大于半径(长轴)
  63. &#160;&#160;&#160; (Progn
  64. &#160;&#160;&#160;&#160;&#160; (Setq E&#160; (Sqrt (Abs (- (* R R) (* D D)))) ;半弦长
  65. &#160;&#160; &#160;&#160;&#160;&#160; An (Angle P1 P2)&#160;&#160; &#160;&#160;&#160; &#160;;线段的角度
  66. &#160;&#160; &#160;&#160;&#160;&#160; P3 (Polar '(0 0) (- An (/ Pi 2)) D) ;垂足点
  67. &#160;&#160; &#160;&#160;&#160;&#160; P4 (Polar P3 An E)&#160;&#160; &#160;&#160;&#160; &#160;;交点1
  68. &#160;&#160; &#160;&#160;&#160;&#160; P5 (Polar P3 An (- E))&#160;&#160; &#160;;交点2
  69. &#160;&#160; &#160;&#160;&#160;&#160; LL (+ (/ (Distance P1 P2) 2) 1e-6) ;线段的半长
  70. &#160;&#160; &#160;&#160;&#160;&#160; Pm (List (/ (+ X1 X2) 2)&#160;&#160; &#160;;线段的中点
  71. &#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160; (/ (+ Y1 Y2) 2)
  72. &#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160; )
  73. &#160;&#160;&#160;&#160;&#160; )
  74. &#160;&#160;&#160;&#160;&#160; (Cond&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;判断到中点的距离
  75. &#160;&#160; &#160;((And (> (Distance P4 Pm) LL)&#160;&#160; &#160;;如果都大于线段的半长
  76. &#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160; (> (Distance P5 Pm) LL)
  77. &#160;&#160; &#160; )
  78. &#160;&#160; &#160; nil&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;则没有交点
  79. &#160;&#160; &#160;)
  80. &#160;&#160; &#160;((> (Distance P4 Pm) LL)
  81. &#160;&#160; &#160; (List (Retransfer P5))&#160;&#160; &#160;&#160;&#160; &#160;;有一个交点
  82. &#160;&#160; &#160;)
  83. &#160;&#160; &#160;((> (Distance P5 Pm) LL)
  84. &#160;&#160; &#160; (List (Retransfer P4))&#160;&#160; &#160;&#160;&#160; &#160;;有一个交点
  85. &#160;&#160; &#160;)
  86. &#160;&#160; &#160;(T
  87. &#160;&#160; &#160; (List&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;有两个交点
  88. &#160;&#160; &#160;&#160;&#160; (Retransfer P4)
  89. &#160;&#160; &#160;&#160;&#160; (Retransfer P5)
  90. &#160;&#160; &#160; )
  91. &#160;&#160; &#160;)
  92. &#160;&#160;&#160;&#160;&#160; )
  93. &#160;&#160;&#160; )
  94. &#160; )
  95. )
  96. (Defun Get-Ellipse-Parameters (Lst / Xpt)
  97. &#160; (Setq&#160;&#160; &#160;Cen (Cdr (Assoc 10 Lst))&#160;&#160; &#160;;中心
  98. &#160;&#160; &#160;P0x (Car Cen)
  99. &#160;&#160; &#160;P0y (Cadr Cen)
  100. &#160;&#160; &#160;Xpt (Cdr (Assoc 11 Lst))&#160;&#160; &#160;;长轴方向
  101. &#160;&#160; &#160;Rat (Cdr (Assoc 40 Lst))&#160;&#160; &#160;;比率
  102. &#160;&#160; &#160;R&#160;&#160; (Distance '(0 0) Xpt)&#160;&#160; &#160;;长轴
  103. &#160;&#160; &#160;An1 (Angle '(0 0) Xpt)&#160;&#160; &#160;&#160;&#160; &#160;;倾斜角
  104. &#160;&#160; &#160;SSS (Sin An1)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;倾斜角正弦
  105. &#160;&#160; &#160;CCC (Cos An1)
  106. &#160; )&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;倾斜角余弦
  107. )
  108. (Defun Get-Line-Parameters (Lst /)
  109. &#160; (Setq&#160;&#160; &#160;Stp (Cdr (Assoc 10 Lst))&#160;&#160; &#160;;线段的起点
  110. &#160;&#160; &#160;Edp (Cdr (Assoc 11 Lst))
  111. &#160; )&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;线段的终点
  112. )
  113. (Defun Transfer&#160;&#160; &#160;(Pt / Px1 Py1 Px2 Py2 Px3 Py3)
  114. &#160; (Setq&#160;&#160; &#160;Px1 (Car Pt)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;要变换的点的X坐标
  115. &#160;&#160; &#160;Py1 (Cadr Pt)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;要变换的点的Y坐标
  116. &#160;&#160; &#160;Px2 (- Px1 P0x)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;平移变换
  117. &#160;&#160; &#160;Py2 (- Py1 P0y)
  118. &#160;&#160; &#160;Px3 (+ (* Px2 CCC) (* Py2 SSS))&#160;&#160; &#160;;旋转变换
  119. &#160;&#160; &#160;Py3 (- (* Py2 CCC) (* Px2 SSS))
  120. &#160;&#160; &#160;Py3 (/ Py3 Rat)
  121. &#160; )&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;比例变换
  122. &#160; (List Px3 Py3)
  123. )
  124. (Defun Retransfer (Pt / Px4 Py4 Px5 Py5 Px6 Py6)
  125. &#160; (Setq&#160;&#160; &#160;Px4 (Car Pt)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;要变换的点的X坐标
  126. &#160;&#160; &#160;Py4 (Cadr Pt)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;要变换的点的Y坐标
  127. &#160;&#160; &#160;Py4 (* Py4 Rat)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;比例变换
  128. &#160;&#160; &#160;Px5 (- (* Px4 CCC) (* Py4 SSS))&#160;&#160; &#160;;旋转变换
  129. &#160;&#160; &#160;Py5 (+ (* Py4 CCC) (* Px4 SSS))
  130. &#160;&#160; &#160;Px6 (+ Px5 P0x)&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;;平移变换
  131. &#160;&#160; &#160;Py6 (+ Py5 P0y)
  132. &#160; )
  133. &#160; (List Px6 Py6)
  134. )
  135. ;;;画交点
  136. (defun Draw-Intersect-Point (pts / pt1 pt2)
  137. &#160; (if (Setq Pt1 (Car Pts))
  138. &#160;&#160;&#160; (Entmake
  139. &#160;&#160;&#160;&#160;&#160; (List
  140. &#160;&#160; &#160;(Cons 0 "POINT")
  141. &#160;&#160; &#160;(Cons 10 Pt1)
  142. &#160;&#160;&#160;&#160;&#160; )
  143. &#160;&#160;&#160; )
  144. &#160; )
  145. &#160; (if (Setq Pt2 (Cadr Pts))
  146. &#160;&#160;&#160; (Entmake
  147. &#160;&#160;&#160;&#160;&#160; (List
  148. &#160;&#160; &#160;(Cons 0 "POINT")
  149. &#160;&#160; &#160;(Cons 10 Pt2)
  150. &#160;&#160;&#160;&#160;&#160; )
  151. &#160;&#160;&#160; )
  152. &#160; )
  153. )
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-22 09:18 , Processed in 0.473815 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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