计算机图形学 椭圆的扫描转换(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版) 孔令德 编著


原文地址:https://www.cnblogs.com/zfyouxi/p/5328041.html