判斷點是否在直線上
這是一個純解析幾何的題目,不是有一個直線外一點到直線的距離公式嗎?是的,不過在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;
}