凸多边形的拾取

实验设计说明书

题目:凸多边形的拾取 学院:国土资源与旅游学院 专业:地理信息系统 组长:黎明

同组成员:李岩、唐鑫、胡仁德、丁王平、张锦华

完成日期:2010 年 6 月 10 日

文档历史

1 引言

1.1 项目简要介绍

在一个CAD系统中,最基本的操作就是对一个图形的拾取,本次实验就是对凸多边形进行拾取。

1.2 项目的创新点

由于本次实验是对凸多边形进行拾取,所以在判断点在其内部时,采用了叉乘法,不涉及三角运算(内角和法)、开方(面积法)和水平垂直交叉线检测。

2 概要设计

2.1 模块

2.2 简要算法

2.2.1 判断点是否在多边形内

叉乘法

若P0在凸多边形内部,则如图所示的向量的乘积应该都是大于0的。

2.2.2 填充算法

我们直接调用了VC函数FloodFill( )对所绘制的多边形进行填充

2.3 步骤

1. 在头文件“shiquView.h”中添加如下成员变量和函数

int polygen[50][2]; int flag,n; int x0,y0,x1,y1; float maximum(float a,float b); float minimum(float a,float b); CShiquDoc* GetDocument(); int mutiply(int a,int b,int c,int d); CShiquView();

CShiquView继承了CView类。我们在CShiquView类中定义了polygen[50][2]对各个顶点的坐标进行存储。变量n存储是边(或者顶点)的个数。变量flag判断凸多边形是否画完,flag初始为0,flag=1表示正在绘制,flag=2绘制结束。x0,y0,x1,y1用来存放线段的端点,并进行循环更新。

2. 在源文件“shiquView.cpp”中的构造函数进行如下初始化

