EasyX趣味化编程note2,绘制基本图形

创意化编程,让编程更有趣

今天介绍的仍为比较简单的效果,由浅入深来进行学习

介绍每个函数都会附上代码和运行结果,感兴趣的大家可以复制粘贴运行一下看看效果,也可以自己进行改动,非常好玩且加深印象。

上节课的知识还是很重要哒,放在这里啦note1

接下来我们正式开始介绍图形化的实现

目录

创意化编程,让编程更有趣

创建窗体的函数

销毁窗体的函数

修改中心坐标函数

缩放函数

绘制点的函数

圆的绘制

直线函数

绘制矩形

绘制椭圆

绘制扇形

绘制一段弧

接下来进行绘制更加复杂的图形

polygon函数

polyline函数

绘制图形时的格式

setlinecolor函数

void setlintstyle

​编辑填充图形

setfillcolor函数

fill+绘制函数的函数

设置背景颜色


在画图之前,我们首先要先创建一个窗体

创建窗体的函数

initgraph(int width,int height,int flag*NULL);

width为窗体宽度,height为窗体高度,最后一个参数可省略暂时不用管。

创建窗体后,我们必然要销毁掉窗体

销毁窗体的函数

void closegraph();

接下来创建一个宽800,高600的窗体,然后调用函数关闭它

int main()
{initgraph(800, 600);closegraph();return 0;
}

运行代码后,发现一个窗体一闪而过,我们可以暂时使用getchar函数暂时阻塞程序的运行,要使用getchar函数,我们又要包含头文件stdio.h。

加入代码后再次运行,效果如图

有了窗体,我们可以尝试画一些基本的图形来看一下

在运行后会出现两个窗体,终端还有创建的窗体,如果觉得不想要它可以改变终端

进入开发者选项后将由windows控制改为控制台主机即可

提前介绍一下画圆的函数

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

x,y为圆心的坐标,radius为圆的半径,加入这段代码,绘制圆心为0,0,半径为300的圆,运行后效果如图

发现只有四分之一的圆,这是为什么呢?


介绍一下Easyx内的坐标系统,分为物理坐标和逻辑坐标,物理坐标和逻辑坐标的初始的坐标系都为下图

他们两个的不同的是

物理坐标系使描述窗体的坐标体系的,坐标原点和轴方向不可以更改,而逻辑坐标用于绘图的坐标体系。他的坐标原点和轴方向可以改变。

修改中心坐标函数

void setorgin(int x,int y);

将中心坐标改为坐标400,300的点,但此时y轴的方向依然是向下的

缩放函数

void setaspectratio(float xasp,float yasp);

xasp为x轴方向上的缩放因子,yasp为y轴方向上的缩放因子,如果传参数为负,则反转坐标系,将第二个参数设置为-1,更改y轴的方向,这时就形成了我们所更加熟练应用的坐标系。

添加后再次运行:

接下来是各种图形的绘制,Easyx配置了形形色色的绘制函数,让我们从绘制点来开始学习

绘制点的函数

void putpixel(int x,int y,COLORREF color);

x,y为在坐标轴的位置,COLOR color是绘制点的颜色,可以用RGB表示颜色,也可以用相应的颜色的大写英文字母来表示。

如下图

试着用绘制点的函数绘制一些点,因为一个点只有一像素,只绘制一个很难看清楚到底绘制出没有,利用for循环和设置随机数的函数生成多个点以便观察。因为我们创建的窗体大小有限制,要对生成的随机数进行处理,不能越过窗体的宽度和高度。

代码如下

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1,-1);for (int i = 0; i < 1000; i++){int x = rand() % (800 + 1) - 400;int y = rand() % (600 + 1) - 300;putpixel(x, y,WHITE);}//circle(0, 0, 300);getchar();closegraph();return 0;
}

运行后效果如图所示

圆的绘制

前边已经介绍过绘制圆的函数,不再详细描述,利用这个函数,我们画一组圆环,中心坐标不变,半径依次增大20像素,直到半径等于300为止。

代码如下

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);for (int i = 0; i <= 300; i+=50){circle(0, 0, i);}getchar();closegraph();return 0;
}

运行后如图所示

直线函数

void line(int x1,int y1,int x2,int y2)

(x1 ,y1)(x2 ,y2)分别为起始点的坐标和终止点的坐标,即线的两端。

使用一下看看效果

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);line(200, 200, -200, -200);line(400, 0, -400, 0);line(0, 300, 0, -300);getchar();closegraph();return 0;
}

浅浅的绘制出坐标系,观察第一个画出的线的效果。

绘制矩形

void rectangle(int left,int top,int right,int bottom);

传入的参数和绘制直线的差不多,但表示的是一个矩形的左上角点的坐标和左下角点的坐标,知道了两个点,可以做出一个矩形。

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);//画出坐标系line(400, 0, -400, 0);line(0, 300, 0, -300);//绘制矩形rectangle(-100,100,200,-200);getchar();closegraph();return 0;
}

运行后如图

绘制椭圆

void ellipse(int left,int top,int right,int bottom);

这个函数的参数和绘制矩形的一样就是在矩形内确定一个唯一的椭圆,画一下清晰可见

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);//画出坐标系line(400, 0, -400, 0);line(0, 300, 0, -300);//绘制矩形rectangle(-100,100,100,-200);ellipse(-100, 100, 100, -200);getchar();closegraph();return 0;
}

更改了矩形的形状,更加体现出这个函数绘制椭圆的形状,如果矩形位正方形,那画出的椭圆就是一个正方形的内接圆。

绘制扇形

void pie(int left,int top,int right,int bottom,double stangle,double endangle);

前边的参数和椭圆的一模一样,后两个参数分别为扇形的起始角度和终止角度,其实就是在上边的椭圆中截取一段,这一段是由该椭圆的原点的x轴开始,顺时针截取一段扇形

代码如下

#define Pai 3.14 
int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);//画出坐标系line(400, 0, -400, 0);line(0, 300, 0, -300);//绘制矩形rectangle(-100,100,100,-200);//ellipse(-100, 100, 100, -200);//将椭圆函数注释掉pie(-100, 100, 100, -200, 0, Pai / 4);getchar();closegraph();return 0;
}

运行后如图,发现正确绘制出一个扇形

绘制一段弧

void arc(int left,int top,int right,int bottom,double stangle,double endangle);

扇形和弧的区别我想大家都知道,直接改变上述代码,把绘制扇形的函数改为绘制弧的函数

代码如下

#define Pai 3.14 
int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);//画出坐标系line(400, 0, -400, 0);line(0, 300, 0, -300);//绘制矩形rectangle(-100,100,100,-200);//ellipse(-100, 100, 100, -200);//将椭圆函数注释掉//pie(-100, 100, 100, -200, 0, Pai / 4);//绘制一段弧arc(-100, 100, 100, -200, 0, Pai / 4);getchar();closegraph();return 0;
}

运行后效果如下

vectory,嘿嘿

接下来进行绘制更加复杂的图形

有了上边的讲解,接下来绘制一些稍微复杂一点点的图形()

绘制三角形就是利用line函数,确定三角形的三个顶点,依次连接即可

代码如下

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);//绘制坐标系line(400, 0, -400, 0);line(0, 300, 0, -300);//绘制三角形line(0, 100, 50, -50);line(50, -50, -50, -50);line(-50, -50, 0, 100);getchar();closegraph();return 0;
}

运行后结果如下

是不是觉得好麻烦?

polygon函数

void polygon(const POINT*points,int num);

第一个函数是一个指针,指向数组的首元素,数组里装的是点的坐标,第二个参数阐明有多少个点,用这个函数绘制这个三角形。

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);//绘制坐标系line(400, 0, -400, 0);line(0, 300, 0, -300);//绘制三角形/*line(0, 100, 50, -50);line(50, -50, -50, -50);line(-50, -50, 0, 100);*/POINT points[] = { {0,100},{50,-50},{-50,-50} };polygon(points, 3);getchar();closegraph();return 0;
}

运行后和上边的三角形一模一样。

