2014-11-10 3 views
0

enter image description here내 프로그램에서 현재 다음 줄을

참조하십시오. 다른 두 개의 정수 변수 인 xy이 있습니다.

이 새로운 지점 (x, y)이이 줄에 있는지 확인하고 싶습니다. 나는 다음과 같은 스레드에서 찾고있다 :

Given a start and end point, and a distance, calculate a point along a line

내가 함께 왔어요 다음

if(x >= x1 && x <= x2 && (y >= y1 && y <= y2 || y <= y1 && y >= y2)) 
{ 
    float vx = x2 - x1; 
    float vy = y2 - y1; 
    float mag = sqrt(vx*vx + vy*vy); 
    // need to get the unit vector (direction) 
    float dvx = vx/mag; // this would be the unit vector (direction) x for the line 
    float dvy = vy/mag; // this would be the unit vector (direction) y for the line 

    float vcx = x - x1; 
    float vcy = y - y1; 
    float magc = sqrt(vcx*vcx + vcy*vcy); 
    // need to get the unit vector (direction) 
    float dvcx = vcx/magc; // this would be the unit vector (direction) x for the point 
    float dvcy = vcy/magc; // this would be the unit vector (direction) y for the point 

    // I was thinking of comparing the direction of the two vectors, if they are the same then the point must lie on the line? 
    if(dvcx == dvx && dvcy == dvy) 
    { 
     // the point is on the line! 
    } 
} 

이 작동하지 않는 것, 또는이 아이디어는 구타입니까?

+2

2 차원에서 (x1, y1) 및 (x2, y2)에서 얻은 선 방정식에 (x, y)를 단순히 두지 않는 이유는 무엇입니까? – P0W

+0

'(x, y)'는 (제목에서 알 수 있듯이) 점 (벡터가 질문을 나타내는 것처럼 보입니다)입니까? 질문이 실제로 의미가있는 것처럼 보일 뿐이지 만 두 벡터에 의해 정의 된 선이 교차하는지 여부를 말하는 것일 수 있습니다. –

+0

먼저, 귀하의 조건/가정을 기재하십시오. 부동 소수점을 처리하는 경우 부동 소수점 부정확성을 고려해야합니다. 수식으로의 직접적인 수학은 효과가 없습니다. – dornhege

답변

4

부동 소수점 숫자의 정밀도가 제한되어 있으므로 계산에서 반올림 오류가 발생하여 수학적으로 같아야하는 값이 약간 달라집니다.

당신은 오류에 대한 작은 허용 오차와 비교해야합니다 : 어려운 부분이 그 허용을 선택하고있다

if (std::abs(dvcx-dvx) < tolerance && std::abs(dvcy-dvy) < tolerance) 
{ 
    // the point is (more or less) on the line! 
} 

. 오류를 받아 들일 수없는 경우 고정 소수점 부동 소수점 값 이외의 다른 값 (예 : 정수)을 사용해야하며 나누기 및 기타 부정확 한 연산을 피하기 위해 재정렬 된 계산이 필요합니다.

어쨌든 제곱근과 같은 것없이이 작업을보다 간단하게 수행 할 수 있습니다. 두 벡터가 평행인지 알아 내야합니다. 그들은 벡터 곱이 제로이거나 등가 적으로 동일한 접선을 갖는 경우입니다. 그래서 당신은 당신의 입력이 곱셈 오버 플로우하지 않을만큼 작은 정수, 경우

if (vx * vcy == vy * vcx) // might still need a tolerance for floating-point 
{ 
    // the point is on the line! 
} 

는 모든 부동 소수점 연산에 대한 필요가 없습니다 필요합니다.

+0

정교하게, x1, y1 및 x2, y2는 정수입니다! –

+0

@ KarlMorrison :이 경우 부동 소수점 헛소리를 피할 수 있어야합니다. 내 업데이트 답변을 참조하십시오. –

0

먼저 선 방정식을 계산해야합니다. 그런 다음이 방정식이 당신이 가지고있는 x와 y의 값에 대해 참이되는지보십시오. 선의 방정식을 계산하려면 y 축의 위치와 기울기를 계산해야합니다. 방정식은 y = mx + c 형식입니다. 여기서 m은 기울기이고 c는 '가로 채기'입니다 (선이 y 축과 교차하는 곳).

부동 소수점 값을
0

는 == 사용하는 대신 작은 차이를 테스트하지 않습니다

float originalTangent = (y2 - y1)/(x2 - x1); 
float newTangent = (y - y1)/(x - x1); 
if (fabs(newTangent - originalTangent) < delta) { ... } 
: 또한

if (fabs(dvcx-dvx) < delta && fabs(dvcy-dvy) < delta) 

, 당신은 정말 그냥 탄젠트를 단위 벡터가 필요하지 않습니다

(델타는 기대하고 정확도에 따라 약간 적은 수 있어야한다.)

0

(x, y)가 포인트 실제로 감안할 때, 작업이 보인다 당신이 만드는 것보다 조금 더 간단합니다.

완벽하게 수평 또는 수직선이 있는지 확인하는 것이 좋습니다. 이 경우 xx1x2 사이에 있는지 (또는 y에서 세로로 y1에서 y2 사이인지) 확인합니다.

그렇지 않으면 x에서 선형 보간을 사용하고 올바른 반올림 허용 오차 내에서 y에 대한 올바른 값을 제공하는지 확인하십시오. 이를 위해 다음과 같은 작업을 수행하십시오.

slope = (y2-y1)/(x2-x1); 
if (abs(slope * (x - x1) - y) < tolerance) 
    // (x,y) is on the line 
else 
    // (x,y) isn't on the line 
1

이 문제를 해결하는 효율적인 방법은 삼각형의 부호가있는 영역을 사용하는 것입니다. {x1,y1}, {x2,y2}{x,y} 점으로 생성 된 삼각형의 부호있는 영역이 0에 가까울 때 {x,y}을 줄에 포함시킬 수 있습니다. 다른 사람들이 언급했듯이 부동 소수점 값을 사용하는 경우 좋은 공차 값을 선택하는 것이 중요한 부분입니다.

bool isPointOnLine (xy p1, xy p2, xy p3) // returns true if p3 is on line p1, p2 
    { 
    xy va = p1 - p2; 
    xy vb = p3 - p2; 
    area = va.x * vb.y - va.y * vb.x; 
    if (abs (area) < tolerance) 
     return true; 
    return false; 
    } 

{x,y}이 라인에 놓여 있는지 알 수 있도록하지만, {x,y}이 선분에 포함되는 경우가 결정되지 않습니다. 이렇게하려면 라인 세그먼트의 경계에 대해 {x,y}을 확인해야합니다.

관련 문제