作者:卿笃军
原文地址:http://blog.csdn.net/qingdujun/article/details/40025917
本文演示,通过自己编写绘制直线函数(像素点填充),绘制任意斜率的直线。
1)创建CP2类
头文件:p2.h
// P2.h: interface for the CP2 class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_) #define AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 //二维点类 class CP2 { public: CP2(); CP2(double x,double y); virtual ~CP2(); public: //方便访问,直接定义为共有 double x; double y; }; #endif // !defined(AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_)
实现文件:p2.cpp
// P2.cpp: implementation of the CP2 class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DrawLine.h" #include "P2.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CP2::CP2() { x=0.0; y=0.0; } CP2::CP2(double x,double y) { this->x=x; this->y=y; } CP2::~CP2() { }
2)创建CLine类
头文件:Line.h
// Line.h: interface for the CLine class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_) #define AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "P2.h" class CLine { public: CLine(); virtual ~CLine(); void MoveTo(CP2 p0); //移动到指定位置 void MoveTo(double x, double y); void LineTo(CP2 p1, CDC *pDC); //绘制直线,不含终点 void LineTo(double x, double y, CDC *pDC); private: CP2 P0; //起点 CP2 P1; //终点 }; #endif // !defined(AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_)
实现文件:Line.cpp
// Line.cpp: implementation of the CLine class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DrawLine.h" #include "Line.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 ////////////////////////////////////////////////////////////////////// CLine::CLine() { } CLine::~CLine() { } void CLine::MoveTo(CP2 p0) //记录直线起点函数 { P0=p0; } void CLine::MoveTo(double x, double y) { P0.x = x; P0.y = y; } void CLine::LineTo(double x, double y, CDC *pDC) //绘制 { CP2 p; p.x = x; p.y = y; LineTo(p, pDC); } void CLine::LineTo(CP2 p1, CDC *pDC) { P1=p1; CP2 p,t; COLORREF clr = RGB(0,0,0); //黑色像素点 if(fabs(P0.x-P1.x)<1e-6) //绘制垂线 { if(P0.y>P1.y) //交换顶点,使得起始点低于终点 { t=P0;P0=P1;P1=t; } for(p=P0;p.y<P1.y;p.y++) //执行绘制,填充像素点 { pDC->SetPixelV(Round(p.x),Round(p.y),clr); } } else { double k,d; k=(P1.y-P0.y)/(P1.x-P0.x); //斜率 if(k>1.0) //绘制k>1(y为主方向) { if(P0.y>P1.y) { t=P0;P0=P1;P1=t; } d=1-0.5*k; //中点初始值 for(p=P0;p.y<P1.y;p.y++) { pDC->SetPixelV(Round(p.x),Round(p.y), clr); if(d>=0) //中点位于将绘制点上方,填充下方点 { p.x++; d=d+1-k; //递推公式:当d>=0时,d(i+1)=d(i)+1-k; } else d+=1; } } if(0.0<=k && k<=1.0) //绘制0<=k<=1(x为主方向) { if(P0.x>P1.x) { t=P0;P0=P1;P1=t; } d=0.5-k; //中点初始值 for(p=P0;p.x<P1.x;p.x++) { pDC->SetPixelV(Round(p.x),Round(p.y), clr); if(d<0) //中点位于将绘制点下方,填充上方点 { p.y++; d=d+1-k; //递推公式:当d<0时,d(i+1)=d(i)+1-k; } else d-=k; } } if(k>=-1.0 && k<0.0)//绘制-1<=k<0(x为主方向) { if(P0.x>P1.x) { t=P0;P0=P1;P1=t; } d=-0.5-k; //中点初始化 for(p=P0;p.x<P1.x;p.x++) { pDC->SetPixelV(Round(p.x),Round(p.y), clr); if(d>0) //中点位于将绘制点上方,填充下方点 { p.y--; d=d-1-k; //递推公式:当d>0时,d(i+1)=d(i)-1-k; } else d-=k; } } if(k<-1.0)//绘制k<-1 (y为主方向) { if(P0.y<P1.y) { t=P0;P0=P1;P1=t; } d=-1-0.5*k; //中点初始化 for(p=P0;p.y>P1.y;p.y--) { pDC->SetPixelV(Round(p.x),Round(p.y), clr); if(d<0) //中点位于将绘制点下方,填充上方点 { p.x++; d=d-1-k;//递推公式:当d>0时,d(i+1)=d(i)-1-k; } else d-=1; } } } P0=p1; //将终点赋值给起点 }
3)OnDraw函数
void CDrawLineView::OnDraw(CDC* pDC) { CDrawLineDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here //绘制直线 CLine *line=new CLine;//动态创建直线绘制类对象 line->MoveTo(100,100); line->LineTo(500,500, pDC); }
4)绘制效果如下
原文地址:http://blog.csdn.net/qingdujun/article/details/40025917
参考文献:计算机图形学基础教程(Visual C++版)(第2版) 孔令德 编著
时间: 2024-10-11 05:52:06