基本绘图和文字输出


一、基本说明

EasyX 是针对 C++ 的图形库,可以帮助 C/C++ 初学者快速上手图形和游戏编程。

比如可以基于 EasyX 图形库很快地用几何图形画一个房子,或者一辆移动的小车,可以编写俄罗斯方块、贪吃蛇、黑白棋等小游戏,可以练习图形学的各种算法,等等。

二、基本概念

2.1 - 颜色

EasyX 使用 24 bit 真彩色,不支持调色板模式

像素是计算机屏幕上所能显示的最小单位,用来表示图像的单位。

分辨率指屏幕上像素的数目,为了控制像素的亮度和彩色深度,每个像素需要很多个二进制位来表示,如果要显示 256 种颜色,则每个像素至少需要 8 位(一个字节)来表示,即 2 ^ 8 = 256;如果要显示 24 位真彩色,则每个像素要用 3 个字节存储。

真彩色是指图像中的每个像素值都分成 R、G、B 三个基色分量,每个基色分量直接决定其基色的强度,这样产生的色彩称为真彩色。

例如图像深度为 24,用 R: G: B = 8: 8: 8 来表示色彩,即 R、G、B 都用 8 位来表示,每个基色分量占一个字节,共 3 个字节,每个像素的颜色就是由这 3 个字节中的数值直接决定,可生成的颜色数就是 2 ^ 24 = 16 777 216 种。24 位真彩色可以达到人眼分辨的极限

表示颜色的方法

  1. 用预定义常量表示颜色,例如 BLACK、WHITE、BLUE 等。
  2. 用 16 进制数字表示颜色,16 进制的颜色表示规则为:0xbbggrr(bb = 蓝,gg = 绿,rr = 红)
  3. 用 RGB 宏合成颜色(详见 RGB)
  4. 用 HSLtoRGB、HSVtoRGB 转换其他色彩模型到 RGB 颜色(详见 HSLtoRGB、HSVtoRGB )
    在这里插入图片描述

2.2 - 坐标

在 EasyX 中,坐标分两种:物理坐标和逻辑坐标

  1. 物理坐标

    物理坐标是描述设备的坐标体系。

    坐标原点在设备的左上角,X 轴向右为正,Y 轴向下为正,度量单位是像素

    坐标原点、坐标轴方向、缩放比例都不能改变

  2. 逻辑坐标

    逻辑坐标是在程序中用于绘图的坐标体系。

    坐标默认的原点在窗口的左上角,X 轴向右为正,Y 轴向下为正,度量单位是点

    默认情况下,逻辑坐标与物理坐标是一一对应的,一个逻辑点等于一个物理像素

    在本手册中,凡是没有注明的坐标,均指逻辑坐标

2.3 - 设备

"设备",是指绘图表面

在 EasyX 中,设备分为两种,一种是默认的绘图窗口,另一种是 IMAGE 对象。通过 SetWorkingImage 函数可以设置当前用于绘图的设备。

设置当前用于绘图的设备后,所有的绘图函数都会绘制在该设备上。

三、绘图设备相关函数

3.1 - initgraph

这个函数用于初始化绘图窗口

HWND initgraph(int width, int height, int flag = NULL);

参数

  • width:绘图窗口的宽度。

  • height:绘图窗口的高度。

  • flag:绘图窗口的样式,默认为 NULL。可以为以下值:

    含义
    EW_DBLCLKS在绘图窗口中支持鼠标双击(double clicks)事件
    EW_NOCLOSE禁用绘图窗口的关闭按钮(no close)
    EW_NOMINIMIZE禁用绘图窗口的最小化按钮(no minimize)
    EW_SHOWCONSOLE显示控制台窗口(show console)

返回值

  • 返回新建绘图窗口的句柄(HWND)

示例

// 创建一个尺寸为 640 x 480 的绘图窗口
initgraph(640, 480);  
// 创建一个尺寸为 640 x 480 的绘图窗口,同时显示控制台窗口
initgraph(640, 480, EW_SHOWCONSOLE);  
// 创建一个尺寸为 640 x 480 的绘图窗口,同时显示控制台窗口,并禁用关闭按钮
initgraph(640, 480, EW_SHOWCONSOLE | EW_NOCLOSE);

3.2 - closegraph

这个函数用于关闭绘图窗口

void closegraph();

3.3 - cleardevice

这个函数使用当前背景色清空绘图设备

void cleardevice();

四、颜色模型

3.1 - RGB

RGB 宏用于将红、绿、蓝颜色分量合成颜色

COLORREF RGB(BYTE byRed, BYTE byGreen, BYTE byBlue);

参数

  • byRed:颜色的红色部分,取值范围:0 ~ 255。
  • byGreen:颜色的绿色部分,取值范围:0 ~ 255。
  • byBlue:颜色的蓝色部分,取值范围:0 ~ 255。

返回值

  • 返回合成的颜色

3.2 - HSLtoRGB

该函数用于转换 HSL 颜色为 RGB 颜色

COLORREF HSLtoRGB(float H, float S, float L);

参数

  • H:原 HSL 颜色模型的 Hue(色相)分量,0 <= H < 360。
  • S:原 HSL 颜色模型的 Saturation(饱和度)分量,0 <= S <= 1。
  • L:原 HSL 颜色模型的 Lightness(亮度)分量,0 <= L <= 1。

HSL 的颜色模型如图所示
在这里插入图片描述

色相 H 是色彩的基本属性,就是平常所说的颜色名称,如红色、黄色等。红色在 0 度,绿色在 120 度,蓝色在 240 度,以此方向过渡

饱和度 S 是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取 0-100% 的数值。

亮度 L 等于 0 时为黑色,等于 0.5 时是色彩最鲜明的状态,等于 1 时为白色。

3.3 - HSVtoRGB

该函数用于转换 HSV 颜色为 RGB 颜色

COLORREF HSVtoRGB(float H, float S, float V);

参数

  • H:原 HSV 颜色模型的 Hue(色相)分量,0 <= H < 360。
  • S:原 HSV 颜色模型的 Saturation(饱和度)分量,0 <= S <= 1。
  • V:原 HSV 颜色模型的 Value(明度)分量,0 <= V <= 1。

HSV 颜色模型如图所示
在这里插入图片描述

明度 V 等于 0 时为黑色,在最大明度 1 时,是色彩最鲜明的状态。

五、图形颜色及样式设置相关函数

5.1 - setbkcolor

这个函数用于设置当前设备绘图背景色

void setbkcolor(COLORREF color);

参数

  • color:指定要设置的背景颜色。

在设置背景颜色之后,并不会改变现有背景色,而只是改变背景色的值,之后再执行绘图语句,例如 outtextxy,会使用新设置的背景色值

如果需要修改全部背景色,可以在设置背景色后再执行 cleardevice() 函数

示例

#include <graphics.h>  // 引入图形库头文件
#include <conio.h> 

#define WIDTH 640
#define HEIGHT 480

int main()
{
	// 初始化绘画窗口
	initgraph(WIDTH, HEIGHT);  

	// 将背景色设置为蓝色
	setbkcolor(BLUE);  
	// 用当前的背景色清空屏幕
	cleardevice();  

	// 按任意键退出
	_getch();  
	closegraph(); 
	return 0;
}

在这里插入图片描述

5.2 - setbkmode

这个函数用于设置当前设备图案填充和文字输出时的背景模式

void setbkmode(int mode);

参数

  • mode:指定图案填充和文字输出时的背景模式。可以是以下值:

    描述
    OPAQUE背景用当前背景色填充**(默认)**
    TRANSPARENT背景是透明的

5.3 - setfillcolor

这个函数用于设置当前设备填充颜色

void setfillcolor(COLORREF color);

参数

  • color:填充颜色。

5.4 - setlinecolor

这个函数用于设置当前设备画线颜色

void setlinecolor(COLORREF color);

参数

  • color:将要设置的画线颜色。

5.5 - setlinestyle

这个函数用于设置当前设备画线样式

void setlinestyle(
    int style,
	int thickness = 1,
	const DWORD *puserstyle = NULL,
	DWORD userstylecount = 0
);

参数

  • style:指定画线样式,该样式由直线样式、端点样式、连接样式三类组成。可以是其中一类或多类的组合。同一类型中只能指定一个样式。

    直线样式可以是以下值

    含义
    PS_SOLID线形为实线
    PS_DASH线形为:------------
    PS_DOT线形为:············
    PS_DASHDOT线形为:-·-·-·-·-·-·
    PS_DASHDOTDOT线形为:-··-··-··-··
    PS_NULL线形不可见
    PS_USERSTYLE线形样式为用户自定义,由参数 puserstyle 和 userstylecount 指定

    宏 PS_STYLE_MASK 是直线样式的掩码,可以通过该宏从画线样式中分离出直线样式。

    端点样式可以是以下值

    含义
    PS_ENDCAP_ROUND端点为圆形
    PS_ENDCAP_SQUARE端点为方形
    PS_ENDCAP_FLAT端点为平坦

    宏 PS_ENDCAP_MASK 是端点样式的掩码,可以通过该宏从画线样式中分离出端点样式。

    连接样式可以是以下值

    含义
    PS_JOIN_BEVEL连接处为斜面
    PS_JOIN_MITER连接处为斜接
    PS_JOIN_ROUND连接处为圆弧

    宏 PS_JOIN_MASK 是连接样式的掩码,可以通过该宏从画线样式中分离处连接样式。

  • thickness:线的宽度,以像素为单位。

  • puserstyle:用户自定义样式数组,仅当线型为 PS_USERSTYLE 时该参数有效。数组第一个元素指定画线长度,第二元素指定空白的长度,第三个元素指定画线的长度,第四个元素指定空白的长度,以此类推。

  • userstylecount:用户自定义样式数组的元素数量。

六、图形绘制相关函数

6.1 - 绘图函数的分类

绘图函数从填充样式分类,可分为:无填充有边框填充以及无边框填充

绘图函数从形状来分类,常用的可分为以下八种:

  1. circle - 画圆
  2. ellipse - 画椭圆
  3. pie - 画扇形
  4. polygon - 画多边形
  5. rectangle - 画矩形
  6. roundrect - 画圆角矩形
  7. line - 画线
  8. putpixel - 画点

6.2 - 圆

  1. 该函数使用当前画线样式绘制无填充的圆

    void circle(int x, int y, int radius);
    

    参数

    • x:圆心 x 坐标。
    • y:圆心 y 坐标。
    • radius:圆的半径。
  2. 该函数使用当前线形和当前填充样式绘制有边框的填充圆

    void fillcircle(int x, int y, int radius);
    

    参数

    • x:圆心 x 坐标。
    • y:圆心 y 坐标。
    • radius:圆的半径。
  3. 该函数使用当前填充样式绘制无边框的填充圆

    void solidcircle(int x, int y, int radius);
    

    参数

    • x:圆心 x 坐标。
    • y:圆心 y 坐标。
    • radius:圆的半径。

6.3 - 示例

#include <graphics.h>  // 引入图形库头文件
#include <conio.h> 

#define WIDTH 640
#define HEIGHT 480

int main()
{
	// 初始化绘画窗口
	initgraph(WIDTH, HEIGHT);  
	// 将背景色设置为黄色
	setbkcolor(HSLtoRGB(60, 1, 0.5));  
	// 用当前的背景色清空屏幕
	cleardevice();  

	// 将画线颜色设置为红色
	setlinecolor(RGB(255, 0, 0));
	// 将画线样式设置为实线,线的宽度为 3 像素
	setlinestyle(PS_SOLID, 3);
	// 将填充颜色设置为绿色
	setfillcolor(0x00ff00); 

	// 使用当前画线样式绘制无填充圆
	circle(50, 50, 50);
	// 使用当前线形和当前填充样式绘制有边框的填充圆
	fillcircle(50, 150, 50);
	// 使用当前填充样式绘制无边框的填充圆
	solidcircle(50, 250, 50);


	// 按任意键退出
	_getch();  
	closegraph(); 
	return 0;
}

在这里插入图片描述

七、文字输出相关函数

7.1 - outtextxy

