判断内核
//poj3335 半平面交
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps = 1e-8;
const int maxn = 105;
int dq[maxn], top, bot, pn, order[maxn], ln;
struct Point {
double x, y;
} p[maxn];
struct Line {
Point a, b;
double angle;
} l[maxn];
int dblcmp(double k) {
if (fabs(k) < eps) return 0;
return k > 0 ? 1 : -1;
}
double multi(Point p0, Point p1, Point p2) {
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
bool cmp(int u, int v) {
int d = dblcmp(l[u].angle-l[v].angle);
if (!d) return dblcmp(multi(l[u].a, l[v].a, l[v].b)) < 0;
return d < 0;
}
void getIntersect(Line l1, Line l2, Point& p) {
double dot1,dot2;
dot1 = multi(l2.a, l1.b, l1.a);
dot2 = multi(l1.b, l2.b, l1.a);
p.x = (l2.a.x * dot2 + l2.b.x * dot1) / (dot2 + dot1);
p.y = (l2.a.y * dot2 + l2.b.y * dot1) / (dot2 + dot1);
}
bool judge(Line l0, Line l1, Line l2) {
Point p;
getIntersect(l1, l2, p);
return dblcmp(multi(p, l0.a, l0.b)) > 0;
}
void addLine(double x1, double y1, double x2, double y2) {
l[ln].a.x = x1; l[ln].a.y = y1;
l[ln].b.x = x2; l[ln].b.y = y2;
l[ln].angle = atan2(y2-y1, x2-x1);
order[ln] = ln;
ln++;
}
void halfPlaneIntersection() {
int i, j;
sort(order, order+ln, cmp);
for (i = 1, j = 0; i < ln; i++)
if (dblcmp(l[order[i]].angle-l[order[j]].angle) > 0)
order[++j] = order[i];
ln = j + 1;
dq[0] = order[0];
dq[1] = order[1];
bot = 0;
top = 1;
for (i = 2; i < ln; i++) {
while (bot < top && judge(l[order[i]], l[dq[top-1]], l[dq[top]])) top--;
while (bot < top && judge(l[order[i]], l[dq[bot+1]], l[dq[bot]])) bot++;
dq[++top] = order[i];
}
while (bot < top && judge(l[dq[bot]], l[dq[top-1]], l[dq[top]])) top--;
while (bot < top && judge(l[dq[top]], l[dq[bot+1]], l[dq[bot]])) bot++;
}
bool isThereACore() {
if (top-bot > 1) return true;
return false;
}
int main()
{
int t, i;
scanf ("%d", &t);
while (t--) {
scanf ("%d", &pn);
for (i = 0; i < pn; i++)
scanf ("%lf%lf", &p[i].x, &p[i].y);
//有方向 顺时针
for (ln = i = 0; i < pn-1; i++)
addLine(p[i].x, p[i].y, p[i+1].x, p[i+1].y);
addLine(p[i].x, p[i].y, p[0].x, p[0].y);
halfPlaneIntersection();
if (isThereACore()) printf ("YES\n");
else printf ("NO\n");
}
return 0;
}
求凸多边形内核面积
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <deque>
using namespace std;
typedef double db;
const db eps=1e-6;
const db pi=acos(-1);
int sign(db k){
if (k>eps) return 1; else if (k<-eps) return -1; return 0;
}
int cmp(db k1,db k2){return sign(k1-k2);}
struct point{
db x,y;
point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
point operator * (db k1) const{return (point){x*k1,y*k1};}
point operator / (db k1) const{return (point){x/k1,y/k1};}
db getP()const { return sign(y)==1||(sign(y)==0&&sign(x)==-1);}
};
db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
db rad(point k1,point k2){ return atan2(cross(k1,k2),dot(k1,k2));}
int compareangle(point k1,point k2){
return k1.getP()<k2.getP()||(k1.getP()==k2.getP()&&sign(cross(k1,k2))>0);
}
point getLL(point k1,point k2,point k3,point k4){
db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3);
return (k1*w2+k2*w1)/(w1+w2);
}
struct line{
point p[2];
line(point k1,point k2){p[0]=k1;p[1]=k2;}
point &operator[](int k){ return p[k];}
int include(point k){ return sign(cross(p[1]-p[0],k-p[0])>0);}
point dir(){ return p[1]-p[0];}
};
point getLL(line k1,line k2){
return getLL(k1[0],k1[1],k2[0],k2[1]);
}
int parallel(line k1,line k2){ return sign(cross(k1.dir(),k2.dir()))==0;}
int sameDir(line k1,line k2){
return parallel(k1,k2)&&sign(dot(k1.dir(),k2.dir()))==1;
}
int operator <(line k1,line k2){
if(sameDir(k1,k2))return k2.include(k1[0]);
return compareangle(k1.dir(),k2.dir());
}
int checkpos(line k1,line k2,line k3){ return k3.include(getLL(k1,k2));}
vector<line> getHL(vector<line> &L){
sort(L.begin(),L.end());deque<line> q;
for(int i=0;i<L.size();i++){
if(i&&sameDir(L[i],L[i-1]))continue;
while (q.size()>1&&!checkpos(q[q.size()-2],q[q.size()-1],L[i]))q.pop_back();
while (q.size()>1&&!checkpos(q[1],q[0],L[i]))q.pop_front();
q.push_back(L[i]);
}
while (q.size()>2&&!checkpos(q[q.size()-2],q[q.size()-1],q[0]))q.pop_back();
while (q.size()>2&&!checkpos(q[1],q[0],q[q.size()-1]))q.pop_front();
vector<line> ans;for(int i=0;i<q.size();i++)ans.push_back(q[i]);
return ans;
}
int t,n;
point p[1551];
bool cw(){//时针
db s=0;
for(int i=1;i<n-1;i++){
s+=cross(p[i]-p[0],p[i+1]-p[0]);
}
return s>0;
}
vector<line>l;
int main(){
scanf("%d",&t);
while (t--){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
if(!cw())reverse(p,p+n);
for(int i=0;i<n;i++){
l.push_back(line(p[i],p[(i+1)%n]));
}
l=getHL(l);
if(l.size()<3){
printf("0.00\n");
} else{
vector<point> a;
for(int i=0;i<l.size();i++){
a.push_back(getLL(l[i],l[(i+1)%l.size()]));
}
db ans = 0;
for(int i=1;i<a.size()-1;i++)
ans+=cross(a[i]-a[0],a[i+1]-a[0]);
ans/=2;
printf("%.2f\n",ans);
}
l.clear();
}
}