Poj 1584 A Round Peg in a Ground Hole

Source: Internet
Author: User

This question requires multiple computational Geometric algorithms. The first is to determine whether a series of points can constitute a convex polygon, and the second is to determine whether a point is inside a simple polygon,
The third is to find the distance from a point to a line segment (or a straight line), and the fourth is to judge whether a circle is otherwise inside a convex polygon.
In fact, I want to judge whether a circle is or else a convex polygon uses algorithm 2 and algorithm 3. In fact, there is no need to judge the center of the circle or the algorithm inside the polygon.
In algorithm 1, the deflection direction of all edges must be clockwise or clockwise. Algorithm 2 is the article I mentioned earlier to improve the arc-length method to determine the relationship between points and polygon,
Algorithm 3 is particularly simple. Take two points above the straight line and use the cross product to find two times the area of the triangle formed by these three points, and divide them by the bottom edge. In algorithm 4, we first judge that the center is inside the polygon, and then
Determine that the distance from the center to all sides is greater than the radius of the circle.
The code is simply used as a template in the future to prevent forgetting and facilitate searching. In fact, you can click it now.

The Code is as follows:
# Include <stdio. h>
# Include <string. h>
# Include <math. h>
# Include <algorithm>
# Include <vector>
Using namespace std;

Const double fPre = 1e-8;
Int DblCmp (double fD)
{
If (fabs (fD) <fPre)
{
Return 0;
}
Else
{
Return fD> 0? 1:-1;
}
}

Struct Point
{
Double x, y;
Bool operator = (const Point & p)
{
Return DblCmp (x-p. x) = 0 & DblCmp (y-p. y) = 0;
}
};

Point operator-(const Point & a, const Point & B)
{
Point p;
P. x = a. x-B. x;
P. y = a. y-B. y;
Return p;
}

Double Det (double fX1, double fY1, double fX2, double fY2)
{
Return fX1 * fY2-fX2 * fY1;
}

Double Cross (Point a, Point B, Point c)
{
Return Det (B. x-a. x, B. y-a. y, c. x-a. x, c. y-a. y );
}

Bool IsConvexPolygon (vector <Point> & vp)
{
Int nN = vp. size ();
Int nDirection = 0;
Bool bLine = true; // avoid collinearity of all vertices
For (int I = 0; I <nN; ++ I)
{
Int nTemp = DblCmp (Cross (vp [I], vp [(I + 1) % nN], vp [(I + 2) % nN]);
If (nTemp)
{
BLine = false;
}
// The direction of this operation must be the same as that of the previous operation or be collocated at three and above.
If (nDirection * nTemp <0)
{
Return false;
}
NDirection = nTemp;
}
Return bLine = false;
}

Int GetQuadrant (Point p)
{
Return p. x> = 0? (P. y> = 0? 0: 3): (p. y> = 0? 1: 2 );
}

Bool IsPtInPolygon (vector <Point> & vp, Point p)
{
Int nN = vp. size ();
Int nA1, nA2, nSum = 0;
Int I;

NA1 = GetQuadrant (vp [0]-p );
For (I = 0; I <nN; ++ I)
{
Int j = (I + 1) % nN;
If (vp [I] = p)
{
Break;
}
Int nC = DblCmp (Cross (p, vp [I], vp [j]);
Int nT1 = DblCmp (vp [I]. x-p. x) * (vp [j]. x-p. x ));
Int nT2 = DblCmp (vp [I]. y-p. y) * (vp [j]. y-p. y ));
If (! NC & nT1 <= 0 & nT2 <= 0)
{
Break;
}
NA2 = GetQuadrant (vp [j]-p );
Switch (nA2-nA1 + 4) % 4)
{
Case 1:
NSum ++;
Break;
Case 2:
If (nC> 0)
{
NSum + = 2;
}
Else
{
NSum-= 2;
}
Break;
Case 3:
NSum --;
Break;
}
NA1 = nA2;
}

If (I <nN | nSum)
{
Return true;
}
Return false;
}

Double PtDis (Point a, Point B)
{
Return sqrt (. x-B. x) * (. x-B. x) + (B. y-. y) * (B. y-. y ));
}
// Distance from point p to line AB
// H = (2 * Spab)/| AB |
Double GetDis (Point a, Point B, Point p)
{
Return fabs (Cross (a, B, p)/PtDis (a, B );
}

Bool IsCircleInPolygon (vector <Point> & vp, Point p, double fR)
{
If (! IsPtInPolygon (vp, p ))
{
Return false;
}

Int nN = vp. size ();
For (int I = 0; I <nN; ++ I)
{
If (GetDis (vp [I], vp [(I + 1) % nN], p) <fR)
{
Return false;
}
}
Return true;
}

Int main ()
{
Int nN;
Double fR, fPx, fPy;
Vector <Point> vp;
Point p;

While (scanf ("% d % lf", & nN, & fR, & fPx, & fPy), nN> = 3)
{
Vp. clear ();
For (int I = 0; I <nN; ++ I)
{
Scanf ("% lf", & p. x, & p. y );
Vp. push_back (p );
} Www.2cto.com

If (IsConvexPolygon (vp ))
{
P. x = fPx;
P. y = fPy;
If (IsCircleInPolygon (vp, p, fR ))
{
Printf ("peg will fit \ n ");
}
Else
{
Printf ("peg will not fit \ n ");
}
}
Else
{
Printf ("hole is ill-FORMED \ n ");
}
}

Return 0;
}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.