这个函数用于在指定位置输出字符串

void outtextxy(int x, int y, LPCTSTR str);

这个函数用于在指定位置输出字符

void outtextxy(int x, int y, TCHAR c);

参数

  • x:字符串输出时头字母的 x 轴的坐标值。
  • y:字符串输出时头字母的 y 轴的坐标值。
  • str:待输出的字符串的指针。
  • c:待输出的字符。

字符串常见的编码有两种:MBCS(Multi-Bytes Character Set,即多字节字符集)和 Unicode(统一码、万国码、单一码)

LPCTSTR 可以同时适应两种编码。为了适应两种编码,请使用 TCHAR 字符串及相关函数

默认情况下,输出字符串的背景会用当前背景色填充。使用函数 setbkmode 可以设置文字的背景部分保存透明或使用背景色填充

7.2 - settextcolor

这个函数用于设置当前文字颜色

void settextcolor(COLORREF color);

参数

  • color:要设置的文字颜色。

7.3 - settextstyle

这个函数用于设置当前字体样式

void settextstyle(
    int nHeight,
    int nWidth,
    LPCTSTR lpszFace
);

参数

  • nHeight:指定高度(逻辑单位)。
  • nWidth:字符的平均宽度(逻辑单位)。如果为 0,则比例自适应。
  • lpszFace:字体名称。

八、示例程序

8.1 - 彩虹

该程序是 HSL 色彩模型的应用范例,程序通过调节 HSL 模型的亮度绘制渐变的天空,调节色相绘制七色彩虹

#include <graphics.h>
#include <conio.h>

#define WIDTH 640
#define HEIGHT 480

int main()
{
	initgraph(WIDTH, HEIGHT);

	// 通过调节 HSL 模型的亮度(Lightness)绘制渐变的天空
	float H = 190;
	float S = 1;
	float L = 0.7f;	
	float increase = (1.0 - L) / HEIGHT;
	for (int y = 0; y < HEIGHT; y++)  // 注意:x 坐标和 y 坐标从 0 开始
	{
		L += increase;
		setlinecolor(HSLtoRGB(H, S, L));
		line(0, y, WIDTH - 1, y);	
	}

	// 调节色相(Hue)绘制七色彩虹
	H = 0;
	S = 1;
	L = 0.5f;
	setlinestyle(PS_SOLID, 2);  // 将线宽设置为 2
	for (int r = 400; r > 344; r--)
	{
		H += 6;
		setlinecolor(HSLtoRGB(H, S, L));
		circle(500, 480, r);
	}
	
	_getch();
	closegraph();
	return 0;
}

在这里插入图片描述

8.2 - 字符阵

该程序示范了常见的绘图操作,包括设置字体、画线等

#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>

#define WIDTH 640
#define HEIGHT 480

int main()
{
	srand((unsigned int)time(NULL));

	initgraph(WIDTH, HEIGHT);

	settextstyle(16, 8, _T("Courier"));  // 将文字的高度和宽度分别设置为 16 和 8,字体为 Courier
	settextcolor(GREEN);  // 将文字颜色设置为绿色
	setbkmode(TRANSPARENT);  // 文字输出时的背景模式为 TRANSPARENT
	setlinecolor(BLACK);  // 将画线颜色设置为黑色

	int x, y;
	char c;
	for (int i = 0; i < HEIGHT; i++)
	{
		for (int j = 0; j < 3; j++)  // 在随机位置显示三个随机字母
		{
			x = rand() % (WIDTH - 7);  // x:0 ~ WIDTH - 8
			y = rand() % (HEIGHT - 15);  // y:0 ~ HEIGHT - 16
			c = rand() % 26 + 65;  // c:65 ~ 90,即 'A' ~ 'Z'
			outtextxy(x, y, c);
		}
		line(0, i, WIDTH - 1, i);  // 画线擦掉一个像素行
		Sleep(10);  // 延时 0.01 秒
		if (i >= HEIGHT - 1)  // 当到最后一行时,置 i 为 -1
			i = -1;  
		if (_kbhit())	// 按任意键退出
			break;		
	}
    
	closegraph();
	return 0;
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值