没有简单很多?如果再装其他的点的坐标,就可以绘制其他的图形,例如矩形,梯形,等等等等,是不是很实用。

我们来画出一个五边形,利用数学知识,确定好各个点的坐标,可以用角度来表示,更简单一点。

分析如下

由于确定坐标位置要用到sin和cos函数,要包含头文件math.h

代码如下

#include <math.h>
#define Pai 3.14
int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);//绘制坐标系line(400, 0, -400, 0);line(0, 300, 0, -300);int r = 200;//半径//初始角度double theta = Pai / 2;//递增角度double delta = 2 * Pai / 5;POINT points[5];//定义一个数组,存放点的坐标for (int i = 0; i < 5; i++){points[i].x = cos(theta + i * delta) * r;points[i].y = sin(theta + i * delta) * r;}polygon(points, 5);getchar();closegraph();return 0;
}

运行后如图

怎么改成五角星呢?其实很简单,把递增角度72°改为144°即可,还是循环五次哦

运行后如下图所示

就不解释啦,大家随便一想就可以明白。

然而

这个函数会将传入的坐标依次连接,如果我们想画一个W型呢,找好坐标,用ploygon函数的话

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1,-1);line(400, 0, -400, 0);line(0, 300, 0, -300);POINT points[] = { {-200,200},{-100,0},{0,80},{100,0},{200,200} };polygon(points, 5);getchar();closegraph();return 0;
}

运行后如图

而我想要的是不封口的,即最后点不连接第一个点

polyline函数

这个函数和polygon几乎一模一样,不同的是他不会连接最后一个点和第一个点来封闭图形,使用polyline函数再次运行

成功!

绘制图形时的格式

前边所学绘制出的图形描边颜色都默认为白色,现在来更改他,利用

setlinecolor函数

void setlinecolor(COLORREF color);

设置描边颜色,一定要在绘制图形之前设置

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);setlinecolor(YELLOW);for (int i = 0; i <= 300; i+=50){circle(0, 0, i);}getchar();closegraph();return 0;
}

还是之前画圆的代码,设置描边颜色后

还可以设置描边的样式

void setlintstyle

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

稀里哗啦一大堆,我们只需要关注前两个参数即可

第一个参数style有很多种类型,可以利用操作符|来进行连接使用,使描边多样式

从线型,端点样式,连接样式里面各挑出几个不容易明白的进行说明

首先说明一下第二个参数为描边的粗细,我们可以设置粗一点更加容易观察。

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1, -1);setlinecolor(BLUE);//线型为实线,端点为圆弧,连接处为斜接setlinestyle(PS_SOLID | PS_ENDCAP_ROUND | PS_JOIN_MITER, 60);POINT points[] = { {-200,200},{-100,0},{0,80},{100,0},{200,200} };polyline(points, 5);//连接处为斜面//setlinestyle(PS_SOLID | PS_ENDCAP_FLAT | PS_JOIN_BEVEL, 60);//POINT points[] = { {-200,200},{-100,0},{0,80},{100,0},{200,200} };//polyline(points, 5);getchar();closegraph();return 0;
}

线型为实线,端点为圆弧,连接为斜接,运行后如图

把第一次绘图的注释掉,把下边的解注释


填充图形

在此之前绘制的所有图形都是十分单调的,没有什么花里胡哨可言,当我们将这些图形进行颜色的填充就可以变得好玩一些。

填充函数只需要在绘制函数前加一个solid即可

solid+图形函数名

例如矩形,三角形,椭圆,只需要将circle换一下即可

绝不仅仅是白色

setfillcolor函数

void setfillcolor(COLORREF color);

设置填充颜色,然后绘制图形,代码如下

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1,-1);setfillcolor(BLUE);solidcircle(0, 0, 200);getchar();closegraph();return 0;
}

运行后效果如下

如果我们想要红色的描边,红色的填充,而不是将描边颜色也改变,就要使用fill函数

fill+绘制函数的函数

改变上述代码,将solid改为fill,再次运行

设置背景颜色

setbkcolor(颜色);

