绘图程序中直线的拾取判断

原创 2002年03月27日 11:33:00

绘图程序中常需要对绘制的对象进行拾取,RectRgn等形状都好说只用简单调用PtInRectPtInRgn函数既可以返回用户是否点击了该图形从而进行拾取,直线是对象里比较特殊的一种,如果一定要求点中直线本身(也就是点击点在直线上)未免难为了用户,毕竟,一个像素的宽度是很不容易掌握的。这时,可以采用计算点击点到直线的距离的办法,如果点击点距离直线在一个可以允许的范围内就判定为拾取直线,如图:



在图中点击点为p(x,y),判断此次点击是否拾取直线(p1,p2)就是计算点p到直线(p1,p2)的距离。如果已知直线方程Ax+By+C=0,那么点(x,y)到直线距离即为d=fabs(Ax+By+C)/sqrt(A*A+B*B)。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


已知直线上两点(p1,p2),那么直线方程就是(y1-y2)*X+(x2-x1)*Y+x1*y2-x2*y1=0 。


常规做法这样就可以了,但是复杂的公式让我们的程序不是变得更多的变量就是有复杂得难以读懂的语句。


我们把上面的直线及点所在坐标系移动一下,复杂的问题会变得简单不少,如图:



也就是在计算前作一下变换:


x1-=x2;
y1-=y2;
x-=x2;
y-=y2;
x2=0;
y2=0;


这样,直线方程就变为y1X-x1Y=0,点到直线距离公式也变为d=fabs(y1*x-x1*y)/sqrt(y1*y1+x1*x1),简单多了吧?


完了?还没有!如果这样判定就算完了的话,点击在直线的延长线上也会判定选中的!所以要确定如果不是点击在包含直线的Rect中,则拾取无效。


该方法封装成函数如下:


BOOL IsSelLine(CPoint p/*鼠标点击点*/,CPoint p1,CPoint p2/*直线的两个端点*/)


{


    //如果点击不在区域中,则返回FALSE


    if(!PtInRect(CRect((*x1<=x2?x1:x2)-5,


        (y1<=y2?y1:y2)-5,


        (x1>x2?x1:x2)+5,


        (y1>y2?y1:y2)+5),p))
        return FALSE;
 


    //坐标变换


    p1.x-=p2.x;
    p1.y-=p2.y;
    p.x-=p2.x;
    p.y-=p2.y;
    p2.x=0;
    p2.y=0;


    //计算距离


    double d=fabs(y1*p.x-x1*p.y)/sqrt(y1*y1+x1*x1);


    if(d<5)return TRUE;//误差值,也可以通过函数参数传进来。


    return FALSE;


}


 


如果没有MFC支持的程序,也可以定义成如下格式:


BOOL IsSelLine(int x,int y/*鼠标点击点*/,int x1,int y1,int x2,int y2/*直线的两个端点*/)


好了,最好补一句:别忘了包含<math.h>


 

OpenGL直线拾取

void WALL::pick(GLfloat xpos,GLfloat ypos) { xpos,ypos; GLint viewport[4]; GLdouble mvmatrix[16],pro...
  • donglei2007
  • donglei2007
  • 2013年05月22日 11:23
  • 700

绘图程序中线段拾取判断的一种简单方法

绘图程序中线段拾取判断的一种简单方法。
  • clever101
  • clever101
  • 2010年12月21日 09:08
  • 4035

OpenGL鼠标拾取

1.OpenGL自带拾取功能。glSelectBuffer等函数完成。   大每一本OpenGL入门的书都会讲到OpenGL的Select模式,它采用一种方法使得可以获取当前鼠标点选的几何图形。简单...
  • daojin505
  • daojin505
  • 2017年08月07日 10:26
  • 81

判断某一点在直线左右侧的方法...

注意向量是有方向的...判断 某一点在直线左右侧 左右方向是相对前进方向的,只要指定了前进方向就可以知道左右(比如指定前进方向是从直线的起点到终点).判断点在直线的左侧还是右侧是计算几何里面的一个最...
  • modiz
  • modiz
  • 2013年08月12日 16:31
  • 4388

判断两线段是否相交的C#代码

今晚参考了 http://www.html-js.com/?p=1066&cpage=1 写了判断两线段是否相交的c#代码。基本思想是相交的两条线段,对于任意一线段的两端点,都在另一条直线的两边。 ...
  • I_code
  • I_code
  • 2011年11月25日 20:43
  • 5591

判断点在直线的一哪侧

转自:http://blog.sina.com.cn/s/blog_4dbb5c5f0101fxzn.html  谢谢分享! 方法1: http://zhidao.baidu.com/questio...
  • u010429424
  • u010429424
  • 2015年04月02日 11:00
  • 3309

轻轻松松做OpenGL鼠标拾取

http://blog.sina.com.cn/liuzhongtu http://www.cnblogs.com/Yuri/ 本文源自于一篇英文《OpenGL Picking Made Easy》,...
  • sangxiansheng
  • sangxiansheng
  • 2010年04月01日 10:28
  • 7146

计算机绘图原理 —— 直线的绘制

任何复杂的几何图形都是由基本图形元素(点、线等)组成的,直线等基本图形生成的关键是如何利用算法及数学公式描述并在图形设备上显示出来。1. 直线的绘制平面直线由两个端点唯一确定,绘制直线函数的一般表达式...
  • lanchunhui
  • lanchunhui
  • 2016年10月19日 10:33
  • 683

判断平面上两条直线是否相交

判断平面上两条直线是否相交 分类: 数据结构与算法设计2013-09-17 09:07 117人阅读 评论(0) 收藏 举报 直线相交 首先引出计算几何学中一个最基本的问...
  • pi9nc
  • pi9nc
  • 2013年09月18日 22:17
  • 6421

[置顶] OpenGL鼠标拾取的实现:终于搞定(包括细节问题)

void OpenGL::pickRects(){ /* GetCursorPos(&mouse); ScreenToClient(hWnd,&mouse); GLuint pickBuff...
  • daojin505
  • daojin505
  • 2017年08月08日 14:53
  • 364
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:绘图程序中直线的拾取判断
举报原因:
原因补充:

(最多只允许输入30个字)