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

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. JS中的内存泄漏

    明天下午面试微店的前端开发职位,有点紧张~~ 刚刚正好看到js中的内存泄露,所以来整理一番. 给DOM对象添加的属性是对一个js对象的引用. var MyObject = {}; document.g ...

  2. HDU 2722 Here We Go(relians) Again

    最短路,建图太麻烦,略过…… #include <cstdio> #include <cstring> #include <queue> const int INF ...

  3. Flex4 设置combobox选项不可编辑

    近日做数据的增删改查,使用的flex4的ComboBox控件---> flex4中ComboBox其实就是TextInput的叠加 flex3中ComboBox其实就是Label的叠加 开始是使 ...

  4. TEX Quotes(字符串,水)

    TEX Quotes Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9674   Accepted: 5073 Descri ...

  5. CodeForces 150B- Quantity of Strings 推算..

    假设 k = 5 , n>k ,   (1,2,3,4,5)  -> 1=5,2=4,3任意 (2,3,4,5,6) -> 2=6,3=5,4任意...综合上面的可得出1=3=5,2 ...

  6. Android 中文API (65) —— BluetoothClass[蓝牙]

    前言 本章内容是android.bluetooth.BluetoothClass,为Android蓝牙部分的章节翻译.用于描述远端设备的类型,特点等信息,通过getBluetoothClass()方法 ...

  7. 【翻译】【中英对照】【企业库6】动手实验 Hands-On Lab 日志应用程序块索引页

    Logging Application Block Hands-On Lab for Enterprise Library 企业库的日志应用程序块动手实验 This walkthrough shoul ...

  8. [C#参考]事件和委托的关系

    前面说了委托,接下来就要说一说事件了,同时最后再说一下委托和事件的区别. 事件和委托很相似,事件就好像是被简化的针对特殊用途的委托.看下面的图: 从这张图中能看到,事件是发布者的一个成员,它不是类型. ...

  9. 新建linux组、用户命令

    之前在安装oracle的时候,出现了一个问题:安装Oracle,新建组.用户的时候的一个错误.看这篇博客前,先看这个链接,学习要从解决出现的问题出手. 建立用户组和用户 下面总结一下Linux建立组和 ...

  10. Java疯狂讲义(四)