将上述代码,设置背景颜色为白色,但是仅仅用这个函数是不行的,我们在创建窗体时,默认窗体已经被黑色填满

cleardevice();

将使用新的颜料粉刷一遍窗体,设置好新的背景后,就可以开始粉刷

代码如下

int main()
{initgraph(800, 600);setorigin(400, 300);setaspectratio(1,-1);setbkcolor(WHITE);cleardevice();setlinecolor(RED);setlinestyle(PS_SOLID,5);setfillcolor(BLUE);fillcircle(0, 0, 200);getchar();closegraph();return 0;
}

运行后如下图

我们今天所学的大概就是如此啦

接下来只会更加精彩哦,欢迎大家点赞评论哇!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 18的未来:新特性和编程实践

文章目录 引言新特性预览1. 基于值的类的进一步改进2. 模式匹配的增强3. 新的垃圾回收器4. 扩展的模块系统5. 更强大的异步编程 编程实践示例1&#xff1a;基于值的类示例2&#xff1a;模式匹配的增强示例3&#xff1a;新的垃圾回收器 结论 &#x1f389;欢迎来到Java学习路线专…

【Java】建筑工地智慧管理系统源码

智慧工地系统运用物联网信息技术&#xff0c;致力于推动建筑工程行业的建设发展&#xff0c;做到全自动、信息化&#xff0c;智能化的全方位智慧工地&#xff0c;实现工程施工可视化智能管理以提高工程管理信息化水平。 智慧工地平台拥有一整套完善的智慧工地解决方案&#xff…

uni-app:canvas-图形实现1

效果 代码 <template><view><!-- 创建了一个宽度为300像素&#xff0c;高度为200像素的canvas元素。canvas-id属性被设置为"firstCanvas"&#xff0c;可以用来在JavaScript中获取该canvas元素的上下文对象。 --><canvas style"width:200p…

DataX: Ⅱ

序言 这里使用的是master分支,因为官网上并没有release分支,所以先用master分支吧,可能会有问题cuiyaonan2000163.com 参考资料: https://github.com/alibaba/DataXhttps://github.com/alibaba/DataX/blob/master/introduction.md --插件说明文档https://github.com/alib…

5.wifi开发【智能家居:上】,开发准备:智能开关灯,智能采集温湿,智能调彩灯

一。wifi智能家居项目开发 【开发准备1】&#xff1a;继电器控制开发 1.智能开关 器件准备&#xff1a;wifi&#xff08;esp8266&#xff0c;使用CP2102&#xff09;继电器 结果&#xff1a; 2.继电器工作原理 &#xff08;1&#xff09;继电器是一种自动电气开关 &#xff…

代码随想录刷题笔记10——动态规划

动态规划理论基础 动态规划定义 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就区…

DHCP(自动分配ip地址实验案例)

目录 实验原理 案例 实验原理 DHCP 使用客户服务器方式&#xff0c;采用请求/应答方式工作。DHCP 基于 UDP 工作&#xff0c;DHCP服务器运行在67号端口&#xff0c;DHCP客户运行在68号端口。 DHCP的工作过程分为以下步骤&#xff1a; &#xff08;1&#xff09;DHCP服务器被…

【2023保研】双非上岸东南网安

个人情况 学校&#xff1a;henu 专业&#xff1a;信息安全 排名&#xff1a;1/66 英语&#xff1a;六级500 竞赛&#xff1a;蓝桥杯PB国一&#xff0c;ISCC国一&#xff0c;密码数学挑战赛国三&#xff0c;还有其他一些省级水奖 论文&#xff1a;一篇EI在投&#xff08;三作通…

python二维码识别tesseract

window安装tesseract 下载路径&#xff1a; https://digi.bib.uni-mannheim.de/tesseract/ 选择 双击安装在D:\sore\teeseract-OCR后&#xff1a; 配置环境变量 配置环境变量Path&#xff1a;D:\sore\teeseract-OCR 配置语言包的环境变量TESSDATA_PREFIX&#xff1a; D:\s…

ElementUI基本介绍及登录注册案例演示