CShiquView::CShiquView() { // TODO: add construction code here flag=0; n=0; }

3. 在源文件“shiquView.cpp”中如下实现成员函数maximum( )和minimum( )

float CShiquView::maximum(float a,float b) { if(a

float CShiquView::minimum(float a,float b) { if(a>b)a=b; return a; }

4. 在源文件“shiquView.cpp”中如下实现成员函数mutiply( ),此函数求向量乘积

int CShiquView::mutiply(int a,int b,int c,int d) { return (a*c+b*d); }

5. 添加WM_LbuttonDown消息。在响应函数OnLButtonDown 中添加如下信息(加粗

部分)

void CShiquView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CDC*pDC=GetDC(); CPen pen; pen.CreatePen(PS_SOLID,1,RGB(0,0,0)); CPen*pold=pDC->SelectObject(&pen); if(!flag) { polygen[n][0]=x0=point.x; polygen[n][1]=y0=point.y; flag=1; } else { n++; pDC->MoveTo(x0,y0); polygen[n][0]=x1=point.x; polygen[n][1]=y1=point.y; pDC->LineTo(x1,y1); x0=x1;y0=y1; } pDC->SelectObject(pold); CView::OnLButtonDown(nFlags, point); }

6. 添加WM_LButtonDblClk消息。在响应函数OnLButtonDblClk 中添加如下信息(加

粗部分)

void CShiquView::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CDC*pDC=GetDC(); CPen pen; pen.CreatePen(PS_SOLID,1,RGB(0,0,0)); CPen*pold=pDC->SelectObject(&pen);

pDC->MoveTo(polygen[n][0],polygen[n][1]); pDC->LineTo(polygen[0][0],polygen[0][1]); ReleaseDC(pDC); flag=2; //CView::OnLButtonDblClk(nFlags, point); }

7. 添加WM_RbuttonDown消息。在响应函数OnRButtonDown 中添加如下信息(加粗

部分)

void CShiquView::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CDC* pDC=GetDC(); CPen pen; int a,b,c,lx,ly,j,i,zero,arrow[50][2],arrow2[50][2]; float b0,b1,b2,k; double d; // arrow[50][2]用于存放边向量,arrow2[50][2]用于存放定点到内部点的向量。 if(flag==2||flag==3) { //点在内部判断 lx=point.x; ly=point.y; for(i=0;in) {

CDC*p_DC=GetDC(); CBrush brush;

brush.CreateSolidBrush(RGB(255,0,0));

CBrush*pold2=p_DC->SelectObject(&brush); int u,v;

u=1.0/2*(polygen[0][0]+polygen[2][0]); v=1.0/2*(polygen[0][1]+polygen[2][1]); p_DC->FloodFill(u,v,RGB(0,0,0)); p_DC->SelectObject(pold2);

//改变线形

pen.CreatePen(PS_SOLID,2,RGB(0,0,255)); CPen* pold=pDC->SelectObject(&pen); for(i=0;iMoveTo(polygen[i][0],polygen[i][1]); pDC->LineTo(polygen[i+1][0],polygen[i+1][1]); }

pDC->MoveTo(polygen[i][0],polygen[i][1]); pDC->LineTo(polygen[0][0],polygen[0][1]); pDC->SelectObject(pold);

}

if(flag==3) { //对边框进行拾取 //对最后一条边进行判断 a=polygen[n][1]-polygen[0][1]; b=polygen[0][0]-polygen[n][0]; c=polygen[n][0]*polygen[0][1]-polygen[0][0]*polygen[n][1]; k=-(float)(polygen[0][0]-polygen[n][0])/(polygen[0][1]-polygen[n][1]); lx=point.x; ly=point.y; d=(float)abs(a*lx+b*ly+c)/sqrt(a*a+b*b); b0=ly-k*lx; b1=polygen[n][1]-k*polygen[n][0]; b2=polygen[0][1]-k*polygen[0][0]; if(d

CPen* pold=pDC->SelectObject(&pen); for(i=0;iMoveTo(polygen[i][0],polygen[i][1]); pDC->LineTo(polygen[i+1][0],polygen[i+1][1]); }

pDC->MoveTo(polygen[i][0],polygen[i][1]); pDC->LineTo(polygen[0][0],polygen[0][1]); pDC->SelectObject(pold);

//拾取后的填充

CDC*p_DC=GetDC(); CBrush brush;

brush.CreateSolidBrush(RGB(255,0,0));

CBrush*pold2=p_DC->SelectObject(&brush); int u,v;

u=1.0/2*(polygen[0][0]+polygen[2][0]); v=1.0/2*(polygen[0][1]+polygen[2][1]); p_DC->FloodFill(u,v,RGB(0,0,255)); p_DC->SelectObject(pold2);

}

//对其他边进行判断 for(j=0;jSelectObject(&pen); for(i=0;i

pDC->MoveTo(polygen[i][0],polygen[i][1]); pDC->LineTo(polygen[i+1][0],polygen[i+1][1]); } pDC->MoveTo(polygen[i][0],polygen[i][1]); pDC->LineTo(polygen[0][0],polygen[0][1]); pDC->SelectObject(pold); //拾取后的填充 CDC*p_DC=GetDC(); CBrush brush; brush.CreateSolidBrush(RGB(255,0,0)); CBrush*pold2=p_DC->SelectObject(&brush); int u,v; u=1.0/2*(polygen[0][0]+polygen[2][0]); v=1.0/2*(polygen[0][1]+polygen[2][1]); p_DC->FloodFill(u,v,RGB(0,0,255)); p_DC->SelectObject(pold2); } } } } CView::OnRButtonDown(nFlags, point); }

8. 在OnDraw(CDC* pDC)函数中添加如下代码(加粗部分) void CShiquView::OnDraw(CDC* pDC) { // TODO: add draw code for native data here CShiquDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDC->TextOut(400,50,"1、单击左键绘制多边形。"); pDC->TextOut(400,70,"2、双击左键结束绘制。"); pDC->TextOut(400,90,"3、单击右键进行拾取。"); }

3 实验结果


© 2024 实用范文网 | 联系我们: webmaster# 6400.net.cn