免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1102 | 回复: 0
打印 上一主题 下一主题

直线的拾取 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-08-07 14:37 |只看该作者 |倒序浏览
在绘图程序中如何直线进行拾取
这段时间在分析一个画图程序,遇到了对直线拾取的问题,去论坛逛了一下,目前有两个方法比较好。
1。利用坐标系变换计算点到直线的距离
鼠标点击点为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,
        (y1
        (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
    return FALSE;
}
2。点到直线距离的变种
/**
  * Tests if a point is on a line.
  */
         //已知两点的坐标为:(x1,y1),(x2,y2),鼠标坐标为(px,py)
boolean lineContainsPoint(int x1, int y1,       int x2, int y2,
   int px, int py) {
  double a, b, x, y;
  a = (double)(y1 - y2) / (double)(x1 - x2);
  b = (double)y1 - a * (double)x1;
  x = (py - b) / a;
  y = a * px + b;
  return (Math.min(Math.abs(x - px), Math.abs(y - py))


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/4654/showart_39527.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP