计算机图形学基础教程(Visual C++版)习题解答与编程实践(第2版)孔令德1-到第3章的直线扫描转换

news2024/11/27 9:50:56

1-到第3章的直线扫描转换(没更新完)

  • 习题1
    • 知识积累
  • 习题2
    • 知识点
      • 映射模式
      • 使用GDI对象
  • 习题3
    • 知识积累
      • 直线的中点Bresenham算法

习题1

1.计算机图形学的定义是什么?说明计算机图形学、图像处理和模式识别之间的关系。
答:

CG是计算机图形学的缩写。随着以计算机为主要工具进行视觉设计和生产的一系列相关产业的形成,国际上习惯将利用计算机技术进行视觉设计和生产的领域通称为CG。

计算机图形学是一门研究如何利用计算机表示、生成、处理和显示图形的学科。 图形主要分为两类,一类是基于线条表示的几何图形,另一类是基于材质、纹理和光照表示的真实感图形。 图形的表示方法有两种:参数法和点阵法。
一般将用参数法描述的图形仍然称为图形,将用点阵描述的图形称为图像。

计算机图形学就是研究将图形的表示法从参数法转换为点阵法的一门学科,或者简单地说,计算机图形就是计算机产生的图像。

关系:
计算机图形学是研究如何利用计算机把描述图形的几何模型通过指定的算法转化为图像显示的一门学科;
图像处理主要是指对数字图像进行增强、去噪、复原、分割、重建、编码、存储、压缩和恢复等不同处理方法的学科;
模式识别是对点阵图像进行特征抽取,然后利用统计学方法给出图形描述的学科。
近年来,随着光栅扫描显示器的广泛应用,这3门学科之间的界限越来越模糊,甚至出现了相互渗透和融合,这3个学科是相互促进和发展的。

IEEE的定义为:Computer graphics is the art or science of producing graphical images with the aid of computer.

……(暂不更新)

知识积累

CG 计算机图形学 computer graphics
UI 图形化用户界面 user interface
CAD 计算机辅助设计 Computer Aided Design
CAM 计算机辅助制造 Computer Aided Manufacturing
在这里插入图片描述

计算机图形学之父——Ivan E. Sutherland

屏幕宽高比(Aspect Ratio): 显示设备中显示图像的横向尺寸与纵向尺寸的比例。
在这里插入图片描述
(考点)
1.5 图形显示器的发展及其工作原理
1.5.4 光栅扫描显示器
在这里插入图片描述
在这里插入图片描述
光栅扫描显示器电子束的强度可以不断变化,所以容易生成颜色连续变化的真实感图像。
光栅扫描显示器是画点设备,可看作是一个点阵单元发生器,并可控制每个点阵单元的亮度,这些点阵单元被称为像素(Picture Element,Pixel)。

荧光点图案:
在这里插入图片描述
帧缓冲器(frame buffer)是显存内用于存储一帧图像的一片连续内存空间。
光栅扫描显示器使用帧缓冲存储屏幕上每个像素的颜色信息,帧缓冲使用位面(bit plane)与屏幕像素一一对应。
在这里插入图片描述

删除线格式

如果屏幕上每个像素的颜色只用一(Bit)表示,其值非0即1,屏幕只能显示黑白二色图像,称为黑白显示器,此时帧缓冲器只有一个位面。
在这里插入图片描述
如果每个像素的颜色可以用一个字节(Byte)表示,帧缓冲器需要用八个位面,可表示256种灰度,称为灰度显示器。 这时候还不是彩色的。
在这里插入图片描述

如果每个像素用R、G、B三原色混合表示,其中每种原色分别用一个字节表示,各对应一把电子枪,每种颜色可有256种亮度,三种颜色的组合是2^24颜色,共有24个位面
在这里插入图片描述

索引色
在这里插入图片描述
在这里插入图片描述

习题2

知识点

在这里插入图片描述
例2-1 设计一个长方形CRectangle类,调用类的成员函数计算长方形的周长和面积。

#include <iostream.h>
class CRectangle
{
public:
	CRectangle();                               
	CRectangle(int width,int height);    
	~CRectangle();                             
	double perimeter(); 
	double area();                              
private:
	int width;                                     
	int height;                                   
};

CRectangle::CRectangle()   
{  
	width=10;
	height=5;	
	cout<<"建立默认对象"<<endl;
}
CRectangle::CRectangle(int width,int height)
{
	this->width=width;
      this->height=height;	
	cout<<"建立对象"<<endl;
}
CRectangle::~CRectangle() 
{
	cout<<"撤销对象"<<endl;
}

double CRectangle::perimeter()    //周长 
{
	return 2*( width+height);
}
double CRectangle::area() //面积
{
	return width*height; 
}
void main() 
{
	CRectangle Rect1,Rect2(30,20),*pRect=&Rect2; 
	cout<<"Rect1的周长为:"<<Rect1.perimeter()<<endl;  
	cout<<"Rect1的面积为:"<<Rect1.area()<<endl;  
	
	cout<<"Rect2的周长为:"<<Rect2.perimeter()<<endl; 
	cout<<"Rect2的面积为:"<<Rect2.area()<<endl; 
	
	cout<<"Rect2的周长为:"<<pRect->perimeter ()<<endl; 
	cout<<"Rect2的面积为:"<<pRect->area()<<endl;  
}

在这里插入图片描述

在这里插入图片描述
建立CRectangle类动态对象并初始化为宽度为40,高度为10的语句如下:

CRectangle* pRect=new CRectangle(40,10) ; 

但使用new运算符创建数组时则无参数,并且只调用默认的构造函数。

例2-2 动态创建CRectangle类二维对象数组,输出每个对象的周长和面积。本例假定二维数组有2行3列。

void main() 
{
	int RowIndex=2,ColIndex=3;            
	CRectangle** pRect;
	//创建二维动态数组
    pRect=new CRectangle* [RowIndex];//设置行
    for(int i=0;i<RowIndex;i++)
    {
       pRect[i]=new CRectangle[ColIndex];//设置列
     }
    //输出周长和面积
    for(i=0;i<RowIndex;i++)
    {
	 for(int j=0;j<ColIndex;j++)
	 {
	    cout<<"Rect["<<i<<","<<j<<"]
          周长为"<<pRect[i][j].perimeter()<<","; 
	    cout<<"面积为"<<pRect[i][j].area()<<endl; 
	  }
    }

	//释放二维动态数组
	for(int k=0;k<RowIndex;k++)
	{
		delete []pRect[k]; 
		pRect[k]=NULL;
	}
	delete []pRect;
	pRect=NULL;
}

在这里插入图片描述

在这里插入图片描述
CPaintDC对象只在响应WM_PAINT消息时使用。
CPaintDC类的构造函数会自动调用BeginPaint()函数。CPaintDC类的析构函数则会自动调用EndPaint()函数。
MFC程序中使用CPaintDC类在视图窗口中绘图时,
需要先添加WM_PAINT消息的映射函数OnPaint(),
然后在OnPaint()函数中编写与CPaintDC类相关的代码,而不是编写在OnDraw()中。
请注意,如果使用OnPaint()函数响应了WM_PAINT消息,则OnDraw()函数将会被自动屏蔽。

void CTestView::OnDraw(CDC* pDC)//绘制椭圆
{
	CTestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	pDC->Ellipse(100,70,900,570);
}
void CTestView::OnPaint() //绘制矩形
{
	CPaintDC dc(this); // device context for painting
	// TODO: Add your message handler code here
	dc.Rectangle(100,70,900,570);
	// Do not call CView::OnPaint() for painting messages
}

OnPaint() 屏蔽了OnDraw()函数,不绘制椭圆。如果删除此函数,则绘制结果为椭圆。

CWindowDC中点(0,0)在屏幕的左上角,而CClientDC和CPaintDC中点(0,0)是屏幕客户区的左上角。

如果在CTestView类中使用CWindowDC类对象进行绘图,只有在使用GetParent()函数获得CWnd指针后,才能在整个屏幕区域内绘图。


在这里插入图片描述
简单数据类型
在这里插入图片描述

CPoint类:存放点坐标(x,y)。
CRect类:存放矩形左上角顶点和右下角顶点的坐标(top,left,right,bottom)
CSize类:存放矩形的宽度和高度的坐标(cx,cy),其中cx为矩形的宽度,cy为矩形的高度。

绘图工具类
在这里插入图片描述
CGdiObject类:GDI绘图工具的基类,一般不能直接使用。
CBitmap:封装了一个GDI位图,提供位图操作的接口。
CBrush类:封装了GDI画刷,可以选作设备上下文的当前画刷。画刷用于填充图形内部
CFont:封装了GDI字体,可以选作设备上下文中的当前字体。
CPallette:封装了GDI调色板,提供应用程序和显示器之间的颜色接口。
CPen:封装了GDI画笔,可以选作设备上下文的当前画笔。画笔用于绘制图形边界线

删除线格式 删除线格式 删除线格式 删除线格式
注意!在选择GDI对象进行绘图时,需要遵循以下步骤:

  1. 绘图开始前,创建一个GDI新对象,并选入当前设备上下文,同时保存原GDI对象指针。
  2. 使用新GDI对象绘图。
  3. 绘图结束后,使用已保存的原GDI对象指针将设备上下文恢复原状。
  4. 如需重复使用同名新对象绘图,则需要先从内存中删除该对象后再使用。否则会有错误提示。

映射模式

把图形显示在屏幕坐标系中的过程称为映射
根据映射模式的不同可以分为

  • 逻辑坐标
  • 设备坐标

逻辑坐标的单位是米制尺度或其它与字体相关的尺度
设备坐标的单位是像素
在这里插入图片描述
在这里插入图片描述

使用GDI对象

创建画笔函数

  • Cpen::CreatePen
  • BOOL CreatePen(int nPenstyle,int nWidth,COLORREF col)
    在这里插入图片描述

创建画刷函数

  • (1)CBrush::CreateSolidBrush
BOOL CreateSolidBrush(COLORREF col)
  • (2) CBrush::CreateHatchBrush
BOOL CreateHatchBrush(int nIndex COLORREF col)
  • (3) CBrush::CreatePatternBrush
BOOL CreatePatternBrush(Cbitmap*pBitmap)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

solid 英[ˈsɒlɪd] 美[ˈsɑːlɪd]

  • n. 固体; 立体图形;
  • adj. 固体的; 坚固的,坚硬的; 无空隙的; 非中空的,实心的; 结实的,牢固的; 质地坚实的,实在的; 纯质的,纯一的; 团结的,全体一致的; 精深的,扎实的; 彻底的,完全的; 可信赖的; 可敬的; 可靠的; 充分的,确实的; 资金雄厚的,殷实的; 不停顿的,持续不断的; 立体的,立方的; (样子或结构)浓密的; 丰盛的,重大的; 有力的; 精彩的,绝妙的; 使用固体燃料的; 相当不错的; 连续的; 纯色的; 立体的; <印>(行间)密排的,不用铅条隔开的“, ”<美口>关系很好的,关系密切的; 结实的,有力的…; 一致的; <澳口>苛刻的,不公正的;
  • adv. 全部地,完全地; 不间断地,连续地; <美口>肯定,无疑;

COLORREF是32位颜色类型,crColor是像素点的颜色值,COLORREF型变量可以利用RGB(bRed,bGreen,bBlue)来指定相应的颜色值,每种颜色用一个字节表示,可以被设定为0~255之间的任意值,0代表无色,255代表全色。

在这里插入图片描述

习题3

知识积累

布雷森汉姆直线算法Bresenham算法。这里主要应用与直线的扫描转化。
尽量使用加减法(增量算法),

MoveTo与LineTo函数无法绘制光滑的(颜色渐变)走样或反走样直线。

直线的中点Bresenham算法

在这里插入图片描述
都很容易理解,都很简单。
在这里插入图片描述
中点误差项的值会导致什么呢?注意看上图↑
在这里插入图片描述
构造中点误差项
在这里插入图片描述
d的正负决定了y的取值。
在这里插入图片描述
在这里插入图片描述
看了这几个式子之后,其实就知道怎么一步步递推中点误差项的了。

中点误差项的初始值
在这里插入图片描述
其实这个递推公式,最根本的还是原隐函数的式子。

在这里插入图片描述
现有的研究已经证明:端点采用整数坐标没有什么益处,因为现在的CPU可以按照与处理整数同样的速度处理浮点数。因此本教材讲解的中点Bresenham算法采用了浮点数运算并且方便地解决了直线的反走样问题。

整个流程:
在这里插入图片描述
自定义函数代码;

void CTestView::BresenhamLine(CDC *pDC)
{
	CPoint p0(-100,-50),p1(200,50),p;
	int dx,dy;
	dx=p1.x-p0.x;
	dy=p1.y-p0.y;
	double k,d;
	k=(double)dy/dx;
	d=0.5-k; 
           for(p=p0;p.x<p1.x;p.x++)//不包括终点(x1,y1)
	{
		pDC->SetPixelV(p,RGB(0,0,0));
        if(d<0)
		{
			p.y++;
			d+=1-k;
		}
		else 
			d-=k;
	}
}

自带的画直线函数里进行构造:

void CTestView::CLine(CDC *pDC)
{
	CPoint p0(-100,-50),p1(200,50),p;
	int  dx=p1.x-p0.x,dy=p1.y-p0.y;
	double k,d;
	k=(double)dy/dx;
	d=0.5-k;
	double dc=1/(double)dx;
           for(p=p0;p.x<p1.x;p.x++)//不包括终点p1
	{
		double r,g,b;
		r=(1-(p.x-p0.x)*dc),g=0,b=(p.x-p0.x)*dc;
		pDC->SetPixelV(p,RGB(r*255,g*255,b*255));
        if(d<0)
		{
			p.y++;
			d+=1-k;
		}
		else 
			d-=k;
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/180688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实验一、旅馆客户服务呼叫显示系统

实验一 旅馆客户服务呼叫显示系统 实验目的 综合应用数字电子技术知识&#xff0c;按照要求设计并完成一个小规模的数字电路系统。进行硬件线路的设计、仿真、焊接、调试与实现。使系统实现一种用于旅馆客户服务呼叫显示系统的实用电路。在呼叫过程中&#xff0c;当8位旅客有…

Spark Core ---- RDD持久化

RDD的数据是过程数据 RDD之间进行相互迭代计算&#xff08;Transformation的转换&#xff09;&#xff0c;当执行开启后&#xff0c;新RDD的生成&#xff0c;代表老RDD的消失 RDD的数据是过程数据&#xff0c;只在处理的过程中存在&#xff0c;一旦处理完成&#xff0c;就不见…

【数据结构和算法】实现带头双向循环链表(最复杂的链表)

前文&#xff0c;我们实现了认识了链表这一结构&#xff0c;并实现了无头单向非循环链表&#xff0c;接下来我们实现另一种常用的链表结构&#xff0c;带头双向循环链表。如有仍不了解单向链表的&#xff0c;请看这一篇文章(7条消息) 【数据结构和算法】认识线性表中的链表&…

Spring Boot之SpringSecurity学习

文章目录一 SpringSecurity简介二 实战演示0. 环境 介绍1. 新建一个初始的springboot项目2. 导入thymeleaf依赖3. 导入静态资源4. 编写controller跳转5. 认证和授权6. 权限控制和注销7. 记住登录8. 定制登录页面三 完整代码3.1 pom配置文件3.2 RouterController.java3.3 Securi…

那些面试官口中常常提到b树(MySQL索引底层数据结构)

各种常见树1.树的基本概念2.二叉树3.b树4.b树5.b树与b树的对比5.MySQL索引底层数据结构1.树的基本概念 树的特点&#xff1a;有一个树根&#xff0c;树根上又有很多枝干&#xff0c;枝干上又有很多树枝&#xff0c;树枝上又有很多叶子 树最为一种数据结构也有相似特点 树是一个…

【计算机网络(考研版)】第二站:物理层(一)

前言 如下图所示&#xff0c;这是我们之前所说的数据流动示意图 我们将按照从下向上的结构进行学习。这一讲学习第一层物理层。物理层关注在一条通信信道上传输原始比特&#xff0c;即无论面对什么样的传输介质(有线或者无线)都可以传输比特流&#xff0c;物理层的作用正是要尽…

Python3 函数

函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段。 函数能提高应用的模块性&#xff0c;和代码的重复利用率。你已经知道Python提供了许多内建函数&#xff0c;比如print()。但你也可以自己创建函数&#xff0c;这被叫做用户…

Node require 正解

require 实现原理 流程概述 步骤1&#xff1a;尝试执行代码require("./1"). 开始调用方法require.步骤2&#xff1a;此时会得到filename&#xff0c;根据filename 会判断缓存中是否已经加载模块&#xff0c;如果加载完毕直接返回&#xff0c;反之继续执行步骤3&…

JavaScript 的数据类型

JavaScript 的数据类型 基本数据类型&#xff08;值类型&#xff09; Number&#xff08;包含小数、整数、负数、科学计数法&#xff09; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"…

【Linux】六、Linux 基础IO(四)|动态库和静态库

目录 十一、动态库和静态库 11.1 动态库和静态库定义 11.2 动静态库的基本原理 11.3 静态库的打包与使用 11.3.1 静态库的打包 11.3.2 静态库的使用 11.4 动态库的打包与使用 11.4.1 动态库的打包 11.4.2 动态库的使用 11.5 动态库的加载 十一、动态库和静态库 11.1…

CB2-2CARD的openSUSE安装NAS环境配置

CB2-2CARD的openSUSE安装&NAS环境配置1. 简介2. 规格3. 系统安装3.1 Linux/Unix稳定镜像3.2 基础功能更新&安装3.2.1 更新源3.2.2 升级系统3.2.3 基础功能安装3.3 OpenSUSE系统情况3.3.1 源操作命令3.3.2 源镜像4. 需求 & 配置4.1 MiniDLNAStep 1&#xff1a;安装M…

Day870.全局锁和表锁 -MySQL实战

全局锁和表锁 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于全局锁和表锁的内容。 数据库锁设计的初衷是处理并发问题。 作为多用户共享的资源&#xff0c;当出现并发访问的时候&#xff0c;数据库需要合理地控制资源的访问规则。锁就是用来实现这些访问规则的重…

数据结构 | C++ | 并查集原理讲解与模拟实现 | 并查集的相关习题

文章目录前言并查集原理并查集的模拟实现leetcode练习省份数量等式方程的可满足性前言 并查集通常会作为高阶数据结构的一个子结构使用&#xff0c;虽然原理不是很难&#xff0c;但其思想值得我们好好学习 并查集原理 并查集是一种树形结构&#xff0c;其保存了多个集合&…

【Maven】多环境配置与应用

目录 1. 多环境配置作用 问题导入 2. 多环境配置步骤 2.1 定义多环境 2.2 使用多环境&#xff08;构建过程&#xff09; 3. 跳过测试&#xff08;了解&#xff09; 问题导入 3.1 应用场景 3.2 跳过测试命令 3.3 细粒度控制跳过测试 1. 多环境配置作用 问题导入 多…

LeetCode 2331. 计算布尔二叉树的值

给你一棵 完整二叉树 的根&#xff0c;这棵树有以下特征&#xff1a; 叶子节点 要么值为 0 要么值为 1 &#xff0c;其中 0 表示 False &#xff0c;1 表示 True 。 非叶子节点 要么值为 2 要么值为 3 &#xff0c;其中 2 表示逻辑或 OR &#xff0c;3 表示逻辑与 AND 。 计算…

【推荐系统】User-Item CF:NGCF

&#x1f4a1; 本次解读的文章是 2019 年发表于 SIGIR 的一篇基于图卷积神经网络的用户物品协同过滤推荐算法论文&#xff0c; 论文将用户-物品交互信息建模为二分图&#xff0c;提出了一个基于二分图的推荐框架 Neural Graph Collaborative Filtering&#xff08;NGCF&#xf…

基于nodejs+vue的社区问答网站与设计

目 录 摘要 I Abstract II 1 绪论 1 1.1 选题背景 1 1.2 选题意义 1 1.3 研究内容 2 2 相关技术介绍 3 3 系统分析 5 3.1可行性分析 5 3.2 需求分析 5 3.2.1非功能性需求 5 3.2.2功能需求 6 3.3 系统用例 6 3.3.1 会员功能需求 6 …

【C++修炼之路】13. priority_queue及仿函数

每一个不曾起舞的日子都是对生命的辜负 stack&&queue一 . priority_queue介绍二. priority_queue的使用三. 仿函数3.1 仿函数的介绍3.2 仿函数的好处四.priority_queue模拟实现五.仿函数之日期比较一 . priority_queue介绍 priority_queue文档介绍 优先队列是一种容器…

机器学习实战(第二版)读书笔记(2)—— LSTMGRU

刚接触深度学习半年的时间&#xff0c;这期间有专门去学习LSTM &#xff0c;这几天读机器学习实战这本书的时候又遇到了&#xff0c;感觉写的挺好的&#xff0c;所以准备结合本书写一下总结方便日后回顾。如有错误&#xff0c;欢迎批评指正。 一、LSTM 优势&#xff1a;可在一…

ApiSix 开启SkyWalking插件,实现链路信息追踪

ApiSix 开启SkyWalking插件&#xff0c;实现链路信息追踪1 ApiSix开启SkyWalking插件1.1 修改config.yml配置文件1.2 在路由中开启SkyWalking插件2 创建两个SpringBoot服务&#xff0c;接入SkyWalking2.1 下载skywalking agent2.2 创建服务2.3 测试SkyWalking1 ApiSix开启SkyWa…