明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2136|回复: 11

关于点到平面距离问题讨论

[复制链接]
发表于 2022-10-28 17:51:41 | 显示全部楼层 |阅读模式
关于点到平面距离问题讨论

点到平面距离公式是d=|Ax0+By0+Cz0+D|/√(A2+B2+C2)。
已知三点p1(x1,y1,z1),p2(x2,y2,z2),p3(x3,y3,z3),要求确定的平面方程
点到平面距离是指空间内一点到平面内一点的最小长度。特殊的,当点在平面内时,该点到平面的距离为0。公式中的平面方程为Ax+By+Cz+D=0


;A = (y2 - y1)*(z3 - z1) - (z2 -z1)*(y3 - y1);

;B = (x3 - x1)*(z2 - z1) - (x2 - x1)*(z3 - z1);

;C = (x2 - x1)*(y3 - y1) - (x3 - x1)*(y2 - y1);
;
;又D = -(A * x1 + B * y1 + C * z1),所以可以求得D的值。



  1. (defun vxs (e / i v lst)
  2.   (vl-load-com)
  3.   (setq i 0)
  4.   (while
  5.     (setq v (vlax-curve-getpointatparam e (setq i (1+ i))))
  6.      (setq lst (cons v lst))
  7.   )
  8.   (reverse lst)
  9.   )
  10. (defun c:ddm (/ x1 x2 x3 y1 y2 y3 z1 z2 z3 a b c d dd pts pt1 )
  11. ;;;;;;;;;;;;;;;
  12.   (setq pts (vxs(car(entsel "\n请选择三角网中一个三角形3dpoly线:"))))
  13. (setq x1  (car(car pts)  )
  14.       y1   (cadr(car pts)  )
  15.       z1    (nth 2 (car pts)  )
  16.       
  17.       x2  (car(cadr pts)  )
  18.       y2   (cadr(cadr pts)  )
  19.       z2    (nth 2 (cadr pts)  )
  20.       
  21.     x3 (car(nth 2 pts)  )
  22.       y3  (cadr(nth 2 pts)  )
  23.       z3    (nth 2 (nth 2 pts)  )

  24.       )
  25. (setq a  (-(* (- y2  y1)(- z3  z1))    (*(- z2 z1)(- y3  y1))   )
  26.       b  (-(* (- x3  x1)(- z2  z1))    (*(- x2  x1)(- z3  z1))   )
  27.       c  (-(* (- x2  x1)(- y3  y1))    (*(- x3  x1)(- y2  y1))   )
  28.       d    (* -1 (+(* a  x1) (* b  y1) (* c  z1)) )
  29.       
  30.        )
  31. ;A = (y2 - y1)*(z3 - z1) - (z2 -z1)*(y3 - y1);

  32. ;B = (x3 - x1)*(z2 - z1) - (x2 - x1)*(z3 - z1);

  33. ;C = (x2 - x1)*(y3 - y1) - (x3 - x1)*(y2 - y1);
  34. ;
  35. ;又D = -(A * x1 + B * y1 + C * z1),所以可以求得D的值。
  36. ;点到平面距离公式是d=|Ax0+By0+Cz0+D|/√(A2+B2+C2)
  37.   (setq pt1(getpoint "\n请选择待求点:"))

  38. (setq dd (/ (+(* a(car pt1))  (* b(cadr pt1))  (* c(nth 2 pt1)) d)

  39.      (sqrt (+ (expt a 2) (expt b 2)(expt c 2) ))
  40.      ) )
  41. ;22、 点
  42. ;(entmake (list '(0 . "POINT") (cons 10 (list (car pt1) (cadr pt1)  (- (nth 2 pt1)dd)  ))))
  43.   (mkgcd (list (car pt1) (cadr pt1)  (- (nth 2 pt1)dd)  )  (- (nth 2 pt1)dd)  1)
  44. (princ)
  45. )


  46. (defun mkgcd (inspt height  scale  / pt  pt1 blkdef obj)
  47.   (setvar "CMDECHO" 0)
  48.   (command "layer" "m" "检查高程点" "c" "1" "" "L" "CONTINUOUS" ""  "")
  49.   (if height
  50.     (setq height (rtos height 2 3))
  51.     (setq height "")
  52.   )

  53.   
  54.   (regapp "SOUTH")
  55.   ;;;检查字体 "HZ" 是否存在
  56.   (if (not (tblobjname "style" "HZ"))
  57.     (command "style" "HZ" "rs.shx,hztxt.shx" 0 1 0 "" "" "")
  58.   )
  59.   ;;;检查是否存在高程点图块定义
  60.   (if (not (tblobjname "block" "GC2000"))
  61.     (progn
  62.       ;13、entmake生成普通块
  63. (defun emkblk ( pt name /  )
  64.   (entmake (list '(0 . "block") (cons 2 name) '(70 . 0) (cons 10 pt)))

  65.   
  66. (entmake (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 4) (cons 10 (list (+ (car pt) 0.75)  (+ (cadr pt) 1)   ))(cons 10 pt) (cons 10 (list (- (car pt) 0.75)  (+ (cadr pt) 1)   ))

  67. (cons 10 (list (+ (car pt) 4.25)  (+ (cadr pt) 1)   ))



  68.          ))
  69.   
  70.   (entmake '((0 . "ENDBLK")))
  71.   
  72.   ;(entmake (list '(0 . "INSERT") (cons 2 name) (cons 10 pt)))
  73. )

  74.   (emkblk '(0 0) "GC2000")
  75.     )
  76.   )
  77.   ;;;插入块
  78.   (entmake (list
  79.              '(0 . "INSERT")
  80.              '(100 . "AcDbEntity")
  81.              '(100 . "AcDbBlockReference")
  82.              '(66 . 1);;;属性跟随标志,1跟随,0不跟随
  83.               (cons 2 "GC2000")
  84.               (cons 10 inspt)
  85.               (cons 41 scale)
  86.               (cons 42 scale)
  87.               (cons 43 scale)
  88.               '(-3 ("SOUTH" (1000 . "202101")))
  89.            )
  90.   )
  91.   ;;;插入属性
  92.   (entmake (list
  93.              '(0 . "ATTRIB")
  94.              '(100 . "AcDbEntity")
  95.              '(100 . "AcDbText")
  96.               (cons 10 (setq pt (polar inspt (* 0.5 PI) (* 2.25 scale))))
  97.               (cons 40 (* 2.0 scale))
  98.               (cons 50 0)
  99.                (cons 62 3)
  100.               (cons 41 0.8)
  101.               (cons 51 0)
  102.               (cons 1 height)
  103.               (cons 7 "HZ")
  104.               (cons 72 0)
  105.               (cons 11 pt)
  106.               '(100 . "AcDbAttribute")
  107.               (cons 2 "height")
  108.               (cons 70  0)
  109.               (cons 74 2)
  110.            )
  111.    )
  112. ;;;;;;;;;;;;;;;;;;;;;;;
  113. ;;;插入属性
  114.   
  115.   
  116.    ;;;结束标志
  117.    (entmake '((0 . "SEQEND")))
  118.    (princ)
  119. )


  120. ;;;;;;;;===========================================


本帖子中包含更多资源

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

x
 楼主| 发表于 2023-4-25 22:35:20 | 显示全部楼层

  1. ;;反正弦函数(asin 值)
  2. (defun asin(x)
  3. (cond
  4. ((or (> x 1) (< x -1)) nil)
  5. ((= x 1) (* pi 0.5))
  6. ((= x -1) (* pi -0.5))
  7. (t (atan (/ x (sqrt (- 1 (* x x))))))
  8. )
  9. )


  10. ;;反余弦函数(acos 值)
  11. (defun acos(x)
  12. (if (>= x 0)
  13. (asin (sqrt (- 1 (* x x))))
  14. (+ pi (- (asin (sqrt (- 1 (* x x))))))
  15. )
  16. )
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2023-4-25 16:40:16 | 显示全部楼层
本帖最后由 树櫴希德 于 2023-4-25 23:24 编辑

  1. ;;反正弦函数(asin 值)
  2. (defun asin(x)
  3. (cond
  4. ((or (> x 1) (< x -1)) nil)
  5. ((= x 1) (* pi 0.5))
  6. ((= x -1) (* pi -0.5))
  7. (t (atan (/ x (sqrt (- 1 (* x x))))))
  8. )
  9. )


  10. ;;反余弦函数(acos 值)
  11. (defun acos(x)
  12. (if (>= x 0)
  13. (asin (sqrt (- 1 (* x x))))
  14. (+ pi (- (asin (sqrt (- 1 (* x x))))))
  15. )
  16. )



  17. ;;;=============================================
  18. ;;;      通用函数  点到平面投影
  19. ;;;参数: pt------原始点
  20. ;;;       pt0/1/2------面上三点
  21. ;;;返回值:投影点
  22. (defun xty-G-pertoface  (pt pt0 pt1 pt2 / nv e)
  23.     (setq nv (mat:vxv (mapcar (function -) pt1 pt0)
  24.         (mapcar (function -) pt2 pt0)))
  25.     (setq
  26.   e (/ (-  (apply (function +) (mapcar (function *) nv pt0))
  27.     (apply (function +) (mapcar (function *) nv pt)))
  28.        (apply (function +) (mapcar (function *) nv nv))))
  29.     (mapcar (function +)
  30.       pt
  31.       (mapcar (function (lambda (x) (* x e))) nv)))
  32. (defun mat:vxv ( u v )
  33.   (list
  34.     (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
  35.     (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
  36.     (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
  37.   )
  38. )  ;@[偏爱云~小吴]偏

  39. (defun xty-g-pertoface1 (pt pt0 pt1 pt2 / nv e)
  40.   (setq nv (mat:vxv (mapcar '- pt1 pt0) (mapcar '- pt2 pt0)))
  41.   (setq e (/ (- (apply '+ (mapcar '* nv pt0)) (apply '+ (mapcar '* nv pt))) (apply '+ (mapcar '* nv nv))))
  42.   (mapcar '+ pt (mapcar (function (lambda (x) (* x e))) nv))
  43. )
  44. ; 53829.5,221425.0
  45. ;(apply'xty-G-pertoface (list(getpoint) (getpoint) (getpoint) (getpoint) ))
  46. (defun PtPerFace (pt p0 p1 p2 / nv e)(setq nv (mat:vxv(mapcar '- p1 p0)(mapcar '- p2 p0))e(/(- (apply '+ (mapcar '* nv p0))(apply '+ (mapcar '* nv pt)))(apply '+ (mapcar '* nv nv))))(mapcar '+ pt(mapcar'(lambda(x)(* x e)) nv)))
  47. ;;
  48. (defun c:ddpm1 (    /  p0 p1 p2 pt p11 p12 juli gcc xcc jd xcd   )
  49.   (alert (strcat "\n ddpm1""\n绿色点为原位重力方向相较于平面的点 " "\n 白色为待求点垂直于平面的点""\n 函数来自[x_s_s_1]生无可恋大神) "))
  50.   (setq p0 (getpoint "\n请指定面上第1点:"))
  51. (setq p1 (getpoint "\n请指定面上第2点:"))
  52. (setq p2 (getpoint"\n请指定面上第3点:"))
  53. (setq pt (getpoint"\n请指定待求点:"))

  54. (setq p11 (apply'xty-G-pertoface (list pt  p0  p1  p2 )))
  55. (entmake (list '(0 . "POINT")(cons 62 7) (cons 10 p11)))
  56. (setq juli       (sqrt (+ (expt (-(car pt) (car p11)) 2.0)    (expt (-(cadr pt) (cadr p11)) 2.0)  )  )   )
  57. (setq gcc (- (last p11) (last pt)   ) )

  58. (setq xcc (sqrt (+(expt juli 2.0) (expt gcc 2.0))   ))
  59. (setq jd (atan (/(abs gcc) juli)   ))
  60. (setq xcd (/ xcc (sin jd) ))
  61. (if  (>= gcc 0)
  62.      (setq xcd xcd)
  63.    
  64. (setq xcd (* -1 xcd))

  65.   )

  66. (setq p12 (list (car pt ) (cadr pt )   (+ (last pt ) xcd)        ))

  67. (entmake (list '(0 . "POINT") (cons 62 3)(cons 10 p12)))

  68. (if  ( < xcd 0)
  69. (alert (strcat "\n待求点比平面高" (rtos (* -1 xcd)2 3) "米"  ))
  70.   (alert (strcat "\n待求点比平面低" (rtos (* 1 xcd)2 3) "米"  ))



  71.   )
  72.   
  73. (princ)
  74.   )

本帖子中包含更多资源

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

x
发表于 2022-10-29 22:43:48 | 显示全部楼层
本帖最后由 tigcat 于 2022-10-29 23:01 编辑

楼主图片展示的似乎是一个平面上各点的线性插值
感觉就像是在平面上线性插值求标高.


如果划分成三角网,三角网三个顶点有三个坐标,从而可以确定一个平面方程Ax+By+Cz+D=0,在这个三角网内确定Xi,yi后都有唯一的Zi对应.
如果是怀疑公式在程序中出错,可以考虑换trans方式对比计算结果.


没有dwg,lisp程序中有一句比较可疑:
  • (setq dd (/ (+(* a(car pt1))  (* b(cadr pt1))  (* c(nth 2 pt1)) d);分子应该加上abs,保证是正值|Ax+By+Cz+D|/......

  •      (sqrt (+ (expt a 2) (expt b 2)(expt c 2) ))
  •      ) )







 楼主| 发表于 2022-10-28 22:21:02 | 显示全部楼层
不知道是精度有问题还是公式错了 本来该10.446的
 楼主| 发表于 2022-10-30 09:46:15 | 显示全部楼层
tigcat 发表于 2022-10-29 22:43
楼主图片展示的似乎是一个平面上各点的线性插值
感觉就像是在平面上线性插值求标高.

分子加上abs是对的 但现在差的很小 如果改正是完全精确的 那么待求点与另外三点可以共面 在CAD里面可以拉伸extrude验证  事实上不能 差少少  是不是vlax-curve-getpointatparam函数获取的三维点精度不够 还是计算中公式精度不够?跟UNITS有没有关系?想不明白
发表于 2022-10-30 10:21:29 来自手机 | 显示全部楼层
curve系列函数有缺陷,当坐标特别大时会出错。
发表于 2022-10-30 14:30:05 | 显示全部楼层
本帖最后由 gzxl 于 2022-10-30 14:32 编辑

印象中 (expt a 2) 要改成 (expt a 2.),不然会影响精度。
会不会就不清楚了,毕竟现在不接触 lisp 了。
 楼主| 发表于 2022-10-30 20:18:11 | 显示全部楼层
tigcat 发表于 2022-10-30 10:21
curve系列函数有缺陷,当坐标特别大时会出错。

估计是 不知道换乘GETPOINT怎么样
 楼主| 发表于 2022-10-30 20:46:12 | 显示全部楼层
gzxl 发表于 2022-10-30 14:30
印象中 (expt a 2) 要改成 (expt a 2.),不然会影响精度。
会不会就不清楚了,毕竟现在不接触 lisp 了。

试了 没有效果
 楼主| 发表于 2023-4-25 21:18:30 | 显示全部楼层
本帖最后由 树櫴希德 于 2023-4-25 23:29 编辑

  1. (setq p11 (apply'xty-G-pertoface (list(getpoint) (getpoint) (getpoint) (getpoint) )))
  2. (entmake (list '(0 . "POINT") (cons 10 p11)))

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-12-23 03:38 , Processed in 0.190062 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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