두 점 $A$와 $B$가 만드는 선분 $\overline{AB}$가 있고, 한 점 $P$에서 이 선분까지 거리를 구하려고 할 때 단순히 $\overline{AB}$를 통과하는 직선과 점 $P$의 거리를 구해서 쓰면 안 된다. 그림처럼 $P$가 $P'$의 위치에 있는 경우에 $\overline{AB}$를 통과하는 직선과의 거리가 더 짧지만, 선분과의 거리는 $P'$와 $A$와 거리로 주어진다. 마찬가지로 $P$가 $P''$에 있을 때는 점 $B$와 거리가 최단거리다. 정리하면,
1. 선분 $\overline{AP}$와 $\overline{AB}$의 사이각이 $90^\circ$를 넘는 경우는 $A$까지 거리;
$$\cos (\text{사이각}) = \frac{(P.x - A.x)*(B.x - A.x) + (P.y - A.y)*(B.y - A.y)}{\overline{AP}\text{ 길이} * \overline{AB}\text{ 길이}} < 0 .$$
2. 선분 $\overline{AP}$의 $\overline{AB}$로의 정사영 길이가 $\overline{AB}$의 길이보다 클 때는 $B$까지 거리:
$$\text{정사영 길이} = \frac{(P.x - A.x)*(B.x - A.x) + (P.y - A.y)*(B.y - A.y)}{ \overline{AB}\text{ 길이}} > \overline{AB}\text{ 길이} .$$
3. 직선 $\overline{AB}$와의 거리 = $\overline{AP}$의 수선으로 정사영 길이:
$$\text{수선으로 정사영} = \frac{-(P.x - A.x)*(B.y - A.y) + (P.y - A.y)*(B.x - A.x)}{\overline{AB}\text{ 길이}} .$$

struct CfPt {
    double x, y;
    double DistanceTo(CfPt P) {
        return hypot(P.x - x, P.y - y);
    }
};
//선분과의 거리;
double SegmentDistance(CfPt A, CfPt B, CfPt P) {
    double lineLen = A.DistanceTo(B);
    if (lineLen == 0) return A.DistanceTo(P);  //A == B;
    // lineLen != 0 case
    double prj = ((P.x - A.x )*(B.x - A.x) + (P.y - A.y) * (B.y - A.y)) / lineLen;
    if (prj < 0) return A.DistanceTo(P);
    else if (prj > lineLen) return B.DistanceTo(P);
    else 
        //return normal_projection
        return fabs((-1)*(P.x - A.x)*(B.y - A.y) + (P.y - A.y)*(B.x - A.x)) / lineLen;
};
 

선분까지 거리를 컬러로 표현

 
728x90

'Computational Geometry' 카테고리의 다른 글

Finding the Convex Hull of Simple Polygon  (0) 2010.07.03
Polyline Simplication  (0) 2010.01.17
삼각형 채우기  (0) 2009.12.19
Triangulation을 이용한 Imge Effect  (0) 2009.12.18
Ellipse Drawing Algorithm  (0) 2008.06.04
Posted by helloktk
,