程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 3130 How I Mathematician Wonder What You Are! - 求多邊形有沒有核

poj 3130 How I Mathematician Wonder What You Are! - 求多邊形有沒有核

編輯:C++入門知識

/*
poj 3130 How I Mathematician Wonder What You Are! - 求多邊形有沒有核



*/
#include <stdio.h>
#include<math.h>
const double eps=1e-8;
const int N=103;
struct point
{
    double x,y;
}dian[N];
inline bool mo_ee(double x,double y)
{
	double ret=x-y;
	if(ret<0) ret=-ret;
	if(ret<eps) return 1;
	return 0;
}
inline bool mo_gg(double x,double y)  {   return x > y + eps;} // x > y
inline bool mo_ll(double x,double y)  {   return x < y - eps;} // x < y
inline bool mo_ge(double x,double y) {   return x > y - eps;} // x >= y
inline bool mo_le(double x,double y) {   return x < y + eps;} 	// x <= y
inline double mo_xmult(point p2,point p0,point p1)//p1在p2左返回負,在右邊返回正
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

point mo_intersection(point u1,point u2,point v1,point v2)
{
    point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
		/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}
/////////////////////////

//切割法求半平面交
point mo_banjiao_jiao[N*2];
point mo_banjiao_jiao_temp[N*2];
void mo_banjiao_cut(point *ans,point qian,point hou,int &nofdian)
{
	int i,k;
	for(i=k=0;i<nofdian;++i)
	{
		double a,b;
		a=mo_xmult(hou,ans[i],qian);
		b=mo_xmult(hou,ans[(i+1)%nofdian],qian);
		if(mo_ge(a,0))//順時針就是<=0
		{
			mo_banjiao_jiao_temp[k++]=ans[i];
		}if(mo_ll(a*b,0))
		{
			mo_banjiao_jiao_temp[k++]=mo_intersection(qian,hou,ans[i],ans[(i+1)%nofdian]);
		}
	}
	for(i=0;i<k;++i)
	{
		ans[i]=mo_banjiao_jiao_temp[i];
	}
	nofdian=k;
}
int mo_banjiao(point *dian,int n)
{
	int i,nofdian;
	nofdian=n;
	for(i=0;i<n;++i)
	{
		mo_banjiao_jiao[i]=dian[i];
	}
	for(i=0;i<n;++i)//i從0開始
	{
		mo_banjiao_cut(mo_banjiao_jiao,dian[i],dian[(i+1)%n],nofdian);
		if(nofdian==0)
		{
			return nofdian;
		}
	}
	return nofdian;
}
/////////////////////////
int main()
{
    int t,i,n;
    while(scanf("%d",&n),n)
    {
        
        for(i=0;i<n;++i)
        {
            scanf("%lf%lf",&dian[i].x,&dian[i].y);
        }
        int ret=mo_banjiao(dian,n);
        if(ret==0)
        {
            printf("0\n");
        }else
        {
            printf("1\n");
        }
    }
    return 0;
}
/*
為什麼ret<3?
*/
#include<stdio.h>
#include<math.h>
#include <algorithm>  
using namespace std;  

const double eps=1e-8;
struct point 
{
	double x,y;
}dian[20000+10];
point jiao[203];
struct line  
{  
    point s,e;  
    double angle;  
}xian[20000+10];  
int n,yong;
bool mo_ee(double x,double y)  
{  
    double ret=x-y;  
    if(ret<0) ret=-ret;  
    if(ret<eps) return 1;  
    return 0;  
}  
bool mo_gg(double x,double y)  {   return x > y + eps;} // x > y     
bool mo_ll(double x,double y)  {   return x < y - eps;} // x < y     
bool mo_ge(double x,double y) {   return x > y - eps;} // x >= y     
bool mo_le(double x,double y) {   return x < y + eps;}     // x <= y     
point mo_intersection(point u1,point u2,point v1,point v2)  
{  
    point ret=u1;  
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))  
		/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));  
    ret.x+=(u2.x-u1.x)*t;  
    ret.y+=(u2.y-u1.y)*t;  
    return ret;  
}  
double mo_xmult(point p2,point p0,point p1)//p1在p2左返回負,在右邊返回正  
{  
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);  
}  


void mo_HPI_addl(point a,point b)  
{  
	xian[yong].s=a;  
	xian[yong].e=b;  
	xian[yong].angle=atan2(b.y-a.y,b.x-a.x);  
	yong++;  
}  
//半平面交
bool mo_HPI_cmp(const line& a,const line& b)
{
	if(mo_ee(a.angle,b.angle))
	{
		return mo_gg( mo_xmult(b.e,a.s,b.s),0);
	}else
	{
		return mo_ll(a.angle,b.angle);
	}
}
int mo_HPI_dq[20000+10];
bool mo_HPI_isout(line cur,line top,line top_1)
{
	point jiao=mo_intersection(top.s,top.e,top_1.s,top_1.e);
	return mo_ll( mo_xmult(cur.e,jiao,cur.s),0);//若順時針時應為mo_gg
}
int mo_HalfPlaneIntersect(line *xian,int n,point *jiao)
{
	int i,j,ret=0;
	sort(xian,xian+n,mo_HPI_cmp);
	for (i = 0, j = 0; i < n; i++)
	{
		if (mo_gg(xian[i].angle,xian[j].angle))
		{
			xian[++j] = xian[i];
		}
	}
	n=j+1;
	mo_HPI_dq[0]=0;
	mo_HPI_dq[1]=1;
	int top=1,bot=0;
	for (i = 2; i < n; i++)
	{
        while (top > bot && mo_HPI_isout(xian[i], xian[mo_HPI_dq[top]], xian[mo_HPI_dq[top-1]])) top--;
        while (top > bot && mo_HPI_isout(xian[i], xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[bot+1]])) bot++;
        mo_HPI_dq[++top] = i; //當前半平面入棧
	}
    while (top > bot && mo_HPI_isout(xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[top]], xian[mo_HPI_dq[top-1]])) top--;
    while (top > bot && mo_HPI_isout(xian[mo_HPI_dq[top]], xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[bot+1]])) bot++;
    mo_HPI_dq[++top] = mo_HPI_dq[bot];
    for (ret = 0, i = bot; i < top; i++, ret++)
	{
		jiao[ret]=mo_intersection(xian[mo_HPI_dq[i+1]].s,xian[mo_HPI_dq[i+1]].e,xian[mo_HPI_dq[i]].s,xian[mo_HPI_dq[i]].e);
	}
	return ret;
}
int main()
{
	int i;
	while(scanf("%d",&n),n)
	{
		yong=0;
		for(i=0;i<n;++i)
		{
			scanf("%lf%lf",&dian[i].x,&dian[i].y);
		}
		for(i=0;i<n;++i)
		{
			mo_HPI_addl(dian[i],dian[(i+1)%n]);
		}
		int ret=mo_HalfPlaneIntersect(xian,n,jiao);
		if(ret<3)
		{
			printf("0\n");
		}else
		{
			printf("1\n");
		}
	}
	return 0;
}	

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved