2선분의 교차 판정 방법(2차원)
그래서 동일 평면상에 존재하는 2선분의 교차 판정 수법에 대해 조사했다.
선분이 교차하는 조건
선분 $AB$ 과 선분 $CD$ 에 대해 생각한다.
(1) 점 $A$ 점 $B$ 를 포함하는 직선 $AB$ 를 경계선으로 하여 평면을 분할할 때 점 $C$ 점 $D$ 가 각각 다른 영역에 존재
(2) 점 $C$ 점 $D$를 포함하는 직선 $CD$를 경계선으로 하여 평면을 분할할 때 점 $A$ 점 $B$가 각각 다른 영역에 존재
(1), (2)의 조건을 모두 만족할 때 선분 $AB$와 선분 $CD$는 교차한다.
점이 존재하는 영역
점 $P$가 평면을 분할하는 직선에 대해 어느 영역에 존재하는지는 직선의 방정식에 점 $P$의 좌표를 대입한 값의 정 부로 판정할 수 있다.
예를 들어, 직선 $x - y = 0$ 에 대한 점 $C$ $(4, -2)$ 의 존재하는 영역을 조사하는 경우
$x - y$ 에 $(x, y) = (4, -2)$ 를 대입하면 $x - y = 6$ $(> 0)$
한편, 직선 $x - y = 0$ 에 대한 점 $D$ $(-4, 2)$ 의 존재하는 영역을 조사하는 경우
$x - y$ 에 $(x, y) = (-4, 2)$ 를 대입하면 $x - y = -6$ $(< 0)$
점 $ C, D $에서 얻은 값의 양수가 다르기 때문에 점 $ C, D $는 다른 영역에 존재한다는 것을 알 수 있습니다.
즉,이 판정
점 $P$가 평면을 분할하는 직선에 대해 어느 영역에 존재하는지는 직선의 방정식에 점 $P$의 좌표를 대입한 값의 정 부로 판정할 수 있다.
예를 들어, 직선 $x - y = 0$ 에 대한 점 $C$ $(4, -2)$ 의 존재하는 영역을 조사하는 경우
$x - y$ 에 $(x, y) = (4, -2)$ 를 대입하면 $x - y = 6$ $(> 0)$
한편, 직선 $x - y = 0$ 에 대한 점 $D$ $(-4, 2)$ 의 존재하는 영역을 조사하는 경우
$x - y$ 에 $(x, y) = (-4, 2)$ 를 대입하면 $x - y = -6$ $(< 0)$
점 $ C, D $에서 얻은 값의 양수가 다르기 때문에 점 $ C, D $는 다른 영역에 존재한다는 것을 알 수 있습니다.
즉,이 판정
로 하면 선분의 교차 판정을 할 수 있다.
(선분의 끝점이 다른 선분 상에 존재하는 경우에 주의)
선분의 교차 판정을 실시하는 알고리즘
우선 점 $A$ $(x_A, y_A),$ 점 $B$ $(x_B, y_B)$ 를 포함한 직선 $AB$ 의 방정식을 구한다.
직선 $AB$의 기울기는 $\frac{y_A - y_B}{x_A - x_B}$
직선 $AB$ 는 점 $A$ 를 포함하기 때문에, 직선 $AB$ 의 방정식은 $y - y_A =\frac{y_A - y_B}{x_A - x_B} (x - x_A)$
식을 변형하면 $(x_A - x_B)(y - y_A) - (y_A - y_B)(x - x_A) = 0$
따라서 점 $C$ $(x_C, y_C),$ 점 $D$ $(x_D, y_D)$ 의 영역 판정을 실시하는 경우
$s = (x_A - x_B)(y_C - y_A) - (y_A - y_B)(x_C - x_A)$
$t = (x_A - x_B)(y_D - y_A) - (y_A - y_B)(x_D - x_A)$
그렇다면 $ st <0 $ 일 때 점 $ C, D $는 직선 $ AB $에 대해 다른 영역에 존재한다고 할 수있다.
상기의 알고리즘을 C++로 기술한 예를 이하에 나타낸다.
typedef struct Point_Coordinates {
double x, y;
} point;
// 線分ab, cdが交差する場合True
// 端点が他方の線分上にある場合もTrue
// 端点が他方の線分の延長線上にある場合もTrueを返すので注意
int Judge(point &a, point &b, point &c, point &d) {
double s, t;
s = (a.x - b.x) * (c.y - a.y) - (a.y - b.y) * (c.x - a.x);
t = (a.x - b.x) * (d.y - a.y) - (a.y - b.y) * (d.x - a.x);
if (s * t > 0)
return false;
s = (c.x - d.x) * (a.y - c.y) - (c.y - d.y) * (a.x - c.x);
t = (c.x - d.x) * (b.y - c.y) - (c.y - d.y) * (b.x - c.x);
if (s * t > 0)
return false;
return true;
}
외적을 이용하는 방법
지금까지 직선의 방정식을 이용하여 영역 판정을 행해 왔지만, 외적을 이용하면 간단하게 판정을 행할 수 있다.
2차원 평면에서 벡터 $\vec{a},\vec{b}$ 의 외적 $\vec{a}\times\vec{b}$ 는 $\vec{a}$ 에서 $\vec{b}$ 에의 오른쪽 나사의 방향을 부호로 가지는 스칼라값이 된다.
따라서 선분 $AB, CD$의 교차 판정을 할 경우
$s =\vec{AB}\times\vec{AC} = (x_B - x_A)(y_C - y_A) - (x_C - x_A)(y_B - y_A)$
$t =\vec{AB}\times\vec{AD} = (x_B - x_A)(y_D - y_A) - (x_D - x_A)(y_B - y_A)$
그렇다면 $ st <0 $ 일 때 점 $ C, D $는 직선 $ AB $에 대해 다른 영역에 존재한다고 할 수있다.
또한 이 $st$ 의 값은 선분의 교차 판정을 실시하는 알고리즘 와 같은 값을 취하는 것을 알 수 있다
요약
겉보기 다른 구하는 방법에서도 같은 식이 인도되는 재미
Reference
이 문제에 관하여(2선분의 교차 판정 방법(2차원)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/zu_rin/items/e04fdec4e3dec6072104
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
typedef struct Point_Coordinates {
double x, y;
} point;
// 線分ab, cdが交差する場合True
// 端点が他方の線分上にある場合もTrue
// 端点が他方の線分の延長線上にある場合もTrueを返すので注意
int Judge(point &a, point &b, point &c, point &d) {
double s, t;
s = (a.x - b.x) * (c.y - a.y) - (a.y - b.y) * (c.x - a.x);
t = (a.x - b.x) * (d.y - a.y) - (a.y - b.y) * (d.x - a.x);
if (s * t > 0)
return false;
s = (c.x - d.x) * (a.y - c.y) - (c.y - d.y) * (a.x - c.x);
t = (c.x - d.x) * (b.y - c.y) - (c.y - d.y) * (b.x - c.x);
if (s * t > 0)
return false;
return true;
}
지금까지 직선의 방정식을 이용하여 영역 판정을 행해 왔지만, 외적을 이용하면 간단하게 판정을 행할 수 있다.
2차원 평면에서 벡터 $\vec{a},\vec{b}$ 의 외적 $\vec{a}\times\vec{b}$ 는 $\vec{a}$ 에서 $\vec{b}$ 에의 오른쪽 나사의 방향을 부호로 가지는 스칼라값이 된다.
따라서 선분 $AB, CD$의 교차 판정을 할 경우
$s =\vec{AB}\times\vec{AC} = (x_B - x_A)(y_C - y_A) - (x_C - x_A)(y_B - y_A)$
$t =\vec{AB}\times\vec{AD} = (x_B - x_A)(y_D - y_A) - (x_D - x_A)(y_B - y_A)$
그렇다면 $ st <0 $ 일 때 점 $ C, D $는 직선 $ AB $에 대해 다른 영역에 존재한다고 할 수있다.
또한 이 $st$ 의 값은 선분의 교차 판정을 실시하는 알고리즘 와 같은 값을 취하는 것을 알 수 있다
요약
겉보기 다른 구하는 방법에서도 같은 식이 인도되는 재미
Reference
이 문제에 관하여(2선분의 교차 판정 방법(2차원)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/zu_rin/items/e04fdec4e3dec6072104
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(2선분의 교차 판정 방법(2차원)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/zu_rin/items/e04fdec4e3dec6072104텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)