凸包求取
来源:互联网 发布:一个二次元软件 有后山 编辑:程序博客网 时间:2024/06/05 09:36
参加了一场在线笔试,有点匆匆忙忙,下线后重写了一下:
#include"Graham.h"void Swap(SPoint **m_Point,int i,int j){ SPoint temp; temp.x=(*m_Point)[i].x; temp.y=(*m_Point)[i].y; temp.angle=(*m_Point)[i].angle; (*m_Point)[i].x=(*m_Point)[j].x; (*m_Point)[i].y=(*m_Point)[j].y; (*m_Point)[i].angle=(*m_Point)[j].angle; (*m_Point)[j].x=temp.x; (*m_Point)[j].y=temp.y; (*m_Point)[j].angle=temp.angle;}int _Partition(SPoint* TPoint,int left,int right){ int pivot=left; int i=left+1; int j=right; while(1) { while(TPoint[i].angle<TPoint[pivot].angle&&i<=right) {i=i+1;} while(TPoint[j].angle>TPoint[pivot].angle&&j>left) {j=j-1;} if(i<j) { Swap(&TPoint,i,j); } else break; } Swap(&TPoint,pivot,j); return j;}void Quick_Sort(SPoint* TPoint,int left,int right){ if(left<right) { int Partition=_Partition(TPoint,left,right); Quick_Sort(TPoint,left,Partition-1); Quick_Sort(TPoint,Partition+1,right); } }int Find_Minumy_Point(SPoint *m_Point,int nLen){ int mid=(nLen-1)/2; float minumy=(float)MINUM; int res=-1; for(int i=0;i<=mid;i++) { if(m_Point[i].y<m_Point[nLen-1-i].y) { if(m_Point[i].y<minumy) { minumy=m_Point[i].y; res=i; } else { if(m_Point[i].y==minumy&&res!=-1) { if(m_Point[i].x<=m_Point[res].x) { minumy=m_Point[i].y; res=i; } } } } else { if(m_Point[nLen-i-1].y<minumy) { minumy=m_Point[nLen-1-i].y; res=nLen-1-i; } else { if(m_Point[nLen-i-1].y==minumy&&res!=-1) { if(m_Point[nLen-1-i].x<=m_Point[res].x) { minumy=m_Point[nLen-1-i].y; res=nLen-1-i; } } } } } return res;}void Compute_Angles(SPoint *m_Point,SPoint *T_Point,int nLen,int index){ float m_tan,x,y; Swap(&m_Point,0,index); for(int i=1;i<nLen;i++) { x=m_Point[i].x-m_Point[0].x; y=m_Point[i].y-m_Point[0].y; if(x>0&&y>0) m_tan=atan(y/x); if(x>=0&&y==0)m_tan=0; if(x>0&&y<0) m_tan=2*val-atan((-y)/x); if(x<0&&y==0)m_tan=-val; if(x<0&&y>0) m_tan=val-atan(y/(-x)); if(x<0&&y<0) m_tan=val+atan((-y)/x); if(x==0&&y>0)m_tan=0.5*val; if(x==0&&y<0)m_tan=1.5*val; //m_Tan=atan2f(y,x); T_Point[i-1].x=m_Point[i].x; T_Point[i-1].y=m_Point[i].y; T_Point[i-1].angle=m_tan; } for(int i=0;i<nLen-1;i++) printf("%f,%f,%f\n",T_Point[i].x,T_Point[i].y,T_Point[i].angle); printf("\n\n\n"); Quick_Sort(T_Point,0,nLen-2);}float distance(SPoint *T_Point,SPoint pt,int flag){ float dis=(T_Point[flag].x-pt.x)*(T_Point[flag].x-pt.x)+(T_Point[flag].y-pt.y)*(T_Point[flag].y-pt.y); dis=sqrtf(dis); return dis;}void sort_by_distance(SPoint *T_Point,SPoint pt,int start,int end){ float dis1,dis2; for(int m=start;m<end;m++) { for(int n=m+1;n<end;n++) { dis1=distance(T_Point,pt,m); dis2=distance(T_Point,pt,n); if(dis1>dis2) Swap(&T_Point,m,n); } }}void Adjustment(SPoint *T_Point,SPoint pt,int nLen){ int p=0,q; int dis1,dis2; while(p<nLen) { q=p+1; if(q>=nLen) break; else { while(T_Point[p].angle==T_Point[q].angle&&q<nLen) { q=q+1; } if(p+1==q) { p=p+1; } else { sort_by_distance(T_Point,pt,p,q-1); } } }}int GraHam(SPoint *m_Point,SPoint *T_Point,p2d* CS,int nLen){ int index=Find_Minumy_Point(m_Point,nLen); printf("The point x=%f,y=%f has minumy\n",m_Point[index].x,m_Point[index].y); Compute_Angles(m_Point,T_Point,nLen,index); Adjustment(T_Point,m_Point[0],nLen-1); for(int i=0;i<nLen-1;i++) printf("%f,%f,%f\n",T_Point[i].x,T_Point[i].y,T_Point[i].angle); CS[0].x=T_Point[nLen-2].x; CS[0].y=T_Point[nLen-2].y; CS[1].x=m_Point[0].x; CS[1].y=m_Point[0].y; int sp=1; int k=0; float D; while(k<nLen-1) { //栈顶两点以及扫描线上一点所构成的三角区符号 //D=CS[sp-1].x*CS[sp].y+CS[sp].x*T_Point[k].y+T_Point[k].x*CS[sp-1].y //-CS[sp-1].y*CS[sp].x-CS[sp].y*T_Point[k].x-T_Point[k].y*CS[sp-1].x; D=(T_Point[k].x-CS[sp].x)*(CS[sp-1].y-CS[sp].y)-(CS[sp-1].x-CS[sp].x)*(T_Point[k].y-CS[sp].y); if(D>=0) { sp=sp+1; CS[sp].x=T_Point[k].x; CS[sp].y=T_Point[k].y; k=k+1; } else { sp=sp-1; /*if(sp==0) { CS[sp].x=T_Point[k].x; CS[sp].y=T_Point[k].y; }*/ } } return (sp+1);}
#ifndef _GRAHAM_H_#define _GRAHAM_H_#include <cstdlib>#include <iostream>#include <cv.h>#include <cxcore.h>#include <highgui.h>#include<Math.h>using namespace std;#define MINUM 65536const float val=3.1415926;typedef float FPoint;typedef struct{ FPoint x; FPoint y;}p2d;typedef struct{ float x; float y; float angle;}SPoint;void Swap(SPoint **m_Point,int i,int j);int _Partition(SPoint* TPoint,int left,int right);void Quick_Sort(SPoint* TPoint,int left,int right);int Find_Minumy_Point(SPoint *m_Point,int nLen);void Compute_Angles(SPoint *m_Point,SPoint *T_Point,int nLen,int index);float distance(SPoint *T_Point,SPoint pt,int flag);void sort_by_distance(SPoint *T_Point,SPoint pt,int start,int end);void Adjustment(SPoint *T_Point,SPoint pt,int nLen);int GraHam(SPoint *m_Point,SPoint *T_Point,p2d* CS,int nLen);#endif
/*****************************************************************Mail:zhjkobe2013@live.com***Author: zhang jie***Function: Graham algorithms***cpp:main.cpp***Create time:2014-12-26 12:26***Last Modify Time: 2014-12-26***************************************************************/#include "Graham.h"//凸壳问题的格雷厄姆#define WIDTH 640#define HEIGHT 480#define N 10const char* win_name="GraHam";int nCount=0;int re=0;void Record_Point_CallBack(int event,int x,int y,int flags,void* param);CvPoint pt;int main(int argc, char *argv[]){ IplImage* Img=cvCreateImage(cvSize(WIDTH,HEIGHT),IPL_DEPTH_8U,3); cvZero(Img); cvNamedWindow(win_name); CvPoint* m_Point=new CvPoint[N]; char c; cvSetMouseCallback(win_name,Record_Point_CallBack,(void*)Img);loop: while(1) { if(nCount>=1&&nCount<=N) { m_Point[nCount-1].x=pt.x; m_Point[nCount-1].y=pt.y; } //printf("nCount=%d\n",nCount); cvShowImage(win_name,Img); c=cvWaitKey(100); if(c=='r') { nCount=0; cvZero(Img); } if(nCount==N+1) break; } SPoint *p_Point=new SPoint[N]; SPoint *T_Point=new SPoint[N-1]; p2d* CS=new p2d[N+1]; for(int i=0;i<N;i++) { p_Point[i].x=(float)m_Point[i].x; p_Point[i].y=(float)m_Point[i].y; p_Point[i].angle=0.0; printf("x=%d,y=%d\n",m_Point[i].x,m_Point[i].y); } printf("start\n"); int nIndex=GraHam(p_Point,T_Point,CS,N); printf("nIndex=%d\n",nIndex); CvPoint pt1,pt2; for(int i=0;i<nIndex;i++) { pt1.x=(int)CS[i%nIndex].x; pt1.y=(int)CS[i%nIndex].y; pt2.x=(int)CS[(i+1)%nIndex].x; pt2.y=(int)CS[(i+1)%nIndex].y; printf("cs[%d].x=%f,cs[%d].y=%f\n",i,CS[i].x,i,CS[i].y); cvLine(Img,pt1,pt2,cvScalar(0,0,255),1,8,0); } printf("Finish\n"); cvShowImage(win_name,Img); re=re+1; if(re==3) cvSaveImage("res.bmp",Img); nCount=0; printf("nCount=%d,re=%d\n",nCount,re);goto loop; cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&Img); if(p_Point) delete[] p_Point; if(m_Point) delete[] m_Point; if(CS) delete[] CS; system("PAUSE"); return EXIT_SUCCESS;}void Record_Point_CallBack(int event,int x,int y,int flags,void* param){ IplImage* pImg=(IplImage*)param; switch(event) { case CV_EVENT_LBUTTONDOWN: { pt.x=x; pt.y=y; if(nCount<N) cvCircle(pImg,cvPoint(pt.x,pt.y),1,cvScalar(255,0,0),1,8,0); nCount+=1; } break; case CV_EVENT_RBUTTONDOWN: { nCount=-1; cvZero(pImg); } break; default: break; }}
效果如下:
0 0
- 凸包求取
- 求取模型的三维凸包问题
- hdu 1392 Surround the Trees(求取凸包并求凸包的周长)
- 计算几何之求取二维点集的凸包/ 凸多边形包围盒
- 计算几何之求取三维维点集的凸包/ 凸多边形包围盒(2D、3D点集)
- MAD求取
- 求取阶乘
- 求取二项分布
- 求取最小公倍数
- 求取VS2005 WinFrom编程
- 求取一元多项式乘积
- 数据序号求取
- opencv求取RGB分量
- 图像Stride求取
- 求取点云法向量
- 求取选手得分
- 多文件组织-求取最大值
- 水仙花数的求取
- Linux Shell常用技巧(五) awk编程
- WebService的简介, 原理, 使用
- CSS—position
- hadoop distcp 实现不同集群之间数据同步
- Oracle Study之--Oracle 触发器(Trigger)
- 凸包求取
- 排序
- C语言解析url
- FreeMarker学习笔记
- 关于工程科研和工业实践的脱节
- Linux Shell常用技巧(三) sed
- spring mvc3.2启动分析
- JAVA中正则表达式总结
- 第六周项目二:-我的数组类