本帖最后由 dtucad 于 2023-9-11 23:13 编辑
利用向量求点到直线垂足的坐标,可用于三维
没啥技术含量,向量入门知识,希望对新手有用。
水平有限,如有错误,请不吝指正。

网友答: ;; 获取点到直线的垂足
(defun FootPoint (P P1 P2 / V)
(setq V (mapcar '- P2 P1)
P1 (trans P1 0 V)
)
(trans (vl-list* (car P1) (cadr P1) (cddr (trans P 0 V))) V 0)
)网友答: 本帖最后由 dtucad 于 2023-9-12 13:14 编辑
谢谢大佬的优化建议,下次手动优化一下(gpt的码确实不够简洁,但是整体流程还是非常清晰),谢谢大佬

网友答:
(vlax-curve-getClosestPointTo curve givenPnt [extend])
功能
返回曲线上离指定点最近的点(在 WCS 上)。
说明
1)参数 curve为要测量的对象。
2)参数 givenPnt 为点(在 WCS 上),寻找曲线上距该点最近的点。
3)参数 extend 若指定该参数且其值不为 nil,那么 vlax-curve-getClosestPointTo 在搜索最近点时扩展曲线。网友答: 代码太复杂了网友答: 本帖最后由 xyp1964 于 2023-9-17 21:03 编辑
网友答:
院长 这样最快(getdist)网友答:
(getdist)完全两码事网友答: 本帖最后由 dtucad 于 2023-9-12 22:46 编辑
vlax-curve-getclosestpointto的实现原理倒是可以研究一下
大量程序运算 为了节省代码 还去画线 本末倒置了
可能一会又有人说用trans了 好吧好吧 轮子最香 我爱轮子
网友答: 另一个思路
网友答:
vlax-curve-getclosestpointto 在很多情况下得到的不是垂足,说不定是一个端点。网友答:
如果垂足不在曲线上,找到的就是曲线比较近的端点。比如直线两点是 (-1,0) 和 (1,0),点 P 是 (5,3),得到的点不是(5,0) 而是 (1,0)
利用向量求点到直线垂足的坐标,可用于三维
没啥技术含量,向量入门知识,希望对新手有用。
水平有限,如有错误,请不吝指正。

- ;利用向量求点到直线垂足的坐标
- ;参数1:直线起点、终点
- ;参数2:直线外一点
- ;返回值:点到直线垂足的坐标
- (defun footcoord (p1 p2 cp / dis dot-product foot projection v-p v-w)
- (setq v-w (mapcar '- p2 p1));向量p1-p2
- (setq v-p (mapcar '- cp p1));向量p1-cp
- ;计算点到直线的投影比例
- (setq dot-product (+ (* (car v-p) (car v-w)) (* (cadr v-p) (cadr v-w)) (* (caddr v-p) (caddr v-w))));点乘
- (setq dis (distance p1 p2))
- (setq projection (/ dot-product (expt dis 2)))
- (setq foot (list (+ (car p1) (* (car v-w) projection)) (+ (cadr p1) (* (cadr v-w) projection)) (+ (caddr p1) (* (caddr v-w) projection))));求垂足的坐标
- )
- ;测试用
- (defun c:tt (/ cp dis p1 p2 pt)
- (if (and
- (setq p1 (getpoint "\n指定直线起点"))
- (setq p2 (getpoint p1 "\n指定直线终点"))
- (setq cp (getpoint "\n指定直线外一点"))
- )
- (progn
- (setq pt (footcoord p1 p2 cp))
- (princ "\n点到直线的垂足坐标为:")(princ pt)
- )
- )
- (princ)
- )
网友答: ;; 获取点到直线的垂足
(defun FootPoint (P P1 P2 / V)
(setq V (mapcar '- P2 P1)
P1 (trans P1 0 V)
)
(trans (vl-list* (car P1) (cadr P1) (cddr (trans P 0 V))) V 0)
)网友答: 本帖最后由 dtucad 于 2023-9-12 13:14 编辑
谢谢大佬的优化建议,下次手动优化一下(gpt的码确实不够简洁,但是整体流程还是非常清晰),谢谢大佬

- ;利用向量求点到直线垂足的坐标
- ;参数1:直线起点、终点
- ;参数2:直线外一点
- ;返回值:点到直线垂足的坐标
- (defun footcoord (p1 p2 cp / dis dot-product foot projection v-p v-w)
- (setq v-w (mapcar '- p2 p1));向量p1-p2
- (setq v-p (mapcar '- cp p1));向量p1-cp
- ;计算点到直线的投影比例
-
- ;(setq dot-product (+ (* (car v-p) (car v-w)) (* (cadr v-p) (cadr v-w)) (* (caddr v-p) (caddr v-w))));点乘
- (setq dot-product (apply '+ (mapcar '* v-w v-p)));点乘
- (setq dis (distance p1 p2))
- (setq projection (/ dot-product (expt dis 2)))
- ;(setq foot (list (+ (car p1) (* (car v-w) projection)) (+ (cadr p1) (* (cadr v-w) projection)) (+ (caddr p1) (* (caddr v-w) projection))));求垂足的坐标
- (mapcar '(lambda (x y)(+ x (* y projection))) p1 v-w);求垂足的坐标
- )
网友答:
vormittag 发表于 2023-9-17 19:40
如果垂足不在曲线上,找到的就是曲线比较近的端点。比如直线两点是 (-1,0) 和 (1,0),点 P 是 (5,3),得 ...
(vlax-curve-getClosestPointTo curve givenPnt [extend])
功能
返回曲线上离指定点最近的点(在 WCS 上)。
说明
1)参数 curve为要测量的对象。
2)参数 givenPnt 为点(在 WCS 上),寻找曲线上距该点最近的点。
3)参数 extend 若指定该参数且其值不为 nil,那么 vlax-curve-getClosestPointTo 在搜索最近点时扩展曲线。网友答: 代码太复杂了网友答: 本帖最后由 xyp1964 于 2023-9-17 21:03 编辑

- (defun PtPer2Pt (p0 p1 p2 / s1 pt)
- "点到两点的垂足"
- (command "line" "non" p1 "non" p2 "")
- (setq pt (vlax-curve-getclosestpointto (setq s1 (entlast)) p0 t)); 参数 t 在搜索最近点时扩展曲线
- (entdel s1)
- pt
- )
dtucad 发表于 2023-9-12 22:29
院长 这样最快(getdist)
(getdist)完全两码事网友答: 本帖最后由 dtucad 于 2023-9-12 22:46 编辑
vlax-curve-getclosestpointto的实现原理倒是可以研究一下
大量程序运算 为了节省代码 还去画线 本末倒置了
可能一会又有人说用trans了 好吧好吧 轮子最香 我爱轮子
网友答: 另一个思路

- (defun get-perp_pt (pt p1 p2 / vec);
- (setq vec (mapcar '- p2 p1))
- (inters pt (mapcar '+ pt (vl-list* (- (cadr vec)) (car vec) (cddr vec))) p1 p2 nil)
- )
vormittag 发表于 2023-9-14 17:11
vlax-curve-getclosestpointto 在很多情况下得到的不是垂足,说不定是一个端点。
如果垂足不在曲线上,找到的就是曲线比较近的端点。比如直线两点是 (-1,0) 和 (1,0),点 P 是 (5,3),得到的点不是(5,0) 而是 (1,0)