计算机图形学 绘制任意斜率的直线(1)

作者:卿笃军

原文地址: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

计算机图形学 绘制任意斜率的直线(1)的相关文章

用中点Bresenham画直线算法绘制任意斜率直线

使用VC 6.0 mfc实现编程 刚学的图像学,挺难学的,show 代码吧 void CLineView::OnDraw(CDC* pDC) { CLineDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here int x1 ,x2 ,y1,y2 ; x1 = 0 ; y1 = 0 ;  x2 = 1000 ; y2 = 500 ; COLORREF c = RGB(25

实验二 绘制任意斜率的直线段

这个题我是参考别人的博客:https://www.cnblogs.com/jdemarryme/p/8806752.html View类中添加的消息的处理程序,会识别鼠标的点击.松开和移动. 在view类里加入的line对象,就是用来画线的线. (这里的消息处理程序,会调用我们创建的对象line中的方法,进行画线.) 创建的Cline类会处理如何画线,保存起点终点,判断斜率,画线,一气呵成. 原文地址:https://www.cnblogs.com/amtop/p/10960769.html

[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)

一.首先说明: 这是啥? —— 这是利用C#FORM写的一个用来演示计算机图形学中 ①Bresenham直线扫描算法(即:连点成线):②种子填充法(即:填充多边形):③扫描线填充法 有啥用? ——  无论是连点成线还是区域填充在高级编程中基本上都提供很高效的库函数来调用.这里拿出这些算法一方面有利于大家理解那些封装的函数底层是实现:另一方面是方便嵌入式TFT屏幕底层驱动开发时借鉴的. 是啥样? ——  如下面的操作,不言而喻. 二.进入正题: 2-1.直线的扫描转换 图形的扫描转换实质就是在光栅

计算机图形学 直线反走样Wu算法(4)

作者:卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/40048285 本文通过一个完整的实例来演示,直线反走样Wu算法. 1)创建CP2类 头文件:P2.h // P2.h: interface for the CP2 class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_P2_H__DD2

计算机图形学 彩色直线段的反走样(5)

作者:卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/40083207 本文通过一个完整的例子来演示彩色直线段的反走样. 1)创建CP2类 头文件:P2.h // P2.h: interface for the CP2 class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_P2_H__DD23

计算机图形学和OpenGL(二)坐标系和绘制点线函数

这节开始前我们先了解一下图元的概念.图形软件包中用来描述各种图形元素的函数称为图形输出原语,也称图元(primitive).而描述对象几何要素的输出图元一般称为几何图元.点和线是最简单的几何图元,本节就会简单介绍点和线段的绘制方法. 一.坐标系统. 坐标系统一般分为屏幕坐标和OpenGL中的绘图坐标. 在上一节中我们简单的写了个示例程序,程序中介绍了gluOrtho2D命令.我们可以利用该命令设定一个二维笛卡尔坐标系.该函数的四个变量制定的是显示图形x和y坐标范围.所以我们可以使用下面代码制定一

计算机图形学 Cohen-Sutherland直线段裁剪算法

作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/40822977 本文通过一个完整的实例演示Cohen-Sutherland直线段裁剪算法. 1)创建类CP2 头文件:P2.h // P2.h: interface for the CP2 class. // ////////////////////////////////////////////////////////////////////// #if !defined

计算机图形学——光栅图形学直线算法简介

本文是对 赵明老师 <计算机图形学>MOOC课程 部分章节的小总结. 直线是组成图形的基础,其算法往往被多次调用,其好坏直接影响图形的显示效果和速度.以下是一些画直线的常用算法. 1.DDA算法: 此算法基于增量思想. 对于直线的斜截式:y=kx+b,考虑每次 x 递增 1, 都有 y[i+1] = y[i] + k,这样就将 kx 部分的乘法转换成递推的加法. 由于像素点都是整数坐标,所以每次求得的 y 都要取整操作,采用加 0.5 取整数部分的方法:(int)(y[i]+0.5). 但是,

计算机图形学 复习笔记

计算机图形学 复习笔记 (个人整理,仅做复习用 :D,转载注明出处:http://blog.csdn.net/hcbbt/article/details/42779341) 第一章 计算机图形学综述 研究内容 图形的概念:计算机图形学的研究对象 能在人的视觉系统中产生视觉印象的客观对象 包括自然景物.拍摄到的图片.用数学方法描述的图形等等 图形的要素 几何要素:刻画对象的轮廓.形状等 非几何要素:刻画对象的颜色.材质等 图形表示法 点阵表示 枚举出图形中所有的点,简称为图像. 参数表示 由图形的