计算机图形学 椭圆的扫描转换(3)
作者:卿笃军
原文地址:http://blog.csdn.net/qingdujun/article/details/40045907
本文通过一个完整的实例,演示椭圆的扫描转换。
1)创建CEllipse类
头文件:Ellipse.h
// Ellipse.h: interface for the CEllipse class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ELLIPSE_H__DBDD57D1_3A14_4067_93E9_B40218C54601__INCLUDED_) #define AFX_ELLIPSE_H__DBDD57D1_3A14_4067_93E9_B40218C54601__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CEllipse { public: CEllipse(); virtual ~CEllipse(); void SymmetryFill(double x, double y,CDC *pDC); //绘制。同一时候依据对称性填充剩下的3/4区域 void OneFour(CDC *pDC); //绘制1/4椭圆 private: CPoint Center; //椭圆中点 double a,b; //椭圆长半轴、短半轴 }; #endif // !defined(AFX_ELLIPSE_H__DBDD57D1_3A14_4067_93E9_B40218C54601__INCLUDED_)实现文件:Ellipse.cpp
// Ellipse.cpp: implementation of the CEllipse class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DrawEllipse.h" #include "Ellipse.h" #include <math.h> #define Round(d) int(floor(d+0.5))//四舍五入宏定义 #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CEllipse::CEllipse() { //设定椭圆的中点 Center.x = 300; Center.y = 300; //初始化长短半轴 a = 200.0; b = 100.0; } CEllipse::~CEllipse() { } void CEllipse::SymmetryFill(double x, double y,CDC *pDC) //绘制。同一时候依据对称性填充剩下的3/4区域 { //定义椭圆的颜色 COLORREF clr=RGB(0,0,255); //绘制 pDC->SetPixelV(Round(x+Center.x),Round(y+Center.y),clr); //同一时候依据对称性填充剩下的3/4区域 pDC->SetPixelV(Round(-x+Center.x),Round(y+Center.y),clr); pDC->SetPixelV(Round(x+Center.x),Round(-y+Center.y),clr); pDC->SetPixelV(Round(-x+Center.x),Round(-y+Center.y),clr); } void CEllipse::OneFour(CDC *pDC) //绘制1/4椭圆 { double x,y,d1,d2; x=0;y=b; //从像素点(0,b)開始填充(椭圆最上方顶点处) d1=b*b+a*a*(-b+0.25); //中点误差项初始值d(10)=b^2+a^2*(-b+0.25) //椭圆AC弧段(x为主方向) while(b*b*(x+1)<a*a*(y-0.5)) //法矢量两分量相等处(b^2*(x+1)==a^2*(y-0.5)) { if (d1<0) { d1=d1+b*b*(2*x+3); //当d1(i)<0时。递推公式:d1(i+1)=d1(i)+b^2*( 2x(i)+3 ) } else { d1=d1+b*b*(2*x+3)+a*a*(-2*y+2);//递推公式:d1(i+1)=d1(i)+b^2*( 2x(i)+3 )+a^2*( -2y(i)+2 ) y--; } x++; SymmetryFill(x,y,pDC); //运行绘制 } //中点误差项初始值d(10)=b^2+a^2*(y-1)^2-a^2*b^2 d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b; //椭圆CB弧段(y为主方向) while(y>0) { if (d2<0) { d2=d2+b*b*(2*x+2)+a*a*(-2*y+3);//当d2(i)<0时,递推公式:d2(i+1)=d2(i)+b^2*( 2x(i)+2 )+a^2*(-2y+3) x++; } else { d2=d2+a*a*(-2*y+3); //递推公式:d2(i+1)=d2(i)+a^2*(-2y+3) } y--; SymmetryFill(x,y,pDC); //运行绘制 } }2)onDraw函数
void CDrawEllipseView::OnDraw(CDC* pDC) { CDrawEllipseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CEllipse *pEllipse = new CEllipse; pEllipse->OneFour(pDC); }3)执行效果
原文地址:http://blog.csdn.net/qingdujun/article/details/40045907
參考文献:计算机图形学基础教程(Visual C++版)(第2版) 孔令德 编著