大致思路:首先对于所给的洞的点,判断是否是凸多边形,图形的输入和输出可以是顺时针或者逆时针,而且允许多点共线

Debug 了好几个小时,发现如下问题

判断三点是否共线,可用斜率公式判断

POINT point_A, point_B, point_C;
if(point_A.x == point_B.x || point_B.x == point_C.x){
if(point_A.x == point_B.x && point_B.x == point_C.x)
continue;
}else{
if((point_B.y - point_A.y) / (point_B.x - point_A.x) \
== (point_C.y - point_B.y) / (point_C.x - point_B.x))
continue;
}

其次,判断圆是否和多边形相切的时候,应用:

if(Ptol(point, line2) - rr >= 0){

而不是:

 if(Ptol(point, line2) - rr >= eps){//eps = 1e-9

否则会出错。

贴代码了QAQ

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
using namespace std; const int INF = 0x3f3f3f3f;
const int MAXN = ;
const double eps = 1e-; int gcd(int a,int b){
return b == ? a : gcd(b, a % b);
}
struct POINT{
double x;
double y;
POINT() : x(), y() {};
POINT(double _x_, double _y_) : x(_x_), y(_y_) {};
}; struct SEG{
POINT a;
POINT b;
SEG() {};
SEG(POINT _a_, POINT _b_) : a(_a_), b(_b_) {};
}; struct LINE{
POINT a;
POINT b;
LINE() {};
LINE(POINT _a_, POINT _b_) : a(_a_), b(_b_) {};
}; struct LINE2{
double A, B, C;
LINE2 () {};
LINE2(double _A_, double _B_, double _C_): A(_A_), B(_B_), C(_C_) {};
}; LINE2 Line2line(const LINE & L){
LINE2 L2;
L2.A = L.b.y - L.a.y;
L2.B = L.a.x - L.b.x;
L2.C = L.b.x * L.a.y - L.a.x * L.b.y;
return L2;
} struct POLY{
int n;
double * x;
double * y;
POLY() : n(), x(NULL), y(NULL) {};
POLY(int _n_, const double * _x_, const double * _y_){
n = _n_;
x = new double[n + ];
memcpy(x, _x_, n * sizeof(double));
x[n] = _x_[];
y = new double[n + ];
memcpy(y, _y_, n * sizeof(double));
y[n] = _y_[];
}
}; POINT vertex(const POLY & poly, int idx){
idx %= poly.n;
return POINT(poly.x[idx], poly.y[idx]);
} SEG Edge(const POLY & poly, int idx){
idx %= poly.n;
return SEG(POINT(poly.x[idx], poly.y[idx]),
POINT(poly.x[idx + ], poly.y[idx + ]));
} void Coefficient(const LINE & L, double & A, double & B, double & C){
A = L.b.y - L.a.y;
B = L.a.x - L.b.x;
C = L.b.x * L.a.y - L.a.x * L.b.y;
} double Ptol(const POINT p, const LINE2 L){
return Abs(L.A * p.x + L.B * p.y + L.C) / sqrt(L.A * L.A + L.B * L.B);
} bool IsEqual(double a, double b){
return (Abs(a - b) < eps);
} bool IsEqual(const POINT & a, const POINT & b){
return (IsEqual(a.x, b.x) && IsEqual(a.y, b.y));
} bool IsEqual(const LINE & A, const LINE & B){
double A1, B1, C1;
double A2, B2, C2;
Coefficient(A, A1, B1, C1);
Coefficient(B, A2, B2, C2);
return IsEqual(A1 * B2, A2 * B1) &&
IsEqual(A1 * C2, A2 * C1) &&
IsEqual(B1 * C2, B2 * C1);
} double Cross(const POINT & a, const POINT & b, const POINT &o){
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
} bool IsParallel(const LINE & A, const LINE & B){
double A1, B1, C1;
double A2, B2, C2;
Coefficient(A, A1, B1, C1);
Coefficient(B, A2, B2, C2);
/*
return (A1 * B2 == A2 * B1) &&
((A1 * C2 != A2 * C1) || (B1 * C2 != B2 * C1));
*/
return (A1 * B2 == A2 * B1);
} bool IsIntersect(const LINE & A, const LINE & B){
return !IsParallel(A, B);
} bool IsIntersect(const SEG & u, const SEG & v){
return (Cross(v.a, u.b, u.a) * Cross(u.b, v.b, u.a) >= ) &&
(Cross(u.a, v.b, v.a) * Cross(v.b, u.b, v.a) >= ) &&
(Max(u.a.x, u.b.x) >= Min(v.a.x, v.b.x)) &&
(Max(v.a.x, v.b.x) >= Min(u.a.x, u.b.x)) &&
(Max(u.a.y, u.b.y) >= Min(v.a.y, v.b.y)) &&
(Max(v.a.y, v.b.y) >= Min(u.a.y, u.b.y));
} bool IsOnSeg(const SEG & seg, const POINT & p){
return (IsEqual(p, seg.a) || IsEqual(p, seg.b)) ||
(((p.x - seg.a.x) * (p.x - seg.b.x) < ||
(p.y - seg.a.y) * (p.y - seg.b.y) < ) &&
(IsEqual(Cross(seg.b, p, seg.a), )));
} bool IsOnPoly(const POLY & poly, const POINT & p){
for(int i = ; i < poly.n; ++i){
if(IsOnSeg(Edge(poly, i), p)){
return true;
}
}
return false;
} bool IsInPoly(const POLY & poly, const POINT & p){
SEG L(p, POINT(INF, p.y));
int count = ;
for(int i = ; i < poly.n; ++i){
SEG S = Edge(poly, i);
if(IsOnSeg(S, p)){
return true;
}
if(!IsEqual(S.a.y, S.b.y)){
POINT & q = (S.a.y > S.b.y) ? (S.a) : (S.b);
if(IsOnSeg(L, q)){
++count;
} else if(!IsOnSeg(L, S.a) && !IsOnSeg(L, S.b) && IsIntersect(S, L)){
++count;
}
}
}
return (count % != );
} POINT InCenter(const POLY & poly){
double S, Si, Ax, Ay;
POINT p;
Si = (poly.x[poly.n - ] * poly.y[] - poly.x[] * poly.y[poly.n - ]);
S = Si;
Ax = Si * (poly.x[] + poly.x[poly.n - ]);
Ay = Si * (poly.y[] + poly.y[poly.n - ]);
for(int i = ; i < poly.n; ++i){
Si = (poly.x[i - ] * poly.y[i] - poly.x[i] * poly.y[i - ]);
Ax += Si * (poly.x[i - ] + poly.x[i]);
Ay += Si * (poly.y[i - ] + poly.y[i]);
S += Si;
}
S = S * ;
return POINT(Ax/S, Ay/S);
} double Area(const POLY & poly){
if(poly.n < ) return double();
double s = poly.y[] * (poly.x[poly.n - ] - poly.x[]);
for(int i = ; i < poly.n; ++i){
s += poly.y[i] * (poly.x[i - ] - poly.x[(i + ) % poly.n]);
}
return s / ;
} int PointInedge(const POLY & poly){
int ans = ;
for(int i = ; i < poly.n; ++i){
double xx = Abs(poly.x[i] - poly.x[i + ]);
double yy = Abs(poly.y[i] - poly.y[i + ]);
if(xx == && yy == )
ans += ;
else if(xx == )
ans += yy - ;
else if(yy == )
ans += xx- ;
else
ans += gcd(xx, yy) - ;
}
return ans + poly.n;
} bool IsConvexPolygon(const POLY & poly){
double ans ,cnt = 1.0;
bool flag ,real = false;
for(int i = ; i < poly.n; ++i){
ans = (poly.x[i] - poly.x[(i + ) % poly.n])\
* (poly.y[(i + ) % poly.n] - poly.y[(i + ) % poly.n])\
- (poly.x[(i + ) % poly.n] - poly.x[(i + ) % poly.n])\
* (poly.y[i] - poly.y[(i + ) % poly.n]); POINT point_A, point_B, point_C;
if(point_A.x == point_B.x || point_B.x == point_C.x){
if(point_A.x == point_B.x && point_B.x == point_C.x)
continue;
}else{
if((point_B.y - point_A.y) / (point_B.x - point_A.x) \
== (point_C.y - point_B.y) / (point_C.x - point_B.x))
continue;
}
if(real && cnt * ans < eps) return false;
cnt = ans;
real = true;
}
return true;
} double x[], y[];
int main(){
int i, j, k;
int t, n, m;
double rr, xx, yy;
while(EOF != scanf("%d",&n)){
if(n < ) break;
POINT point;
scanf("%lf%lf%lf",&rr,&point.x,&point.y);
for(i = ; i < n; ++i)
scanf("%lf%lf",&x[i],&y[i]);
POLY poly(n, x, y); if(!IsConvexPolygon(poly))
printf("HOLE IS ILL-FORMED\n");
else{
if(!IsInPoly(poly, point)){ printf("PEG WILL NOT FIT\n");
}
else{
for(i = ; i < n; ++i){
SEG seg = Edge(poly, i);
LINE line;
LINE2 line2;
line.a = seg.a;
line.b = seg.b;
line2 = Line2line(line); if(Ptol(point, line2) - rr >= ){
continue;
}
else{
printf("PEG WILL NOT FIT\n");
break;
}
}
if(i == n){
printf("PEG WILL FIT\n");
}
}
}
}
return ;
}

poj1584 A Round Peg in a Ground Hole 判断多边形凹凸,点到线的距离【基础计算几何】的更多相关文章

  1. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,判断点在凸多边形内

    A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5456   Acc ...

  2. POJ 1584 A Round Peg in a Ground Hole[判断凸包 点在多边形内]

    A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6682   Acc ...

  3. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内

    首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...

  4. poj1584 A round peg in a ground hole【计算几何】

    含[判断凸包],[判断点在多边形内],[判断圆在多边形内]模板  凸包:即凸多边形 用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点. The ...

  5. A Round Peg in a Ground Hole(判断是否是凸包,点是否在凸包内,圆与多边形的关系)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4628   Accepted: 1434 Description The D ...

  6. POJ1584 A Round Peg in a Ground Hole 凸包判断 圆和凸包的关系

    POJ1584 题意:给定n条边首尾相连对应的n个点 判断构成的图形是不是凸多边形 然后给一个圆 判断圆是否完全在凸包内(相切也算) 思路:首先运用叉积判断凸多边形 相邻三条边叉积符号相异则必有凹陷 ...

  7. A Round Peg in a Ground Hole(凸包应用POJ 1584)

    A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5684 Accepte ...

  8. POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)

    A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4438   Acc ...

  9. POJ 1518 A Round Peg in a Ground Hole【计算几何=_=你值得一虐】

    链接: http://poj.org/problem?id=1584 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

随机推荐

  1. multi-threaded copy command - robocopy

    we can copy files by the powerful robocopy tool, and it allow copy using muliti-threaded as well. As ...

  2. uva 1561 - Cycle Game(推理)

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=4336" style=""& ...

  3. BZOJ 1864: [Zjoi2006]三色二叉树( 树形dp )

    难得的ZJOI水题...DFS一遍就行了... ----------------------------------------------------------------------- #inc ...

  4. Oracle语句优化规则(二)

    21.       用EXISTS替换DISTINCT 当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换  例如: ...

  5. Python学习之路——函数

    一.Python2.X内置函数表: 注:以上为pyton2.X内置函数,官方网址:https://docs.python.org/2/library/functions.html 二.Python3. ...

  6. ajax是怎么发请求的和浏览器发的请求一样吗?cookie

    下午设置cookie时出现了个问题 用ajax发的post请求php,在php的方法里设置了cookie,然后在浏览器请求的php里打印cookie值但是一直获取不到cookie的值 分析: 1.aj ...

  7. shell学习之用户管理和文件属性

    1.组和用户的添加 添加组: groupadd [-g gid [-o]] [-r] [-f] group 示例: groupadd -g testgoup1 #添加组testgroup1,同时指定g ...

  8. Week14(12月9日)

    Part I:提问 =========================== 1.ASP.NET MVC围绕事件驱动的页面声明周期而建立,在渲染的页面上可以触发事件. 2.ASP.NET MVC脱离了H ...

  9. Xamarin.Android开发实践(一)

    原文:Xamarin.Android开发实践(一) 一.准备工作 1.创建一个空的解决方案,并命名为Phoneword 2.右击解决方案 新建->新建项目 并命名为Phoneword_Droid ...

  10. Windows Phone 8初学者开发—第8部分:理解编译和部署

    原文 Windows Phone 8初学者开发—第8部分:理解编译和部署 第8部分:理解编译和部署 原文地址: http://channel9.msdn.com/Series/Windows-Phon ...