poj1584 A round peg in a ground hole【計算幾何】
含【判斷凸包】,【判斷點在多邊形內】,【判斷圓在多邊形內】模板
凸包:即凸多邊形
用不嚴謹的話來講,給定二維平面上的點集,凸包就是將最外層的點連接起來構成的凸多邊形,它能包含點集中所有的點。
The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces of wood are attached to one another using a wooden peg that fits into pre-cut holes in each piece to be attached. The pegs have a circular cross-section and so are intended to fit inside a round hole.
A recent factory run of computer desks were flawed when an automatic grinding machine was mis-programmed. The result is an irregularly shaped hole in one piece that, instead of the expected circular shape, is actually an irregular polygon. You need to figure out whether the desks need to be scrapped or if they can be salvaged by filling a part of the hole with a mixture of wood shavings and glue.
There are two concerns. First, if the hole contains any protrusions (i.e., if there exist any two interior points in the hole that, if connected by a line segment, that segment would cross one or more edges of the hole), then the filled-in-hole would not be structurally sound enough to support the peg under normal stress as the furniture is used. Second, assuming the hole is appropriately shaped, it must be big enough to allow insertion of the peg. Since the hole in this piece of wood must match up with a corresponding hole in other pieces, the precise location where the peg must fit is known.
Write a program to accept descriptions of pegs and polygonal holes and determine if the hole is ill-formed and, if not, whether the peg will fit at the desired location. Each hole is described as a polygon with vertices (x1, y1), (x2, y2), . . . , (xn, yn). The edges of the polygon are (xi, yi) to (x i+1
Input
Input consists of a series of piece descriptions. Each piece description consists of the following data:Line 1 < nVertices > < pegRadius > < pegX > < pegY >
number of vertices in polygon, n (integer)
radius of peg (real)
X and Y position of peg (real)
n Lines < vertexX > < vertexY >
On a line for each vertex, listed in order, the X and Y position of vertex The end of input is indicated by a number of polygon vertices less than 3.
Output
HOLE IS ILL-FORMED if the hole contains protrusions
PEG WILL FIT if the hole contains no protrusions and the peg fits in the hole at the indicated position
PEG WILL NOT FIT if the hole contains no protrusions but the peg will not fit in the hole at the indicated position
Sample Input
5 1.5 1.5 2.0 1.0 1.0 2.0 2.0 1.75 2.0 1.0 3.0 0.0 2.0 5 1.5 1.5 2.0 1.0 1.0 2.0 2.0 1.75 2.5 1.0 3.0 0.0 2.0 1
Sample Output
HOLE IS ILL-FORMED PEG WILL NOT FIT
題意:
給定n個點 這n個點組成一個多邊形
給定一個peg的坐標和半徑
首先判斷這個多邊形是不是凸多邊形 若不是 輸出“HOLE IS ILL-FORMED”
否則判斷peg和多邊形的關系 若peg所代表的圓在多邊形內部輸出“PEG WILL FIT”
否則輸出“PEG WILL NOT FIT”
思路:
首先將n個點構造成封閉圖形,判斷是不是一個凸包
求連續兩條邊的叉乘,如果正負號與之前的出現了不同,說明不是凸包
再判斷圓心與多邊形的關系
設圓心為P,逐條枚舉n邊形的邊AB,利用
計算PA和PB的夾角,最後求和得到的就是環顧角。
(1) 圓心在多邊形內部時,環顧角=±360
(2) 圓心在多邊形外部時,環顧角=0
(3) 圓心在多邊形邊上時(不包括頂點),環顧角=±180
(4) 圓心在多邊形頂點時,環顧角為(0,360)之間的任意角,其實就是圓心所在的頂點的兩條鄰接邊的夾角。
最後判斷整個圓是否在多邊形內部
只需要求出圓心到邊的最短距離 若大於半徑則在多邊形內
設圓心為P,逐條枚舉n邊形的邊AB,利用得到△PAB的面積,
再根據公式S=0.5*|AB|*h,可以得到
枚舉所有h與圓的半徑R比對,只要所有的邊都有h - R>=0,則說明圓在多邊形內
1 //#include <bits/stdc++.h> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<stdio.h> 6 7 using namespace std; 8 typedef long long int LL; 9 10 const double eps = 1e-6; 11 const double pi = 3.141592654; 12 int n; 13 double radius; 14 struct point{ 15 double x, y; 16 }peg; 17 18 int precision(double x) 19 { 20 if(fabs(x) <= eps){ 21 return 0; 22 } 23 return x > 0 ? 1: -1; 24 } 25 26 double dotdet(double x1, double y1, double x2, double y2) 27 { 28 return x1 * x2 + y1 * y2; 29 } 30 31 double det(double x1, double y1, double x2, double y2) 32 { 33 return x1 * y2 - x2 * y1; 34 } 35 36 double cross(point a, point b, point c, point d) 37 { 38 return det(b.x - a.x, b.y - a.y, d.x - c.x, d.y - c.y); 39 } 40 41 double distant(point a, point b) 42 { 43 return sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y)); 44 } 45 46 double angle(point a, point b, point p) 47 { 48 return acos(dotdet(a.x - p.x, a.y - p.y, b.x - p.x, b.y - p.y) / (distant(a, p) * distant(b, p))); 49 } 50 51 bool isconvex(point *vectex) 52 { 53 int direction = 0; 54 //1, 逆時針;-1, 順時針 55 for(int i = 0; i < n; i++){ 56 int temp = precision(cross(vectex[i], vectex[i + 1], vectex[i + 1], vectex[i + 2])); 57 58 if(!direction){ 59 direction = temp; 60 } 61 if(direction * temp < 0){ 62 return false; 63 } 64 } 65 return true; 66 } 67 68 bool is_in(point *vectex) 69 { 70 double circleAngle = 0.0; 71 for(int i = 1; i <= n; i++){ 72 if(precision(cross(peg, vectex[i], peg, vectex[i + 1])) >= 0){ 73 circleAngle += angle(vectex[i], vectex[i + 1], peg); 74 } 75 else{ 76 circleAngle -= angle(vectex[i], vectex[i + 1], peg); 77 } 78 } 79 80 if(precision(circleAngle) == 0){ 81 return false; 82 //peg在多邊形外部 83 } 84 else if(precision(circleAngle - pi) == 0 || precision(circleAngle + pi) == 0){ 85 //peg在多邊形邊上 86 if(precision(radius) == 0){ 87 return true; 88 } 89 } 90 else if(precision(circleAngle - 2 * pi) == 0 || precision(circleAngle + 2 * pi) == 0){ 91 return true; 92 } 93 else{ 94 //peg在多邊形頂點上 95 if(precision(radius) == 0){ 96 return true; 97 } 98 } 99 return false; 100 } 101 102 bool isfit(point *vectex) 103 { 104 for(int i = 0; i <= n; i++){ 105 int k = precision(fabs(cross(peg, vectex[i], peg, vectex[i + 1]) / distant(vectex[i], vectex[i + 1])) - radius); 106 if(k < 0){ 107 return false; 108 } 109 } 110 return true; 111 } 112 113 int main() 114 { 115 while(scanf("%d", &n) != EOF && n >= 3){ 116 cin>> radius >> peg.x >> peg.y; 117 point *vectex = new point[n + 2]; 118 119 for(int i = 1; i <= n; i++){ 120 cin>>vectex[i].x >> vectex[i].y; 121 } 122 123 //構成封閉多邊形 124 vectex[0].x = vectex[n].x; 125 vectex[0].y = vectex[n].y; 126 vectex[n + 1].x = vectex[1].x; 127 vectex[n + 1].y = vectex[1].y; 128 129 if(!isconvex(vectex)){ 130 cout<<"HOLE IS ILL-FORMED"<<endl; 131 } 132 else{ 133 bool flag1 = is_in(vectex); 134 bool flag2 = isfit(vectex); 135 136 if(flag1 && flag2){ 137 cout<<"PEG WILL FIT"<<endl; 138 } 139 else{ 140 cout<<"PEG WILL NOT FIT"<<endl; 141 } 142 } 143 delete vectex; 144 } 145 return 0; 146 }
poj1584 A round peg in a ground hole【計算幾何】