判断点是否在直线上

这是一个纯解析几何的题目,不是有一个直线外一点到直线的距离公式吗?是的,不过在GDI的领域,不需要这样去考虑问题,不需要考虑直一方程,我们直接可以从坐标对上着手。

 

struct CGeoXY
{
 double dx,dy;
};

 

/*参数说明

    pXY是一条直线的所有坐标对数组

    nPointCount是数组中的点数

    dx,dy是要计算的点

    dOffset 是偏移量,即dx,dy与直线的距离差< dOffset 即可判断为在直线上。

*/

bool isPtAtLine(CGeoXY* pXY, int nPointCount,double dx,double dy,double dOffset)
{
 double dx1,dy1,dx2,dy2;
 double dA1,dA2;

 for (int i = 0;i < nPointCount - 1;i++){
  dx1 = pXY[i].dx;
  dy1 = pXY[i].dy;

  dx2 = pXY[i + 1].dx;
  dy2 = pXY[i + 1].dy;

  if (isPtInRect(dx,dy,dx1,dy1,dx2,dy2)){
      dA1 = getDirection(dx1,dy1,dx,dy);
          dA2 = getDirection(dx1,dy1,dx2,dy2);

   if (abs(sin(dA1 - dA2) * getDistance(dx1,dy1,dx,dy)) < dOffset){
           return true;
   }
  }
  else{
   if (abs(dx1 - dx2) < dOffset){
    if (dy > min(dy1,dy2) && dy < max(dy1,dy2) && abs(dx - dx1) < dOffset){
     return true;
    }
   }
   if (abs(dy1 - dy2) < dOffset){
    if (dx > min(dx1,dx2) && dx < max(dx1,dx2) && abs(dy - dy1) < dOffset){
     return true;
    }
   }
  } 
 }
 return false;
}

 

里面还用到了两个函数:

 

/* 计算点是否在矩形范围内*/

//left一定比right小,top一定比bottom小
bool isPtInRect(double dx,double dy, double dLeft,double dTop,double dRight,double dBottom)
{
 if (dLeft > dRight) { dLeft = dLeft + dRight; dRight = dLeft - dRight; dLeft = dLeft - dRight;}
 if (dTop > dBottom) { dTop = dTop + dBottom; dBottom = dTop - dBottom; dTop = dTop - dBottom;}

 if (dx < dLeft || dx > dRight || dy < dTop || dy > dBottom)
  return false;
 else
  return true;
}

 

 

/*计算两点的斜率或角度,弧度*/

double getDirection(double dx1,double dy1,double dx2, double dy2)
{
 double dBufLen, dDirection;

 dBufLen = getDistance(dx1,dy1,dx2,dy2);

 if (abs(dx2 - dx1) < 10e-300) {
  if (abs(dy2 - dy1)< 10e-300){
  //等于没有移动}
  }
  else {
   if ( dy1 - dy2 > 0) dDirection = PI/2;
   else dDirection = 3*PI/2;
  }
 }
 else {
  if (atan((dy1 - dy2)/(dx2 - dx1)) > 0){
   if (sin((dy1-dy2)/dBufLen)>0)
    dDirection = atan((dy1-dy2)/(dx2-dx1));
              else
    dDirection =atan((dy1-dy2)/(dx2 - dx1)) + PI;
  }
  else {
           if (sin((dy1-dy2)/dBufLen) > 0 )
    dDirection = atan((dy1-dy2)/(dx2 - dx1)) + PI;
   else
    dDirection = atan((dy1-dy2)/(dx2 - dx1));
           
   if (dDirection == 0 && dx1 > dx2) dDirection = PI;
  }
 }
 
 if (dDirection < 0) dDirection = 2 * PI + dDirection;
    return dDirection;
}

你可能感兴趣的:(地理信息世界,程序生涯)