明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 6735|回复: 13

[namezg][源码]判断点与直线的位置关系

  [复制链接]
发表于 2011-12-20 21:29 | 显示全部楼层 |阅读模式
本帖最后由 namezg 于 2011-12-20 21:38 编辑

看过以前的判断点和直线关系的,觉得不够完善,今天例用数学知道自己编写了一个,简单的程序一点难度没有,不过是来明经半年来第一次发源码,呵呵!


;************************************************************************************
;namezg2011.12.20
;功能:判断点与直线的位置关系  
;参数:pt1,pt2:直线上的两点
;            pt0:所要判断的点
;返回值:                    
;"On"          点在直线上   
;"UpperRight"  点在直线右上  
;"LowerRight"  点在直线右下  
;"UpperLeft"   点在直线左上  
;"LowerLeft"   点在直线左下  
;"Upper"       点在直线上   
;"Lower"       点在直线下   
;"Right"       点在直线右   
;"Left"        点在直线左   
(defun zg-PointOnLine (pt1 pt2 pt0 / x1 y1 x2 y2 x0 y0 k b y position)
        (setq x1 (car pt1))
        (setq y1 (cadr pt1))
        (setq x2 (car pt2))
        (setq y2 (cadr pt2))
        (setq x0 (car pt0))
        (setq y0 (cadr pt0))
        (if (= x1 x2)
                ;直线垂直
                (cond
                        ((< x0 x1)  ;((< x0 x2)
                                (princ "\n直线垂直,点在直线左。")
                                (setq position "Left")
                        )
                        ((> x0 x1)  ;((> x0 x2)
                                (princ "\n直线垂直,点在直线右。")
                                (setq position "Right")
                        )
                        ((= x0 x1)  ;((= x0 x2)
                                (princ "\n直线垂直,点在直线上。")
                                (setq position "On")
                        )
                )
                ;直线水平或倾斜
                (progn
                        (setq k (/ (- y1 y2) (- x1 x2)))
                        (setq b (- y1 (* k x1)))  ;(setq b (- y2 (* k x2)))
                        (setq y (+ (* k x0) b))
                        (cond
                                ;直线向右倾斜
                                ((> k 0)
                                        (cond
                                                ((< y0 y)
                                                        (princ "\n直线向右倾斜,点在直线右下。")
                                                        (setq position "LowerRight")
                                                )
                                                ((> y0 y)
                                                        (princ "\n直线向右倾斜,点在直线左上。")
                                                        (setq position "UpperLeft")
                                                )
                                                ((= y0 y)
                                                        (princ "\n直线向右倾斜,点在直线上。")
                                                        (setq position "On")
                                                )
                                        )
                                       
                                )
                                ;直线向左倾斜
                                ((< k 0)
                                        (cond
                                                ((< y0 y)
                                                        (princ "\n直线向左倾斜,点在直线左下。")
                                                        (setq position "LowerLeft")
                                                )
                                                ((> y0 y)
                                                        (princ "\n直线向左倾斜,点在直线右上。")
                                                        (setq position "UpperRight")
                                                )
                                                ((= y0 y)
                                                        (princ "\n直线向左倾斜,点在直线上。")
                                                        (setq position "On")
                                                )
                                        )        
                                )
                                ;直线水平
                                ((= k 0)
                                        (cond
                                                ((< y0 y)
                                                        (princ "\n直线水平,点在直线下。")
                                                        (setq position "Lower")
                                                )
                                                ((> y0 y)
                                                        (princ "\n直线水平,点在直线上。")
                                                        (setq position "Upper")
                                                )
                                                ((= y0 y)
                                                        (princ "\n直线水平,点在直线上。")
                                                        (setq position "On")
                                                )
                                        )
                                       
                                )
                        )
                )
        )
        position
)
;测试:
(defun c:zg-PointOnLine (/ en en_dxf pt1 pt2 pt0 value)
        (setq en (car (entsel "\n请选择一条直线:")))
        (setq en_dxf (entget en))
        (setq pt1 (cdr (assoc 10 en_dxf)))
        (setq pt2 (cdr (assoc 11 en_dxf)))
        (setq pt0 (getpoint "\n请选择一点:"))
        (setq value (zg-PointOnLine pt1 pt2 pt0))
        (princ)
)
;************************************************************************************

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2011-12-21 06:01 | 显示全部楼层
沙发支持啊~~~
发表于 2011-12-22 00:31 | 显示全部楼层
不推荐用纯几何方法,用向量判断比较好
发表于 2011-12-24 23:45 来自手机 | 显示全部楼层
我觉得直接用坐标转换最简单,最容易理解。
发表于 2011-12-26 13:33 | 显示全部楼层
要是ucs一转,全完了。
发表于 2011-12-26 14:48 | 显示全部楼层
获取的点要都转为世界坐标,或其他统一坐标
发表于 2011-12-28 10:57 | 显示全部楼层
millermin 发表于 2011-12-26 13:33
要是ucs一转,全完了。

只是把点坐标转到对象坐标系中判断,怎么会完呢?晕。
发表于 2011-12-28 12:53 | 显示全部楼层
我的情况有点不一样。ucs跟随转,就是说世界坐标也不水平了。同时我的程序也不同,测试立面图中不同点的标高。正负零零我取的是一根水平基线,所以要求基线头尾y坐标一致。如果坐标系变了,就算水平线,y坐标也不一致。在同一图形文件里有总平面图要求的地形图,目标要求水平放置。通常会直接转坐标使目标被转成水平。我也不知道说清楚没有。
发表于 2011-12-28 21:06 | 显示全部楼层
millermin 发表于 2011-12-28 12:53
我的情况有点不一样。ucs跟随转,就是说世界坐标也不水平了。同时我的程序也不同,测试立面图中不同点的标高 ...

其实是这样步骤:
1.获取基线在当前ucs中的坐标startpoint(x1 y1),endpoint(x2 y2),然后转换成以startpoint为原点,以endpoint为x正方向的临时坐标系。
2.获取要判断的点在当前ucs中的坐标p(x y),然后转换成在临时坐标系中的坐标p(x' y')。
3.当y'为正时,点在基线的左边,当y'为负时,点在基线的右边,当y'为0时,点在基线上。
完成判断。从头到尾没有动过当前的ucs,只是做了个临时的判断,根本就没有对图形做任何改动。
这种做法我觉得比矢量法更直观一点,更容易理解一点。呵,晕!
发表于 2011-12-29 02:18 | 显示全部楼层
feng582304 发表于 2011-12-28 21:06
其实是这样步骤:
1.获取基线在当前ucs中的坐标startpoint(x1 y1),endpoint(x2 y2),然后转换成以startp ...

我也尝试一下你的方法。转换坐标好像计算挺复杂。有角度就需要三角函数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-3 13:46 , Processed in 2.185825 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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