应该是很常用的:
已知点p(x,y)。
线段的两个端点(x1,y1) (x2,y2).判断点是否在该线段上?
有哪位仁兄可以给我现成源代码的?谢谢。:)

解决方案 »

  1.   

    如下步骤:
    1. 点p, 端点p1, p2;计算矢量 v = p2-p1; v 单位化
    2. 计算v的垂直向量,
      n.x = -v.y;
      n.y = v.x;
    3. 计算矢量 vd = p-p1;
    4. 计算投影 fProj = vd * n;  注意这是点乘
    5. 取 fProj 绝对值;如果绝对值小于 fTolerance(一个小量)那么就认为点p落于直线p1p2上。注意是直线而不是线段
    6. (p-p1) * (p-p2) 如果小于0,则点p落于线段之上,否则,点p落于线段之外。
    ============================================================================
    提问题时标题要简明扼要地说明问题内容,切忌使用"急","求救"之类不能说明问题的标题
    http://www.betajin.com/alphasun/index.htm          给我发信息请附带原帖地址
    http://alphasun.18en.com/                    http://shakingtoolkit.9126.com/
    DocWizard C++程序文档自动生成工具 | Wave OpenGL | HttpProxy | AjaxParser词法分析
      

  2.   

    已经经过调试,结果正确。
    #include <stdio.h>
    #include <math.h>void main()
    {
    int x1, x2, y1, y2;
    int x, y;
    int d, d1, d2;
    x1 = x2 = 10;
    y1 = 0;
    y2 = 100;
    printf("请输入x, y");
    scanf("%d %d", &x, &y); 
    d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
    d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
    d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
    if(d == (d1 + d2))
    printf("点在直线上");
    else
    printf("点不在直线上");}
      

  3.   

    如果改成float型或double型。
    那么需要像楼上说的,加入一个最小值
    if(d == (d1 + d2))
    改为if(abs((d - d1 - d2) < mini))
      

  4.   

    d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
    d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
    d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
    if(d == (d1 + d2))
    printf("点在直线上");
    else
    printf("点不在直线上");
    这段代码在线段上也可以行得通?确认没错了么?
      

  5.   

    (m_ipTraceX[i]-m_ipTraceX[0])+m_ipTraceY[0];
    if(iTemY>=m_MidPoint.y-0.9&&iTemY<m_MidPoint.y+0.9&&m_ipTraceX[i]>m_MidPoint.x)
    {
    //AfxMessageBox("ok1");
    break;//此时点在其上
    }
    凑热闹
    炮炮说的对。我用两点直线公式计算
      

  6.   

    没贴全:
    if((m_ipTraceX[i]-m_ipTraceX[0])==0)continue;
    iTemY=(float)(m_MidPoint.x-m_ipTraceX[0])*(m_ipTraceY[i]-m_ipTraceY[0])/
    (m_ipTraceX[i]-m_ipTraceX[0])+m_ipTraceY[0];
    if(iTemY>=m_MidPoint.y-0.9&&iTemY<m_MidPoint.y+0.9&&m_ipTraceX[i]>m_MidPoint.x)
    {
    //AfxMessageBox("ok1");
    break;
    }
      

  7.   

    if(d == (d1 + d2))
    这样是算不对的
      

  8.   

    http://msdn.microsoft.com/library/en-us/dngdi/html/msdn_hittest2.asp?frame=trueMSDN提供的技术文档“Win32: Hit Testing Lines and Curves”
      

  9.   

    // 线段而不是直线
    if (x<x1 && x<x2) return false;
    if (x>x1 && x>x2) return false;
    if (y<y1 && y<y2) return false;
    if (y>y1 && y>y2) return false;
    // 点重合
    if (x==x1 && y==y1) return true;
    if (x==x2 && y==y2) return true;const double point10_x = double(x )-double(x1);
    const double point10_y = double(y )-double(y1);
    const double point12_x = double(x2)-double(x1);
    const double point12_y = double(y2)-double(y1);
    if (0==point10_x  ||  0==point12_x)// 有竖直线
      return   0==point10_x && 0==point12_x;// both 竖直线if (point10_y/point10_x  ==  point12_y/point12_x)
      return true; // 斜率相同
    return false;
      

  10.   

    如果原来的点也是用double 保存的话
    最多是18浮点次加法、2次浮点乘法如果原来的点也是用long 保存的话
    最多是12次整数加法、6次浮点加法、2次浮点乘法
      

  11.   

    to syl08341(沈阳老零):
    try the followed codes on.x1 = 0;y1 = 0;
    x2 = 1;y2 = 2;
    x  = 1;y  = 1;d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
    d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
    d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
    if(d == (d1 + d2))
      MessageBox ("点在直线上");
    else
      MessageBox ("点不在直线上");
      

  12.   

    [上面那个例子不典型]x1 = 0;y1 = 0;
    x2 = 1;y2 = 4; // <= change y2 to be 4 (or more large number) 
    x  = 1;y  = 1;d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
    d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
    d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
    if(d == (d1 + d2))
      MessageBox ("点在直线上");
    else
      MessageBox ("点不在直线上");
      

  13.   

    我的程序在整数情况下肯定是可行的。
    对于浮点数或double型,我在第一个贴子后面就说了,
    见我的第二个贴子。
    /*
    如果改成float型或double型。
    那么需要像楼上说的,加入一个最小值
    if(d == (d1 + d2))
    改为if(abs((d - d1 - d2) < mini))
    */
      

  14.   

    To Panr(光荣):谢谢你给我指出问题,不过我编写这个程序主要是提供一个思路。
    而且在程序后面已经有一个贴子说明了对于整数可行,对于浮点数的改法。
      

  15.   

    没错,思路是对的(其实我的代码也是应该加个误差值判断比较好 ^_^)其实我想说的是
    int d, d1, d2;
    to be 
    double d, d1, d2;