弄了2天区块链结果还是没弄出什么东西来。。然后回来继续学计算几何。。。

半平面交的模板还是不太好背的 。。玄学公式+双端队列。。emmmmmm

双端队列这东西貌似从斜率优化后就没用到了。。非常生疏。。

算法有2个,一个n^2,一个nlogn。。当然选nlogn。。。

思路是让半平面按极角排序。。然后依次加入队列中排除多余半平面即可。。

细节非常多。。例如:加入队列时要先去队尾再去队首。。最后要先去队首再去队尾。。(坑了我半天。。

然后 cmp那块if判断叉积是否为正时不造为什么老是要丢掉后面的>eps。。。

还有。。就是那个求交点的intersect。。有个玄学公式。。需要用到相似。。这里证明一下。。


poj3130(半平面交模板)_#define

如上图所示,对于向量AB和向量CD,其交点为P,现在要求P的坐标。设S1为三角形ACB的面积,S2为三角形ADB的面积,由叉积的性质可得:S1 = cross(A,B,C) / 2,即向量AB和向量AC叉积的一半(注意结果的正负),同理,S2 = cross(A,D,B)。此外,再做三角形ACB和三角形ADB在AB边上的垂线CE和DF,则S1 = |CE| * |AB| / 2,S2 = |DF| * |AB| / 2,而且注意到两个直角三角形CPE和DPF相似,则得到比例关系:|CP| / |PD| = |CE| / |DF|  ,此时由以上五个等式得到:S1 / S2 = |CE| / |DF| = |CP| / |PD|。

设P坐标为(xp,yp),则由S1 / S2 = |CP| / |PD|   ==》 (xc - xp) / (xp - xd) = (yc - yp) / (yp - yd) = S1 / S2  ==》 xp = (S1 * xd + S2 * xc) / (S1 + S2)  , yp = (S1 * yd + S2 * yc) / (S1 + S2)。

然后道理窝是懂。。可是为什么t1、t2非得那样求不可啊。。




#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define eps 1e-8
#define inf 1e9
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define ls T[i<<1]
#define rs T[i<<1|1]
#define op T[i]
#define mid (x+y>>1)
#define NM 10005
#define nm 100498
#define pi 3.141592653
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}

struct P{
double x,y;
P(double x=0,double y=0):x(x),y(y){}
double operator*(const P&o){return x*o.y-y*o.x;}
P operator-(const P&o){return P(x-o.x,y-o.y);}
}p[NM];
struct L{P a,b;double k;}l[NM];
int n,tmp[NM],q[NM],qh,qt,m;
bool cmp(int x,int y){
if(fabs(l[x].k-l[y].k)<eps)return (l[y].b-l[x].a)*(l[x].b-l[x].a)>eps;
else return l[x].k<l[y].k;
}
void intersect(L x,L y,P&p){
double t1=(x.b-y.a)*(x.a-y.a),t2=(y.b-x.b)*(x.a-x.b);
p.x=(y.a.x*t2+y.b.x*t1)/(t1+t2);
p.y=(y.a.y*t2+y.b.y*t1)/(t1+t2);
}

bool judge(L a,L b,L c){
P p;
intersect(b,c,p);
return (a.b-a.a)*(p-a.a)+eps<0;
}

void solve(){
sort(tmp+1,tmp+1+n,cmp);m=1;
inc(i,2,n)if(fabs(l[tmp[i]].k-l[tmp[m]].k)>eps)tmp[++m]=tmp[i];
mem(q);qh=1;qt=0;
inc(k,1,m){
int i=tmp[k];
while(qh<qt&&judge(l[i],l[q[qt-1]],l[q[qt]]))qt--;
while(qh<qt&&judge(l[i],l[q[qh+1]],l[q[qh]]))qh++;
q[++qt]=i;
}
while(qh<qt&&judge(l[q[qt]],l[q[qh+1]],l[q[qh]]))qh++;
while(qh<qt&&judge(l[q[qh]],l[q[qt-1]],l[q[qt]]))qt--;
}

int main(){
//freopen("data.in","r",stdin);
while(n=read()){
inc(i,1,n)p[i].x=read(),p[i].y=read();
p[n+1]=p[1];
inc(i,1,n){
l[i].a=p[i];l[i].b=p[i+1];
l[i].k=atan2(p[i+1].y-p[i].y,p[i+1].x-p[i].x);
tmp[i]=i;
}
solve();
//printf("%d %d\n",qh,qt);
printf("%d\n",qt>qh+1);
}
return 0;
}








How I Mathematician Wonder What You Are!


Time Limit: 5000MS

 

Memory Limit: 65536K

Total Submissions: 4057

 

Accepted: 2184


Description


After counting so many stars in the sky in his childhood, Isaac, now an astronomer and a mathematician uses a big astronomical telescope and lets his image processing program count stars. The hardest part of the program is to judge if shining object in the sky is really a star. As a mathematician, the only way he knows is to apply a mathematical definition ofstars.

The mathematical definition of a star shape is as follows: A planar shape F is star-shaped if and only if there is a point C ∈ F such that, for any point P ∈F, the line segment CP is contained in F. Such a point C is called acenter of F. To get accustomed to the definition let’s see some examples below.




poj3130(半平面交模板)_#include_02


The first two are what you would normally call stars. According to the above definition, however, all shapes in the first row are star-shaped. The two in the second row are not. For each star shape, a center is indicated with a dot. Note that a star shape in general has infinitely many centers. Fore Example, for the third quadrangular shape, all points in it are centers.

Your job is to write a program that tells whether a given polygonal shape is star-shaped or not.


Input


The input is a sequence of datasets followed by a line containing a single zero. Each dataset specifies a polygon, and is formatted as follows.

n x1y1x2y2

xnyn

The first line is the number of vertices, n, which satisfies 4 ≤ n ≤ 50. Subsequent n lines are the x- and y-coordinates of then vertices. They are integers and satisfy 0 ≤ xi ≤ 10000 and 0 ≤yi ≤ 10000 (i = 1, …, n). Line segments (xi,yi)–(xi + 1, yi + 1) (i = 1, …,n − 1) and the line segment (xn, yn)–(x1,y1) form the border of the polygon in the counterclockwise order. That is, these line segments see the inside of the polygon in the left of their directions.

You may assume that the polygon is simple, that is, its border never crosses or touches itself. You may assume assume that no three edges of the polygon meet at a single point even when they are infinitely extended.


Output


For each dataset, output “​​1​​​” if the polygon is star-shaped and “​​0​​” otherwise. Each number must be in a separate line and the line should not contain any other characters.


Sample Input


6 66 13 96 61 76 98 13 94 4 0 45 68 8 27 21 55 14 93 12 56 95 15 48 38 46 51 65 64 31 0


Sample Output


10


Source


​Japan 2006​


[​​Submit​​​]   [Go Back]   [​​Status​​​]   [​​Discuss​​]