凸多边形的拾取

实验设计说明书

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

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

完成日期: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 实验结果

实验设计说明书

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

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

完成日期: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 实验结果


相关文章

  • 工具螺丝刀建模
  • 一.实验目的 1. 了解3Dmax的主要功能,熟练操作技巧. 2. 掌握3dmax的综合运用,包括菜单.工具.控制面板的组合使用: 3. 熟练3Dmax关于材质和渲染方面的知识. . 二.实验内容 制作工具螺丝刀 三.实验用设备仪器 软件: ...查看


  • 如何使用画图软件
  • 如何使用画图软件 想在电脑上画画吗?很简单,windows已经给你设计了一个简洁好用的画图工具.它在开始菜单的程序项里的附件中,名字就叫做"画图". 启动它后,屏幕右边的这一大块白色就是你的画布了.左边是工具箱,下面是颜 ...查看


  • 天正结构tssd教程
  • 天正结构tssd教程 作者:佚名 来源:本站整理 发布时间:2008-10-22 10:52:58 减小字体 增大字体 欢迎加入本站3dmax学习交流QQ群:17494142 练习一. 柱.基础平面图 目的:熟悉TSSD的菜单结构,初步了解 ...查看


  • 粗糙度符号制作
  • 表面粗糙度符号的"图块"制作 1.绘制符号(图1) (1) 用"多边形"功能绘制三角形: 点击命令 输入边的数目 : 3↓ 指定正多边形的中心点或 [边(E)]:在适当位置点击 输入选项 [内接于圆( ...查看


  • 计算机图形学知识点
  • 总复习知识点 第1章 绪论 数字图像处理.计算机图形学.计算机模式识别概念.关系.区别 计算机图形学的应用范围和实例 第2章 计算机图形系统硬件 计算机图形系统工作流程.基本组成和典型计算机图形系统 计算机图形系统设备: 图形输入设备: 掌 ...查看


  • 公差的表示方法
  • 公差的表示方法 一:把你的直径50标注出来 有了直径50 之后 用ED命令 或者双击50这个尺寸 (会弹出文字格式对话框,a/b就在里面,撤销符号后面) %%C50+0.02 ^ +0.01 "^ " 就是"6 ...查看


  • 计算机图形学全部知识点
  • 1. 计算机图形学的研究内容 什么是计算机图形学? (1/2) 什么是计算机图形学? (2/2) 什么是交互式计算机图形学? (1/3) 什么是交互式计算机图形学? (2/3) 什么是交互式计算机图形学? (3/3) 基本概念--图形 图形 ...查看


  • 淘宝美工设计教程以及相关知识
  • 淘宝美工需掌握的软件 Photoshop, Dreamweaver Flash, Illustrator, 另外,还需要网络美工具备如下素质:扎实的美术功底.丰富的想象力和良好的创造力,网页设计/平面设计/广告设计工作经验,美术类/平面设计 ...查看


  • Illustrator模拟题
  • 1. Edit>Preference(编辑>预置)子菜单中有很多设定项用来定义Illustrator 的操作环境,下列哪个选项不属于Preference (预置)中的设定项? 4 (1). Smart Guide(智能参考线) ...查看


热门内容