[C++ / Algorithm] 선분과 점 사이의 거리 #23
1. 선분과 점의 위치 관계 분석
이 문제는 선분 AB와 P의 위치관계를 분석해서 3가지의 예외상황으로 나누어 풀면 쉽습니다.
이 3가지의 상황은 AP 벡터를 AB 벡터에 정사영시켜 구분할 수 있습니다.
AP 벡터와 AB 벡터를 정사영시킨 벡터의 길이가 0 이하이라면 아래 그림과 같이 점 P는 선분 AB에 수선을 그을 수 없을 상태이며, 점 A와의 거리가 선분 AB와의 거리가 된다는 것을 알 수 있습니다.
만약 길이가 선분 AB의 길이보다 작거나 같은 양수라면 아래 그림과 같이 선분 AB에 수선을 그려서 거리를 측정할 수 있습니다.
마지막으로 길이가 선분 AB의 길이보다 크다면 점 B와의 거리가 선분 AB와의 거리가 됩니다.
2. 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <cmath>
using namespace std;
struct Vector {
double x;
double y;
};
double length(Vector a) {
return sqrt(a.x * a.x + a.y * a.y);
}
double getDistance(Vector a, Vector b) {
double dx = b.x - a.x;
double dy = b.y - a.y;
return length({ dx, dy });
}
double dot(Vector a, Vector b) {
return a.x * b.x + a.y * b.y;
}
double getSegmentDistance(Vector a, Vector b, Vector p) {
Vector line = { b.x - a.x, b.y - a.y };
double lineLength = length(line);
if (lineLength == 0) return getDistance(a, p);
double projection = dot({ p.x - a.x, p.y - a.y }, { b.x - a.x, b.y - a.y }) / lineLength;
if (projection <= 0) return getDistance(a, p);
else if (projection >= lineLength) return getDistance(b, p);
else {
Vector projectionVector = {
a.x + line.x * projection / lineLength,
a.y + line.y * projection / lineLength
};
return getDistance(projectionVector, p);
}
}
int main() {
Vector a, b, p;
cin >> a.x >> a.y;
cin >> b.x >> b.y;
cin >> p.x >> p.y;
std::cout << getSegmentDistance(a, b, p);
return 0;
}
1
2
3
0 0
5 0
1 1
1
1
This post is licensed under
CC BY 4.0
by the author.