目录 前言 一.简介 二.优缺点 三.Element完成登录注册 1. 环境配置及前端演示 1.1 安装Element-UI模块 1.2 安装axios和qs(发送get请求和post请求) 1.3 导入依赖 2 页面布局 2.1组件与界面 3.方法实现功能数据交互 3.1 通过方法进行页面跳转 3.2 axios发送get请求 …

chrome extensions mv3通过content scripts注入/获取原网站的window数据

开发插件的都知道插件的content scripts和top window只共享Dom不共享window和其他数据&#xff0c;如果想拿挂载在window的数据还有点难度&#xff0c;下面会通过事件的方式传递cs和top window之间的数据写一个例子 代码 manifest.json 这里只搞了2个js&#xff0c;content.…

什么是Promise链(Promise chaining)?它在异步编程中的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是 Promise 链&#xff1f;⭐ 异步编程中的作用⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、…

动态内存操作(2)

接上一篇文章http://t.csdn.cn/1ONDq&#xff0c;这次我们继续讲解关于动态内存的相关知识。 一、常见的动态内存错误 1.对NULL指针进行解引用操作 #include<stdio.h> #include<stdlib.h> #include<limits.h> int main() {int* p (int*)malloc(INT_MAX/4);…

map和set的具体用法 【C++】

文章目录 关联式容器键值对setset的定义方式set的使用 multisetmapmap的定义方式insertfinderase[]运算符重载map的迭代器遍历 multimap 关联式容器 关联式容器里面存储的是<key, value>结构的键值对&#xff0c;在数据检索时比序列式容器效率更高。比如&#xff1a;set…

什么是数学建模(mooc笔记)

什么是数学建模 前提&#xff1a;我们数学建模国赛计划选择C题&#xff0c;故希望老师的教学中侧重与C题相关性大的模型及其思想进行培训。之后的学习内容中希望涉及以下知识点&#xff1a; logistic回归相关知识点。如&#xff1a;用法、适用、限制范围等。精学数学建模中常…

【Vue2.0源码学习】生命周期篇-挂载阶段(mount)

文章目录 1. 前言2. 挂载阶段分析3. 总结 1. 前言 模板编译阶段完成之后&#xff0c;接下来就进入了挂载阶段&#xff0c;从官方文档给出的生命周期流程图中可以看到&#xff0c;挂载阶段所做的主要工作是创建Vue实例并用其替换el选项对应的DOM元素&#xff0c;同时还要开启对…

高德地图根据两点的经纬度计算两点之间的距离(修正版)

SQL语句可以用来计算两个经纬度之间的距离。下面是一个示例的SQL语句&#xff1a; SELECT id, ( 6371 * ACOS( COS( RADIANS( lat1 ) ) * COS( RADIANS( lat2 ) ) * COS( RADIANS( lng2 ) - RADIANS( lng1 ) ) SIN( RADIANS( lat1 ) ) * SIN( RADIANS( lat2 ) ) ) ) AS dista…

阿里巴巴K8S集成seata

正文 在K8S集成seata&#xff0c;官方配置 代码 apiVersion: v1 kind: Service metadata:name: seata-servernamespace: wmz-devlabels:k8s-app: seata-server spec:type: NodePortports:- port: 8091nodePort: 30091protocol: TCPname: httpselector:k8s-app: seata-server-…

实例讲解Spring boot动态切换数据源

前言 在公司的系统里&#xff0c;由于数据量较大&#xff0c;所以配置了多个数据源&#xff0c;它会根据用户所在的地区去查询那一个数据库&#xff0c;这样就产生了动态切换数据源的场景。 今天&#xff0c;就模拟一下在主库查询订单信息查询不到的时候&#xff0c;切换数据…

elementui 菜单选中优化

/** 父级菜单悬浮样式**/ .el-submenu__title:hover {color:#1890ff!important; } /** 父级菜单箭头悬浮样式**/ .el-submenu__title:hover>.el-submenu__icon-arrow{font-size: 13px!important;} /** 子菜单悬浮样式**/ .el-menu-item:hover{color:#1890ff!important; } /*…