Question: Calculate the closest distance between two non-Intersecting polygon.
Http://poj.org/problem? Id = 3608
Here is a detailed explanation: http://cgm.cs.mcgill.ca /~ Orm/mind2p.html
This is to find the point in the lower left corner of the first convex bag, find the point in the lower right corner of the second convex, two parallel lines are stuck.
And then start to rotate, divided into three situations:
The two wires and Two convex packets overlap and overlap with one of them.
The shortest distance between a line and a line segment, and the shortest distance between a point and a line segment. Note that the distance between a line and a line is not equivalent to the shortest distance between a line and a line.
It's a tough question. It's estimated that few people have 1A, and there are a lot of details.
[Cpp]
# Include <iostream>
# Include <fstream>
# Include <iomanip>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <cstdlib>
# Include <cmath>
# Include <set>
# Include <map>
# Include <queue>
# Include <stack>
# Include <string>
# Include <vector>
# Include <sstream>
# Include <ctime>
# Include <cassert>
# Define LL long
# Define eps 1e-8
# Define inf 999999.0
# Define zero (a) abs (a) <eps
# Define N 20
# Define pi acos (-1.0)
Using namespace std;
Struct Point {
Double x, y;
} P [10005], q [10005], pos;
Vector <Point> s1, s2;
Double dist (Point p1, Point p2 ){
Return sqrt (p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y ));
}
Double xmul (Point p0, Point p1, Point p2 ){
Return (p1.x-Snapshot X) * (p2.y-Snapshot y)-(p2.x-Snapshot X) * (p1.y-Snapshot y );
}
// Graham_scan convex hull
Bool cmp (Point p1, Point p2 ){
If (xmul (pos, p1, p2)> eps) return true;
Else if (zero (xmul (pos, p1, p2) & dist (pos, p1) <dist (pos, p2) return true;
Return false;
}
Void Graham_scan (vector <Point> & s, Point p [], int n ){
For (int I = 1; I <n; I ++)
If (p [I]. y <p [0]. y | (zero (p [I]. y = p [0]. y) & p [I]. x <p [0]. x ))
Swap (p [I], p [0]);
Pos = p [0];
Sort (p + 1, p + n, cmp );
S. clear ();
S. push_back (p [0]); s. push_back (p [1]); s. push_back (p [2]);
For (int I = 3; I <n; I ++ ){
While (s. size ()> = 2 & xmul (s [s. size ()-2], s [s. size ()-1], p [I]) <eps) s. pop_back ();
S. push_back (p [I]);
}
}
// Obtain the positional relationship between the a1b1 and a2b2 vectors.
Double Get_angle (Point a1, Point b1, Point a2, Point b2 ){
Point t;
T. x = a2.x-(b2.x-a1.x );
T. y = a2.y-(b2.y-a1.y );
Return xmul (a1, b1, t );
}
Double Dist_Point_Seg (Point p, Point a, Point B ){
Point t = p;
T. x + = a. y-b.y; t. y + = B. x-a.x;
If (xmul (a, t, p) * xmul (B, t, p)> eps)
Return dist (p, a) + eps <dist (p, B )? Dist (p, a): dist (p, B );
Else
Return fabs (xmul (p, a, B)/dist (a, B );
}
Double Min_Dist_Two_Polygons (vector <Point> s1, vector <Point> s2 ){
Int na = s1.size (), nb = s2.size ();
Int lp = 0, SCSI = 0;
For (int I = 1; I <na; I ++)
If (s1 [I]. y <s1 [lp]. y | (zero (s1 [I]. A y-s1 [lp]. y) & s1 [I]. x <s1 [lp]. x ))
Lp = I;
For (int I = 1; I <nb; I ++)
If (s2 [I]. y> s2 [SCSI]. y | (zero (s2 [I]. y-s2 [SCSI]. y) & s2 [I]. x> s2 [SCSI]. x ))
SCSI = I;
S1.push _ back (s1 [0]); s2.push _ back (s2 [0]);
Double ans = dist (s1 [lp], s2 [SCSI]);
Int tp = lp, tq = SCSI;
Do {
Double angle = Get_angle (s1 [tp], s1 [tp + 1], s2 [tq], s2 [tq + 1]);
// Overlap with the edges of the Two convex packets
If (zero (angle )){
Ans = min (ans, Dist_Point_Seg (s1 [tp], s2 [tq], s2 [tq + 1]);
Ans = min (ans, Dist_Point_Seg (s1 [tp + 1], s2 [tq], s2 [tq + 1]);
Ans = min (ans, Dist_Point_Seg (s2 [tq], s1 [tp], s1 [tp + 1]);
Ans = min (ans, Dist_Point_Seg (s2 [tq + 1], s1 [tp], s1 [tp + 1]);
Tp = (tp + 1) % na; tq = (tq + 1) % nb;
}
Else {
// Overlap with the edges of the second convex hull
If (angle <-eps ){
Ans = min (ans, Dist_Point_Seg (s1 [tp], s2 [tq], s2 [tq + 1]);
Tq = (tq + 1) % nb;
}
// Overlap with the edges of the first convex hull
Else {
Ans = min (ans, Dist_Point_Seg (s2 [tq], s1 [tp], s1 [tp + 1]);
Tp = (tp + 1) % na;
}
}
} While (! (Lp = tp & SCSI = tq ));
Return ans;
}
Int main (){
Int n, m;
While (scanf ("% d", & n, & m )! = EOF & n + m ){
For (int I = 0; I <n; I ++)
Scanf ("% lf", & p [I]. x, & p [I]. y );
Graham_scan (s1, p, n );
For (int I = 0; I <m; I ++)
Scanf ("% lf", & q [I]. x, & q [I]. y );
Graham_scan (s2, q, m );
Printf ("%. 5f \ n", Min_Dist_Two_Polygons (s1, s2 ));
}
Return 0;
}