标签:ble 否则 into radius 1.5 must spec flag diy
含【判断凸包】,【判断点在多边形内】,【判断圆在多边形内】模板
凸包:即凸多边形
用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。
Input
Output
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【计算几何】
标签:ble 否则 into radius 1.5 must spec flag diy
原文地址:https://www.cnblogs.com/wyboooo/p/9736459.html