内容发布更新时间 : 2024/12/27 2:21:18星期一 下面是文章的全部内容请认真阅读。
计算机图形学实验报告
实验1 使用画线算法,绘制直线段
姓名 杜艾莲 系别班级 地信101 学号 1008140925 实验日期 2011.10.10 指导教师 实验成绩 一. 实验目的及要求
(1)掌握图形学中常用的三种画线算法:数值微分法、中点画线法和Bresenham画线算法。 (2)掌握绘制直线的程序设计方法。
(3)掌握使用文件来保存直线段的方法。 (4)掌握从文本文件中恢复出直线的方法。
二. 实验内容
使用VC++ 6.0开发环境,分别实现中点画线算法和Bresenham画线算法,绘制直线(注意,不能使用VC中已有的绘制直线的函数),并以文本文件的形式保存绘制的结果,可以从文本文件中恢复出以前绘制过的直线。
三. 算法设计与分析
输入P0(X0,Y0) 和P1(X1,Y1) 计算初始值△x,△y d=△x-2△y,x=X0,y=Y0 (x,y) 更新为(x+1,y+1),d更新为d+2△x-2△y (x,y)更新为(x+1,y),d更新为d-2△y 结束
Bresenham算法绘制直线的程序(仅包含整数运算)。 void MidBresenhamLine(int x0,int y0,int x1,int y1,int color) {
int dx,dy,d,UpIncre,DownIncre,x,y; if(x0>x1){
x=x1;x1=x0;x0=x;
y=y1;y1=y0;y0=y; }
x=x0;y=y0;
dx=x1-x0;dy=y1-y0; d=dx-2*dy;
UpIncre=2*dx-2*dy;DownIncre=-2*dy; while(x<=x1){ putpixel(x,y,color); X++; if(d<0){ y++;
d+=UpIncre; }
else d+=DownIncre; } }
四. 程序调试及运行结果的自我分析与自我评价
// testView.cpp : implementation of the CTestView class #include \#include \#include \#include \#include
#include
#include \//CDlgInput类的头文件
using namespace std; #ifdef _DEBUG
#define new DEBUG_NEW #undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
// CTestView
IMPLEMENT_DYNCREATE(CTestView, CView)
BEGIN_MESSAGE_MAP(CTestView, CView) //{{AFX_MSG_MAP(CTestView) ON_COMMAND(ID_MENUITEM32771, OnMenuitem32771) ON_COMMAND(ID_MENUBRESENHAMLINE, OnMenubresenhamline) ON_COMMAND(ID_MENUCLEARVIEW, OnMenuclearview) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_FILE_SAVE, OnFileSave) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP()
// CTestView construction/destruction
CTestView::CTestView() { // TODO: add construction code here m_nFlag = -1; // 不是任何绘图类型 }
CTestView::~CTestView() { }
BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); }
// CTestView drawing
void CTestView::OnDraw(CDC* pDC) { CTestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here if(1==m_nFlag) // 中点画线 { MidPointLine(m_X0, m_Y0, m_X1, m_Y1, RGB(255,0,0) ); } else if(2==m_nFlag) // Bresenham画线 { BresenhamLine(m_X0, m_Y0, m_X1, m_Y1, RGB(0,255,0) ); } }
// CTestView printing
BOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); }
void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing }
void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing
}
// CTestView diagnostics #ifdef _DEBUG
void CTestView::AssertValid() const { CView::AssertValid(); }
void CTestView::Dump(CDumpContext& dc) const { CView::Dump(dc); }
CTestDoc* CTestView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc))); return (CTestDoc*)m_pDocument; }
#endif //_DEBUG
// CTestView message handlers
void CTestView::OnMenuitem32771() { // TODO: Add your command handler code here m_nFlag = 1; // 中点画线 CDlgInput dlg; if(IDOK==dlg.DoModal()) { m_X0=dlg.m_nX0; m_Y0=dlg.m_nY0; m_X1=dlg.m_nX1; m_Y1=dlg.m_nY1; RedrawWindow(); //重绘窗口 } }
void CTestView::OnMenubresenhamline() { // TODO: Add your command handler code here m_nFlag = 2; // Bresenham画线 CDlgInput dlg; if(IDOK==dlg.DoModal()) { m_X0=dlg.m_nX0; m_Y0=dlg.m_nY0; m_X1=dlg.m_nX1; m_Y1=dlg.m_nY1; RedrawWindow(); //重绘窗口
} }
// 算法: 中点画线
// 输入: 起点(x0,y0),终点(x1,y1); // 输入要求x0<=x1;
void CTestView::MidPointLine( int x0, int y0, int x1, int y1, int color ) { CDC * pDC=GetDC(); int a,b,d0,d1,d2,d3,d4,d5,d,x,y; a=y0-y1; b=x1-x0; // 之前的设置已经保证始终有x1>=x0 d=2*a+b; d0=2*a-b; d1=2*a; d2=2*(a+b); d3=2*b; d4=2*(a-b); d5=a-2*b; x=x0; y=y0; pDC->SetPixel(x,y,color); if(x==x1) // 斜率k为无穷大 { if(y<=y1) { while(y<=y1) { pDC->SetPixel(x,y,color); y++; } } else { while(y>=y1) { pDC->SetPixel(x,y,color); y--; } } }// if 斜率k为无穷大 else // 斜率k为有限值 { // double k=-a/b; // if( k+1>1e-6 && k-1<1e-6 || fabs(k-1)<1e-6 || fabs(k+1)<1e-6) // |k|<=1(即:-1<= k <=1),与1e-6比较是浮点数比较方法 if( -b<=-a && -a<=b ) // 用浮点数比较在|k|=1.0f时容易出问题,所以直接用整数比较(将斜率k转换为a与b的比较;之前的设置已经保证b为正数) { if(y<=y1)