• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

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

发布: 2007-7-01 20:40 | 作者: admin | 来源: | 查看: 21次 | 进入软件测试论坛讨论

领测软件测试网

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



在图中点击点为p(x,y),判断此次点击是否拾取直线(p1,p2)就是计算点p到直线(p1,p2)的距离。如果已知直线方程Ax+By+C=0,那么点(x,y)到直线距离即为d=fabs(Ax+By+C)/sqrt(A*A+B*B)。


已知直线上两点(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>


 


延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网