凸包生成算法实验报告.docx
- 文档编号:2147346
- 上传时间:2022-10-27
- 格式:DOCX
- 页数:22
- 大小:74.73KB
凸包生成算法实验报告.docx
《凸包生成算法实验报告.docx》由会员分享,可在线阅读,更多相关《凸包生成算法实验报告.docx(22页珍藏版)》请在冰豆网上搜索。
凸包生成算法实验报告
实验报告
班级:
学生姓名:
学号:
201101218
日期:
2014年5月11日
判断点线关系及计算多边形内角
一、点与线的关系
(1)定义:
平面上的三点P1(x1,y1),P2(x2,y2),P3(x3,y3)的面积量:
|x1x2x3|
S(P1,P2,P3)=|y1y2y3|=(x1-x3)*(y2-y3)-(y1-y3)*(x2-x3)
|111|
当P1P2P3逆时针时S为正的,当P1P2P3顺时针时S为负的。
令矢量的起点为A,终点为B,判断的点为C,
如果S(A,B,C)为正数,则C在矢量AB的左侧;
如果S(A,B,C)为负数,则C在矢量AB的右侧;
如果S(A,B,C)为0,则C在直线AB上。
(2)算法
intMyMath:
:
IsRightInLine(MyPointp1,MyPointp2,MyPointp3)
{
ints;
s=(p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
if(s>0)
{
return1;//点在直线左侧
}
elseif(s<0)
{
return2;//点在直线右侧
}
else
{
return0;//点在直线上
}
}
二、计算多边形内角
(1)算法过程
第一步:
输入一系列的离散点;
第二步:
找x坐标值最小的点p0,这样能确定由此点构成的多边形的角是凸的;
第三步:
定义与p0点相邻的前后两个点p1,p2,若超出数组边界,则用首点或尾点取代;
第四步:
计算p2与向量p1p0的位置关系,若p2在向量p1p0的左边,则多边形呈逆时针方向;若p2在向量p1p0的右边,则多边形呈顺时针方向。
第五步:
计算多边形的各个内角,利用两个向量的夹角公式计算。
由于多边形有凹凸性,所以算角时要分情况。
找规律可知,若多边形是逆时针走向,那么,若三个相邻的点构成凸角,三点的走向始终是逆时针走向,否则,是顺时针走向,故可根据此来确定角度。
(2)算法实现
1、定义点类
classMyPoint
{
public:
MyPoint();
virtual~MyPoint();
public:
intid;
intx,y,z;
};
2、定义数学计算类
classMyMath
{
public:
MyMath();
virtual~MyMath();
public:
staticfloatCalcuAngle(MyPointp1,MyPointp2,MyPointp3,intflag);//算角度
staticintIsRightInLine(MyPointp1,MyPointp2,MyPointp3);//判断点与直线位置关系
protected:
staticfloatVectorAngel(MyPointp1,MyPointp2,MyPointp3);//计算向量角
staticfloatCalCuMatrix(MyPointp1,MyPointp2,MyPointp3);
};
详细代码:
//点与直线的关系
intMyMath:
:
IsRightInLine(MyPointp1,MyPointp2,MyPointp3)
{
ints;
s=(p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
if(s>0)
{
return1;//点在直线左侧
}
elseif(s<0)
{
return2;//点在直线右侧
}
else
{
return0;//点在直线上
}
}
//计算角度
floatMyMath:
:
CalcuAngle(MyPointp1,MyPointp2,MyPointp3,intflag)
{
//判断正逆方向
floatd=CalCuMatrix(p1,p2,p3);
floatangle=VectorAngel(p1,p2,p3);
if(flag==1)
{
if(d>0)//逆时针,凸多边形(在数学坐标系中正确,程序中相反)
{
return(180.0-angle);
}
else//顺时针,凹多边形
{
return(180.0+angle);
}
}
if(flag==2)
{
if(d>0)//逆时针,凸多边形
{
return(180.0+angle);
}
else//顺时针,凹多边形
{
return(180.0-angle);
}
}
}
//求矩阵,用于判断走向
floatMyMath:
:
CalCuMatrix(MyPointp1,MyPointp2,MyPointp3)
{
return((p1.x*p2.y+p1.y*p3.x+p2.x*p3.y)-(p2.y*p3.x+p3.y*p1.x+p1.y*p2.x));
}
//求向量夹角
floatMyMath:
:
VectorAngel(MyPointp1,MyPointp2,MyPointp3)
{
intdx1=p2.x-p1.x;
intdy1=p2.y-p1.y;
intdx2=p3.x-p2.x;
intdy2=p3.y-p2.y;
floata=(dx1*dx2+dy1*dy2)/(sqrt(dx1*dx1+dy1*dy1)*sqrt(dx2*dx2+dy2*dy2));
return(180*acos(a))/3.1415;
}
3、定义多边形类
classMyPolygon
{
public:
MyPolygon();
virtual~MyPolygon();
public:
CArray
CArray
intflag;//判断顺逆方向,逆为2,顺为1,初始为0
public:
voidAddPoint(MyPointp);//加点
voidDrawPolygon(CDC*pDC);//画多边形
boolCacul();//计算夹角
};
详细代码:
//画多边形
voidMyPolygon:
:
DrawPolygon(CDC*pDC)
{
CPen*pen=newCPen(0,1,RGB(255,0,0));
CPen*oldPen=pDC->SelectObject(pen);
intix,iy;
intdianCount=dingDianArray.GetSize();
//画点
for(inti=0;i { ix=dingDianArray[i].x; iy=dingDianArray[i].y; pDC->Ellipse(ix-3,iy-3,ix+3,iy+3); } //画边 if(dianCount>=3) { pDC->MoveTo(dingDianArray[0].x,dingDianArray[0].y); for(inti=1;i { pDC->LineTo(dingDianArray[i].x,dingDianArray[i].y); } pDC->LineTo(dingDianArray[0].x,dingDianArray[0].y); } //画角度 if(trangleArray.GetSize()>0) { for(inti=0;i { CStrings; s.Format("%d",trangleArray[i]); pDC->TextOut(dingDianArray[i].x,dingDianArray[i].y,s); } } pDC->SelectObject(oldPen); } //加点 voidMyPolygon: : AddPoint(MyPointp) { dingDianArray.Add(p); } //计算方向和角度 boolMyPolygon: : Cacul() { if(dingDianArray.GetSize()<3) { flag=0; returnfalse; } else { //找x值最小的点 intindex=0; MyPointp=dingDianArray[0]; for(inti=1;i { MyPointpi=dingDianArray[i]; if(p.x>pi.x) { index=i; p=pi; } } //定义与当前点相邻的两点 inti_1=index-1; inti1=index+1; if(i_1<0) { i_1=dingDianArray.GetSize()-1; } if(i1>dingDianArray.GetSize()-1) { i1=0; } MyPointpi_1=dingDianArray[i_1]; MyPointpi1=dingDianArray[i1]; //判断点线位置关系,确定多边形的走向 intisRight=MyMath: : IsRightInLine(pi_1,p,pi1); if(isRight==1) { flag=1; } elseif(isRight==2) { flag=2; } else { flag=0; } //计算多边形内角 trangleArray.RemoveAll(); for(i=0;i { i_1=i-1; i1=i+1; if(i_1<0) { i_1=dingDianArray.GetSize()-1; } if(i1>dingDianArray.GetSize()-1) { i1=0; } p=dingDianArray[i]; pi_1=dingDianArray[i_1]; pi1=dingDianArray[i1]; floatangle=MyMath: : CalcuAngle(pi_1,p,pi1,flag); trangleArray.Add((int)angle); } returntrue; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 生成 算法 实验 报告