Given a point, a circle, and a rectangle, how short is the shortest distance from a point to a circle to a rectangle? To reach a target, you can just join or pass through it.
Solution: currently, we only know that dividing from one point to the Circle based on the two half circles of [0, Pi], [Pi, 2 * Pi] is indeed a concave function to satisfy the distance, however, if the distance to the rectangle is still three points, you don't know how to get it. The specific method is to first translate the entire coordinate system so that the center of the circle falls at (0, 0), and then enumerate the points on the circle by three points. The distance consists of two parts, one of which is the distance from the point to the point on the circle, one part is the distance from the point to the rectangle, and the latter is converted to the distance from the point to the four line segments.
CodeAs follows:
# Include <cstdlib> # Include <Cstring> # Include <Cstdio> # Include <Algorithm> # Include <Iostream> # Include <Cmath> Using Namespace STD; Const Double EPS = 1E- 6 ; Const Double Pi = ACOs (- 1.0 ); Double CX, Cy, CR; // Circle center and radius Inline Int Sign ( Double X ){ Return X <-EPS? - 1 : X> EPS? 1 : 0 ;} Struct Point { Double X, Y; point ( Double Xx = 0 , Double YY = 0 ): X (XX), y (yy) {} Point Operator -(Const Point & ot) Const { // Difference between two vertices to obtain the Vector Return Point (X-ot. X, Y- Ot. Y );} Double Operator *( Const Point & ot) Const { // Heavy load point Product Return X * ot. x + y * Ot. Y ;} Double Operator ^ ( Const Point & ot) Const { // Heavy Load Cross Product Return X * ot. Y-y * Ot. X ;} Bool Operator <( Const Point & ot) Const { If (Sign (X-Ot. X )){ Return Sign (X-ot. X) < 0 ; // First, sort by abscissa } Else { // Then sort by ordinate Return Sign (Y-ot. Y) < 0 ;}} Void Show () {printf ( " X = %. 2f, y = %. 2f \ n " , X, y) ;}}; point it, RP [ 4 ]; Double Dist ( Const Point &, Const Point & B ){ Return SQRT (A. x-b.x) * (A. x-b.x) + (A. y-b.y) * (A. Y- B. Y ));} Double Dtol ( Const Point & NP,Const Point & St, Const Point & ED ){ // Distance from a point to a line segment Double RET; If (Sign (ED-St) * (NP-St)> 0 & Sign (St-ed) * (NP-ed)> 0 )){ // Used to determine the projection of a point on the Line Segment Ret = FABS (St-np) ^ (ED-np ))/ Dist (St, Ed );} Else {RET = Min (Dist (NP, St), dist (NP, Ed )); // A small value from point to two endpoints } Return RET ;} Double Dtor ( Const Point & NP ){ // Shortest distance to four line segments Double D1 = min (dtol (NP, RP [ 0 ], RP [ 1 ]), Dtol (NP, RP [ 0 ], RP [ 2 ]); Double D2 = min (dtol (NP, RP [ 1 ], RP [ 3 ]), Dtol (NP, RP [ 2 ], RP [ 3 ]); Return Min (D1, D2 );} Double Tsearch ( Double L, Double R ){ Double Delta; While (R-l> = EPS) {Delta = (R-l )/ 3.0 ; // Delta indicates 1/3 of the Interval Length. Point LP (Cr * Cos (L + delta), Cr * sin (L + Delta); point RP (Cr * Cos (R-delta), Cr * sin (R- Delta )); Double D1 = dist (it, LP) + Dtor (LP ); Double D2 = dist (it, RP) +Dtor (RP ); If (Sign (D1-D2)> 0 ) {L + = Delta ;} Else {R -= Delta ;}} point FP (Cr * Cos (R), Cr * Sin (R )); Return Dist (it, FP) + Dtor (FP );} Void Solve (){ // First 3 points [0, Pi], angle within 3 points [Pi, 2 * Pi] Printf ( " %. 2f \ n " , Min (tsearch ( 0 , Pi), tsearch (PI, 2 * Pi )));} Int Main (){ While (Scanf ( " % Lf " , & It. X, & it. Y), sign (it. x) | Sign (it. y) {scanf ( " % Lf " , & CX, & cy, & Cr ); // Read center coordinates and radius It. X-= Cx, it. Y-= Cy; // Translate the center of the circle to the source point, and change other coordinates. Scanf ( " % Lf " , & RP [ 0 ]. X, & RP [ 0 ]. Y); RP [ 0 ]. X-= Cx, RP [ 0 ]. Y-= Cy; scanf ( " % Lf " , & RP [ 1 ]. X, & RP [ 1 ]. Y); RP [ 1 ]. X-= Cx, RP [ 1 ]. Y-= Cy; RP [ 2 ]. X = RP [ 0 ]. X, RP [ 2 ]. Y = RP [ 1 ]. Y; RP [ 3 ]. X = RP [ 1 ]. X, RP [ 3 ]. Y = RP [ 0 ]. Y; sort (RP, RP + 4 ); // Obtains and sorts the four vertices of a rectangle to obtain the relationship between a line segment and a vertex. Double T = SQRT ( 2.0 )/ 2 ; Solve ();} Return 0 ;}