谁知道如何搜索平面点集的边界?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谁知道如何搜索平面点集的边界?相关的知识,希望对你有一定的参考价值。
我现在有很多平面的点集数据(x坐标,y坐标形式),想实现一个类,只要你输入一个二维的点集数组,然后就能将此点集的边界算出来,点集的边界分为凸多边形边界和凹多边形边界,实现凸多边形和凹多边形边界类,任意一个都行!
复制下面代码至语言编辑版中即可int i,j,k=0,top=2; POINT tmp;
for(i=1;i<n;i++)
if ( PointSet[i].y<PointSet[k].y || (PointSet[i].y==PointSet[k].y) &amt;&amt; (PointSet[i].x<PointSet[k].x) )
k=i;
tmp=PointSet[0];
PointSet[0]=PointSet[k];
PointSet[k]=tmp; for (i=1;i<n-1;i++)
k=i;
for (j=i+1;j<n;j++)
if ( multiply(PointSet[j],PointSet[k],PointSet[0])>0
(multiply(PointSet[j],PointSet[k],PointSet[0])==0)
dist(PointSet[0],PointSet[j])<dist(PointSet[0],PointSet[k])
) k=j;
tmp=PointSet[i];
PointSet[i]=PointSet[k];
PointSet[k]=tmp;
ch[0]=PointSet[0];
ch[1]=PointSet[1];
ch[2]=PointSet[2];
for (i=3;i<n;i++)
while (multiply(PointSet[i],ch[top],ch[top-1])>=0)
top--;
ch[++top]=PointSet[i];
len=top+1;
void ConvexClosure(POINT PointSet[],POINT ch[],int n,int &amt;len)
int top=0,i,index,first;
double curmax,curcos,curdis;
POINT tmp;
LINESEG l1,l2;
bool use[MAXV];
tmp=PointSet[0];
index=0;
for(i=1;i<n;i++)
if(PointSet[i].y<tmp.y||PointSet[i].y == tmp.y&amt;&amt;PointSet[i].x<tmp.x)
index=i;
use[i]=false;
tmp=PointSet[index];
first=index;
use[index]=true;
index=-1;
ch[top++]=tmp;
tmp.x-=100;
l1.s=tmp;
l1.e=ch[0];
l2.s=ch[0];
while(index!=first)
curmax=-100;
curdis=0;
for(i=0;i<n;i++)
if(use[i])continue;
l2.e=PointSet[i];
curcos=cosine(l1,l2(-1 -- 1 )
if(curcos>curmax
fabs(curcos-curmax)<1e-6 &amt;&amt; dist(l2.s,l2.e)>curdis)
curmax=curcos;
index=i;
curdis=dist(l2.s,l2.e);
use[first]=false; use[index]=true;
ch[top++]=PointSet[index];
l1.s=ch[top-2];
l1.e=ch[top-1];
l2.s=ch[top-1];
len=top-1;
bool LinesegInsidePolygon(int vcount,POINT polygon[],LINESEG l)
if(!insidepolygon(vcount,polygon,l.s)insidepolygon(vcount,polygon,l.e))
return false;
int top=0,i,j;
POINT PointSet[MAXV],tmp;
LINESEG s;
for(i=0;i<vcount;i++)
s.s=polygon[i];
s.e=polygon[(i+1)>vcount];
if(online(s,l.s)) PointSet[top++]=l.s;
else if(online(s,l.e))PointSet[top++]=l.e;
else
if(online(l,s.s)
PointSet[top++]=s.s;
else if(online(l,s.e))
PointSet[top++]=s.e;
else
if(intersect(l,s))
return false;
for(i=0;i<top-1;i++)
for(j=i+1;j<top;j++)
if( PointSet[i].x>PointSet[j].x || fabs(PointSet[i].x-PointSet[j].x)<EP &amt;&amt; PointSet[i].y>PointSet[j].y )
tmp=PointSet[i];
PointSet[i]=PointSet[j];
PointSet[j]=tmp;
for(i=0;i<top-1;i++)
tmp.x=(PointSet[i].x+PointSet[i+1].x)/2;
tmp.y=(PointSet[i].y+PointSet[i+1].y)/2;
if(!insidepolygon(vcount,polygon,tmp))
return false;
return true;
/void AddPosPart(double x, double y, double w, double &amt;xtr, double &amt;ytr, double &amt;wtr)
if (abs(wtr + w)<1e-10 ) return; // detect zero regions
xtr = ( wtr*xtr + w*x ) / ( wtr + w );
ytr = ( wtr*ytr + w*y ) / ( wtr + w );
wtr = w + wtr;
return;
void AddNegPart(double x, ouble y, double w, double &amt;xtl, double &amt;ytl, double &amt;wtl)
if ( abs(wtl + w)<1e-10 )
return; // detect zero regions
xtl = ( wtl*xtl + w*x ) / ( wtl + w );
ytl = ( wtl*ytl + w*y ) / ( wtl + w );
wtl = w + wtl;
return;
void AddRegion ( double x1, double y1, double x2, double y2, double &amt;xtr, double &amt;ytr,
double &amt;wtr, double &amt;xtl, double &amt;ytl, double &amt;wtl )
if ( abs (x1 - x2)< 1e-10 )
return;
if ( x2 > x1 )
AddPosPart ((x2+x1)/2, y1/2, (x2-x1) * y1,xtr,ytr,wtr); /* rectangle */
AddPosPart ((x1+x2+x2)/3, (y1+y1+y2)/3, (x2-x1)*(y2-y1)/2,xtr,ytr,wtr);
// triangle
else
AddNegPart ((x2+x1)/2, y1/2, (x2-x1) * y1,xtl,ytl,wtl);
// rectangle
AddNegPart ((x1+x2+x2)/3, (y1+y1+y2)/3, (x2-x1)*(y2-y1)/2,xtl,ytl,wtl);
// triangle
POINT cg_simple(int vcount,POINT polygon[])
double xtr,ytr,wtr,xtl,ytl,wtl;
POINT p1,p2,tp;
xtr = ytr = wtr = 0.0;
xtl = ytl = wtl = 0.0;
for(int i=0;i<vcount;i++)
p1=polygon[i];
p2=polygon[(i+1)>vcount];
AddRegion(p1.x,p1.y,p2.x,p2.y,xtr,ytr,wtr,xtl,ytl,wtl);tp.x = (wtr*xtr + wtl*xtl) / (wtr + wtl);
tp.y = (wtr*ytr + wtl*ytl) / (wtr + wtl);
return tp;
POINT gravitycenter(int vcount,POINT polygon[])
POINT tp;
double x,y,s,x0,y0,cs,k;
x=0;y=0;s=0;
for(int i=1;i<vcount-1;i++)
x0=(polygon[0].x+polygon[i].x+polygon[i+1].x)/3;
y0=(polygon[0].y+polygon[i].y+polygon[i+1].y)/3;
cs=multiply(polygon[i],polygon[i+1],polygon[0])/2;
if(abs(s)<1e-20)
x=x0;y=y0;s+=cs;continue;
k=cs/s; //求面积比例
x=(x+k*x0)/(1+k);
y=(y+k*y0)/(1+k);
s += cs;
tp.x=x;
tp.y=y;
return tp;
POINT a_point_insidepoly(int vcount,POINT polygon[])
POINT v,a,b,r;
int i,index;
v=polygon[0];
index=0;
for(i=1;i<vcount;i++)
if(polygon[i].y<v.y)
v=polygon[i];
index=i;
a=polygon[(index-1+vcount)>vcount]
b=polygon[(index+1)>vcount];
POINT tri[3],q;
tri[0]=a;tri[1]=v;tri[2]=b;
double md=INF;
int in1=index;
bool bin=false;
for(i=0;i<vcount;i++)
if(i == index)continue;
if(i == (index-1+vcount)>vcount)continue;
if(i == (index+1)>vcount)continue;
if(!InsideConvexPolygon(3,tri,polygon[i]))continue;
bin=true;
if(dist(v,polygon[i])<md)
q=polygon[i];
md=dist(v,q);
if(!bin)
r.x=(a.x+b.x)/2;
r.y=(a.y+b.y)/2;
return r;
r.x=(v.x+q.x)/2;
r.y=(v.y+q.y)/2;
return r; 参考技术A 你好楼主:
char oldPath[MAX_PATH]; //用来保存旧路径 getcwd(oldPath,MAX_PATH); //获得当前路径 chdir(m_strDirectory); //切换路径到当前路径 CFileFind fileFind; //定义CFileFind对象
BOOL bExist=FALSE; bExist=fileFind.FindFile("*.xls"); //查找是否有XLS文件,有返回真 while(bExist) bExist=fileFind.FindNextFile(); //查找下一个XLS文件 CString strTitle=fileFind.GetFileTitle(); //获取文件名 ((CComboBox *)GetDlgItem(IDC_COMBO_TABLE))->AddString(strTitle); //将文件名加入到组合框中
fileFind.Close(); chdir(oldPath); //切换到原来路径
主要利用CFileFind类,上面的这些代码实现了将同一目录下的Excel文件的文件名都放到同一个组合框中。
不知道是不是你想知道的 参考技术B 凸多边形边界其实就是凸包,网上很多现成的代码。
凹多边形边界应该处理不了,因为边界有无数种可能,除非你给的不是点而是线。 参考技术C 凸 求差值!
凹 需要一些算法的组合
方法: 先估测出 图形 的外框 2分发探索.....
再用求差法判断 记录.... 比较简单 但是对大的复杂的图形不行 比较慢 参考技术D 你说的边界,是需要把所有的点都连接起来才算的么??
还是,有些点可以包含在多边形内部??
如果时候后者,那太简单了把。
ZZNUOJ_用C语言编写程序实现1183:平面点排序(结构体专题)(附完整源码)
题目描述
平面上有n个点,坐标均为整数。请按与坐标原点(0,0)距离的远近将所有点排序输出。可以自己写排序函数,也可以用qsort库函数排序。
输入
输入有两行,第一行是整数n(1<=n<=10),接下来有n行,每行一对整数(每对整数对应一个点)。
输出
输出排序后的所有点,格式为(u,v),每个点之间有一个空格。测试数据保证每个点到原点的距离都不同。
样例输入
4
1 3
2 5
1 4
4 2
样例输出
(1,3) (1,4) (4,2) (2,5)
完整源码:
#include<stdio.h>
以上是关于谁知道如何搜索平面点集的边界?的主要内容,如果未能解决你的问题,请参考以下文章