dtucad 发表于 2023-9-11 21:58:26

利用向量求点到直线的垂直距离

本帖最后由 dtucad 于 2023-9-11 23:12 编辑

上次弄了个利用向量计算两条直线的夹角http://bbs.mjtd.com/thread-188543-1-1.html

这次利用上次的函数求点到直线的垂直距离
没啥技术含量,向量入门知识,希望对新手有用。
水平有限,如有错误,请不吝指正。

;利用向量求点到直线的垂直距离
;参数1、2:直线起点、终点
;参数3:直线外一点
;返回值:点到直线的垂直距离
(defun distance-to-line (p1 p2 cp / ang dis)
(setq ang (angle-between-lines p1 p2 p1 cp));以p1为起点的2条直线的夹角
(setq dis (distance p1 cp));三角形斜边长度
(* dis (sin ang))
)

;利用向量计算两条直线的夹角 上次发过的函数
;参数:直线1起点、终点,直线2起点、终点
;返回夹角的弧度值
(defun angle-between-lines (p1 p2 p3 p4 / cosa dp m-v1 m-v2 v1 v2)
(setq v1 (mapcar '- p2 p1)); 计算直线1的方向向量
(setq v2 (mapcar '- p4 p3)); 计算直线2的方向向量
(setq dp (+ (* (car v1) (car v2)) (* (cadr v1) (cadr v2)) (* (caddr v1) (caddr v2)))) ; 计算两个向量的点积
(setq m-v1 (sqrt (+ (* (car v1) (car v1)) (* (cadr v1) (cadr v1)) (* (caddr v1) (caddr v1))))) ; 计算向量v1的模长
(setq m-v2 (sqrt (+ (* (car v2) (car v2)) (* (cadr v2) (cadr v2)) (* (caddr v2) (caddr v2))))) ; 计算向量v2的模长
(setq cosA (/ dp (* m-v1 m-v2))) ; 计算夹角的余弦值
(if (zerop cosA) ; 判断是否0值
    (/ pi 2) ; 0值时为0.5pi
    (atan (sqrt (- 1.0 (* cosA cosA))) cosA) ; 利用反正切函数求反余弦
)
)

;测试用
(defun c:tt (/ cp dis p1 p2)
(if (and
      (setq p1 (getpoint "\n指定直线起点"))
      (setq p2 (getpoint p1 "\n指定直线终点"))
      (setq cp (getpoint "\n指定直线外一点"))
      )
    (progn
      (setq dis (distance-to-line p1 p2 cp))
      (princ (strcat "\n点到直线的距离为:" (rtos dis 2 4)))
    )
)
(princ)
)


tigcat 发表于 2023-9-11 23:24:27

点到直线距离应该是一句话函数.高飞版主trans讲课中最后实例有提到.

自贡黄明儒 发表于 2023-9-12 07:34:33

tigcat 发表于 2023-9-11 23:24
点到直线距离应该是一句话函数.高飞版主trans讲课中最后实例有提到.

这里解释得也很清楚http://bbs.mjtd.com/thread-188468-1-1.html

dtucad 发表于 2023-9-12 09:50:04

trans背后实质是用的矩阵变换,这只是桌子提供的一个轮子,虽然用起来很方便,但是并不是因为有了这个轮子,我们就不用学习向量、矩阵的知识了。
这只是向量应用的一个例子而已,并不是说它有多高级,有多省代码,主要是帮助学习向量,理解底层原理,理解了底层原理才能造出新的轮子。
假如桌子没有提供distance函数,你能利用向量计算出两点的距离吗?

x_s_s_1 发表于 2023-9-12 10:58:05

没那么复杂
(defun distance-to-line       (p1 p2 cp / vxv)
    (defun vxv        (u v)
        (list (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
              (- (* (car v) (caddr u)) (* (car u) (caddr v)))
              (- (* (car u) (cadr v)) (* (car v) (cadr u)))))
    (/ (distance '(0 0 0)
               (vxv (mapcar '- cp p1) (mapcar '- cp p2)))
       (distance p1 p2)))

vormittag 发表于 2023-9-12 11:06:06

dtucad 发表于 2023-9-12 09:50
trans背后实质是用的矩阵变换,这只是桌子提供的一个轮子,虽然用起来很方便,但是并不是因为有了这个轮子 ...

(sqrt (apply '+ (mapcar '(lambda (x y)(* (- x y) (- x y)) ) pt1 pt2)))

用这一问太简单了。
页: [1]
查看完整版本: 利用向量求点到直线的垂直距离