C语言绘制动态图

教育   2024-09-26 23:35   宁夏  

前言

有时候我们在访问网页的时候,看到网页的背景是好多点和线组成的那种动态图,今天我就来实现一下这个动态图的生成,其中包含了随机运动的点和基于距离感知的连线。下面,我们将深入讲解这一系统的生成原理。

一、随机运动点的生成

  1. 初始化:每个点(Point类的一个实例)在创建时,会被赋予一个随机的初始位置(xy坐标)以及一个随机的速度(xSpeedySpeed),这些速度决定了点将如何移动。

  2. 边界回弹:为了防止点移出屏幕,我们设置了边界回弹机制。当点触碰到屏幕的边缘时,它的速度方向会反转,从而使其“反弹”回来,继续在屏幕内移动。

  3. 绘制与更新:在每次绘制循环中,我们首先更新每个点的位置(通过在其当前位置上加上速度),然后绘制这些点。这里使用了圆形(solidcircle函数)来表示每个点,并设置了统一的填充颜色。

二、距离感知的连线

  1. 计算距离:对于屏幕上的每一对点,我们计算它们之间的欧几里得距离。这是通过计算两点在x轴和y轴上距离的平方和,然后开平方根得到的。

  2. 条件判断与连线:如果两点之间的距离小于或等于设定的最大距离(maxDis),则在这两点之间绘制一条线。这条线的颜色会根据距离动态变化,距离越近,颜色越亮;距离越远,颜色越暗。

  3. 颜色映射:为了将距离映射到颜色上,我们使用了一个简单的线性插值方法。具体来说,我们根据距离与最大距离的比例,计算出一个介于0和255之间的数值(NUM),然后将这个数值加上一个偏移量(offset),以得到一个更加明亮的颜色范围。最后,我们使用这个计算出的颜色值来设置连线的颜色。

三、整体流程

整个程序运行在一个无限循环中,不断地更新和绘制屏幕上的点和连线。为了提高绘制效率,我们使用了批量绘制技术(BeginBatchDrawFlushBatchDraw),这可以减少绘制过程中的屏幕刷新次数,从而提高程序的性能。

四、源码

///////////////////////////////////////////////////// 程序名称:动态图// 编译环境:Mictosoft Visual Studio 2022, EasyX_20200315(beta)// 作  者:luoyh <2864292458@qq.com>// 最后修改:2024-9-26// 公 众 号:C语言研究//
#include <graphics.h> #include <conio.h> #include <time.h> #include <math.h>
// 设置随机数产生方法 int getRandom(int min, int max){ return rand() % (max - min + 1) + min;}
// Point类 class Point {public: int x, y; int xSpeed, ySpeed; int r;
Point() { r = 3; // 点的半径 x = getRandom(0, getwidth() - r); y = getRandom(0, getheight() - r); xSpeed = getRandom(-3, 3); ySpeed = getRandom(-3, 3); }
void draw(){ // 更新坐标 x += xSpeed; y += ySpeed;
// 超出边界回弹 if (x > getwidth() - r) { x = getwidth() - r; xSpeed = -xSpeed; } else if (x < 0) { x = 0; xSpeed = -xSpeed; } if (y > getheight() - r) { y = getheight() - r; ySpeed = -ySpeed; } else if (y < 0) { y = 0; ySpeed = -ySpeed; }
// 绘制点 setfillcolor(RGB(200,200,200)); solidcircle(x, y, r); }};
// Graph类 class Graph {private: Point* points; int pointNumber; int maxDis;
public: Graph(int pointNum = 80, int maxDistance =70) { pointNumber = pointNum; maxDis = maxDistance; points = new Point[pointNumber]; }
~Graph() { delete[] points; }
void draw() { BeginBatchDraw(); while (true) { for (int i = 0; i < pointNumber; i++) { points[i].draw();
for (int j = i + 1; j < pointNumber; j++) { int dx = points[i].x - points[j].x; int dy = points[i].y - points[j].y; int distance = sqrt(dx * dx + dy * dy);
if (distance <= maxDis) { int NUM = 255-static_cast<int>(distance * 255.0 / maxDis); // 确保NUM是整数 int offset = 50; setlinecolor(RGB(NUM+ offset, NUM+ offset, NUM+ offset)); // 当NUM接近0时,颜色接近黑色;当NUM接近255时,颜色接近白色 line(points[i].x, points[i].y, points[j].x, points[j].y); } } } Sleep(20); FlushBatchDraw(); cleardevice(); // 清空画布 } EndBatchDraw(); }};
int main(){ initgraph(640, 480); srand(time(NULL)); Graph g; g.draw(); closegraph(); // 关闭图形窗口 return 0;}

五、效果

C语言研究
写给自己的笔记,时常写写,时常看看,仅此而已。