现在进行误差项的递推。di<0,取正右方像素Pu(xi?1,yi),欲判断再下一个像素应取哪一个,应计算
di?1?F(xi?2,yi?0.5) ?(xi?22)?y(i? 0.2?5R)2 ?(xi?12)?y(i?0.25)?R2?xi2 ?3 ?di?2xi?3
所以,沿正右方向,di的增量为2xi?3。di≥0时,应取右下方像素
P,yi?1),要判断再下一个像素,则要计算 d(xi?1
di?1?F(xi?2,yi?1.5) ?(xi?22)?y(i? 1.2?5R)2 ?(xi?12)?y(i?0.25)?R2?xi(2? ?di?2(xi?y )5i?3?)?y2?i(
2)所以,沿右下方向,判别式di的增量为2(xi?yi)?5。
显然所绘制圆弧段的第一个像素点为P0(0,R),因此判别式di的初始值 d0?F(1,R?0.5) ?1?(R?0.5)2?R2
?1.25?R
由于使用的只是di的符号,因此可以用di-0.25代替di来摆脱小数。此时算法只涉及整数运算。这样初始化运算d0?1.25?R对应于d0?1?R。判别式di<0对应于di<-0.25。di<-0.25等价于di<0。
于是可写出中点Bresenham画圆算法的步骤如下: ① 输入圆半径R;
- 8 -
② 计算初始值d0?1?R,x=0,y=R;
③ 绘制点(x,y)及其在八分圆中的另外7个对称点;
④ 判断d的符号。若d<0,则先将d更新为d+2x+3,再将(x,y)更新为(x+1,y);否则先将d更新为d+2(x-y)+5,再将(x,y)更新为(x+1,y-1); ⑤ 当x int x,y,d; x=0;y=r;d=1-r; while (x<=y) { CirclePoint(x,y,color); if(d<0)d+=2*x+3; else { d+=2*(x-y)+5; y--; } x++; } } 6.程序运行结果 - 9 - - 10 - 7、总结 通过这次课程设计,使我们加深了对Bresenham算法的了解和应用。增强了我们的实践能力,对以后的学习和工作有很大帮助。 8、参考资料: 《计算机图形学基础(第2版)》 陆枫 何云峰 编著 太原工业学院精品课程 9、附录:源程序代码清单 ●TestView.h // TestView.h : interface of the CTestView class // ///////////////////////////////////////////////////////////////////////////// #if !defined(AFX_TESTVIEW_H__A75FDCFB_621C_4E38_A154_C344803E6372__INCLUDED_) #define AFX_TESTVIEW_H__A75FDCFB_621C_4E38_A154_C344803E6372__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include \对话框头文件 #include \ class CTestView : public CView { protected: // create from serialization only CTestView(); DECLARE_DYNCREATE(CTestView) // Attributes public: CTestDoc* GetDocument(); // Operations public: void Mbline();//Bresenham函数 void GetMaxY();//获得屏幕的最大x值函数 void GetMaxX();//获得屏幕的最大y值函数 void CirclePoint(double x,double y);//八分法画圆子函数 void Mbcircle();//Bresenham算法 // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CTestView) - 11 - public: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); //}}AFX_VIRTUAL // Implementation public: virtual ~CTestView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: double x0, y0, x1, y1;//直线的起点和终点坐标 int MaxX,MaxY;//屏幕x和y的最大坐标 double R;//圆的半径 // Generated message map functions protected: //{{AFX_MSG(CTestView) afx_msg void OnMENUMbline(); afx_msg void OnMENUMbcircle(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; #ifndef _DEBUG // debug version in TestView.cpp inline CTestDoc* CTestView::GetDocument() { return (CTestDoc*)m_pDocument; } #endif ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_TESTVIEW_H__A75FDCFB_621C_4E38_A154_C344803E6372__INCLUDED_) - 12 -