这是一个纯解析几何的题目,不是有一个直线外一点到直线的距离公式吗?是的,不过在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;
}