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


  • 相关阅读:
    接口表与临时表的用途
    mac电脑连接oracle报错ora-24454,客户主机名未设置
    项目管理口径与法人管理口径会计分录公司信息生成问题
    关于接口的一些理解
    梳理EBS系统中上下文的概念和用法
    数据库系统的用途浅析
    EBS与外围系统数据的交互方式——接口表与API的区别
    四年EBS系统顾问风雨之路回顾——002话
    Web服务器处理请求过程浅谈
    ZOOKEEPER+KAFKA 集群搭建
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5328041.html
Copyright © 2020-2023  润新知