点线面论

对CAD中 关于直线,点,线段的一些研究,包含了大量实用函数。
其中点的定分比,直线的相交,以及空间直线的相交,三角形的周长,面积等各种性质的数学算法,多段线的面积,质心的数学算法,点线面的一些基本几何关系。等等。
下面是相关的代码。

  1. ;|*********************************************************************************************;
  2. 软件作者: Highflybird                                                                          ;
  3. 软件用途: 为AutoCAD 的LISP定制的一些算法和函数                                                 ;
  4. 日期地点: 2012.12.12 深圳                                                                      ;
  5. 程序语言: AutoLISP,Visual LISP                                                                 ;
  6. 版本号:   Ver. 1.0.121212                                                                      ;
  7. ===============================================================================================;
  8. 本软件为开源软件: 以下是开源申明:                                                               
  9. -----------------------------------------------------------------------------------------------;
  10. 本页面的软件遵照GPL协议开放源代码,您可以自由传播和修改,在遵照下面的约束条件的前提下:          
  11.                                                                                                 
  12. 一. 只要你在本开源软件的每一副本上明显和恰当地出版版权声明,保持此许可证的声明和没有担保的声明完
  13. 整无损,并和程序一起给每个其他的程序接受者一份许可证的副本,你就可以用任何媒体复制和发布你收到的
  14. 原始的程序的源代码。你也可以为转让副本的实际行动收取一定费用,但必须事先得到的同意。            
  15.                                                                                                 
  16. 二. 你可以修改本开源软件的一个或几个副本或程序的任何部分,以此形成基于程序的作品。只要你同时满足
  17. 下面的所有条件,你就可以按前面第一款的要求复制和发布这一经过修改的程序或作品。                  
  18. 1.你必须在修改的文件中附有明确的说明: 你修改了这一文件及具体的修改日期。                        
  19. 2.你必须使你发布或出版的作品(它包含程序的全部或一部分,或包含由程序的全部或部分衍生的作品)允许
  20.   第三方作为整体按许可证条款免费使用。                                                          
  21. 3.如果修改的程序在运行时以交互方式读取命令,你必须使它在开始进入常规的交互使用方式时打印或显示声
  22.   明: 包括适当的版权声明和没有担保的声明(或者你提供担保的声明);用户可以按此许可证条款重新发布
  23.   程序的说明;并告诉用户如何看到这一许可证的副本。(例外的情况: 如果原始程序以交互方式工作,它并
  24.   不打印这样的声明,你的基于程序的作品也就不用打印声明。                                        
  25.                                                                                                 
  26. 三. 只要你遵循一、二条款规定,您就可以自由使用并传播本源代码,但必须原封不动地保留原作者信息。  
  27. ===============================================================================================;
  28. **********************************************************************************************|;
  29.  
  30. ;;;****************************************************;
  31. ;;;几何部分                                            ;
  32. ;;;****************************************************;
  33.  
  34. ;;;----------------------------------------------------;
  35. ;;;功能: 比例缩放点                                    ;
  36. ;;;输入: 要缩放的点pt,基点pBase,缩放因子k             ;
  37. ;;;输出: 缩放后的点位置                                ;
  38. ;;;----------------------------------------------------;
  39. (defun GEO:Scale (Pt pBase k)
  40.   (mapcar (function (lambda (u v) (+ u (* k (- v u))))) pBase Pt)
  41. )
  42.  
  43. ;;;----------------------------------------------------;
  44. ;;;功能: 比例缩放点2倍                                 ;
  45. ;;;输入: 要缩放的点pt,基点pBase                        ;
  46. ;;;输出: 缩放后的点位置                                ;
  47. ;;;----------------------------------------------------;
  48. (defun GEO:Scale2 (Pt pBase)
  49.   (mapcar (function (lambda (u v) (+ v (- v u)))) pBase Pt)
  50. )
  51.  
  52. ;;;----------------------------------------------------;
  53. ;;;功能: 两点之中点                                    ;
  54. ;;;输入: 两点p1,P2                                     ;
  55. ;;;输出: 中点位置                                      ;
  56. ;;;----------------------------------------------------;
  57. (defun GEO:Midpoint (p1 p2)
  58.   (mapcar (function (lambda (e1 e2) (* (+ e1 e2) 0.5))) p1 p2)
  59. )
  60.  
  61. ;;;----------------------------------------------------;
  62. ;;;功能: 两个距离之中位值                              ;
  63. ;;;输入: 共线三点O,P,Q                                 ;
  64. ;;;输出: 中位点位置                                    ;
  65. ;;;----------------------------------------------------;
  66. (defun GEO:MeanPoint (O P Q)
  67.   (polar O (angle O P) (sqrt (* (distance O P) (distance O Q))))
  68. )
  69.  
  70. ;;;----------------------------------------------------;
  71. ;;;功能: 定比点P,使得P1P / PP2 = k (此函数于三维)    ;
  72. ;;;输入: 两点p1,P2和比例系数k                          ;
  73. ;;;输出: 定比点位置                                    ;
  74. ;;;----------------------------------------------------;
  75. (defun GEO:Proportion (p1 p2 k)
  76.   (if (/= k -1)
  77.     (mapcar (function (lambda (x1 x2) (/ (+ x1 (* k x2)) (+ 1.0 k)))) p1 p2)
  78.   )
  79. )
  80.  
  81. ;;;----------------------------------------------------;
  82. ;;;功能: 两点法旋转某个点90度                          ;
  83. ;;;输入: 基点,矢量的第一点P1,第二点P1                ;
  84. ;;;输出: 旋转90度后点位置                              ;
  85. ;;;----------------------------------------------------;
  86. (defun GEO:Rot90 (ptBase P1 P2)
  87.   (mapcar '+ ptBase (MAT:Rot90 (mapcar '- p2 p1)))
  88. )
  89.  
  90. ;;;----------------------------------------------------;
  91. ;;;功能: 以基点旋转一点到指定的角度                    ;
  92. ;;;输入: 要旋转的点Pt,基点和旋转角度                  ;
  93. ;;;输出: 旋转后点位置                                  ;
  94. ;;;----------------------------------------------------;
  95. (defun GEO:Rot2D (Pt PtBase Ang)  
  96.   (mapcar '+ PtBase (MAT:Rot2D (mapcar '- Pt PtBase) Ang))
  97. )
  98.  
  99. ;;;----------------------------------------------------;
  100. ;;;功能: 以基点和角度镜像某点                          ;
  101. ;;;输入: 要镜像的点Pt,基点和镜像轴角度                ;
  102. ;;;输出: 镜像点位置                                    ;
  103. ;;;说明: 只适用与二维情况下,但速度最快                ;
  104. ;;;----------------------------------------------------;
  105. (defun GEO:Mirror2D (Pt pBase Ang)
  106.   (polar pBase (+ ang (- ang (angle pbase pt))) (distance pt pBase))
  107. )
  108.  
  109. ;;;----------------------------------------------------;
  110. ;;;功能: 镜像点(可以用于3D情况)                      ;
  111. ;;;输入: 要镜像的点Pt,镜像轴第一点和第二点            ;
  112. ;;;输出: 镜像点位置                                    ;
  113. ;;;说明: 可以适用于三维情况                            ;
  114. ;;;----------------------------------------------------;
  115. (defun GEO:Mirror3D (Pt P1 P2 / v1 v2 dd P3 P4)
  116.   (if (equal P1 P2 1e-8)
  117.     (GEO:Scale2 P1 Pt)
  118.     (setq v1 (mapcar '- Pt P1)
  119.           v2 (mapcar '- P2 P1)
  120.           dd (MAT:Dot v2 v2)
  121.           P3 (GEO:Scale P2 P1 (/ (MAT:Dot v1 v2) dd))
  122.           P4 (GEO:Scale2 P3 Pt)
  123.     )    
  124.   ) 
  125. )
  126.  
  127. ;;;----------------------------------------------------;
  128. ;;;功能: 镜像点(另一方法,相当于用 Mirror命令的结果) ;
  129. ;;;输入: 要镜像的点Pt,镜像轴第一点和第二点            ;
  130. ;;;输出: 镜像点位置                                    ;
  131. ;;;----------------------------------------------------;
  132. (defun GEO:Mirror2D-1 (Pt P1 P2 / v p)
  133.   (setq v (mapcar '- p2 p1))
  134.   (setq p (trans (mapcar '- Pt P1) 0 v))
  135.   (setq p (list (- (car p)) (cadr p) (caddr p)))
  136.   (mapcar '+ P1 (trans p v 0))
  137. )
  138.  
  139. ;;;----------------------------------------------------;
  140. ;;;功能: 计算有限点集的质心                            ;
  141. ;;;输入: 有限个点集  Pts                               ;
  142. ;;;输出: 质心坐标,用点表表示                          ;
  143. ;;;----------------------------------------------------;
  144. (defun GEO:Centroid (Pts / )
  145.   (MAT:vxs (apply 'mapcar (cons '+ pts)) (/ 1.0 (length pts)))
  146. )
  147.  
  148. ;;;----------------------------------------------------;
  149. ;;;多个物体的质心                                      ;
  150. ;;;输入: 截面的质心列表CenList和相应的面积列表AreaList ;
  151. ;;;输出: 一个数值,如果为正则是CCW(逆时针),否则顺时针 ;
  152. ;;;----------------------------------------------------;
  153. (defun GEO:Centroid_Composition (CenList AreaList / s)
  154.   (setq S (apply '+ AreaList))
  155.   (if (/= s 0)
  156.     (list (Mat:vxs (MAT:SxVs CenList AreaList) (/ 1.0 s)) S)
  157.   )
  158. )
  159.  
  160. ;;;****************************************************;
  161. ;;;直线部分                                            ;
  162. ;;;****************************************************;
  163.  
  164. ;;;----------------------------------------------------;
  165. ;;;直线的方程                                          ;
  166. ;;;Coefficient Equation                                ;
  167. ;;;参数: 两点                                          ;
  168. ;;;返回: 直线的方程Ax+By+C=0 的三个系数A,B,C           ;
  169. ;;;----------------------------------------------------;
  170. (defun LINE:Equation (p1 p2)
  171.   (list
  172.     (- (cadr p1) (cadr p2))
  173.     (- (car  p2) (car  p1))
  174.     (- (* (car p1) (cadr p2)) (* (cadr p1) (car p2)))
  175.   )
  176. )
  177.  
  178. ;;;----------------------------------------------------;
  179. ;;;直线的方程1                                         ;
  180. ;;;点矢量式方程  P0+k*Vector                           ;
  181. ;;;参数: 两点                                          ;
  182. ;;;返回: 直线的方程用一点和直线的方向矢量表达          ;
  183. ;;;----------------------------------------------------;
  184. (defun LINE:Equation_1 (p0 p1)        
  185.   (list P0 (mapcar '- p1 p0))
  186. )
  187.  
  188. ;;;----------------------------------------------------;
  189. ;;;功能: 偏移一条线段                                  ;
  190. ;;;输入: 两点和一个距离(负数代表直线段的下方)        ;
  191. ;;;输出: 偏移后的两点                                  ;
  192. ;;;----------------------------------------------------;
  193. (defun LINE:Offset (p1 p2 d / a)
  194.   (setq a (+ (angle p1 p2) (* pi 0.5)))
  195.   (list (polar p1 a d) (polar p2 a d))
  196. )
  197.  
  198.  
  199. ;;;----------------------------------------------------;
  200. ;;;功能: 求过直线外一点作已知角度的线与已知直线的交点  ;
  201. ;;;输入: 两点代表的直线MN和直线外一点P以及已知角a      ;
  202. ;;;输出: 交点或者nil                                   ;
  203. ;;;----------------------------------------------------;
  204. (defun LINE:PAMN (p a M N /)
  205.   (inters P (polar P a 1) M N nil)
  206. )
  207.  
  208. ;;;----------------------------------------------------;
  209. ;;;功能: 点Pt到直线P1P2的距离(带方向)                ;
  210. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  211. ;;;输出: 带符号的距离,为正P1,P2,Pt逆时针,否则顺时针  ;
  212. ;;;----------------------------------------------------;
  213. (defun LINE:Perpendicular_Distance (pt p1 p2 / A B C) 
  214.   (setq A (- (cadr p1) (cadr p2)))
  215.   (setq B (- (car  p2) (car  p1)))
  216.   (setq C (- (* (car p1) (cadr p2)) (* (cadr p1) (car p2))))
  217.   (if (not (and (= A 0) (= b 0)))
  218.     (/ (+ (* A (car pt)) (* B (cadr pt)) C)
  219.        (sqrt (+ (* A A) (* B B)))
  220.     )
  221.   )
  222. )
  223.  
  224. ;;;----------------------------------------------------;
  225. ;;;功能: 已知直线方程系数求点到直线的距离(带方向)    ;
  226. ;;;输入: 要求的点Pt,和直线方程的三个系数              ;
  227. ;;;输出: 带符号的距离,为正Pt在直线方向的上方,负则反之;
  228. ;;;----------------------------------------------------;
  229. (defun LINE:Perpendicular_Distance_1 (Pt A B C / AA BB AB k x0 y0 x y D)
  230.   (if (not (and (= a 0) (= b 0)))
  231.     (progn 
  232.       (setq AA (* A A))
  233.       (setq BB (* B B))
  234.       (setq AB (* A B))
  235.       (setq k  (+ AA BB))
  236.       (setq x0 (car pt))
  237.       (setq y0 (cadr pt))
  238.  
  239.       (setq x  (/ (- (* BB x0) (* AB y0) (* A C)) k))
  240.       (setq y  (/ (- (* AA y0) (* AB x0) (* B C)) k))
  241.       (setq D  (/ (+ (* A x0) (* B y0) C) (sqrt k)))
  242.       (list D (list x y))
  243.     )
  244.   )
  245. )
  246.  
  247. ;;;----------------------------------------------------;
  248. ;;;功能: 点到直线的距离(带方向)                      ;
  249. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  250. ;;;输出: 带符号的距离,为正P1,P2,Pt逆时针,否则顺时针  ;
  251. ;;;----------------------------------------------------;
  252. (defun LINE:Perpendicular_Distance_2 (pt p1 p2 / )
  253.   (car (trans (mapcar '- pt p1) 0 (mapcar '- p2 p1)))
  254. )
  255.  
  256. ;;;----------------------------------------------------;
  257. ;;;功能: 点到直线的距离(适合三维情况)                ;
  258. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  259. ;;;输出: 所求距离                                      ;
  260. ;;;----------------------------------------------------;
  261. (defun LINE:Perpendicular_Distance_3 (p0 p1 p2 / v0 v1)
  262.   (setq v0 (mapcar '- P0 p1))
  263.   (setq v1 (mapcar '- p2 p1))
  264.   (/ (MAT:Norm3D (MAT:vxv v0 v1)) (MAT:Norm3D v1))
  265. )
  266.  
  267. ;;;----------------------------------------------------;
  268. ;;;功能: 点到直线的距离和垂足                          ;
  269. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  270. ;;;输出: 所求距离和垂足                                ;
  271. ;;;----------------------------------------------------;
  272. (defun LINE:Perpendicular_Foot (pt p1 p2 / d)
  273.   (setq d (LINE:Perpendicular_Distance pt p1 p2))
  274.   (list d (polar pt (- (angle p1 p2) (/ pi 2)) d))
  275. )
  276.  
  277. (defun LINE:Perpendicular_Foot_2 (P p1 p2 / pt)
  278.   (setq pt (mapcar '+ (MAT:Rot90 (mapcar '- p1 p2)) p))  
  279.   (inters p1 p2 p pt nil)        
  280. )
  281.  
  282. (defun LINE:Perpendicular_Foot_3 (p p1 p2 / p0)         ;???
  283.   (setq p0 (trans (mapcar '- p p1) 0 (mapcar '- p2 p1)))
  284.   (mapcar '+ p1 (list (car p0) (last p0) (cadr p0)))
  285. )
  286.  
  287. ;;;----------------------------------------------------;
  288. ;;;功能: 点到直线的垂足                                ;
  289. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  290. ;;;输出: 所求的垂足                                    ;
  291. ;;;----------------------------------------------------;
  292. (defun LINE:Perpendicular_Foot_1 (pt p1 p2)
  293.   (inters pt (mapcar '+ pt (MAT:Rot90 (mapcar '- p1 p2))) p1 p2 nil)
  294. )
  295.  
  296. ;;;----------------------------------------------------;
  297. ;;;功能: 求空间两直线的最短距离                        ;
  298. ;;;输入: 两条直线的四个端点P1,P2,P3,P4                 ;
  299. ;;;输出: 所求距离                                      ;
  300. ;;;----------------------------------------------------;
  301. (defun LINE:Distance_LineToLine (P1 P2 P3 P4 / v1 v2 v3)
  302.   (setq v1 (mapcar '- p2 p1))
  303.   (setq v2 (mapcar '- p4 p3))
  304.   (setq v3 (MAT:vxv v1 v2))
  305.   (/ (Mat:Dot (mapcar '- P1 P3) v3) (Mat:Norm3D v3))
  306. )
  307.  
  308. ;;;----------------------------------------------------;
  309. ;;;功能: 两条直线求交点函数(跟inters函数稍微有区别)    ;
  310. ;;;输入: 两条直线的四个端点P1,P2,P3,P4                 ;
  311. ;;;输出: nil 说明这两条平行或者共线,否则返回交点      ;
  312. ;;;----------------------------------------------------;
  313. (defun LINE:Intersection (p1 p2 p3 p4 / DA DB DD X1 X2 X3 X4 Y1 Y2 Y3 Y4)
  314.   (setq x1 (car  p1)
  315.         x2 (car  p2)
  316.         x3 (car  p3)
  317.         x4 (car  p4)
  318.         y1 (cadr p1)
  319.         y2 (cadr p2)
  320.         y3 (cadr p3)
  321.         y4 (cadr p4)
  322.   )
  323.   (setq dd (- (* (- x1 x2) (- y3 y4)) (* (- x3 x4) (- y1 y2))))
  324.   (setq da (- (* x1 y2) (* y1 x2)))
  325.   (setq db (- (* x3 y4) (* y3 x4)))
  326.   (if (not (equal dd 0 1e-8))
  327.     (list (/ (- (* da (- x3 x4)) (* db (- x1 x2))) dd)
  328.           (/ (- (* da (- y3 y4)) (* db (- y1 y2))) dd)
  329.     )
  330.   )
  331. )
  332.  
  333. ;;;----------------------------------------------------;
  334. ;;;功能: 两条直线的角平分线                            ;
  335. ;;;输入: 两条直线的四个端点P1,P2,P3,P4                 ;
  336. ;;;输出: 角平分线的两个端点                            ;
  337. ;;;----------------------------------------------------;
  338. (defun LINE:Angular_Bisector (p1 p2 p3 p4 / an1 an2 an3 an4 int)
  339.   (if (setq int (inters p1 p2 p3 p4 nil))
  340.     (progn
  341.       (setq eps 1e-6)
  342.       (if (equal int p1 eps)
  343.         (setq an1 (angle int p2))
  344.         (setq an1 (angle int p1))
  345.       )
  346.       (if (equal int p3 eps)
  347.         (setq an2 (angle int p4))
  348.         (setq an2 (angle int p3))
  349.       )
  350.       (setq an3 (* (+ an1 an2) 0.5))
  351.       (setq an4 (+ an3 (* 0.5 pi)))
  352.       (list
  353.         (list int (polar int an3 1000))
  354.         (list int (polar int an4 1000))
  355.       )
  356.     )
  357.     (list 
  358.       (list
  359.         (Geo:midpoint p1 p3)
  360.         (Geo:midpoint p2 p4)
  361.       )
  362.     )
  363.   )
  364. )
  365.  
  366. ;;;----------------------------------------------------;
  367. ;;;功能: 判断平面上的三点是否共线                      ;
  368. ;;;输入: 三点 P1,P2,P3                                 ;
  369. ;;;输出: T 说明三点共线,否则不共线                    ;
  370. ;;;----------------------------------------------------;
  371. (defun LINE:Colinearity (p1 p2 p3 / a b c eps)
  372.   (setq eps 1e-6)
  373.   (setq a (distance p2 p3))
  374.   (setq b (distance p3 p1))
  375.   (setq c (distance p1 p2))
  376.   (or (equal (+ a b) c eps)
  377.       (equal (+ b c) a eps)
  378.       (equal (+ c a) b eps)
  379.   )
  380. )
  381.  
  382. ;;;----------------------------------------------------;
  383. ;;;功能: 判断空间上三点是否共线(跟上面的方法效率差不多);
  384. ;;;输入: 三点 P1,P2,P3                                 ;
  385. ;;;输出: T 说明三点共线,否则不共线                    ;
  386. ;;;----------------------------------------------------;
  387. (defun LINE:Colinearity3D (p1 p2 p3 / a1 a2)
  388.   (equal (TRI:Det3P p1 p2 p3) 0 1e-8)
  389. )
  390.  
  391. ;;;----------------------------------------------------;
  392. ;;;功能: 判断两点是否在一条直线的同一侧                ;
  393. ;;;输入: 要判断的两点点P1,P2和直线的两个端点Pa,Pb      ;
  394. ;;;输出: T 说明同侧,nil异侧                           ;
  395. ;;;----------------------------------------------------;
  396. (defun LINE:IsSameSide (P1 P2 Pa Pb / d1 d2 eps)
  397.   (setq eps 1e-6)
  398.   (setq d1 (TRI:Det3P P1 PA PB))
  399.   (setq d2 (TRI:Det3P P2 PA PB))
  400.   (or (and (<= d1 eps) (<= d2 eps))
  401.       (and (>= d1 (- eps)) (>= d2 (- eps)))
  402.   )
  403. )
  404.  
  405. ;;;****************************************************;
  406. ;;;空间平面部分                                        ;
  407. ;;;****************************************************;
  408.  
  409. ;;;----------------------------------------------------;
  410. ;;;功能: 点法线的平面方程                              ;
  411. ;;;输入: P0平面上的一点,N平面的法线矢量               ;
  412. ;;;输出: 平面方程的系数列表                            ;
  413. ;;;----------------------------------------------------;
  414. (defun PLANE:Equation (P0 N)
  415.   (append N (list (- (MAT:Dot P0 N))))
  416. )
  417.  
  418. ;;;----------------------------------------------------;
  419. ;;;功能: 三点式平面方程                                ;
  420. ;;;输入: 平面上的三点                                  ;
  421. ;;;输出: 平面方程的系数列表                            ;
  422. ;;;----------------------------------------------------;
  423. (defun PLANE:Equation_3P (P0 P1 P2 / v1 v2 N)
  424.   (setq v1 (mapcar '- p1 p0))
  425.   (setq v2 (mapcar '- P2 p0))
  426.   (setq N  (MAT:vxv v1 v2))
  427.   (PLANE:Equation P0 N)
  428. )
  429.  
  430. ;;;----------------------------------------------------;
  431. ;;;功能: 点到平面的距离(有向的距离)                  ;
  432. ;;;输入: 一点P和平面的方程为Ax+By+Cz+D=0的四个系数     ;
  433. ;;;输出: 该点到平面的距离                              ;
  434. ;;;----------------------------------------------------;
  435. (defun PLANE:Distance (P A B C D)
  436.   (if (and (zerop A) (zerop B) (zerop C))
  437.     nil
  438.     (/ (+ (* A (car P)) (* B (cadr P)) (* C (caddr P)) D)
  439.        (distance '(0 0 0) (list A B C))
  440.     )
  441.   )
  442. )
  443.  
  444. ;;;----------------------------------------------------;
  445. ;;;功能: 点到三点决定的平面的距离(有向的距离)        ;
  446. ;;;输入: 一点P和平面的方程为Ax+By+Cz+D=0的四个系数     ;
  447. ;;;输出: 该点到平面的距离                              ;
  448. ;;;----------------------------------------------------;
  449. (defun PLANE:Distance_1 (P p1 p2 p3 /) 
  450.   (Apply 'PLANE:Distance (cons p (PLANE:Equation_3P p1 p2 p3)))
  451. )
  452.  
  453. ;;;----------------------------------------------------;
  454. ;;;功能: 点到三点决定的平面的距离和该点在平面上的投影点;
  455. ;;;输入: 一点P和三点P1,P2,P3决定的平面                 ;
  456. ;;;输出: 该点到平面的垂足                              ;
  457. ;;;----------------------------------------------------;
  458. (defun PLANE:Perpendicular_Foot_1 (P p1 p2 p3 / F A B C D H N L)
  459.   (setq F (PLANE:Equation_3P p1 p2 p3))
  460.   (setq A (car f)
  461.         B (cadr f)
  462.         C (caddr f)
  463.         D (last f)
  464.   )
  465.   (setq H (PLANE:Distance p A B C D))
  466.   (setq N (List A B C))
  467.   (setq L (distance '(0 0 0) N)) 
  468.   (if (not (zerop L)) 
  469.     (list H (Geo:scale (mapcar '+ p N) P (- (/ H L))))
  470.   )
  471. )
  472.  
  473. ;;;----------------------------------------------------;
  474. ;;;功能: 点到三点决定的平面的距离和该点在平面上的投影点;
  475. ;;;输入: 一点P和通过P0法线矢量为Normal决定的平面       ;
  476. ;;;输出: 该点到平面的垂足                              ;
  477. ;;;----------------------------------------------------;
  478. (defun PLANE:Perpendicular_Foot (P P0 Normal / l d)
  479.   (setq l (distance '(0 0 0) Normal))
  480.   (setq d (caddr (trans (mapcar '- p p0) 0 Normal T)))
  481.   (mapcar '- P (mat:vxs Normal (/ d l)))
  482. )
  483.  
  484. (defun PLANE:Perpendicular_Foot_2 (P P0 Normal / l d)
  485.   (setq l (distance '(0 0 0) Normal))
  486.   (setq l (* l l))
  487.   (setq d (mat:dot Normal (mapcar '- p p0)))
  488.   (mapcar '- P (mat:vxs Normal (/ d l)))
  489. )
  490.  
  491. ;;;----------------------------------------------------;
  492. ;;;功能: 求空间直线与平面的交点                        ;
  493. ;;;输入: 决定直线的两点Pa,Pb和三点P1,P2,P3决定的平面   ;
  494. ;;;输出: 该点到平面的距离                              ;
  495. ;;;----------------------------------------------------;
  496. (defun PLANE:Line_Inters_Plane (Pa Pb A B C D / h1 h2)
  497.   (setq h1 (Plane:Distance Pa A b c d))
  498.   (setq h2 (plane:distance Pb a b c d))
  499.   (if (and h1 h2)
  500.     (cond
  501.       ( (equal h1 0 1e-14) Pa)
  502.       ( (equal h2 0 1e-14) Pb)
  503.       (t (GEO:Proportion Pa Pb (- (/ h1 h2))))
  504.     )
  505.   )
  506. )
  507.  
  508. ;;;****************************************************;
  509. ;;;三角形部分                                          ;
  510. ;;;****************************************************;
  511.  
  512. ;;;----------------------------------------------------;
  513. ;;;功能: 判断是否构成三角形                            ;
  514. ;;;输入: 三边的长度a,b,c                               ;
  515. ;;;输出: 构成三角形则返回T,否则返回nil                ;
  516. ;;;----------------------------------------------------;
  517. (defun TRI:IsTriangle (a b c /)
  518.   (and (> (+ a b) c) (> (+ b c) a) (> (+ c a) b))
  519. )
  520.  
  521. ;;;----------------------------------------------------;
  522. ;;;功能: 求三角形外心   TRI:CircumCenter,ExCenter     ;
  523. ;;;输入: 给定不共线的三个点                            ;
  524. ;;;输出: 这三点的外接圆的圆心和半径                    ;
  525. ;;;说明: 尽管这样写很麻烦,显得代码很多,但运行却很快  ;
  526. ;;;----------------------------------------------------;
  527. (defun TRI:CircumCenter (P0 P1 P2 / X0 Y0 X1 Y1 X2 Y2 DX1 DY1 DX2 DY2 D 2D C1 C2 CE)
  528.   (setq X0  (car  P0)
  529.         Y0  (cadr P0)
  530.         X1  (car  P1)
  531.         Y1  (cadr P1)
  532.         X2  (car  P2)
  533.         Y2  (cadr P2)
  534.         DX1 (- X1 X0)
  535.         DY1 (- Y1 Y0)
  536.         DX2 (- X2 X0)
  537.         DY2 (- Y2 Y0)
  538.   )
  539.   (setq D (- (* DX1 DY2) (* DX2 DY1)))
  540.   (if (equal D 0 1e-14)
  541.     nil
  542.     (progn
  543.       (setq 2D (+ D D)
  544.             C1 (+ (* DX1 (+ X0 X1)) (* DY1 (+ Y0 Y1)))
  545.             C2 (+ (* DX2 (+ X0 X2)) (* DY2 (+ Y0 Y2)))
  546.             CE (List (/ (- (* C1 DY2) (* C2 DY1)) 2D)
  547.                      (/ (- (* C2 DX1) (* C1 DX2)) 2D)
  548.                )
  549.       )
  550.       (list CE (distance CE P0))
  551.     )
  552.   )
  553. )
  554.  
  555. ;;;----------------------------------------------------;
  556. ;;;功能: 三角形内心                                    ;
  557. ;;;公式: (aX1+bx2+cx3)/(a+b+c),(aY2+bY2+CY3)/(a+b+c)   ;
  558. ;;;输入: 给定不共线的三个点                            ;
  559. ;;;输出: 这三点的内切圆的圆心和半径                    ;
  560. ;;;----------------------------------------------------;
  561. (defun TRI:InCenter (pa pb pc / a b c L I r)
  562.   (setq a (distance pb pc))
  563.   (setq b (distance pc pa))
  564.   (setq c (distance pa pb))
  565.   (setq L (+ a b c))
  566.   (if (/= L 0.0)
  567.     (setq I (MAT:SxVs (list pa pb pc) (list (/ a L) (/ b L) (/ c L)))
  568.           R (list I (abs (LINE:Perpendicular_Distance I pa pb)))
  569.     )
  570.     (list pa 0)
  571.   )
  572. )
  573.  
  574. ;;;----------------------------------------------------;
  575. ;;;功能: 三角形垂心                                    ;
  576. ;;;输入: 给定不共线的三个点                            ;
  577. ;;;输出: 这个三点形成的三角形的垂心                    ;
  578. ;;;----------------------------------------------------;
  579. (defun TRI:OrthoCenter (pa pb pc / p1 p2)
  580.   (setq p1 (GEO:Rot90 Pa pb pc))
  581.   (setq p2 (GEO:Rot90 pb pc pa))
  582.   (inters pa p1 pb p2 nil)
  583. )
  584.  
  585. ;;;----------------------------------------------------;
  586. ;;;功能: 三角形重心                                    ;
  587. ;;;输入: 给定不共线的三个点                            ;
  588. ;;;输出: 这个三点形成的三角形的重心                    ;
  589. ;;;----------------------------------------------------;
  590. (defun TRI:Barycenter (p1 p2 p3)
  591.   (mapcar (function (lambda (e1 e2 e3) (/ (+ e1 e2 e3) 3.0))) p1 p2 p3)
  592. )
  593.  
  594. ;;;----------------------------------------------------;
  595. ;;;功能: 三角形的九点圆                                ;
  596. ;;;输入: 给定不共线的三个点                            ;
  597. ;;;输出: 这个三点形成的三角形的九点圆的圆心和半径      ;
  598. ;;;----------------------------------------------------;
  599. (defun TRI:9P_Circle (pa pb pc)
  600.   (apply 'TRI:CircumCenter
  601.          (mapcar 'GEO:Midpoint  (list pa pb pc) (list pb pc pa))
  602.   )
  603. )
  604.  
  605. ;;;----------------------------------------------------;
  606. ;;;三线坐标转化为世界坐标      k = 2S/(ax+by+cz)       ;
  607. ;;;注意: 三线坐标跟笛卡尔坐标的表示上的不同            ;
  608. ;;;输入: 三线坐标P(list x y z)=>x:y:z和对应三点Pa,Pb,Pc;
  609. ;;;输出: 返回世界坐标系的点                            ;
  610. ;;;----------------------------------------------------;
  611. (defun TRI:TCS->WCS (P Pa Pb Pc / x y z V1 V2 V3 p1 p2 p3 int)
  612.   (setq V1 (LINE:Offset Pb Pc (car P)))
  613.   (setq V2 (LINE:Offset Pc Pa (cadr p)))
  614.   (setq V3 (LINE:Offset Pa Pb (caddr p)))
  615.   (setq p1 (inters (car V2) (cadr V2) (car V3) (cadr V3) nil))
  616.   (setq p2 (inters (car V3) (cadr V3) (car V1) (cadr V1) nil))
  617.   (setq p3 (inters (car V1) (cadr V1) (car V2) (cadr V2) nil))
  618.   (if (setq int (inters Pa P1 Pb P2 nil))
  619.     int
  620.     (if (setq int (inters Pb P2 Pc P3 nil))
  621.       int
  622.       (inters Pc P3 Pa P1 nil)
  623.     )
  624.   )
  625. )
  626.  
  627. ;;;----------------------------------------------------;
  628. ;;;功能: 相似重心,Lemoine Point ,or symmedian point    ;
  629. ;;;输入: 给定不共线的三个点                            ;
  630. ;;;输出: 这个三点形成的三角形的相似重心                ;
  631. ;;;----------------------------------------------------;
  632. (defun TRI:Symmedian_Point (Pa Pb Pc / a b c)
  633.   (setq a (distance Pb Pc))
  634.   (setq b (distance pc Pa))
  635.   (setq c (distance Pa Pb))
  636.   (TRI:TCS->WCS (list a b c) Pa Pb Pc)
  637. )
  638.  
  639. ;;;----------------------------------------------------;
  640. ;;;功能: 某点对给定三角形的等角共轭点                  ;
  641. ;;;输入: 一点Pt 和构成三角形的三点Pa Pb Pc             ;
  642. ;;;输出: 这点对给定三角形的等角共轭点                  ;
  643. ;;;----------------------------------------------------;
  644. (defun TRI:Isogonal-Conjugate-Point (Pt Pa Pb Pc / Pt1 Pt2 Inc)
  645.   (setq InC (car (TRI:InCenter Pa Pb Pc)))
  646.   (setq Pt1 (GEO:Mirror3D Pt Pa Inc))
  647.   (setq pt2 (GEO:Mirror3D Pt Pb Inc))
  648.   (inters Pa Pt1 Pb Pt2 nil)
  649. )
  650.  
  651. ;;;----------------------------------------------------;
  652. ;;;功能: 某点对给定三角形的等角共轭点                  ;
  653. ;;;输入: 一点Pt 和构成三角形的三点Pa Pb Pc             ;
  654. ;;;输出: 这点对给定三角形的等角共轭点                  ;
  655. ;;;说明: 如果已知三角形内心,则可以简略计算            ;
  656. ;;;----------------------------------------------------;
  657. (defun TRI:Isogonal-Conjugate-Point-1 (Pt Pa Pb Inc /)
  658.   (inters Pa (GEO:Mirror3D Pt Pa Inc) Pb (GEO:Mirror3D Pt Pb Inc) nil)
  659. )
  660.  
  661. ;;;----------------------------------------------------;
  662. ;;;根据三角形的三边长获取三角形信息                    ;
  663. ;;;输入: 三边的边长a,b,c                               ;
  664. ;;;输出: 三角形的三个角度,面积和周长,内心和内切圆半径;
  665. ;;;      旁切圆的圆心和半径,外心和外接圆半径,垂心,  ;
  666. ;;;      重心,类似重心,等周心以及九点圆圆心          ;
  667. ;;;----------------------------------------------------;
  668. ;|
  669. http://en.wikipedia.org/wiki/Trilinear_coordinates      
  670. where a, b, c are the respective sidelengths BC, CA, AB,
  671. and σ = area of ABC.                                   
  672. A = 1 : 0 : 0                                           
  673. B = 0 : 1 : 0                                           
  674. C = 0 : 0 : 1                                           
  675. incenter = 1 : 1 : 1                                    
  676. centroid = bc:ca:ab = 1/a:1/b:1/c = cscA : cscB : cscC. 
  677. circumcenter = cos A : cos B : cos C.                   
  678. orthocenter = sec A : sec B : sec C.                    
  679. nine-point center = cos(B - C) : cos(C - A) : cos(A - B)
  680. symmedian point = a : b : c = sin A : sin B : sin C.    
  681. A-excenter = -1 : 1 : 1                                 
  682. B-excenter = 1 : -1 : 1                                 
  683. C-excenter = 1 : 1 : -1.                                
  684. ;;;de Longchamps point                                  
  685. ;;;http://en.wikipedia.org/wiki/De_Longchamps_point     
  686. ;;;symmedian point                                      
  687. ;;;http://en.wikipedia.org/wiki/Symmedian_point         
  688. http://mathworld.wolfram.com/TriangleCenter.html        
  689. |; 
  690. (defun TRI:InfoBy3Sides (a b c / p S 2S Aa Ab Ac D K Ri Re Ra Rb Rc Ca Cb Cc Sa Sb Sc)
  691.   (setq p  (* 0.5 (+ a b c)))                           ;半周长
  692.   (setq S  (sqrt (* p (- p a) (- p b) (- p c))))        ;面积
  693.   (setq Ri (/ S p))                                     ;内切圆半径
  694.   (setq K  (* 2 Ri p))
  695.   (setq Ra (/ k (+ b c (- a))))                         ;边A旁切圆半径
  696.   (setq Rb (/ k (+ c a (- b))))                         ;边B旁切圆半径
  697.   (setq Rc (/ k (+ a b (- c))))                         ;边C旁切圆半径
  698.   (setq Re (/ (* a b c 0.25) S))                        ;外接圆半径
  699.   (setq D  (+ Re Re))                                   ;外接圆直径
  700.   (setq Ca (/ (+ (* b b) (* (+ c a) (- c a))) 2 b c))   ;角A余弦
  701.   (setq Cb (/ (+ (* c c) (* (+ a b) (- a b))) 2 c a))   ;角B余弦
  702.   (setq Cc (/ (+ (* a a) (* (+ b c) (- b c))) 2 a b))   ;角C余弦
  703.   (setq Sa (/ a D))                                     ;角A正弦
  704.   (setq Sb (/ b D))                                     ;角B正弦
  705.   (setq Sc (/ c D))                                     ;角C正弦
  706.   (setq Aa (atan Sa Ca))                                ;角A
  707.   (setq Ab (atan Sb Cb))                                ;角B
  708.   (Setq Ac (atan Sc Cc))                                ;角C
  709.   (setq 2S (+ S S))
  710.   (list (list Aa Ab Ac)                                 ;三个角
  711.         (list S (+ p p))                                ;面积和周长
  712.         (list '( 1  1  1) Ri)                           ;内心
  713.         (list '(-1  1  1) Ra)                           ;边A旁切圆半径
  714.         (list '( 1 -1  1) Rb)                           ;边B旁切圆半径
  715.         (list '( 1  1 -1) Rc)                           ;边C旁切圆半径
  716.         (list (list Ca Cb Cc) Re)                       ;外心
  717.         (list (list (/ 1 Ca) (/ 1 Cb) (/ 1 Cc)))        ;垂心
  718.         (list (list (/ 1 a) (/ 1 b) (/ 1 c)))           ;重心
  719.         (list (list a b c))                             ;类似重心
  720.         (list (list (cos (- Ab Ac))
  721.                     (cos (- Ac Aa))
  722.                     (cos (- Aa Ab))
  723.               )                                         ;九点圆圆心
  724.               (* 0.5 Re)                                ;九点圆半径
  725.         )
  726.         (list (list (1- (/ 2S a (+ b c (- a))))      
  727.                     (1- (/ 2S b (+ c a (- b))))
  728.                     (1- (/ 2S c (+ a b (- c))))
  729.               )
  730.         )                                               ;等周点(Isoperimetric Point)
  731.   )
  732. )
  733.  
  734. ;;;----------------------------------------------------;
  735. ;;;功能: 定义三点的行列式,即三点之倍面积               ;
  736. ;;;输入: 三点P1,P2,P3                                  ;
  737. ;;;输出: 这三点形成的三角形的面积的2倍,符号指示方向。 ;
  738. ;;;----------------------------------------------------;
  739. (defun TRI:Det3P (p1 p2 p3)
  740.   (- (* (- (car p2) (car p1)) (- (cadr p3) (cadr p1)))
  741.      (* (- (car p3) (car p1)) (- (cadr p2) (cadr p1)))
  742.   )
  743. )
  744.  
  745. ;;;----------------------------------------------------;
  746. ;;;功能: 用海伦公式(Heron's formula)求三角形面积       ;
  747. ;;;输入: 三角形的三个边长a,b,c                         ;
  748. ;;;输出: 三角形面积                                    ;
  749. ;;;----------------------------------------------------;
  750. (defun TRI:Area (a b c / p)
  751.   (setq p (* 0.5 (+ a b c)))
  752.   (sqrt (* p (- p a) (- p b) (- p c)))
  753. )
  754.  
  755.  
  756. ;;;----------------------------------------------------;
  757. ;;; 功能: 根据三边求三个角(利用余弦定理)               ;
  758. ;;; 输入: 构成三角形的三边a,b,c                        ;
  759. ;;; 输出: 返会三条边对应的三个角                       ;
  760. ;;;----------------------------------------------------;
  761. (defun TRI:CosinesLaw (a b c / cc sc a1 a2)
  762.   (if (TRI:IsTriangle a b c)
  763.     (progn
  764.       (setq a  (float a))                                       ;为了防止整除
  765.       (setq cc (/ (+ (* a a) (* (+ b c) (- b c))) (+ a a) b))   ;角C的余弦
  766.       (setq sc (sqrt (* (- 1 cc) (1+ cc))))                     ;角C的正弦
  767.       (setq a1 (atan (* a sc) (- b (* a cc))))                  ;角A
  768.       (setq a2 (atan sc cc))                                    ;角C
  769.       (list a1 (- pi a1 a2) a2)                                 ;返回三个角度的列表
  770.     )
  771.   )
  772. )
  773.  
  774.  
  775. ;;;----------------------------------------------------;
  776. ;;;功能: 计算已知空间三点的三角形面积                  ;
  777. ;;;输入: 空间三点 P1,P2,P3                             ;
  778. ;;;输出: 三角形面积                                    ;
  779. ;;;----------------------------------------------------;
  780. (defun TRI:Area3D (p1 p2 p3 / v1 v2 d1 d2 d3)
  781.   (setq v1 (mapcar '- p2 p1))
  782.   (setq v2 (mapcar '- p3 p1))
  783.   (setq d1 (MAT:Det2 (car   v1) (cadr  v1) (car   v2) (cadr  v2)))
  784.   (setq d2 (MAT:Det2 (cadr  v1) (caddr v1) (cadr  v2) (caddr v2)))
  785.   (setq d3 (MAT:Det2 (caddr v1) (car   v1) (caddr v2) (car   v2)))
  786.   (* 0.5 (sqrt (+ (* d1 d1) (* d2 d2) (* d3 d3))))
  787. )
  788.  
  789. ;;;****************************************************;
  790. ;;;多边形部分                                          ;
  791. ;;;****************************************************;
  792.  
  793. (defun POLY:IsInside (p Pts)
  794.   (setq ans (mapcar (function (lambda (x) (angle p x))) pts))
  795.   (mapcar '+ ans)
  796. )
  797.  
  798. (defun c:ppp ()
  799.   (initget 1)
  800.   (setq p (getpoint "n点:"))
  801.   (setq sel (ssget ":S" '((0 . "*POLYLINE"))))
  802.   (if (and p sel)
  803.     (progn
  804.       (setq ent (ssname sel 0))
  805.       (setq num (vlax-curve-getEndParam ent))
  806.       (setq i 0)
  807.       (repeat (fix num)
  808.         (setq pt (vlax-curve-getPointAtParam ent i))
  809.         (setq pts (cons pt pts))
  810.         (setq i (1+ i))
  811.       )
  812.       (setq pts (reverse pts))
  813.       (setq ret (POLY:IsInside  p pts))
  814.     )
  815.   )
  816. )
  817.  
  818. ;;;----------------------------------------------------;
  819. ;;;功能: 计算多边形面积(为简单多边形,不自交的多边形)  ;
  820. ;;;输入: 多边形顶点列表  Pts                           ;
  821. ;;;输出: 一个数值,如果为正则是CCW(逆时针),否则顺时针 ;
  822. ;;;参考: Centroid  Shoelace formula                    ;
  823. ;;;----------------------------------------------------;
  824. (defun POLY:Area (pts)
  825.   (* (apply '+ (mapcar 'MAT:Det2V pts (MISC:1st->Last Pts))) 0.5)
  826. )
  827.  
  828. ;;;----------------------------------------------------;
  829. ;;;功能: 计算多边形周长                                ;
  830. ;;;输入: 多边形顶点列表  Pts                           ;
  831. ;;;输出: 一个数值,表示多边形周长                      ;
  832. ;;;----------------------------------------------------;
  833. (defun POLY:Perimeter (pts)
  834.   (apply '+ (mapcar 'distance pts (MISC:1st->Last Pts)))
  835. )
  836.  
  837. ;;;----------------------------------------------------;
  838. ;;;功能: 判断多边形的方向(为简单多边形,不自交的多边形);
  839. ;;;输入: 多边形顶点列表  Pts                           ;
  840. ;;;输出: 返回T则是CCW(逆时针),否则顺时针              ;
  841. ;;;----------------------------------------------------;
  842. (defun POLY:IsCCW (Pts)
  843.   (> (POLY:Area pts) 0.0)
  844. )
  845.  
  846. ;;;----------------------------------------------------;
  847. ;;;功能: 获取多边形信息(质心,面积,周长)              ;
  848. ;;;输入: Pts---多边形顶点列表                          ;
  849. ;;;输出: 列表:第一个为多边形的面积中心(质心),用2d点表示;
  850. ;;;      第二个为数值,正数表示多边形方向是CCW(逆时针) ;
  851. ;;;      负数表示顺时针;第三个为周长.                 ;
  852. ;;;参考: http://en.wikipedia.org/wiki/Centroid         ;
  853. ;;;----------------------------------------------------;
  854. (defun POLY:Infomation (Pts / Pts1 Ai S lst cen)
  855.   (setq Pts1 (MISC:1st->Last Pts))                      ;another point of every side
  856.   (setq Ai   (mapcar 'MAT:Det2V Pts Pts1))              ;area of every side 
  857.   (setq S    (* (apply '+ Ai) 0.5))                     ;Total area
  858.   (Setq Cen  (MAT:SxVs (mapcar 'MAT:v+v Pts Pts1) Ai))
  859.   (setq Cen  (MAT:vxs Cen (/ 0.166666666666666667 S)))  ;base on the formula
  860.   (list Cen S (apply '+ (mapcar 'distance pts pts1)))   ;Return Centroid,Total area and Perimeter
  861. )
  862.  
  863. ;;;----------------------------------------------------;
  864. ;;;Circular segment                                    ;
  865. ;;;弓的质心求以及弓形的面积                            ;
  866. ;;;输入: C---圆心;Center                               ;
  867. ;;;      R---半径;Radius                               ;
  868. ;;;      A1--起始角;0 <= A1 <= 2*Pi Start Angle(Radian);
  869. ;;;      A2--终止角;0 <= A2 <= 2*Pi End Angle(Radian)  ;
  870. ;;;      IsCW--是否顺时针                              ;
  871. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为弧长;
  872. ;;;----------------------------------------------------;
  873. (defun CIR:Circular_Segment (C R A1 A2 IsCW / A k d S e)
  874.   (and isCW (setq A A2 A2 A1 A1 A))
  875.   (if (> A1 A2)
  876.     (setq A (- (+ pi pi A2) A1 ))
  877.     (setq A (- A2 A1))
  878.   )
  879.   (setq k (sin (* 0.5 A)))
  880.   (setq k (* 1.333333333333333333333 R k k k))
  881.   (setq e (- A (sin A)))
  882.   (setq S (* 0.5 R R e))
  883.   (and IsCW (setq S (- S)))                             ;如果顺时针,面积为负
  884.   (setq d (/ k e))
  885.   (if (> A1 A2) (setq d (- d)))                         ;这种情况下要反向
  886.   (list (polar C (* 0.5 (+ A1 A2)) d) S (* A R))
  887. )
  888.  
  889. ;;;----------------------------------------------------;
  890. ;;;Circular sector                                     ;
  891. ;;;扇形的质心,面积和周长                              ;
  892. ;;;输入: C---圆心;Center                               ;
  893. ;;;      R---半径;Radius                               ;
  894. ;;;      A1--起始角;0 <= A1 <= 2*Pi Start Angle(Radian);
  895. ;;;      A2--终止角;0 <= A2 <= 2*Pi End Angle(Radian)  ;
  896. ;;;      IsCW--是否顺时针                              ;
  897. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为周长;
  898. ;;;----------------------------------------------------;
  899. (defun CIR:Circular_Sector (C R A1 A2 IsCW / A d S L)
  900.   (and IsCW (setq A A2 A2 A1 A1 A))
  901.   (if (> A1 A2)
  902.     (setq A (- (+ pi pi A2) A1))
  903.     (setq A (- A2 A1))
  904.   )
  905.   (setq d (/ (* 4 R (sin (* 0.5 A))) 3 A))
  906.   (setq S (* 0.5 A R R))                                
  907.   (and IsCW (setq S (- S)))                             ;如果顺时针,面积为负
  908.   (setq L (* R (+ A 2)))                                ;周长
  909.   (if (> A1 A2) (setq d (- d)))                         ;这种情况下要反向
  910.   (list (polar C (* 0.5 (+ A1 A2)) d) S L)
  911. )
  912.  
  913. ;;;----------------------------------------------------;
  914. ;;;获得轻多段线的有弧段处的顶点的信息                  ;
  915. ;;;输入: P1---顶点坐标(OCS)                            ;
  916. ;;;      P2---下一顶点坐标(OCS)                        ;
  917. ;;;      b----凸度(不为零)                           ;
  918. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为弧长;
  919. ;;;----------------------------------------------------;
  920. (defun POLY:Info_Bulge (P1 P2 b / D A k C R)
  921.   (setq D (distance p1 p2))
  922.   (setq A (angle p1 p2))
  923.   (setq k (* d (1+ (* b b)) 0.25))
  924.   (setq C (polar p1 (+ a (- (* pi 0.5) (* 2 (atan b)))) (/ k b)))
  925.   (setq R (/ k (abs b)))
  926.   (CIR:Circular_Segment C R (angle c p1) (angle c p2) (< b 0))
  927. )
  928.  
  929. ;;;----------------------------------------------------;
  930. ;;;获得轻多段线的信息                                  ;
  931. ;;;输入: LWPoly---轻多段线的实体名                     ;
  932. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为弧长;
  933. ;;;----------------------------------------------------;
  934. (defun POLY:Info_LWPoly (LWPoly / eps Object Points Number IsOpen I P P0 Q Ret b Cen1
  935.                                   Area1 List1 List2 Part1 Leng1 Leng2 AreaLst CenLst)
  936.   (setq eps 1e-6)
  937.   (setq Object (vlax-ename->vla-object LWPoly))
  938.   (setq Points (vlax-get Object 'Coordinates))
  939.   (setq Number (/ (length Points) 2))
  940.   (setq IsOpen (= (vla-get-closed Object) :vlax-false))
  941.   (and IsOpen (setq Number (1+ Number)))
  942.   (setq i 0)
  943.  
  944.   (setq p0  (list (car Points) (cadr Points)))
  945.   (setq p p0)
  946.   (repeat number
  947.     (if (setq Points (cddr Points))
  948.       (setq q (list (car Points) (cadr Points)))        ;下一顶点
  949.       (setq q P0)                                       ;如果顶点是最后点,则取第一点
  950.     )
  951.     (if (not (equal p q eps))                           ;这步为的是消除重合的点。
  952.       (progn
  953.         (setq b (vla-getbulge Object i))                ;取得这点的凸度
  954.         (if (or (/= b 0.0) (and (null points) IsOpen))  ;如果有凸度或者在末端
  955.           (setq List1 (cons (list P b 0) List1))        ;则不计算这点长度
  956.           (setq List1 (cons (list p b (distance p q)) List1))      
  957.         )
  958.         (if (and (/= b 0.0) (or Points (not IsOpen)))   ;如果有凸度(末端不封闭情况不计算)
  959.           (setq List2 (cons (POLY:Info_Bulge p q b) List2))
  960.         )
  961.       )
  962.     )
  963.     (setq p q)
  964.     (setq i (1+ i))
  965.   )
  966.   (setq list1 (reverse List1))
  967.   (setq list2 (reverse list2))
  968.   (setq part1 (POLY:Infomation (mapcar 'car list1)))    ;不含弧段的部分
  969.   (setq Cen1  (car Part1))                              ;不含弧段部分的质心
  970.   (setq Area1 (cadr Part1))                             ;不含弧段部分的面积
  971.   (setq leng1 (apply '+ (mapcar 'last list1)))          ;不含弧段部分的总长
  972.   (if List2                                             ;含弧段的部分
  973.     (setq leng2   (apply '+ (mapcar 'last list2))       ;含弧段部分的总长
  974.           CenLst  (cons Cen1 (mapcar 'car list2))       ;含弧段部分的质心
  975.           AreaLst (cons Area1 (mapcar 'cadr list2))     ;含弧段部分的面积
  976.           ret     (GEO:Centroid_Composition CenLst AreaLst)
  977.           ret     (list (car ret) (cadr ret) (+ leng1 leng2))
  978.     ) 
  979.     (list Cen1 Area1 leng1)
  980.   )
  981. )
  982.  
  983. ;;;****************************************************;
  984. ;;;数学部分                                            ;
  985. ;;;****************************************************;
  986.  
  987. ;;;----------------------------------------------------;
  988. ;;;变号                                                ;
  989. ;;;----------------------------------------------------;
  990. (defun Math:Sign_reversal (y x)
  991.   (if (< x 0) (- y) y)
  992. )
  993.  
  994. ;;;----------------------------------------------------;
  995. ;;;判断是否异号                                        ;
  996. ;;;----------------------------------------------------;
  997. (defun MATH:Opposite_Sign (x y)
  998.   (or (and (> x 0) (< y 0)) (and (< x 0) (> y 0)))
  999. )
  1000.  
  1001. ;;;----------------------------------------------------;
  1002. ;;;判断是否同号                                        ;
  1003. ;;;----------------------------------------------------;
  1004. (defun MATH:Same_Sign (x y)
  1005.   (or (and (> x 0) (> y 0)) (and (< x 0) (< y 0)))
  1006. )
  1007.  
  1008. ;;;****************************************************;
  1009. ;;;实体创建部分                                        ;
  1010. ;;;****************************************************;
  1011.  
  1012. ;;;----------------------------------------------------;
  1013. ;;;创建一个点                                          ;
  1014. ;;;输入: 一个三维或者二维的点                          ;
  1015. ;;;输出: 点实体的图元名                                ;
  1016. ;;;----------------------------------------------------;
  1017. (defun Ent:Make_Point (p)
  1018.   (entmakex (list '(0 . "POINT") (cons 10 p)))
  1019. )
  1020.  
  1021. ;;;----------------------------------------------------;
  1022. ;;;创建一个带颜色的点(此函数为测试或者其他用途)      ;
  1023. ;;;输入: 一个三维或者二维的点表和一个颜色号            ;
  1024. ;;;输出: 点实体的图元名                                ;
  1025. ;;;----------------------------------------------------;
  1026. (defun Ent:MakePoint-1 (p c)
  1027.   (entmakex (list '(0 . "POINT") (cons 10 p) (cons 62 c)))
  1028. )
  1029.  
  1030. ;;;----------------------------------------------------;
  1031. ;;;创建一条直线段                                      ;
  1032. ;;;输入: 两个三维或者二维的点                          ;
  1033. ;;;输出: 线段实体的图元名                              ;
  1034. ;;;----------------------------------------------------;
  1035. (defun Ent:Make_Line (p q)
  1036.   (entmakeX (list '(0 . "LINE") (cons 10 p) (cons 11 q)))
  1037. )
  1038.  
  1039. ;;;----------------------------------------------------;
  1040. ;;;创建一个由三条直线组成的三角形                      ;
  1041. ;;;输入: 三个三维或者二维的点                          ;
  1042. ;;;输出: 由三条直线组成的三角形                        ;
  1043. ;;;----------------------------------------------------;
  1044. (defun Ent:Make_Triangle (p1 p2 p3)
  1045.   (mapcar 'Ent:Make_Line (list p1 p2 p3) (list p2 p3 p1))
  1046. )
  1047.  
  1048. ;;;----------------------------------------------------;
  1049. ;;;创建一个三维多段线                                  ;
  1050. ;;;输入: 三维的点集                                    ;
  1051. ;;;输出: 三维多段线实体                                ;
  1052. ;;;----------------------------------------------------;
  1053. (defun Ent:Make_Poly (pts / e)
  1054.   (setq e (Entmake (list '(0 . "POLYLINE") '(70 . 9))))
  1055.   (foreach p pts
  1056.     (entmake (list '(0 . "VERTEX") '(70 . 32) (cons 10 p)))
  1057.   )
  1058.   (entmake '((0 . "SEQEND")))
  1059.   (entlast)
  1060. )
  1061.  
  1062.  
  1063. ;;;----------------------------------------------------;
  1064. ;;;创建轻多段线                                        ;
  1065. ;;;输入: 二维的点集                                    ;
  1066. ;;;输出: 轻多段线实体名                                ;
  1067. ;;;----------------------------------------------------;
  1068. (defun Ent:Make_LWPoly (pts closed /)
  1069.   (entmakeX                                              
  1070.     (append
  1071.       '((0 . "LWPOLYLINE")
  1072.         (100 . "AcDbEntity") 
  1073.         (100 . "AcDbPolyline")
  1074.        )
  1075.       (list (cons 90 (length pts)))                     ;顶点个数
  1076.       (mapcar (function (lambda (x) (cons 10 x))) pts)  ;多段线顶点
  1077.       (list (cons 70 (if closed 1 0)))                  ;闭合的
  1078.     )
  1079.   )
  1080. )
  1081.  
  1082. ;;;----------------------------------------------------;
  1083. ;;;创建圆实体                                          ;
  1084. ;;;输入: 圆心C和半径R                                  ;
  1085. ;;;输出: 圆的实体名                                    ;
  1086. ;;;----------------------------------------------------;
  1087. (defun Ent:Make_Circle (C R)
  1088.   (entmakex (list '(0 . "CIRCLE") (cons 10 C) (cons 40 R)))
  1089. )
  1090.  
  1091. ;;;----------------------------------------------------;
  1092. ;;;创建弧实体(注意: 弧段总是逆时针方向的)            ;
  1093. ;;;输入: 弧的圆心C和半径R以及起始角度A1和终止角度A2    ;
  1094. ;;;输出: 弧的实体名                                    ;
  1095. ;;;----------------------------------------------------;
  1096. (defun Ent:Make_ARC (C R A1 A2)
  1097.   (entmakeX (list '(0 . "ARC")
  1098.                   (cons 10 C)
  1099.                   (cons 40 R)
  1100.                   (cons 50 A1)
  1101.                   (cons 51 A2)
  1102.             )
  1103.   )
  1104. )
  1105.  
  1106. ;;;****************************************************;
  1107. ;;;杂项                                                ;
  1108. ;;;****************************************************;
  1109.  
  1110. ;;;----------------------------------------------------;
  1111. ;;;表中是否存在某个元素                                ;
  1112. ;;;----------------------------------------------------;
  1113. (defun MISC:IsExist (x lst func / f y ret)
  1114.   (setq f (eval func))
  1115.   (while (setq y (car lst))
  1116.     (setq lst (cdr lst))
  1117.     (if (f x y)
  1118.       (setq ret T lst nil)
  1119.     )
  1120.   )
  1121.   ret
  1122. )
  1123.  
  1124. ;;;----------------------------------------------------;
  1125. ;;;根据x的函数求y                                      ;
  1126. ;;;----------------------------------------------------;
  1127. (defun MISC:Apply (x y)
  1128.   (mapcar 'apply x (mapcar 'list y))
  1129.   ;;(mapcar 'eval (mapcar 'list x y))            ;Slower
  1130. )
  1131.  
  1132. ;;;----------------------------------------------------;
  1133. ;;;交换两个元素                                        ;
  1134. ;;;----------------------------------------------------;
  1135. (defun MISC:Swap (e1 e2 / temp)
  1136.   (setq temp e2 e2 e1 e1 temp)
  1137.   (list e1 e2)
  1138. )
  1139.  
  1140. ;;;----------------------------------------------------;
  1141. ;;;把表的第一项放到最后                                ;
  1142. ;;;----------------------------------------------------;
  1143. (defun MISC:1st->Last (lst)
  1144.   (append (cdr lst) (list (car lst)))
  1145. )
  1146.  
  1147. ;;;----------------------------------------------------;
  1148. ;;;把2d或者3d点集转化为表                              ;
  1149. ;;;----------------------------------------------------;
  1150. (defun MISC:PtList->List (Ptlst / l)
  1151.   (reverse
  1152.     (foreach p Ptlst
  1153.       (foreach x p
  1154.         (setq l (cons x l))
  1155.       )
  1156.     )
  1157.   )
  1158. )
  1159.  
  1160. ;;;----------------------------------------------------;
  1161. ;;;把表转化为2d或者3d点集                              ;
  1162. ;;;----------------------------------------------------;
  1163. (defun MISC:List->PtList (lst dim / l p x)
  1164.   (while lst 
  1165.     (setq p nil)
  1166.     (repeat dim
  1167.       (setq p (cons (car lst) p))
  1168.       (setq lst (cdr lst))
  1169.     )
  1170.     (setq l (cons (reverse p) l))
  1171.   )
  1172.   (reverse l)
  1173. )
  1174.  
  1175. ;;;----------------------------------------------------;
  1176. ;;;把表转化为变量                                      ;
  1177. ;;;----------------------------------------------------;
  1178. (defun MISC:List->Variant (Ptlst / lst dim arr)         ; allocate space for an array of 2d or 3d points stored as doubles
  1179.   (setq lst (MISC:PtList->List Ptlst))
  1180.   (setq dim (cons 0 (1- (length lst))))
  1181.   (setq arr (vlax-make-safearray vlax-vbDouble dim))    ; array dimension, element type is vlax-vbDouble
  1182.   (vlax-make-variant (vlax-safearray-fill arr lst))     ; return array variant
  1183. )
  1184.  
  1185. ;;;----------------------------------------------------;
  1186. ;;;变量转化为表                                        ;
  1187. ;;;----------------------------------------------------;
  1188. (defun MISC:Variant->List (var)
  1189.   (vlax-safearray->list (vlax-variant-value var))
  1190. )
  1191.  
  1192. (defun p-t(p p1 p2)
  1193.   (<= (abs (- (/ (caddr (trans (mapcar '- p p1) 0 (mapcar '- p2 p1))) (distance p1 p2)) 0.5)) (+ 0.5 1e-8))
  1194. )
  1195.  
  1196. (defun LINE:P-t (p p1 p2 / a b c)
  1197.   (setq a (distance p1 p2))
  1198.   (setq b (distance p p1))
  1199.   (setq c (distance p p2))
  1200.   (> (* a a) (abs (* (+ b c) (- b c))))
  1201. )
  1202.  
  1203. (defun p-t-1 (p p1 p2)
  1204.   (< 0 (caddr (trans (mapcar '- p p1) 0 (mapcar '- p2 p1))) (distance p1 p2))
  1205. )
  1206.  
  1207. (defun LINE:p-t-1 (p p1 p2 / v)
  1208.   (setq v (mapcar '- p2 p1))
  1209.   (and
  1210.     (> (Mat:dot v (mapcar '- p p1)) 0)
  1211.     (> (mat:dot v (mapcar '- p2 p)) 0)
  1212.   )
  1213. )
  1214.  
  1215. (defun Line:Angle (P0 P1 P2 / an)
  1216.   (setq an (abs (- (angle p0 P1) (angle P0 P2))))
  1217.   (if (> an pi)
  1218.     (- (+ pi pi) an)
  1219.     an
  1220.   )
  1221. )
  1222.  
  1223. (defun LINE:p-t-2 (p p1 p2 / HalfPi)
  1224.   (setq HalfPi (* pi 0.5))
  1225.   (and
  1226.     (< (Line:angle P1 P0 P2) HalfPi)
  1227.     (< (Line:angle P2 P0 P1) HalfPi)
  1228.   )
  1229. )
  1230.  
  1231.  
  1232. ;;;----------------------------------------------------;
  1233. ;;;测试用函数(benchMark function)                      ;
  1234. ;;;----------------------------------------------------;
  1235. (defun MISC:Test (Times Expressions / s)
  1236.   (defun Benchmark (Func times / TDUSRTIMER0 TDUSRTIMER1 Speed Value FName)
  1237.     (setq TDUSRTIMER0 (getvar "TDUSRTIMER"))
  1238.     (repeat times
  1239.       (setq Value (eval Func))
  1240.     )
  1241.     (setq TDUSRTIMER1 (getvar "TDUSRTIMER"))
  1242.     (setq TDUSRTIMER1 (* (- TDUSRTIMER1 TDUSRTIMER0) 86400000))
  1243.     (setq Speed (/ TDUSRTIMER1 times 1.0))
  1244.     (setq FName (vl-princ-to-string (car Func)))
  1245.     (list FName times TDUSRTIMER1 Speed Value)
  1246.   )
  1247.   (defun Princ-Column (str value / s)
  1248.     (setq s (vl-princ-to-string value))
  1249.     (princ s)
  1250.     (repeat (- (strlen str) (strlen s))
  1251.       (princ " ")
  1252.     )
  1253.   )
  1254.   (defun Print-Result (lst)
  1255.     (princ "n")
  1256.     (princ-Column "Statement                         " (car lst)) 
  1257.     (princ-Column "Times    " (cadr lst)) 
  1258.     (princ-Column "Elapse(ms)    " (caddr lst))
  1259.     (princ-Column "Average(ms/time)" (cadddr lst))
  1260.   )
  1261.  
  1262.   (foreach Func Expressions 
  1263.     (setq S (cons (BenchMark Func Times) S))
  1264.   )
  1265.  
  1266.   (princ "nStatement                         Times    Elapse(ms)    Average(ms/time)")
  1267.   (princ "n-------------------------------------------------------------------------")
  1268.   (setq s (vl-sort s (function (lambda (a b) (< (caddr a) (caddr b))))))
  1269.   (mapcar 'Print-Result s) 
  1270.   (gc)
  1271.   s
  1272. )
  1273.  
  1274. ;|*****************************************************;
  1275. ;;;以下为测试所用,大家可各取所需                       ;
  1276. ;;;*****************************************************;
  1277.  
  1278. (defun c:testPerpendicularFoot (/ p p0 normal)
  1279.   (setq p '(1 2 43))
  1280.   (setq p0 (getvar 'ucsorg))
  1281.   (setq Normal (trans '(0 0 1) 1 0 T))
  1282.   
  1283.   (misc:test 10001
  1284.     '((PLANE:Perpendicular_Foot p p0 normal)
  1285.       (PLANE:Perpendicular_Foot_2 p p0 normal)
  1286.     )
  1287.   )
  1288. )
  1289.  
  1290. ;;;测试坐标变换函数Mat:TransU2W和TransW2U
  1291. (defun C:TestTransU2W (/ x y s e d p q v)
  1292.   (initget 1)
  1293.   (setq x (getdist "nX:"))
  1294.   (initget 1)
  1295.   (setq y (getdist "nY:"))
  1296.   (initget 1)
  1297.   (setq s (ssget ":S" '((0 . "LINE"))))
  1298.   (if (and x y s)
  1299.     (progn
  1300.       (setq e (ssname s 0))
  1301.       (setq d (entget e))
  1302.       (setq p (cdr (assoc 10 d)))
  1303.       (setq q (cdr (assoc 11 d)))
  1304.       (setq v (MAT:TransU2W (list x y) p (mapcar '- q p)))
  1305.       (Ent:Make_Point V)
  1306.     )
  1307.   )
  1308. )
  1309.  
  1310. ;;;测试旋转函数GEO:Rot2d
  1311. (defun c:TestRot2d ( / pt pb an)
  1312.   (initget 1)
  1313.   (setq pt (getpoint "n要旋转的点:"))
  1314.   (initget 1)
  1315.   (setq pb (getpoint "n基点:"))
  1316.   (initget 1) 
  1317.   (setq an (getangle "n角度:"))
  1318.   (ent:make_point pt)
  1319.   (ent:make_point pb)
  1320.   (ent:make_point (GEO:Rot2d Pt Pb an))
  1321.   (princ)
  1322. )
  1323.  
  1324. ;;;测试镜像函数
  1325. (defun c:TestMirror (/ p1 p2 pt s)
  1326.   (initget 1)
  1327.   (setq p1 (getpoint "n1:"))
  1328.   (initget 1)
  1329.   (setq p2 (getpoint "n2:"))
  1330.   (initget 1) 
  1331.   (setq pt (getpoint "n要镜像的点:"))
  1332.   (grdraw p1 p2 1)
  1333.   (setq s (MiSC:Test 10000
  1334.                      '((GEO:Mirror2D pt p1 (angle p1 p2))
  1335.                        (GEO:Mirror3D Pt p1 p2)
  1336.                        (GEO:Mirror2D-1 Pt p1 p2)
  1337.                       )
  1338.           )
  1339.   )
  1340.   (mapcar 'Ent:Make_Line (list pt pt pt) (mapcar 'last s))
  1341.   (princ)
  1342. )
  1343.  
  1344. ;;;测试垂足是否在线段之间
  1345. (defun c:ppp ()
  1346.   (initget 1)
  1347.   (setq p0 (getpoint "n第一点"))
  1348.   (initget 1)
  1349.   (setq p1 (getpoint "n第二点"))
  1350.   (initget 1)
  1351.   (setq p2 (getpoint "n第三点"))
  1352.   (if (p-t p0 p1 p2)
  1353.     (princ "n亲,在!!!")
  1354.     (princ "n亲,不在哦!!!!!")
  1355.   )
  1356.   (if (LINE:P-t p0 p1 p2)
  1357.     (princ "n亲,在!!!")
  1358.     (princ "n亲,不在哦!!!!!")
  1359.   )
  1360.   (if (LINE:P-t-2 p0 p1 p2)
  1361.     (princ "n亲,在!!!")
  1362.     (princ "n亲,不在哦!!!!!")
  1363.   )
  1364.   (misc:test
  1365.     100000
  1366.     '((LINE:P-t p0 p1 p2)
  1367.       (LINE:P-t-1 p0 p1 p2)
  1368.       (LINE:P-t-2 p0 p1 p2)
  1369.       (p-t p0 p1 p2)
  1370.       (p-t-1 p0 p1 p2)
  1371.      )
  1372.   )
  1373.   (princ)
  1374. )
  1375.  
  1376. ;;;测试垂足和垂距函数
  1377. (defun C:LPF(/ p1 p2 pt f a b c s)
  1378.   (initget 1)
  1379.   (setq p1 (getpoint "n直线端点1:"))
  1380.   (initget 1)
  1381.   (setq p2 (getpoint "n直线端点2:"))
  1382.   (initget 1)
  1383.   (setq pt (getpoint "n要求的点p:"))
  1384.  
  1385.   (setq f (LINE:Equation p1 p2))
  1386.   (setq A (car f))
  1387.   (setq B (cadr f))
  1388.   (setq C (caddr f))
  1389.  
  1390.   (setq S (MISC:Test 10000 
  1391.                 '((LINE:Perpendicular_Foot pt p1 p2)
  1392.                   (LINE:Perpendicular_Foot_1 pt p1 p2)
  1393.                   (LINE:Perpendicular_Foot_2 pt p1 p2)
  1394.                   (LINE:Perpendicular_Foot_3 pt p1 p2)
  1395.                  )
  1396.           )
  1397.   )
  1398.  
  1399.   (grdraw p1 p2 1)
  1400.   (Ent:Make_Point pt)
  1401.   (Ent:MakePoint-1 (cadr (last (car  s))) 1)
  1402.   (Ent:MakePoint-1 (last (cadr s)) 2)
  1403.   (Ent:MakePoint-1 (last (caddr s)) 3)
  1404.   (Ent:MakePoint-1 (last (cadddr s)) 4)
  1405.   
  1406.   (setq S (MISC:Test 10000
  1407.                 '((LINE:Perpendicular_Foot pt p1 p2)
  1408.                   (LINE:Perpendicular_Distance_1 pt A B C)
  1409.                   (LINE:Perpendicular_Distance_2 pt P1 p2)
  1410.                   (LINE:Perpendicular_Distance_3 Pt P1 P2)
  1411.                   (MAT:TransW2U pt P1 (mapcar '- p2 p1)))
  1412.           )
  1413.   )
  1414.                         
  1415.   (princ (mapcar 'last s))
  1416.   (princ)
  1417. )
  1418.  
  1419. ;;;测试线段相交函数
  1420. (defun C:Inters (/ p1 p2 p3 p4 s)
  1421.   (initget 1)
  1422.   (setq p1 (getpoint "n1:"))
  1423.   (initget 1)
  1424.   (setq p2 (getpoint p1 "n2:"))
  1425.   (initget 1)
  1426.   (setq p3 (getpoint "n3:"))
  1427.   (initget 1)
  1428.   (setq p4 (getpoint p3 "n4:"))
  1429.  
  1430.   (grdraw p1 p2 1)
  1431.   (grdraw p3 p4 2)
  1432.   (setq s (MISC:Test 100000
  1433.                      '((LINE:Intersection p1 p2 p3 p4)
  1434.                        (inters p1 p2 p3 p4 nil)
  1435.                       )
  1436.           )
  1437.   )
  1438.   (foreach p (mapcar 'last s)
  1439.     (Ent:make_Point p)
  1440.   )
  1441. )
  1442.  
  1443. ;;;测试角平分线函数
  1444. (defun c:pf(/ e1 e2 d1 d2 p1 p2 p3 p4 ret)
  1445.   (setq e1 (car (entsel "n直线1:")))
  1446.   (setq e2 (car (entsel "n直线2:")))
  1447.   (setq d1 (entget e1))
  1448.   (setq d2 (entget e2))
  1449.   (setq p1 (cdr (assoc 10 d1)))
  1450.   (setq p2 (cdr (assoc 11 d1)))
  1451.   (setq p3 (cdr (assoc 10 d2)))
  1452.   (setq p4 (cdr (assoc 11 d2)))
  1453.   (setq ret (LINE:Angular_Bisector p1 p2 p3 p4))
  1454.   (foreach n ret
  1455.     (apply 'Ent:Make_line n)
  1456.   )
  1457. )
  1458.  
  1459. ;;;测试偏移两点函数LINE:Offset
  1460. (defun C:LineOffset (/ p1 p2 d)
  1461.   (initget 1)
  1462.   (setq p1 (getpoint "n1:"))
  1463.   (initget 1)
  1464.   (setq p2 (getpoint p1 "n2:"))
  1465.   (initget 1)
  1466.   (setq d (getdist p1 "n偏移距离:"))
  1467.   (Ent:make_line p1 p2)
  1468.   (apply 'Ent:make_line (LINE:Offset p1 p2 d))
  1469.   (princ)
  1470. )
  1471.  
  1472. ;;;测试共线检测函数LINE:Colinearity,LINE:Colinearity_1
  1473. (defun C:Colinearity (/ p1 p2 p3)
  1474.   (setq eps 1e-6)
  1475.   (setq p1 (getpoint "n1:"))
  1476.   (setq p2 (getpoint "n2:"))
  1477.   (setq p3 (getpoint "n3:"))
  1478.   (MISC:Test 100000
  1479.              '((LINE:Colinearity p1 p2 p3)
  1480.                (LINE:Colinearity3D p1 p2 p3)
  1481.               )
  1482.   )
  1483.   (princ)
  1484. )
  1485.  
  1486. ;;;平面部分测试函数
  1487. (defun c:PlaneTest(/ pa pb p1 p2 p3 d1 d2 arg)
  1488.   (initget 1)
  1489.   (setq pa (getpoint "npa:"))
  1490.   (setq pa (trans pa 1 0))
  1491.   (initget 1)
  1492.   (setq pb (getpoint "npb:"))
  1493.   (setq pb (trans pb 1 0))
  1494.   
  1495.   (initget 1)
  1496.   (setq p1 (getpoint "n1:"))
  1497.   (setq p1 (trans p1 1 0))
  1498.   (initget 1)
  1499.   (setq p2 (getpoint "n2:"))
  1500.   (setq p2 (trans p2 1 0))
  1501.   (initget 1)
  1502.  
  1503.   (setq p3 (getpoint "n3:"))
  1504.   (setq p3 (trans p3 1 0))
  1505.   
  1506.   (mapcar 'Ent:make_Point (list pa pb p1 p2 p3))
  1507.   
  1508.   (princ (PLANE:Distance_1 Pa p1 p2 p3))
  1509.   
  1510.   (setq d1 (PLANE:Perpendicular_Foot Pa p1 p2 p3))
  1511.   (setq d2 (PLANE:Perpendicular_Foot Pb p1 p2 p3))
  1512.   (setq arg (cons pa (cons Pb (PLANE:Equation_3P p1 p2 p3))))
  1513.   (setq ret (apply 'PLANE:Line_Inters_Plane arg))
  1514.   (Ent:make_Point (cadr d1))
  1515.   (Ent:make_Point (cadr d2))
  1516.   (Ent:make_Point ret)
  1517.   (princ (LINE:Distance_LineToLine pa pb p1 p2))
  1518.   (princ)
  1519. )
  1520.  
  1521. ;;;三线坐标系统测试
  1522. (defun C:InfoBy3Sides (/ p1 p2 p3 a b c ret)
  1523.   (initget 1)
  1524.   (setq p1 (getpoint "n1:"))
  1525.   (initget 1)
  1526.   (setq p2 (getpoint "n2:"))
  1527.   (initget 1)
  1528.   (setq p3 (getpoint "n3:"))
  1529.   (setq p1 (trans p1 1 0))
  1530.   (setq p2 (trans p2 1 0))
  1531.   (setq p3 (trans p3 1 0))
  1532.   (setq a  (distance p2 p3))
  1533.   (setq b  (distance p3 p1))
  1534.   (setq c  (distance p1 p2))
  1535.   (Ent:make_Poly (list p1 p2 p3))
  1536.   (setq ret (TRI:InfoBy3Sides a b c))
  1537.   (princ ret)
  1538.   (foreach n (cddr ret)
  1539.     (setq p (TRI:TCS->WCS (car n) p1 p2 p3))
  1540.     (Ent:make_Point p)
  1541.     (if (setq r (cadr n))
  1542.       (Ent:make_Circle p r)
  1543.     )
  1544.   )
  1545.   (princ)
  1546. )
  1547.  
  1548. ;;;Test for "POLY:Info_LWPoly" "Geo:Centroid" "POLY:Area" "POLY:Perimeter" "POLY:Infomation"
  1549. ;;;为段线的质心和面积的测试
  1550. (defun C:CentroidTest (/ sel ent en1 dxf pts cen aaa len ret i)
  1551.   (setq i -1)
  1552.   (setq sel (ssget '((0 . "*POLYLINE"))))
  1553.   (if sel
  1554.     (repeat (sslength sel)
  1555.       (setq ent (ssname sel (setq i (1+ i))))
  1556.       (setq obj (vlax-ename->vla-object ent))
  1557.       (setq dxf (entget ent))
  1558.       (if (= (cdr (assoc 0 DXF)) "POLYLINE")
  1559.         (setq pts (MISC:List->PtList (vlax-get obj 'coordinates) 3)
  1560.               Cen (GEO:Centroid pts)
  1561.               aaa (POLY:Area pts)
  1562.               len (POLY:Perimeter pts)
  1563.               ret (POLY:Infomation pts)
  1564.               en1 (Ent:MakePoint-1 Cen 2)       
  1565.         )
  1566.         (setq ret (POLY:Info_LWPoly ent)
  1567.               aaa (vla-get-area obj)
  1568.         )
  1569.       )
  1570.       (setq cen (car ret))
  1571.       (setq len (vla-get-length obj))
  1572.       (Ent:MakePoint-1 cen 1)
  1573.       (princ (strcat "n第" (itoa i) "个物体信息: "))
  1574.       (princ (list ret Cen aaa len))
  1575.       (princ)
  1576.     )
  1577.   )
  1578. )
  1579.  
  1580. ;;;弧段的质心和面积的测试
  1581. (defun C:TestArcCentroid (/ A1 A2 C R E1 I O1 O2 O3 O4 P1 P2 S1 S2 SS V3 V4)
  1582.   (setq i -1)
  1583.   (if (setq ss (ssget '((0 . "ARC"))))
  1584.     (repeat (sslength ss)
  1585.       (setq e1 (ssname ss (setq i (1+ i))))
  1586.       (setq o1 (vlax-ename->vla-object e1))
  1587.  
  1588.       (setq C (vlax-get o1 'Center))
  1589.       (setq R (vla-get-radius o1))
  1590.       (setq A1 (vla-get-startangle o1))
  1591.       (setq A2 (vla-get-endangle o1))
  1592.  
  1593.       (setq V3 (CIR:Circular_Segment C R A1 A2 nil))    ;圆弧总是逆时针的
  1594.       (setq V4 (CIR:Circular_Sector C R A1 A2 nil))     ;圆弧总是逆时针的
  1595.  
  1596.       (setq p1 (vlax-curve-getstartpoint e1))           ;弧起点
  1597.       (setq p2 (vlax-curve-getendPoint e1))             ;弧终点
  1598.       (setq s1 (ssadd e1))
  1599.       (setq s1 (ssadd (Ent:Make_Line p1 p2) S1))
  1600.  
  1601.       (setq o2 (vla-copy o1))                           ;拷贝圆弧用来测试扇形
  1602.       (setq s2 (ssadd (vlax-vla-object->ename o2)))
  1603.       (setq s2 (ssadd (Ent:Make_Line p1 C) s2))
  1604.       (setq s2 (ssadd (Ent:Make_Line p2 C) s2))
  1605.  
  1606.       (command "region" s1 "")                          ;弓形计算与建模做比较
  1607.       (setq o3 (vlax-ename->vla-object (entlast)))
  1608.       (command "region" s2 "")                          ;扇形计算与建模做比较
  1609.       (setq o4 (vlax-ename->vla-object (entlast)))
  1610.  
  1611.       (Ent:MakePoint-1 (car V3) 1)                      ;计算出来的弓形质心
  1612.       (Ent:MakePoint-1 (car V4) 2)                      ;计算出来的扇形质心
  1613.       (Ent:MakePoint-1 (vlax-get o3 'centroid) 3)       ;弓形建模的质心
  1614.       (Ent:MakePoint-1 (vlax-get o4 'centroid) 4)       ;扇形建模的质心
  1615.  
  1616.       (princ (list V3 (vla-get-area O3) (vla-get-perimeter O3)))
  1617.       (princ (list V4 (vla-get-area O4) (vla-get-perimeter O4)))
  1618.       (princ)
  1619.     )
  1620.   )
  1621. )
  1622. ;;;测试3点的行列式
  1623. (defun c:ttt()
  1624.   (initget 1)
  1625.   (setq p1 (getpoint "n1:"))
  1626.   (initget 1)
  1627.   (setq p2 (getpoint p1 "n2:"))
  1628.   (initget 1)
  1629.   (setq p3 (getpoint "n3:"))
  1630.  
  1631.   (setq s (MISC:Test 100000
  1632.                      '((TRI:Det3p p1 p2 p3))
  1633.           )
  1634.   )
  1635.   (princ (mapcar 'last s))
  1636.   (princ)
  1637. ) 
  1638. ;;;获取截面的质心
  1639. (defun C:GetRegionCentroid (/ sel ent obj i)
  1640.   (setq i -1)
  1641.   (if (setq sel (ssget '((0 . "REGION"))))
  1642.     (repeat (sslength sel)
  1643.       (setq ent (ssname sel (setq i (1+ i))))
  1644.       (setq obj (vlax-ename->vla-object ent))
  1645.       (Ent:MakePoint-1 (vlax-get obj 'Centroid) 3)
  1646.     )
  1647.   )
  1648. )
  1649. ;|;

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注