| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 690 人关注过本帖, 1 人收藏
标题:求把平面点集逆时针化的算法
取消只看楼主 加入收藏
DSL
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2010-7-19
收藏(1)
 问题点数:0 回复次数:0 
求把平面点集逆时针化的算法
求把平面点集逆时针化的算法,我自己写了个,好像是错的,也改不出来,所以这边求个好的,能用的。
我把自己的贴下:
ACM中常常用到平面点集的逆时针或顺时针性质,所以自己写了个把平面点集逆时针化的函数,但是在HDU 1115上,验证了下,通不过,而这个数据也比较难验证,看有哪位好心人,帮忙验证下,或者找出这个函数的不足之处,万分感激。

函数的基本思路是将点集先按y轴从小到大排序,如果y相等,按x轴从小到大排序,那么此时取出数组的两端,连线L,然后将其他点根据在L右侧、左侧、共线分为三个数组,然后对右侧排序,按照极角从小到大排序,如果极角相同,那么按照y轴从小到大排序,如果y相等,按x轴从小到大排序;然后对左侧排序,先按照极角从小到大排序,如果极角相同,那么按照y轴从大到小排序,如果y相等,按x轴从小到大排序

代码如下:
#include <iostream>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;

#define maxn 1000010
#define eps 1e-8//精度
#define zero(x)(((x)>0?(x):(-x))<eps)

struct Point
{
double x,y;
};

//多边形重心,输入点需要顺时针或者逆时针
Point barycenter(Point * p,int m)
{
p[m]=p[0];//p[m]=p[0]
Point ret;
ret.x=0;
ret.y=0;
double sum=0;
for(int i=0;i<m;i++)
{
ret.x+=(p[i].x+p[i+1].x)*(p[i].x*p[i+1].y-p[i+1].x*p[i].y);
ret.y+=(p[i].y+p[i+1].y)*(p[i].x*p[i+1].y-p[i+1].x*p[i].y);
sum+=(p[i].x*p[i+1].y-p[i+1].x*p[i].y)/2;
}
ret.x=ret.x/sum/6;
ret.y=ret.y/sum/6;
return ret;
}


//叉积 (P1-P0)x(P2-P0)
double xmult(Point p1,Point p2,Point p0){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
Point basepoint;
bool cmp0(const Point& a,const Point& b)
{
if(a.y!=b.y)
return a.y<b.y;
else
return a.x<b.x;
}
bool cmp1(const Point& a,const Point& b)
{
if(xmult(a,b,basepoint)>=eps)
return true;
else if(zero(xmult(a,b,basepoint)))
{
if(a.y!=b.y)
return a.y<b.y;
else
return a.x<b.x;
}
}
bool cmp2(const Point& a,const Point& b)
{
if(xmult(a,b,basepoint)>=eps)
return true;
else if(zero(xmult(a,b,basepoint)))
{
if(a.y!=b.y)
return a.y>b.y;
else
return a.x<b.x;
}
}
Point leftp[maxn],rightp[maxn],middlep[maxn];
int anticlockwise(Point* p,int n)
{
sort(p,p+n,cmp0);
basepoint=p[0];
int leftsize=0;
int rightsize=0;
int middlesize=0;
for(int j=1;j<n-1;j++)
{
if(xmult(p[j],p[n-1],p[0])>=eps)
rightp[rightsize++]=p[j];
else if(xmult(p[j],p[n-1],p[0])<=-eps)
leftp[leftsize++]=p[j];
else  
middlep[middlesize++]=p[j];
}
if(leftsize!=0)
sort(leftp,leftp+leftsize,cmp2);
if(rightsize!=0)
sort(rightp,rightp+rightsize,cmp1);
int i=1;
for(int j=0;j<rightsize;j++)
p[i++]=rightp[j];
if(leftsize!=0)
{
for(int j=0;j<middlesize;j++)
p[i++]=middlep[j];
p[i++]=p[n-1];
for(int j=0;j<leftsize;j++)
p[i++]=leftp[j];
}
else if(leftsize==0)
{
p[i++]=p[n-1];
for(int j=middlesize-1;j>=0;j--)
p[i++]=middlep[j];
}
if(i==n)
return 1;
else  
return 0;
}
Point input[maxn];
int main()
{
int n;
int t;
Point temp;
scanf("%d",&t);
for(;t--;)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf %lf",&input[i].x,&input[i].y);
}
anticlockwise(input,n);
temp=barycenter(input,n);
cout<<fixed<<setprecision(2)<<temp.x<<" "<<temp.y<<endl;
}
}

 
 
搜索更多相关主题的帖子: 时针 算法 平面 
2010-07-27 17:46
快速回复:求把平面点集逆时针化的算法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025183 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved