明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 21195|回复: 63

【越飞越高讲堂17】论点、线、面、三角形及多边形

    [复制链接]
发表于 2013-1-12 15:08:16 | 显示全部楼层 |阅读模式
点、线、面、三角形和多边形

这里我整理和编写了一些关于几何算法上的一些LISP程序。
一些程序出于研究的目的,有可能代码不是最简洁的,但是执行效率高。
虽然经过了很多次测试,但未能保证完全正确。所以有什么错误或者bug请大家多多指教。
并贴上附件包含本主题所有源代码,和一些测试代码。
其内容已经同步到http://highflybird.mjtd.com上。
申明:如需转载,请注明作者和来源地址!
另:如果有些函数不能在附件或者此贴中找到,请移步:
http://bbs.mjtd.com/thread-99926-1-1.html
一、点
1.  比例缩放点
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 比例缩放点                                    ;
  3. ;;;输入: 要缩放的点pt,基点pBase,缩放因子k             ;
  4. ;;;输出: 缩放后的点位置                                ;
  5. ;;;----------------------------------------------------;
  6. (defun GEO:Scale (Pt pBase k)
  7.   (mapcar (function (lambda (u v) (+ u (* k (- v u))))) pBase Pt)
  8. )

  9. ;;;----------------------------------------------------;
  10. ;;;功能: 比例缩放点2倍                                 ;
  11. ;;;输入: 要缩放的点pt,基点pBase                        ;
  12. ;;;输出: 缩放后的点位置                                ;
  13. ;;;----------------------------------------------------;
  14. (defun GEO:Scale2 (Pt pBase)
  15.   (mapcar (function (lambda (u v) (+ v (- v u)))) pBase Pt)
  16. )


2、定比点
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 两点之中点                                    ;
  3. ;;;输入: 两点p1,P2                                     ;
  4. ;;;输出: 中点位置                                      ;
  5. ;;;----------------------------------------------------;
  6. (defun GEO:Midpoint (p1 p2)
  7.   (mapcar (function (lambda (e1 e2) (* (+ e1 e2) 0.5))) p1 p2)
  8. )

  9. ;;;----------------------------------------------------;
  10. ;;;功能: 定比点P,使得P1P / PP2 = k (此函数于三维)    ;
  11. ;;;输入: 两点p1,P2和比例系数k                          ;
  12. ;;;输出: 定比点位置                                    ;
  13. ;;;----------------------------------------------------;
  14. (defun GEO:Proportion (p1 p2 k)
  15.   (if (/= k -1)
  16.     (mapcar (function (lambda (x1 x2) (/ (+ x1 (* k x2)) (+ 1.0 k)))) p1 p2)
  17.   )
  18. )


3、点的旋转和镜像
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 两点法旋转某个点90度                          ;
  3. ;;;输入: 基点,矢量的第一点P1,第二点P1                ;
  4. ;;;输出: 旋转90度后点位置                              ;
  5. ;;;----------------------------------------------------;
  6. (defun GEO:Rot90 (ptBase P1 P2)
  7.   (mapcar '+ ptBase (MAT:Rot90 (mapcar '- p2 p1)))
  8. )

  9. ;;;----------------------------------------------------;
  10. ;;;功能: 以基点旋转一点到指定的角度                    ;
  11. ;;;输入: 要旋转的点Pt,基点和旋转角度                  ;
  12. ;;;输出: 旋转后点位置                                  ;
  13. ;;;----------------------------------------------------;
  14. (defun GEO:Rot2D (Pt PtBase Ang)  
  15.   (mapcar '+ PtBase (MAT:Rot2D (mapcar '- Pt PtBase) Ang))
  16. )

  17. ;;;----------------------------------------------------;
  18. ;;;功能: 以基点和角度镜像某点                          ;
  19. ;;;输入: 要镜像的点Pt,基点和镜像轴角度                ;
  20. ;;;输出: 镜像点位置                                    ;
  21. ;;;说明: 只适用与二维情况下,但速度最快                ;
  22. ;;;----------------------------------------------------;
  23. (defun GEO:Mirror2D (Pt pBase Ang)
  24.   (polar pBase (+ ang (- ang (angle pbase pt))) (distance pt pBase))
  25. )

  26. ;;;----------------------------------------------------;
  27. ;;;功能: 镜像点(可以用于3D情况)                      ;
  28. ;;;输入: 要镜像的点Pt,镜像轴第一点和第二点            ;
  29. ;;;输出: 镜像点位置                                    ;
  30. ;;;说明: 可以适用于三维情况                            ;
  31. ;;;----------------------------------------------------;
  32. (defun GEO:Mirror3D (Pt P1 P2 / v1 v2 dd P3 P4)
  33.   (if (equal P1 P2 1e-8)
  34.     (GEO:Scale2 P1 Pt)
  35.     (setq v1 (mapcar '- Pt P1)
  36.           v2 (mapcar '- P2 P1)
  37.           dd (MAT:Dot v2 v2)
  38.           P3 (GEO:Scale P2 P1 (/ (MAT:Dot v1 v2) dd))
  39.           P4 (GEO:Scale2 P3 Pt)
  40.     )   
  41.   )
  42. )

  43. ;;;----------------------------------------------------;
  44. ;;;功能: 镜像点(另一方法,相当于用 Mirror命令的结果) ;
  45. ;;;输入: 要镜像的点Pt,镜像轴第一点和第二点            ;
  46. ;;;输出: 镜像点位置                                    ;
  47. ;;;----------------------------------------------------;
  48. (defun GEO:Mirror2D-1 (Pt P1 P2 / v p)
  49.   (setq v (mapcar '- p2 p1))
  50.   (setq p (trans (mapcar '- Pt P1) 0 v))
  51.   (setq p (list (- (car p)) (cadr p) (caddr p)))
  52.   (mapcar '+ P1 (trans p v 0))
  53. )


4、点集的质心
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 计算有限点集的质心                            ;
  3. ;;;输入: 有限个点集  Pts                               ;
  4. ;;;输出: 质心坐标,用点表表示                          ;
  5. ;;;----------------------------------------------------;
  6. (defun GEO:Centroid (Pts / )
  7.   (MAT:vxs (apply 'mapcar (cons '+ pts)) (/ 1.0 (length pts)))
  8. )


5、有关点集的其他几何算法:
   a.点集的凸包
     http://bbs.mjtd.com/forum.php?mod=viewthread&tid=56069
   b.点集的最小包围圆
     http://bbs.mjtd.com/forum.php?mod=viewthread&tid=55997
   c.点集的最小包围盒和直径
     http://bbs.mjtd.com/forum.php?mod=viewthread&tid=81308
   d.点集的最小距离点对
     http://bbs.mjtd.com/forum.php?mod=viewthread&tid=56310
   e.点集的三角网构建
     http://bbs.mjtd.com/thread-82644-2-1.html
   f.容差范围内的点集
     http://www.theswamp.org/index.php?topic=32874.60

二、线
1、直线方程

  1. ;;;----------------------------------------------------;
  2. ;;;直线的方程                                          ;
  3. ;;;Coefficient Equation                                ;
  4. ;;;参数: 两点                                          ;
  5. ;;;返回: 直线的方程Ax+By+C=0 的三个系数A,B,C           ;
  6. ;;;----------------------------------------------------;
  7. (defun LINE:Equation (p1 p2)
  8.   (list
  9.     (- (cadr p1) (cadr p2))
  10.     (- (car  p2) (car  p1))
  11.     (- (* (car p1) (cadr p2)) (* (cadr p1) (car p2)))
  12.   )
  13. )

  14. ;;;----------------------------------------------------;
  15. ;;;直线的方程1                                         ;
  16. ;;;点矢量式方程  P0+k*Vector                           ;
  17. ;;;参数: 两点                                          ;
  18. ;;;返回: 直线的方程用一点和直线的方向矢量表达          ;
  19. ;;;----------------------------------------------------;
  20. (defun LINE:Equation_1 (p0 p1)        
  21.   (list P0 (mapcar '- p1 p0))
  22. )


2、直线偏移
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 偏移一条线段                                  ;
  3. ;;;输入: 两点和一个距离(负数代表直线段的下方)        ;
  4. ;;;输出: 偏移后的两点                                  ;
  5. ;;;----------------------------------------------------;
  6. (defun LINE:Offset (p1 p2 d / v L)
  7.   (setq v (mapcar '- p2 p1))
  8.   (setq L (distance p1 p2))
  9.   (setq v (Mat:vxs (Mat:Rot90 v) (/ d L)))
  10.   (list (mapcar '+ p1 v) (mapcar '+ p2 v))
  11. )


3、点到直线的距离和垂足
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 点Pt到直线P1P2的距离(带方向)                ;
  3. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  4. ;;;输出: 带符号的距离,为正P1,P2,Pt逆时针,否则顺时针  ;
  5. ;;;----------------------------------------------------;
  6. (defun LINE:Perpendicular_Distance (pt p1 p2 / A B C)
  7.   (setq A (- (cadr p1) (cadr p2)))
  8.   (setq B (- (car  p2) (car  p1)))
  9.   (setq C (- (* (car p1) (cadr p2)) (* (cadr p1) (car p2))))
  10.   (if (not (and (= A 0) (= b 0)))
  11.     (/ (+ (* A (car pt)) (* B (cadr pt)) C)
  12.        (sqrt (+ (* A A) (* B B)))
  13.     )
  14.   )
  15. )

  16. ;;;----------------------------------------------------;
  17. ;;;功能: 已知直线方程系数求点到直线的距离(带方向)    ;
  18. ;;;输入: 要求的点Pt,和直线方程的三个系数              ;
  19. ;;;输出: 带符号的距离,为正Pt在直线方向的上方,负则反之;
  20. ;;;----------------------------------------------------;
  21. (defun LINE:Perpendicular_Distance_1 (Pt A B C / AA BB AB k x0 y0 x y D)
  22.   (if (not (and (= a 0) (= b 0)))
  23.     (progn
  24.       (setq AA (* A A))
  25.       (setq BB (* B B))
  26.       (setq AB (* A B))
  27.       (setq k  (+ AA BB))
  28.       (setq x0 (car pt))
  29.       (setq y0 (cadr pt))

  30.       (setq x  (/ (- (* BB x0) (* AB y0) (* A C)) k))
  31.       (setq y  (/ (- (* AA y0) (* AB x0) (* B C)) k))
  32.       (setq D  (/ (+ (* A x0) (* B y0) C) (sqrt k)))
  33.       (list D (list x y))
  34.     )
  35.   )
  36. )

  37. ;;;----------------------------------------------------;
  38. ;;;功能: 点到直线的距离(带方向)                      ;
  39. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  40. ;;;输出: 带符号的距离,为正P1,P2,Pt逆时针,否则顺时针  ;
  41. ;;;----------------------------------------------------;
  42. (defun LINE:Perpendicular_Distance_2 (pt p1 p2 / )
  43.   (car (trans (mapcar '- pt p1) 0 (mapcar '- p2 p1)))
  44. )

  45. ;;;----------------------------------------------------;
  46. ;;;功能: 点到直线的距离(适合三维情况)                ;
  47. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  48. ;;;输出: 所求距离                                      ;
  49. ;;;----------------------------------------------------;
  50. (defun LINE:Perpendicular_Distance_3 (p0 p1 p2 / v0 v1)
  51.   (setq v0 (mapcar '- P0 p1))
  52.   (setq v1 (mapcar '- p2 p1))
  53.   (/ (MAT:Norm3D (MAT:vxv v0 v1)) (MAT:Norm3D v1))
  54. )

  55. ;;;----------------------------------------------------;
  56. ;;;功能: 点到直线的距离和垂足                          ;
  57. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  58. ;;;输出: 所求距离和垂足                                ;
  59. ;;;----------------------------------------------------;
  60. (defun LINE:Perpendicular_Foot (pt p1 p2 / d)
  61.   (setq d (LINE:Perpendicular_Distance pt p1 p2))
  62.   (list d (polar pt (- (angle p1 p2) (/ pi 2)) d))
  63. )

  64. ;;;----------------------------------------------------;
  65. ;;;功能: 点到直线的垂足                                ;
  66. ;;;输入: 要求的点Pt,和直线的两个端点P1,P2             ;
  67. ;;;输出: 所求的垂足                                    ;
  68. ;;;----------------------------------------------------;
  69. (defun LINE:Perpendicular_Foot_1 (pt p1 p2)
  70.   (inters pt (mapcar '+ pt (MAT:Rot90 (mapcar '- p1 p2))) p1 p2 nil)
  71. )


4.空间两直线的距离
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 求空间两直线的最短距离                        ;
  3. ;;;输入: 两条直线的四个端点P1,P2,P3,P4                 ;
  4. ;;;输出: 所求距离                                      ;
  5. ;;;----------------------------------------------------;
  6. (defun LINE:Distance_LineToLine (P1 P2 P3 P4 / v1 v2 v3)
  7.   (setq v1 (mapcar '- p2 p1))
  8.   (setq v2 (mapcar '- p4 p3))
  9.   (setq v3 (MAT:vxv v1 v2))
  10.   (/ (Mat:Dot (mapcar '- P1 P3) v3) (Mat:Norm3D v3))
  11. )


5.我的直线求交
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 两条直线求交点函数(跟inters函数稍微有区别)    ;
  3. ;;;输入: 两条直线的四个端点P1,P2,P3,P4                 ;
  4. ;;;输出: nil 说明这两条平行或者共线,否则返回交点      ;
  5. ;;;----------------------------------------------------;
  6. (defun LINE:Intersection (p1 p2 p3 p4 / DA DB DD X1 X2 X3 X4 Y1 Y2 Y3 Y4)
  7.   (setq x1 (car  p1)
  8.         x2 (car  p2)
  9.         x3 (car  p3)
  10.         x4 (car  p4)
  11.         y1 (cadr p1)
  12.         y2 (cadr p2)
  13.         y3 (cadr p3)
  14.         y4 (cadr p4)
  15.   )
  16.   (setq dd (- (* (- x1 x2) (- y3 y4)) (* (- x3 x4) (- y1 y2))))
  17.   (setq da (- (* x1 y2) (* y1 x2)))
  18.   (setq db (- (* x3 y4) (* y3 x4)))
  19.   (if (not (equal dd 0 1e-8))
  20.     (list (/ (- (* da (- x3 x4)) (* db (- x1 x2))) dd)
  21.           (/ (- (* da (- y3 y4)) (* db (- y1 y2))) dd)
  22.     )
  23.   )
  24. )

6.有关直线的一些判断
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 判断平面上的三点是否共线                      ;
  3. ;;;输入: 三点 P1,P2,P3                                 ;
  4. ;;;输出: T 说明三点共线,否则不共线                    ;
  5. ;;;----------------------------------------------------;
  6. (defun LINE:Colinearity (p1 p2 p3 / a b c eps)
  7.   (setq eps 1e-6)
  8.   (setq a (distance p2 p3))
  9.   (setq b (distance p3 p1))
  10.   (setq c (distance p1 p2))
  11.   (or (equal (+ a b) c eps)
  12.       (equal (+ b c) a eps)
  13.       (equal (+ c a) b eps)
  14.   )
  15. )

  16. ;;;----------------------------------------------------;
  17. ;;;功能: 判断空间上三点是否共线(跟上面的方法效率差不多);
  18. ;;;输入: 三点 P1,P2,P3                                 ;
  19. ;;;输出: T 说明三点共线,否则不共线                    ;
  20. ;;;----------------------------------------------------;
  21. (defun LINE:Colinearity3D (p1 p2 p3 / a1 a2)
  22.   (equal (TRI:Det3P p1 p2 p3) 0 1e-8)
  23. )

  24. ;;;----------------------------------------------------;
  25. ;;;功能: 判断两点是否在一条直线的同一侧                ;
  26. ;;;输入: 要判断的两点点P1,P2和直线的两个端点Pa,Pb      ;
  27. ;;;输出: T 说明同侧,nil异侧                           ;
  28. ;;;----------------------------------------------------;
  29. (defun LINE:IsSameSide (P1 P2 Pa Pb / d1 d2 eps)
  30.   (setq eps 1e-6)
  31.   (setq d1 (TRI:Det3P P1 PA PB))
  32.   (setq d2 (TRI:Det3P P2 PA PB))
  33.   (or (and (<= d1 eps) (<= d2 eps))
  34.       (and (>= d1 (- eps)) (>= d2 (- eps)))
  35.   )
  36. )


三、面和空间
1.平面方程
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 点法线的平面方程                              ;
  3. ;;;输入: P0平面上的一点,N平面的法线矢量               ;
  4. ;;;输出: 平面方程的系数列表                            ;
  5. ;;;----------------------------------------------------;
  6. (defun PLANE:Equation (P0 N)
  7.   (append N (list (- (MAT:Dot P0 N))))
  8. )

  9. ;;;----------------------------------------------------;
  10. ;;;功能: 三点式平面方程                                ;
  11. ;;;输入: 平面上的三点                                  ;
  12. ;;;输出: 平面方程的系数列表                            ;
  13. ;;;----------------------------------------------------;
  14. (defun PLANE:Equation_3P (P0 P1 P2 / v1 v2 N)
  15.   (setq v1 (mapcar '- p1 p0))
  16.   (setq v2 (mapcar '- P2 p0))
  17.   (setq N  (MAT:vxv v1 v2))
  18.   (PLANE:Equation P0 N)
  19. )


2.点到平面的距离
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 点到平面的距离(有向的距离)                  ;
  3. ;;;输入: 一点P和平面的方程为Ax+By+Cz+D=0的四个系数     ;
  4. ;;;输出: 该点到平面的距离                              ;
  5. ;;;----------------------------------------------------;
  6. (defun PLANE:Distance (P A B C D)
  7.   (if (and (zerop A) (zerop B) (zerop C))
  8.     nil
  9.     (/ (+ (* A (car P)) (* B (cadr P)) (* C (caddr P)) D)
  10.        (distance '(0 0 0) (list A B C))
  11.     )
  12.   )
  13. )

  14. ;;;----------------------------------------------------;
  15. ;;;功能: 点到三点决定的平面的距离(有向的距离)        ;
  16. ;;;输入: 一点P和平面的方程为Ax+By+Cz+D=0的四个系数     ;
  17. ;;;输出: 该点到平面的距离                              ;
  18. ;;;----------------------------------------------------;
  19. (defun PLANE:Distance_1 (P p1 p2 p3 /)
  20.   (Apply 'PLANE:Distance (cons p (PLANE:Equation_3P p1 p2 p3)))
  21. )

  22. ;;;----------------------------------------------------;
  23. ;;;功能: 点到三点决定的平面的距离和该点在平面上的投影点;
  24. ;;;输入: 一点P和三点P1,P2,P3决定的平面                 ;
  25. ;;;输出: 该点到平面的距离                              ;
  26. ;;;----------------------------------------------------;
  27. (defun PLANE:Perpendicular_Foot (P p1 p2 p3 / F A B C D H N L)
  28.   (setq F (PLANE:Equation_3P p1 p2 p3))
  29.   (setq        A (car f)
  30.         B (cadr f)
  31.         C (caddr f)
  32.         D (last f)
  33.   )
  34.   (setq H (PLANE:Distance p A B C D))
  35.   (setq N (List A B C))
  36.   (setq L (distance '(0 0 0) N))
  37.   (if (not (zerop L))
  38.     (list H (Geo:scale (mapcar '+ p N) P (- (/ H L))))
  39.   )
  40. )


3.空间直线与平面的交点
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 求空间直线与平面的交点                        ;
  3. ;;;输入: 决定直线的两点Pa,Pb和三点P1,P2,P3决定的平面   ;
  4. ;;;输出: 该点到平面的距离                              ;
  5. ;;;----------------------------------------------------;
  6. (defun PLANE:Line_Inters_Plane (Pa Pb A B C D / h1 h2)
  7.   (setq h1 (Plane:Distance Pa A b c d))
  8.   (setq h2 (plane:distance Pb a b c d))
  9.   (if (and h1 h2)
  10.     (cond
  11.       ( (equal h1 0 1e-14) Pa)
  12.       ( (equal h2 0 1e-14) Pb)
  13.       (t (GEO:Proportion Pa Pb (- (/ h1 h2))))
  14.     )
  15.   )
  16. )


四、三角形

1.根据边长判断是否构成三角形
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 判断是否构成三角形                            ;
  3. ;;;输入: 三边的长度a,b,c                               ;
  4. ;;;输出: 构成三角形则返回T,否则返回nil                ;
  5. ;;;----------------------------------------------------;
  6. (defun TRI:IsTriangle (a b c /)
  7.   (and (> (+ a b) c) (> (+ b c) a) (> (+ c a) b))
  8. )


2.三角形的外心,内心,重心,垂心,九点圆圆心
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 求三角形外心   TRI:CircumCenter,ExCenter     ;
  3. ;;;输入: 给定不共线的三个点                            ;
  4. ;;;输出: 这三点的外接圆的圆心和半径                    ;
  5. ;;;说明: 尽管这样写很麻烦,显得代码很多,但运行却很快  ;
  6. ;;;----------------------------------------------------;
  7. (defun TRI:CircumCenter (P0 P1 P2 / X0 Y0 X1 Y1 X2 Y2 DX1 DY1 DX2 DY2 D 2D C1 C2 CE)
  8.   (setq        X0  (car  P0)
  9.         Y0  (cadr P0)
  10.         X1  (car  P1)
  11.         Y1  (cadr P1)
  12.         X2  (car  P2)
  13.         Y2  (cadr P2)
  14.         DX1 (- X1 X0)
  15.         DY1 (- Y1 Y0)
  16.         DX2 (- X2 X0)
  17.         DY2 (- Y2 Y0)
  18.   )
  19.   (setq D (- (* DX1 DY2) (* DX2 DY1)))
  20.   (if (equal D 0 1e-14)
  21.     nil
  22.     (progn
  23.       (setq 2D (+ D D)
  24.             C1 (+ (* DX1 (+ X0 X1)) (* DY1 (+ Y0 Y1)))
  25.             C2 (+ (* DX2 (+ X0 X2)) (* DY2 (+ Y0 Y2)))
  26.             CE (List (/ (- (* C1 DY2) (* C2 DY1)) 2D)
  27.                      (/ (- (* C2 DX1) (* C1 DX2)) 2D)
  28.                )
  29.       )
  30.       (list CE (distance CE P0))
  31.     )
  32.   )
  33. )

  34. ;;;----------------------------------------------------;
  35. ;;;功能: 三角形内心                                    ;
  36. ;;;公式: (aX1+bx2+cx3)/(a+b+c),(aY2+bY2+CY3)/(a+b+c)   ;
  37. ;;;输入: 给定不共线的三个点                            ;
  38. ;;;输出: 这三点的内切圆的圆心和半径                    ;
  39. ;;;----------------------------------------------------;
  40. (defun TRI:InCenter (pa pb pc / a b c L I r)
  41.   (setq a (distance pb pc))
  42.   (setq b (distance pc pa))
  43.   (setq c (distance pa pb))
  44.   (setq L (+ a b c))
  45.   (if (/= L 0.0)
  46.     (setq I (MAT:SxVs (list pa pb pc) (list (/ a L) (/ b L) (/ c L)))
  47.           R (list I (abs (LINE:Perpendicular_Distance I pa pb)))
  48.     )
  49.     (list pa 0)
  50.   )
  51. )

  52. ;;;----------------------------------------------------;
  53. ;;;功能: 三角形垂心                                    ;
  54. ;;;输入: 给定不共线的三个点                            ;
  55. ;;;输出: 这个三点形成的三角形的垂心                    ;
  56. ;;;----------------------------------------------------;
  57. (defun TRI:OrthoCenter (pa pb pc / p1 p2)
  58.   (setq p1 (GEO:Rot90 Pa pb pc))
  59.   (setq p2 (GEO:Rot90 pb pc pa))
  60.   (inters pa p1 pb p2 nil)
  61. )

  62. ;;;----------------------------------------------------;
  63. ;;;功能: 三角形重心                                    ;
  64. ;;;输入: 给定不共线的三个点                            ;
  65. ;;;输出: 这个三点形成的三角形的重心                    ;
  66. ;;;----------------------------------------------------;
  67. (defun TRI:Barycenter (p1 p2 p3)
  68.   (mapcar (function (lambda (e1 e2 e3) (/ (+ e1 e2 e3) 3.0))) p1 p2 p3)
  69. )

  70. ;;;----------------------------------------------------;
  71. ;;;功能: 三角形的九点圆                                ;
  72. ;;;输入: 给定不共线的三个点                            ;
  73. ;;;输出: 这个三点形成的三角形的九点圆的圆心和半径      ;
  74. ;;;----------------------------------------------------;
  75. (defun TRI:9P_Circle (pa pb pc)
  76.   (apply 'TRI:CircumCenter
  77.          (mapcar 'GEO:Midpoint  (list pa pb pc) (list pb pc pa))
  78.   )
  79. )


3.三角形的三线坐标和其他心及其点(相似重心,等周点,等角共轭点等)
  1. ;;;----------------------------------------------------;
  2. ;;;三线坐标转化为世界坐标      k = 2S/(ax+by+cz)       ;
  3. ;;;注意: 三线坐标跟笛卡尔坐标的表示上的不同            ;
  4. ;;;输入: 三线坐标P(list x y z)=>x:y:z和对应三点Pa,Pb,Pc;
  5. ;;;输出: 返回世界坐标系的点                            ;
  6. ;;;----------------------------------------------------;
  7. (defun TRI:TCS->WCS (P Pa Pb Pc / x y z V1 V2 V3 p1 p2 p3 int)
  8.   (setq V1 (LINE:Offset Pb Pc (car P)))
  9.   (setq V2 (LINE:Offset Pc Pa (cadr p)))
  10.   (setq V3 (LINE:Offset Pa Pb (caddr p)))
  11.   (setq p1 (inters (car V2) (cadr V2) (car V3) (cadr V3) nil))
  12.   (setq p2 (inters (car V3) (cadr V3) (car V1) (cadr V1) nil))
  13.   (setq p3 (inters (car V1) (cadr V1) (car V2) (cadr V2) nil))
  14.   (if (setq int (inters Pa P1 Pb P2 nil))
  15.     int
  16.     (if (setq int (inters Pb P2 Pc P3 nil))
  17.       int
  18.       (inters Pc P3 Pa P1 nil)
  19.     )
  20.   )
  21. )

  22. ;;;----------------------------------------------------;
  23. ;;;功能: 相似重心,Lemoine Point ,or symmedian point    ;
  24. ;;;输入: 给定不共线的三个点                            ;
  25. ;;;输出: 这个三点形成的三角形的相似重心                ;
  26. ;;;----------------------------------------------------;
  27. (defun TRI:Symmedian_Point (Pa Pb Pc / a b c)
  28.   (setq a (distance Pb Pc))
  29.   (setq b (distance pc Pa))
  30.   (setq c (distance Pa Pb))
  31.   (TRI:TCS->WCS (list a b c) Pa Pb Pc)
  32. )

  33. ;;;----------------------------------------------------;
  34. ;;;功能: 某点对给定三角形的等角共轭点                  ;
  35. ;;;输入: 一点Pt 和构成三角形的三点Pa Pb Pc             ;
  36. ;;;输出: 这点对给定三角形的等角共轭点                  ;
  37. ;;;----------------------------------------------------;
  38. (defun TRI:Isogonal-Conjugate-Point (Pt Pa Pb Pc / Pt1 Pt2 Inc)
  39.   (setq InC (car (TRI:InCenter Pa Pb Pc)))
  40.   (setq Pt1 (GEO:Mirror3D Pt Pa Inc))
  41.   (setq pt2 (GEO:Mirror3D Pt Pb Inc))
  42.   (inters Pa Pt1 Pb Pt2 nil)
  43. )

  44. ;;;----------------------------------------------------;
  45. ;;;功能: 某点对给定三角形的等角共轭点                  ;
  46. ;;;输入: 一点Pt 和构成三角形的三点Pa Pb Pc             ;
  47. ;;;输出: 这点对给定三角形的等角共轭点                  ;
  48. ;;;说明: 如果已知三角形内心,则可以简略计算            ;
  49. ;;;----------------------------------------------------;
  50. (defun TRI:Isogonal-Conjugate-Point-1 (Pt Pa Pb Inc /)
  51.   (inters Pa (GEO:Mirror3D Pt Pa Inc) Pb (GEO:Mirror3D Pt Pb Inc) nil)
  52. )

  53. ;;;----------------------------------------------------;
  54. ;;;根据三角形的三边长获取三角形信息                    ;
  55. ;;;输入: 三边的边长a,b,c                               ;
  56. ;;;输出: 三角形的三个角度,面积和周长,内心和内切圆半径;
  57. ;;;      旁切圆的圆心和半径,外心和外接圆半径,垂心,  ;
  58. ;;;      重心,类似重心,等周心以及九点圆圆心          ;
  59. ;;;----------------------------------------------------;
  60. ;|
  61. http://en.wikipedia.org/wiki/Trilinear_coordinates      
  62. where a, b, c are the respective sidelengths BC, CA, AB,
  63. and σ = area of ABC.                                   
  64. A = 1 : 0 : 0                                          
  65. B = 0 : 1 : 0                                          
  66. C = 0 : 0 : 1                                          
  67. incenter = 1 : 1 : 1                                    
  68. centroid = bc:ca:ab = 1/a:1/b:1/c = cscA : cscB : cscC.
  69. circumcenter = cos A : cos B : cos C.                  
  70. orthocenter = sec A : sec B : sec C.                    
  71. nine-point center = cos(B - C) : cos(C - A) : cos(A - B)
  72. symmedian point = a : b : c = sin A : sin B : sin C.   
  73. A-excenter = -1 : 1 : 1                                 
  74. B-excenter = 1 : -1 : 1                                 
  75. C-excenter = 1 : 1 : -1.                                
  76. ;;;de Longchamps point                                 
  77. ;;;http://en.wikipedia.org/wiki/De_Longchamps_point     
  78. ;;;symmedian point                                      
  79. ;;;http://en.wikipedia.org/wiki/Symmedian_point         
  80. http://mathworld.wolfram.com/TriangleCenter.html        
  81. |;
  82. (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)
  83.   (setq p  (* 0.5 (+ a b c)))                                ;半周长
  84.   (setq S  (sqrt (* p (- p a) (- p b) (- p c))))        ;面积
  85.   (setq Ri (/ S p))                                        ;内切圆半径
  86.   (setq K  (* 2 Ri p))
  87.   (setq Ra (/ k (+ b c (- a))))                                ;边A旁切圆半径
  88.   (setq Rb (/ k (+ c a (- b))))                                ;边B旁切圆半径
  89.   (setq Rc (/ k (+ a b (- c))))                                ;边C旁切圆半径
  90.   (setq Re (/ (* a b c 0.25) S))                        ;外接圆半径
  91.   (setq D  (+ Re Re))                                        ;外接圆直径
  92.   (setq Ca (/ (+ (* b b) (* (+ c a) (- c a))) 2 b c))   ;角A余弦
  93.   (setq Cb (/ (+ (* c c) (* (+ a b) (- a b))) 2 c a))   ;角B余弦
  94.   (setq Cc (/ (+ (* a a) (* (+ b c) (- b c))) 2 a b))   ;角C余弦
  95.   (setq Sa (/ a D))                                        ;角A正弦
  96.   (setq Sb (/ b D))                                     ;角B正弦
  97.   (setq Sc (/ c D))                                     ;角C正弦
  98.   (setq Aa (atan Sa Ca))                                ;角A
  99.   (setq Ab (atan Sb Cb))                                ;角B
  100.   (Setq Ac (atan Sc Cc))                                ;角C
  101.   (setq 2S (+ S S))
  102.   (list (list Aa Ab Ac)                                  ;三个角
  103.         (list S (+ p p))                                ;面积和周长
  104.         (list '( 1  1  1) Ri)                           ;内心
  105.         (list '(-1  1  1) Ra)                                 ;边A旁切圆半径
  106.         (list '( 1 -1  1) Rb)                                ;边B旁切圆半径
  107.         (list '( 1  1 -1) Rc)                                ;边C旁切圆半径
  108.         (list (list Ca Cb Cc) Re)                       ;外心
  109.         (list (list (/ 1 Ca) (/ 1 Cb) (/ 1 Cc)))        ;垂心
  110.         (list (list (/ 1 a) (/ 1 b) (/ 1 c)))           ;重心
  111.         (list (list a b c))                             ;类似重心
  112.         (list (list (cos (- Ab Ac))
  113.                     (cos (- Ac Aa))
  114.                     (cos (- Aa Ab))
  115.               )                                                ;九点圆圆心
  116.               (* 0.5 Re)                                ;九点圆半径
  117.         )
  118.         (list (list (1- (/ 2S a (+ b c (- a))))      
  119.                     (1- (/ 2S b (+ c a (- b))))
  120.                     (1- (/ 2S c (+ a b (- c))))
  121.               )
  122.         )                                               ;等周点(Isoperimetric Point)
  123.   )
  124. )


4.三角形的面积
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 定义三点的行列式,即三点之倍面积               ;
  3. ;;;输入: 三点P1,P2,P3                                  ;
  4. ;;;输出: 这三点形成的三角形的面积的2倍,符号指示方向。 ;
  5. ;;;----------------------------------------------------;
  6. (defun TRI:Det3P (p1 p2 p3)
  7.   (- (* (- (car p2) (car p1)) (- (cadr p3) (cadr p1)))
  8.      (* (- (car p3) (car p1)) (- (cadr p2) (cadr p1)))
  9.   )
  10. )

  11. ;;;----------------------------------------------------;
  12. ;;;功能: 用海伦公式(Heron's formula)求三角形面积       ;
  13. ;;;输入: 三角形的三个边长a,b,c                         ;
  14. ;;;输出: 三角形面积                                    ;
  15. ;;;----------------------------------------------------;
  16. (defun TRI:Area (a b c / p)
  17.   (setq p (* 0.5 (+ a b c)))
  18.   (sqrt (* p (- p a) (- p b) (- p c)))
  19. )

  20. ;;;----------------------------------------------------;
  21. ;;;功能: 计算已知空间三点的三角形面积                  ;
  22. ;;;输入: 空间三点 P1,P2,P3                             ;
  23. ;;;输出: 三角形面积                                    ;
  24. ;;;----------------------------------------------------;
  25. (defun TRI:Area3D (p1 p2 p3 / v1 v2 d1 d2 d3)
  26.   (setq v1 (mapcar '- p2 p1))
  27.   (setq v2 (mapcar '- p3 p1))
  28.   (setq d1 (MAT:Det2 (car   v1) (cadr  v1) (car   v2) (cadr  v2)))
  29.   (setq d2 (MAT:Det2 (cadr  v1) (caddr v1) (cadr  v2) (caddr v2)))
  30.   (setq d3 (MAT:Det2 (caddr v1) (car   v1) (caddr v2) (car   v2)))
  31.   (* 0.5 (sqrt (+ (* d1 d1) (* d2 d2) (* d3 d3))))
  32. )


五、多边形

1.多边形的面积和周长
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 计算多边形面积(为简单多边形,不自交的多边形)  ;
  3. ;;;输入: 多边形顶点列表  Pts                           ;
  4. ;;;输出: 一个数值,如果为正则是CCW(逆时针),否则顺时针 ;
  5. ;;;参考: Centroid  Shoelace formula                    ;
  6. ;;;----------------------------------------------------;
  7. (defun POLY:Area (pts)
  8.   (* (apply '+ (mapcar 'MAT:Det2V pts (MISC:1st->Last Pts))) 0.5)
  9. )
  10. ;;;----------------------------------------------------;
  11. ;;;功能: 计算多边形周长                                ;
  12. ;;;输入: 多边形顶点列表  Pts                           ;
  13. ;;;输出: 一个数值,表示多边形周长                      ;
  14. ;;;----------------------------------------------------;
  15. (defun POLY:Perimeter (pts)
  16.   (apply '+ (mapcar 'distance pts (MISC:1st->Last Pts)))
  17. )


2.多边形的方向
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 判断多边形的方向(为简单多边形,不自交的多边形);
  3. ;;;输入: 多边形顶点列表  Pts                           ;
  4. ;;;输出: 返回T则是CCW(逆时针),否则顺时针              ;
  5. ;;;----------------------------------------------------;
  6. (defun POLY:IsCCW (Pts)
  7.   (> (POLY:Area pts) 0.0)
  8. )


3.获取含有弧段的多边形的信息(面积,周长,质心)  
此方法纯为lisp计算,并非通过region建模获得,因而更快速,适合重复运算。
  1. ;;;----------------------------------------------------;
  2. ;;;功能: 获取多边形信息(质心,面积,周长)              ;
  3. ;;;输入: Pts---多边形顶点列表                          ;
  4. ;;;输出: 列表:第一个为多边形的面积中心(质心),用2d点表示;
  5. ;;;      第二个为数值,正数表示多边形方向是CCW(逆时针) ;
  6. ;;;      负数表示顺时针;第三个为周长.                 ;
  7. ;;;参考: http://en.wikipedia.org/wiki/Centroid         ;
  8. ;;;----------------------------------------------------;
  9. (defun POLY:Infomation (Pts / Pts1 Ai S lst cen)
  10.   (setq Pts1 (MISC:1st->Last Pts))                        ;another point of every side
  11.   (setq Ai   (mapcar 'MAT:Det2V Pts Pts1))                 ;area of every side
  12.   (setq S    (* (apply '+ Ai) 0.5))                        ;Total area
  13.   (Setq Cen  (MAT:SxVs (mapcar 'MAT:v+v Pts Pts1) Ai))
  14.   (setq Cen  (MAT:vxs Cen (/ 0.166666666666666667 S)))  ;base on the formula
  15.   (list Cen S (apply '+ (mapcar 'distance pts pts1)))   ;Return Centroid,Total area and Perimeter
  16. )

  17. ;;;----------------------------------------------------;
  18. ;;;Circular segment                                    ;
  19. ;;;弓的质心求以及弓形的面积                            ;
  20. ;;;输入: C---圆心;Center                               ;
  21. ;;;      R---半径;Radius                               ;
  22. ;;;      A1--起始角;0 <= A1 <= 2*Pi Start Angle(Radian);
  23. ;;;      A2--终止角;0 <= A2 <= 2*Pi End Angle(Radian)  ;
  24. ;;;      IsCW--是否顺时针                              ;
  25. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为弧长;
  26. ;;;----------------------------------------------------;
  27. (defun CIR:Circular_Segment (C R A1 A2 IsCW / A k d S e)
  28.   (and isCW (setq A A2 A2 A1 A1 A))
  29.   (if (> A1 A2)
  30.     (setq A (- (+ pi pi A2) A1 ))
  31.     (setq A (- A2 A1))
  32.   )
  33.   (setq k (sin (* 0.5 A)))
  34.   (setq k (* 1.333333333333333333333 R k k k))
  35.   (setq e (- A (sin A)))
  36.   (setq S (* 0.5 R R e))
  37.   (and IsCW (setq S (- S)))                                ;如果顺时针,面积为负
  38.   (setq d (/ k e))
  39.   (if (> A1 A2) (setq d (- d)))                                ;这种情况下要反向
  40.   (list (polar C (* 0.5 (+ A1 A2)) d) S (* A R))
  41. )

  42. ;;;----------------------------------------------------;
  43. ;;;Circular sector                                     ;
  44. ;;;扇形的质心,面积和周长                              ;
  45. ;;;输入: C---圆心;Center                               ;
  46. ;;;      R---半径;Radius                               ;
  47. ;;;      A1--起始角;0 <= A1 <= 2*Pi Start Angle(Radian);
  48. ;;;      A2--终止角;0 <= A2 <= 2*Pi End Angle(Radian)  ;
  49. ;;;      IsCW--是否顺时针                              ;
  50. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为周长;
  51. ;;;----------------------------------------------------;
  52. (defun CIR:Circular_Sector (C R A1 A2 IsCW / A d S L)
  53.   (and IsCW (setq A A2 A2 A1 A1 A))
  54.   (if (> A1 A2)
  55.     (setq A (- (+ pi pi A2) A1))
  56.     (setq A (- A2 A1))
  57.   )
  58.   (setq d (/ (* 4 R (sin (* 0.5 A))) 3 A))
  59.   (setq S (* 0.5 A R R))                                
  60.   (and IsCW (setq S (- S)))                                ;如果顺时针,面积为负
  61.   (setq L (* R (+ A 2)))                                ;周长
  62.   (if (> A1 A2) (setq d (- d)))                                ;这种情况下要反向
  63.   (list (polar C (* 0.5 (+ A1 A2)) d) S L)
  64. )

  65. ;;;----------------------------------------------------;
  66. ;;;获得轻多段线的有弧段处的顶点的信息                  ;
  67. ;;;输入: P1---顶点坐标(OCS)                            ;
  68. ;;;      P2---下一顶点坐标(OCS)                        ;
  69. ;;;      b----凸度(不为零)                           ;
  70. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为弧长;
  71. ;;;----------------------------------------------------;
  72. (defun POLY:Info_Bulge (P1 P2 b / D A k C R)
  73.   (setq D (distance p1 p2))
  74.   (setq A (angle p1 p2))
  75.   (setq k (* d (1+ (* b b)) 0.25))
  76.   (setq C (polar p1 (+ a (- (* pi 0.5) (* 2 (atan b)))) (/ k b)))
  77.   (setq R (/ k (abs b)))
  78.   (CIR:Circular_Segment C R (angle c p1) (angle c p2) (< b 0))
  79. )

  80. ;;;----------------------------------------------------;
  81. ;;;获得轻多段线的信息                                  ;
  82. ;;;输入: LWPoly---轻多段线的实体名                     ;
  83. ;;;输出: 列表: 第一项为质心,第二项为面积,第三项为弧长;
  84. ;;;----------------------------------------------------;
  85. (defun POLY:Info_LWPoly (LWPoly / eps Object Points Number IsOpen I P P0 Q Ret b Cen1
  86.                                   Area1 List1 List2 Part1 Leng1 Leng2 AreaLst CenLst)
  87.   (setq eps 1e-6)
  88.   (setq Object (vlax-ename->vla-object LWPoly))
  89.   (setq Points (vlax-get Object 'Coordinates))
  90.   (setq Number (/ (length Points) 2))
  91.   (setq IsOpen (= (vla-get-closed Object) :vlax-false))
  92.   (and IsOpen (setq Number (1+ Number)))
  93.   (setq i 0)

  94.   (setq p0  (list (car Points) (cadr Points)))
  95.   (setq p p0)
  96.   (repeat number
  97.     (if (setq Points (cddr Points))
  98.       (setq q (list (car Points) (cadr Points)))        ;下一顶点
  99.       (setq q P0)                                        ;如果顶点是最后点,则取第一点
  100.     )
  101.     (if (not (equal p q eps))                                ;这步为的是消除重合的点。
  102.       (progn
  103.         (setq b (vla-getbulge Object i))                ;取得这点的凸度
  104.         (if (or (/= b 0.0) (and (null points) IsOpen))  ;如果有凸度或者在末端
  105.           (setq List1 (cons (list P b 0) List1))        ;则不计算这点长度
  106.           (setq List1 (cons (list p b (distance p q)) List1))      
  107.         )
  108.         (if (and (/= b 0.0) (or Points (not IsOpen)))   ;如果有凸度(末端不封闭情况不计算)
  109.           (setq List2 (cons (POLY:Info_Bulge p q b) List2))
  110.         )
  111.       )
  112.     )
  113.     (setq p q)
  114.     (setq i (1+ i))
  115.   )
  116.   (setq list1 (reverse List1))
  117.   (setq list2 (reverse list2))
  118.   (setq part1 (POLY:Infomation (mapcar 'car list1)))    ;不含弧段的部分
  119.   (setq Cen1  (car Part1))                                ;不含弧段部分的质心
  120.   (setq Area1 (cadr Part1))                                ;不含弧段部分的面积
  121.   (setq leng1 (apply '+ (mapcar 'last list1)))                ;不含弧段部分的总长
  122.   (if List2                                                ;含弧段的部分
  123.     (setq leng2   (apply '+ (mapcar 'last list2))        ;含弧段部分的总长
  124.           CenLst  (cons Cen1 (mapcar 'car list2))        ;含弧段部分的质心
  125.           AreaLst (cons Area1 (mapcar 'cadr list2))        ;含弧段部分的面积
  126.           ret     (GEO:Centroid_Composition CenLst AreaLst)
  127.           ret     (list (car ret) (cadr ret) (+ leng1 leng2))
  128.     )
  129.     (list Cen1 Area1 leng1)
  130.   )
  131. )


六、附带的一些函数
详细参见附件。包括了实体的创建,程序的测试,和一些其他相关函数。
  1. ;;;----------------------------------------------------;
  2. ;;;创建一个点                                          ;
  3. ;;;输入: 一个三维或者二维的点                          ;
  4. ;;;输出: 点实体的图元名                                ;
  5. ;;;----------------------------------------------------;
  6. (defun Ent:Make_Point (p)
  7.   (entmakex (list '(0 . "POINT") (cons 10 p)))
  8. )

  9. ;;;----------------------------------------------------;
  10. ;;;创建一个带颜色的点(此函数为测试或者其他用途)      ;
  11. ;;;输入: 一个三维或者二维的点表和一个颜色号            ;
  12. ;;;输出: 点实体的图元名                                ;
  13. ;;;----------------------------------------------------;
  14. (defun Ent:MakePoint-1 (p c)
  15.   (entmakex (list '(0 . "POINT") (cons 10 p) (cons 62 c)))
  16. )

  17. ;;;----------------------------------------------------;
  18. ;;;创建一条直线段                                      ;
  19. ;;;输入: 两个三维或者二维的点                          ;
  20. ;;;输出: 线段实体的图元名                              ;
  21. ;;;----------------------------------------------------;
  22. (defun Ent:Make_Line (p q)
  23.   (entmakeX (list '(0 . "LINE") (cons 10 p) (cons 11 q)))
  24. )

  25. ;;;----------------------------------------------------;
  26. ;;;创建一个由三条直线组成的三角形                      ;
  27. ;;;输入: 三个三维或者二维的点                          ;
  28. ;;;输出: 由三条直线组成的三角形                        ;
  29. ;;;----------------------------------------------------;
  30. (defun Ent:Make_Triangle (p1 p2 p3)
  31.   (mapcar 'Ent:Make_Line (list p1 p2 p3) (list p2 p3 p1))
  32. )

  33. ;;;----------------------------------------------------;
  34. ;;;创建一个三维多段线                                  ;
  35. ;;;输入: 三维的点集                                    ;
  36. ;;;输出: 三维多段线实体                                ;
  37. ;;;----------------------------------------------------;
  38. (defun Ent:Make_Poly (pts / e)
  39.   (setq e (Entmake (list '(0 . "POLYLINE") '(70 . 9))))
  40.   (foreach p pts
  41.     (entmake (list '(0 . "VERTEX") '(70 . 32) (cons 10 p)))
  42.   )
  43.   (entmake '((0 . "SEQEND")))
  44.   e
  45. )

  46. ;;;----------------------------------------------------;
  47. ;;;创建轻多段线                                        ;
  48. ;;;输入: 二维的点集                                    ;
  49. ;;;输出: 轻多段线实体名                                ;
  50. ;;;----------------------------------------------------;
  51. (defun Ent:Make_LWPoly (pts closed /)
  52.   (entmakeX                                                
  53.     (append
  54.       '((0 . "LWPOLYLINE")
  55.         (100 . "AcDbEntity")
  56.         (100 . "AcDbPolyline")
  57.        )
  58.       (list (cons 90 (length pts)))                        ;顶点个数
  59.       (mapcar (function (lambda (x) (cons 10 x))) pts)        ;多段线顶点
  60.       (list (cons 70 (if closed 1 0)))                        ;闭合的
  61.     )
  62.   )
  63. )


七、测试部分
以下程序为测试用,包含了多个函数的测试。
  1. ;;|*****************************************************;
  2. ;;;以下为测试所用,大家可各取所需                       ;
  3. ;;;*****************************************************;

  4. ;;;测试坐标变换函数Mat:TransU2W和TransW2U
  5. (defun C:TestTransU2W (/ x y s e d p q v)
  6.   (initget 1)
  7.   (setq x (getdist "\nX:"))
  8.   (initget 1)
  9.   (setq y (getdist "\nY:"))
  10.   (initget 1)
  11.   (setq s (ssget ":S" '((0 . "LINE"))))
  12.   (if (and x y s)
  13.     (progn
  14.       (setq e (ssname s 0))
  15.       (setq d (entget e))
  16.       (setq p (cdr (assoc 10 d)))
  17.       (setq q (cdr (assoc 11 d)))
  18.       (setq v (MAT:TransU2W (list x y) p (mapcar '- q p)))
  19.       (Ent:Make_Point V)
  20.     )
  21.   )
  22. )

  23. ;;;测试旋转函数GEO:Rot2d
  24. (defun c:TestRot2d ( / pt pb an)
  25.   (initget 1)
  26.   (setq pt (getpoint "\n要旋转的点:"))
  27.   (initget 1)
  28.   (setq pb (getpoint "\n基点:"))
  29.   (initget 1)
  30.   (setq an (getangle "\n角度:"))
  31.   (ent:make_point pt)
  32.   (ent:make_point pb)
  33.   (ent:make_point (GEO:Rot2d Pt Pb an))
  34.   (princ)
  35. )

  36. ;;;测试镜像函数
  37. (defun c:TestMirror (/ p1 p2 pt s)
  38.   (initget 1)
  39.   (setq p1 (getpoint "\n1:"))
  40.   (initget 1)
  41.   (setq p2 (getpoint "\n2:"))
  42.   (initget 1)
  43.   (setq pt (getpoint "\n要镜像的点:"))
  44.   (grdraw p1 p2 1)
  45.   (setq        s (MiSC:Test 10000
  46.                      '((GEO:Mirror2D pt p1 (angle p1 p2))
  47.                        (GEO:Mirror3D Pt p1 p2)
  48.                        (GEO:Mirror2D-1 Pt p1 p2)
  49.                       )
  50.           )
  51.   )
  52.   (mapcar 'Ent:Make_Line (list pt pt pt) (mapcar 'last s))
  53.   (princ)
  54. )

  55. ;;;测试垂足和垂距函数
  56. (defun C:LPF(/ p1 p2 pt f a b c s)
  57.   (initget 1)
  58.   (setq p1 (getpoint "\n直线端点1:"))
  59.   (initget 1)
  60.   (setq p2 (getpoint "\n直线端点2:"))
  61.   (initget 1)
  62.   (setq pt (getpoint "\n要求的点p:"))

  63.   (setq f (LINE:Equation p1 p2))
  64.   (setq A (car f))
  65.   (setq B (cadr f))
  66.   (setq C (caddr f))

  67.   (setq S (MISC:Test 10000
  68.                 '((LINE:Perpendicular_Foot pt p1 p2)
  69.                   (LINE:Perpendicular_Distance_1 pt A B C)
  70.                   (LINE:Perpendicular_Distance_2 pt P1 p2)
  71.                   (LINE:Perpendicular_Distance_3 Pt P1 P2)
  72.                   (MAT:TransW2U pt P1 (mapcar '- p2 p1)))
  73.           )
  74.   )
  75.                                  
  76.   (grdraw p1 p2 1)
  77.   (Ent:Make_Point pt)
  78.   (Ent:MakePoint-1 (cadr (last (car  s))) 1)
  79.   (Ent:MakePoint-1 (cadr (last (cadr s))) 2)
  80.   (princ (mapcar 'last s))
  81.   (princ)
  82. )

  83. ;;;测试线段相交函数
  84. (defun C:Inters (/ p1 p2 p3 p4 s)
  85.   (initget 1)
  86.   (setq p1 (getpoint "\n1:"))
  87.   (initget 1)
  88.   (setq p2 (getpoint p1 "\n2:"))
  89.   (initget 1)
  90.   (setq p3 (getpoint "\n3:"))
  91.   (initget 1)
  92.   (setq p4 (getpoint p3 "\n4:"))

  93.   (grdraw p1 p2 1)
  94.   (grdraw p3 p4 2)
  95.   (setq        s (MISC:Test 100000
  96.                      '((LINE:Intersection p1 p2 p3 p4)
  97.                        (inters p1 p2 p3 p4 nil)
  98.                       )
  99.           )
  100.   )
  101.   (foreach p (mapcar 'last s)
  102.     (Ent:make_Point p)
  103.   )
  104. )

  105. ;;;测试偏移两点函数LINE:Offset
  106. (defun C:LineOffset (/ p1 p2 d)
  107.   (initget 1)
  108.   (setq p1 (getpoint "\n1:"))
  109.   (initget 1)
  110.   (setq p2 (getpoint p1 "\n2:"))
  111.   (initget 1)
  112.   (setq d (getdist p1 "\n偏移距离:"))
  113.   (Ent:make_line p1 p2)
  114.   (apply 'Ent:make_line (LINE:Offset p1 p2 d))
  115.   (princ)
  116. )

  117. ;;;测试共线检测函数LINE:Colinearity,LINE:Colinearity_1
  118. (defun C:Colinearity (/ p1 p2 p3)
  119.   (setq eps 1e-6)
  120.   (setq p1 (getpoint "\n1:"))
  121.   (setq p2 (getpoint "\n2:"))
  122.   (setq p3 (getpoint "\n3:"))
  123.   (MISC:Test 100000
  124.              '((LINE:Colinearity p1 p2 p3)
  125.                (LINE:Colinearity3D p1 p2 p3)
  126.               )
  127.   )
  128.   (princ)
  129. )

  130. ;;;平面部分测试函数
  131. (defun c:PlaneTest(/ pa pb p1 p2 p3 d1 d2 arg)
  132.   (initget 1)
  133.   (setq pa (getpoint "\npa:"))
  134.   (setq pa (trans pa 1 0))
  135.   (initget 1)
  136.   (setq pb (getpoint "\npb:"))
  137.   (setq pb (trans pb 1 0))

  138.   (initget 1)
  139.   (setq p1 (getpoint "\n1:"))
  140.   (setq p1 (trans p1 1 0))
  141.   (initget 1)
  142.   (setq p2 (getpoint "\n2:"))
  143.   (setq p2 (trans p2 1 0))
  144.   (initget 1)

  145.   (setq p3 (getpoint "\n3:"))
  146.   (setq p3 (trans p3 1 0))

  147.   (mapcar 'Ent:make_Point (list pa pb p1 p2 p3))

  148.   (princ (PLANE:Distance_1 Pa p1 p2 p3))

  149.   (setq d1 (PLANE:Perpendicular_Foot Pa p1 p2 p3))
  150.   (setq d2 (PLANE:Perpendicular_Foot Pb p1 p2 p3))
  151.   (setq arg (cons pa (cons Pb (PLANE:Equation_3P p1 p2 p3))))
  152.   (setq ret (apply 'PLANE:Line_Inters_Plane arg))
  153.   (Ent:make_Point (cadr d1))
  154.   (Ent:make_Point (cadr d2))
  155.   (Ent:make_Point ret)
  156.   (princ (LINE:Distance_LineToLine pa pb p1 p2))
  157.   (princ)
  158. )

  159. ;;;三线坐标系统测试
  160. (defun C:InfoBy3Sides (/ p1 p2 p3 a b c ret)
  161.   (initget 1)
  162.   (setq p1 (getpoint "\n1:"))
  163.   (initget 1)
  164.   (setq p2 (getpoint "\n2:"))
  165.   (initget 1)
  166.   (setq p3 (getpoint "\n3:"))
  167.   (setq p1 (trans p1 1 0))
  168.   (setq p2 (trans p2 1 0))
  169.   (setq p3 (trans p3 1 0))
  170.   (setq a  (distance p2 p3))
  171.   (setq b  (distance p3 p1))
  172.   (setq c  (distance p1 p2))
  173.   (Ent:make_Poly (list p1 p2 p3))
  174.   (setq ret (TRI:InfoBy3Sides a b c))
  175.   (princ ret)
  176.   (foreach n (cddr ret)
  177.     (setq p (TRI:TCS->WCS (car n) p1 p2 p3))
  178.     (Ent:make_Point p)
  179.     (if (setq r (cadr n))
  180.       (Ent:make_Circle p r)
  181.     )
  182.   )
  183.   (princ)
  184. )

  185. ;;;Test for "POLY:Info_LWPoly" "Geo:Centroid" "POLY:Area" "POLY:Perimeter" "POLY:Infomation"
  186. ;;;为段线的质心和面积的测试
  187. (defun C:CentroidTest (/ sel ent en1 dxf pts cen aaa len ret i)
  188.   (setq i -1)
  189.   (setq sel (ssget '((0 . "*POLYLINE"))))
  190.   (if sel
  191.     (repeat (sslength sel)
  192.       (setq ent (ssname sel (setq i (1+ i))))
  193.       (setq obj (vlax-ename->vla-object ent))
  194.       (setq dxf (entget ent))
  195.       (if (= (cdr (assoc 0 DXF)) "POLYLINE")
  196.         (setq pts (MISC:List->PtList (vlax-get obj 'coordinates) 3)
  197.               Cen (GEO:Centroid pts)
  198.               aaa (POLY:Area pts)
  199.               len (POLY:Perimeter pts)
  200.               ret (POLY:Infomation pts)
  201.               en1 (Ent:MakePoint-1 Cen 2)        
  202.         )
  203.         (setq ret (POLY:Info_LWPoly ent)
  204.               aaa (vla-get-area obj)
  205.         )
  206.       )
  207.       (setq cen (car ret))
  208.       (setq len (vla-get-length obj))
  209.       (Ent:MakePoint-1 cen 1)
  210.       (princ (strcat "\n第" (itoa i) "个物体信息: "))
  211.       (princ (list ret Cen aaa len))
  212.       (princ)
  213.     )
  214.   )
  215. )

  216. ;;;弧段的质心和面积的测试
  217. (defun C:TestArcCentroid (/ A1 A2 C R E1 I O1 O2 O3 O4 P1 P2 S1 S2 SS V3 V4)
  218.   (setq i -1)
  219.   (if (setq ss (ssget '((0 . "ARC"))))
  220.     (repeat (sslength ss)
  221.       (setq e1 (ssname ss (setq i (1+ i))))
  222.       (setq o1 (vlax-ename->vla-object e1))

  223.       (setq C (vlax-get o1 'Center))
  224.       (setq R (vla-get-radius o1))
  225.       (setq A1 (vla-get-startangle o1))
  226.       (setq A2 (vla-get-endangle o1))

  227.       (setq V3 (CIR:Circular_Segment C R A1 A2 nil))        ;圆弧总是逆时针的
  228.       (setq V4 (CIR:Circular_Sector C R A1 A2 nil))        ;圆弧总是逆时针的

  229.       (setq p1 (vlax-curve-getstartpoint e1))           ;弧起点
  230.       (setq p2 (vlax-curve-getendPoint e1))                ;弧终点
  231.       (setq s1 (ssadd e1))
  232.       (setq s1 (ssadd (Ent:Make_Line p1 p2) S1))

  233.       (setq o2 (vla-copy o1))                                ;拷贝圆弧用来测试扇形
  234.       (setq s2 (ssadd (vlax-vla-object->ename o2)))
  235.       (setq s2 (ssadd (Ent:Make_Line p1 C) s2))
  236.       (setq s2 (ssadd (Ent:Make_Line p2 C) s2))

  237.       (command "region" s1 "")                             ;弓形计算与建模做比较
  238.       (setq o3 (vlax-ename->vla-object (entlast)))
  239.       (command "region" s2 "")                                ;扇形计算与建模做比较
  240.       (setq o4 (vlax-ename->vla-object (entlast)))

  241.       (Ent:MakePoint-1 (car V3) 1)                        ;计算出来的弓形质心
  242.       (Ent:MakePoint-1 (car V4) 2)                        ;计算出来的扇形质心
  243.       (Ent:MakePoint-1 (vlax-get o3 'centroid) 3)       ;弓形建模的质心
  244.       (Ent:MakePoint-1 (vlax-get o4 'centroid) 4)        ;扇形建模的质心

  245.       (princ (list V3 (vla-get-area O3) (vla-get-perimeter O3)))
  246.       (princ (list V4 (vla-get-area O4) (vla-get-perimeter O4)))
  247.       (princ)
  248.     )
  249.   )
  250. )
  251. ;;;测试3点的行列式
  252. (defun c:ttt()
  253.   (initget 1)
  254.   (setq p1 (getpoint "\n1:"))
  255.   (initget 1)
  256.   (setq p2 (getpoint p1 "\n2:"))
  257.   (initget 1)
  258.   (setq p3 (getpoint "\n3:"))

  259.   (setq        s (MISC:Test 100000
  260.                      '((TRI:Det3p p1 p2 p3))
  261.           )
  262.   )
  263.   (princ (mapcar 'last s))
  264.   (princ)
  265. )
  266. ;;;获取截面的质心
  267. (defun C:GetRegionCentroid (/ sel ent obj i)
  268.   (setq i -1)
  269.   (if (setq sel (ssget '((0 . "REGION"))))
  270.     (repeat (sslength sel)
  271.       (setq ent (ssname sel (setq i (1+ i))))
  272.       (setq obj (vlax-ename->vla-object ent))
  273.       (Ent:MakePoint-1 (vlax-get obj 'Centroid) 3)
  274.     )
  275.   )
  276. )
  277. ;|;











本帖子中包含更多资源

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

x

评分

参与人数 18明经币 +27 金钱 +192 收起 理由
urings + 1 赞一个!
lishucheng96 + 1
伪书虫86 + 1 赞一个!
qjchen + 2 + 30 赞一个!
jh1005 + 1 很给力!
sieben + 1 + 50 赞一个!
vormittag + 1 赞一个! 一直想写曲边三角形的形心、惯矩计.
gufeng + 1 + 9 神马都是浮云
xiaxiang + 3 感谢分享!
VBALISPER + 1 很给力!

查看全部评分

"觉得好,就打赏"
    共1人打赏

本帖被以下淘专辑推荐:

发表于 2018-2-9 10:11:22 | 显示全部楼层
大师级算法,下载学习,感谢分享
发表于 2018-2-3 07:55:43 | 显示全部楼层
先收藏  慢慢吸收
发表于 2013-1-12 15:21:24 | 显示全部楼层
支持一下慢慢看,也许看不懂.
发表于 2013-1-12 15:27:29 | 显示全部楼层
高飞总有精品
发表于 2013-1-12 16:10:57 | 显示全部楼层
感谢分享,飞鸟兄的代码看着很舒服,中规中矩。
发表于 2013-1-12 16:41:42 | 显示全部楼层
什么情况?地板都坐不到了
发表于 2013-1-12 17:55:05 | 显示全部楼层
精品必须的!
发表于 2013-1-12 18:25:29 | 显示全部楼层
支持一个...
发表于 2013-1-12 19:00:32 | 显示全部楼层
太精彩了。
发表于 2013-1-12 19:07:18 | 显示全部楼层
支持高飞鸟!!!
发表于 2013-1-12 19:50:49 | 显示全部楼层
受教了,谢谢高飞鸟!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-25 13:51 , Processed in 0.265226 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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