Basado en easyX y vs usando c ++ para dibujar el sistema de coordenadas y la visualización en tiempo real

Dado que algunos algoritmos están escritos en lenguaje C en Windows, el lenguaje C no tiene su propia biblioteca de interfaz gráfica, por lo que es muy inconveniente depurarlo. Creo que esto afectará a muchos amigos que utilizan el desarrollo del lenguaje C. Recientemente escribí un programa de trazado de datos en tiempo real basado en easyX, espero poder brindarle algo de ayuda.

easyX es una biblioteca de gráficos C ++, que solo se puede usar en Windows, y generalmente solo se puede usar en VS o vc (yo uso VS). Hay muchas restricciones. Si desea usarlo, debe instalar el software honestamente. Instale vs primero, luego instale easyX. easyX es fácil de instalar.

Déjame mostrarte el efecto primero:

Pantalla estática (sin cuadrícula):

 

Pantalla estática (con cuadrícula, donde la línea de cuadrícula cubre el signo negativo del valor de la escala, comprensión de larga duración):

Dibujo dinámico (sin cuadrícula):

Dibujo dinámico (con cuadrícula):

Cuando se dibuja dinámicamente, se usa una cola circular, y luego todos los elementos de la cola se vuelven a dibujar cada vez

El siguiente es el código:

Primero, el código para la cola circular:

queue.h

#ifndef _QUEUE_H
#define _QUEUE_H

//循环队列的大小
#define MAXSIZE  1000  

typedef struct queueint {
	int data[MAXSIZE];
	int front, rear;
}QueueInt;

typedef struct queueintfloat {
	float data[MAXSIZE];
	int front, rear;
}QueueFloat;

void queueInitFloat(QueueFloat* queue);

int insertFloat(QueueFloat* queue,float a);

int deleteFloat(QueueFloat* queue);

int getSizeFloat(QueueFloat* queue);

void queueInitInt(QueueInt* queue);

int insertInt(QueueInt* queue, int a);

int deleteInt(QueueInt* queue);

int getSizeInt(QueueInt* queue);


#endif

queue.cpp

#include "queue.h"


void queueInitFloat(QueueFloat* queue) {
	queue->front = 0;
	queue->rear = 0;
	for (int i = 0; i < MAXSIZE; i++)
		queue->data[i] = 0;
}

int insertFloat(QueueFloat* queue, float a) {
	if ((queue->rear + 1)%MAXSIZE==queue->front) {
		return 1;
	}
	queue->data[queue->rear++] = a;
	return 0;
}

int deleteFloat(QueueFloat* queue) {
	if (queue->front == queue->rear) {
		return 1;
	}
	queue->front++;
	return 0;
}

int getSizeFloat(QueueFloat* queue) {
	int res = queue->rear - queue->front;
	if (res < 0) {
		res += MAXSIZE;
	}
	return res;
}

void queueInitInt(QueueInt* queue) {
	queue->front = 0;
	queue->rear = 0;
	for (int i = 0; i < MAXSIZE; i++)
		queue->data[i] = 0;
}

int insertInt(QueueInt* queue, int a) {
	if ((queue->rear + 1) % MAXSIZE == queue->front) {
		return 1;
	}
	queue->data[queue->rear++] = a;
	queue->rear %= MAXSIZE;
	return 0;
}

int deleteInt(QueueInt* queue) {
	if (queue->front == queue->rear) {
		return 1;
	}
	queue->front++;
	queue->front %= MAXSIZE;
	return 0;
}

int getSizeInt(QueueInt* queue) {
	int res = queue->rear - queue->front;
	if (res < 0) {
		res += MAXSIZE;
	}
	return res;
}

Luego, el dibujo del sistema de coordenadas y el código de dibujo.

drawCoordinateSystem.h

#pragma once
#ifndef DrawCoordinateSystem 
#define DrawCoordinateSystem
#include "queue.h"
/*
这是绘制坐标系的函数
1、轴
2、刻度
3、原点
4、网格
5、图幅
6、箭头
*/

//轴结构体
struct Axis {
	int xlow, xhigh;
	int ylow, yhigh;
	int centerx,centery;
	float ax, ay;   //压缩
	int color;
};

//刻度结构体
struct Scale {
	int openflag;  //是否开启
	int scalex;     //刻度大小
	int scaley;
	int color;
};
struct Grid{
	int openflag;
	int color;
};

typedef struct coordinatesystem {
	struct Axis axis;
	struct Scale scale;
	int zerox, zeroy;  //坐标系原点
	struct Grid grid;
	int length, width;  //图幅长宽
	int color;     //背景颜色
	int borderx, brodery; //边界空出的范围
}CoordinateSystem;


void coordinateSystemInit(CoordinateSystem* cs);

void createCS(CoordinateSystem* cs);

void plotInt(CoordinateSystem* cs, int* data, int len, int color);

void plotFloat(CoordinateSystem* cs, float* data, int len, int color);

void dynamicPlotInt(CoordinateSystem* cs,QueueInt* queue,int color);

void addInt(QueueInt* queue,int a);


#endif // !DrawCoordinateSystem 


 

drawCoordinateSystem.cpp

#include "drawCoordinateSystem.h"
#include <easyx.h>			// 引用图形库头文件
#include <Windows.h>
#include <math.h>
#include <stdio.h>
#include "queue.h"


void coordinateSystemInit(CoordinateSystem* cs) {
	//图幅初始化
	cs->length = 1280;
	cs->width = 780;
	//坐标轴初始化
	cs->axis.xhigh = 100;
	cs->axis.xlow = -100;
	cs->axis.yhigh = 100;
	cs->axis.ylow = 0;
	cs->axis.centerx = (cs->axis.xhigh + cs->axis.xlow) / 2;
	cs->axis.centery = (cs->axis.yhigh + cs->axis.ylow) / 2;
	int len1 = cs->axis.xhigh - cs->axis.xlow;
	int len2 = cs->axis.yhigh - cs->axis.ylow;
	cs->axis.ax = cs->length*1.0 / len1;
	cs->axis.ay = cs->width*1.0 / len2;
	cs->axis.color = BLACK;
	//坐标原点初始化
	cs->zerox = 0;
	cs->zeroy = 50;
	//刻度初始化
	cs->scale.openflag = 1;
	cs->scale.scalex = 10;
	cs->scale.scaley = 10;
	cs->scale.color = BLACK;
	//网格初始化
	cs->grid.openflag = 1;
	cs->grid.color = BLACK;
	//边界空出范围
	cs->borderx = 10;
	cs->brodery = 10;
	cs->color = WHITE;
	//创建窗口
	HWND hwnd = initgraph(cs->length + cs->borderx, cs->width + cs->brodery, EW_SHOWCONSOLE);
	setrop2(R2_MASKPEN); //加一个光栅更好看
}

int transX(CoordinateSystem* cs, float x) {
	x -= cs->axis.centerx;
	x *= cs->axis.ax;
	int k = x;
	if (x - k > 0.5)
		k++;
	return k;
}
int transY(CoordinateSystem* cs, float y) {
	y -= cs->axis.centery;
	y *= cs->axis.ay;
	int k = y;
	if (y - k > 0.5)
		k++;
	return k;
}

void createCS(CoordinateSystem* cs) {
	
	//设置原点
	int avex = (cs->length + cs->borderx) / 2;
	int avey = (cs->width + cs->brodery) / 2;
	setorigin(avex, avey);

	//设置缩放与坐标轴方向
	setaspectratio(1,-1); //将y轴翻转为 向上为正

	//设置背景色
	setbkcolor(cs->color);
	cleardevice();
	//绘制坐标轴
	setlinecolor(cs->axis.color); //设置颜色
	setlinestyle(PS_SOLID,3);     //线的样式:实线,宽度
	line(-cs->length/2,0,cs->length/2,0);
	line(transX(cs,cs->zerox),cs->width/2, transX(cs, cs->zerox),-cs->width/2);
	//绘制箭头
	float angle = 15/180.0*3.14159; //箭头角度
	float len3 =20;
	float x11 = cs->zerox*1.0;
	float x12 = cs->zerox*1.0 + len3 * tan(angle)/cs->axis.ax;
	float x13 = cs->zerox*1.0 - len3 * tan(angle) / cs->axis.ax;
	float y11 = cs->axis.yhigh*1.0;
	float y12 = cs->axis.yhigh*1.0 - len3 / cs->axis.ay;
	float y13 = cs->axis.yhigh*1.0 - len3/cs->axis.ay;
	line(transX(cs,x11),cs->width/2,transX(cs, x12 ),cs->width/2-len3);
	line(transX(cs, x11), cs->width / 2, transX(cs, x13), cs->width / 2 - len3);

	float x21 = cs->axis.xhigh;
	float x22 = cs->axis.xhigh - len3 / cs->axis.ax;
	float x23 = cs->axis.xhigh - len3 / cs->axis.ax;
	float y21 = cs->zeroy;
	float y22 = cs->zeroy+len3* tan(angle) / cs->axis.ay;
	float y23 = cs->zeroy - len3 * tan(angle) / cs->axis.ay;
	line(transX(cs, x21), transY(cs, y21), transX(cs, x22), transY(cs, y22));
	line(transX(cs, x21), transY(cs, y21), transX(cs, x23), transY(cs, y23));
	// 绘制刻度
	if (cs->scale.openflag) {
		int len4 = 5;  //刻度的高度
		float rlen = 50 / cs->axis.ax, rwid = 30 / cs->axis.ay; //刻度值长宽
		int bias = 2; //刻度值离坐标轴的距离
		char s[10];
		int i = 0;
		setaspectratio(1, 1); //将y轴翻转为 向上为负
		settextcolor(cs->scale.color); //设置文字颜色
		setbkmode(TRANSPARENT); //背景透明
		while (cs->zerox - i * cs->scale.scalex > cs->axis.xlow) {
			setlinecolor(cs->axis.color); //设置刻度颜色
			setlinestyle(PS_SOLID, 3);     //线的样式:实线,宽度

			line(transX(cs, cs->zerox - i * cs->scale.scalex), transY(cs, cs->zeroy), transX(cs, cs->zerox - i * cs->scale.scalex), transY(cs, cs->zeroy) - len4);
			RECT r = { transX(cs, cs->zerox - i * cs->scale.scalex - rlen / 2), transY(cs, cs->zeroy) + bias,transX(cs, cs->zerox - i * cs->scale.scalex + rlen / 2),transY(cs, cs->zeroy + rwid) + bias };
			sprintf(s, "%d", cs->zerox - i * cs->scale.scalex);
	//		printf("%s\n", s);
			drawtext(s, &r, DT_CENTER | DT_TOP | DT_SINGLELINE);
			//绘制网格
			if (cs->grid.openflag&&i!=0) {
				setlinecolor(cs->grid.color); //设置网格颜色
				setlinestyle(PS_DASH, 1);     //线的样式:虚线,宽度
				line(transX(cs, cs->zerox - i * cs->scale.scalex), transY(cs, cs->axis.ylow), transX(cs, cs->zerox - i * cs->scale.scalex), transY(cs, cs->axis.yhigh));
			}
			i++;
		}
		i = 1;
		while (cs->zerox + i * cs->scale.scalex < cs->axis.xhigh) {
			setlinecolor(cs->axis.color); //设置刻度颜色
			setlinestyle(PS_SOLID, 3);     //线的样式:实线,宽度

			line(transX(cs, cs->zerox + i * cs->scale.scalex), transY(cs, cs->zeroy), transX(cs, cs->zerox + i * cs->scale.scalex), transY(cs, cs->zeroy) - len4);
			RECT r = { transX(cs, cs->zerox + i * cs->scale.scalex - rlen / 2), transY(cs, cs->zeroy) + bias,transX(cs, cs->zerox + i * cs->scale.scalex + rlen / 2),transY(cs, cs->zeroy + rwid) + bias };
			sprintf(s, "%d", cs->zerox + i * cs->scale.scalex);
//			printf("%s\n", s);
			drawtext(s, &r, DT_CENTER | DT_TOP | DT_SINGLELINE);
			//绘制网格
			if (cs->grid.openflag&&i != 0) {
				setlinecolor(cs->grid.color); //设置网格颜色
				setlinestyle(PS_DASH, 1);     //线的样式:虚线,宽度
				line(transX(cs, cs->zerox + i * cs->scale.scalex), transY(cs, cs->axis.ylow), transX(cs, cs->zerox + i * cs->scale.scalex), transY(cs, cs->axis.yhigh));
			}
			i++;
		}
		i = 0;
		while (cs->zeroy - i * cs->scale.scaley > cs->axis.ylow) {
			setlinecolor(cs->axis.color); //设置刻度颜色
			setlinestyle(PS_SOLID, 3);     //线的样式:实线,宽度

			line(transX(cs, cs->zerox), transY(cs, cs->zeroy + i * cs->scale.scaley), transX(cs, cs->zerox) + len4, transY(cs, cs->zeroy + i * cs->scale.scaley));
			RECT r = { transX(cs, cs->zerox - rlen) - bias, transY(cs,cs->zeroy + i * cs->scale.scaley - rwid / 2),transX(cs, cs->zerox) - bias, transY(cs,cs->zeroy + i * cs->scale.scaley + rwid / 2) };
			sprintf(s, "%d", cs->zeroy - i * cs->scale.scaley);
//			printf("%s\n", s);
			drawtext(s, &r, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
			//绘制网格
			if (cs->grid.openflag&&i != 0) {
				setlinecolor(cs->grid.color); //设置网格颜色
				setlinestyle(PS_DASH, 1);     //线的样式:虚线,宽度
				line(transX(cs, cs->axis.xlow), transY(cs, cs->zeroy + i * cs->scale.scaley), transX(cs, cs->axis.xhigh), transY(cs, cs->zeroy + i * cs->scale.scaley));
			}
			i++;
		}
		i = 1;
		while (cs->zeroy + i * cs->scale.scaley < cs->axis.yhigh) {
			setlinecolor(cs->axis.color); //设置刻度颜色
			setlinestyle(PS_SOLID, 3);     //线的样式:实线,宽度

			line(transX(cs, cs->zerox), transY(cs, cs->zeroy - i * cs->scale.scaley), transX(cs, cs->zerox) + len4, transY(cs, cs->zeroy - i * cs->scale.scaley));
			RECT r = { transX(cs, cs->zerox - rlen) - bias, transY(cs,cs->zeroy - i * cs->scale.scaley - rwid / 2),transX(cs, cs->zerox) - bias, transY(cs,cs->zeroy - i * cs->scale.scaley + rwid / 2) };
			sprintf(s, "%d", cs->zeroy + i * cs->scale.scaley);
//			printf("%s\n", s);
			drawtext(s, &r, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
			//绘制网格
			if (cs->grid.openflag&&i != 0) {
				setlinecolor(cs->grid.color); //设置网格颜色
				setlinestyle(PS_DASH, 1);     //线的样式:虚线,宽度
				line(transX(cs, cs->axis.xlow), transY(cs, cs->zeroy - i * cs->scale.scaley), transX(cs, cs->axis.xhigh), transY(cs, cs->zeroy - i * cs->scale.scaley));
			}
			i++;
		}
	}
}

void setRange(CoordinateSystem*cs, int xlow, int xhigh, int ylow, int yhigh) {
	cs->axis.ylow = ylow;
	cs->axis.yhigh = yhigh;
	cs->axis.xlow = xlow;
	cs->axis.xhigh = xhigh;
	cs->axis.centerx = (cs->axis.xlow + cs->axis.xhigh) / 2;
	cs->axis.centery = (cs->axis.ylow + cs->axis.yhigh) / 2;
	int len1 = cs->axis.xhigh - cs->axis.xlow;
	int len2 = cs->axis.yhigh - cs->axis.ylow;
	cs->axis.ax = cs->length*1.0 / len1;
	cs->axis.ay = cs->width*1.0 / len2;
	cs->scale.scalex =(int) (100 / cs->axis.ax)/10*10;
	cs->scale.scaley = (int)(100 / cs->axis.ay) / 10*10;
	if (cs->scale.scalex <= 0)
		cs->scale.scalex=(int)(100 / cs->axis.ax);
	if (cs->scale.scaley <= 0)
		cs->scale.scaley=(int)(100 / cs->axis.ay);
	if (cs->scale.scalex <= 0)
		cs->scale.scalex = 1;
	if (cs->scale.scaley <= 0)
		cs->scale.scaley = 1;
	cs->zerox = 0;
	cs->zeroy = cs->axis.centery;
}

//直接给一组数据,将数据绘制出来
void plotInt(CoordinateSystem* cs, int* data, int len, int color) {
	//找出最大最小值
	int min = data[0];
	int max = data[0];
	for (int i = 1; i < len; i++) {
		if (data[i] > max) {
			max = data[i];
		}
		if (data[i] < min) {
			min = data[i];
		}
	}
	int range = max - min;
	coordinateSystemInit(cs);
	setRange(cs, 0-len*0.1, len*1.1, min-range*0.1, max+range*0.1);
	
	createCS(cs);
	setlinecolor(color);
	setaspectratio(1, -1);
	setlinestyle(PS_SOLID, 2);
	for (int i = 0; i < len - 1; i++) {
		line(transX(cs,i + 1),transY(cs, data[i]),transX(cs, i + 2),transY(cs, data[i + 1]));
	}
	for (int i = 0; i < len; i++) {
		putpixel(transX(cs,i + 1),transY(cs, data[i]),color);
	}
}

//直接给一组数据,将数据绘制出来
void plotFloat(CoordinateSystem* cs, float* data, int len, int color) {
	//找出最大最小值
	float min = data[0];
	float max = data[0];
	for (int i = 1; i < len; i++) {
		if (data[i] > max) {
			max = data[i];
		}
		if (data[i] < min) {
			min = data[i];
		}
	}
	float range = max - min;
	coordinateSystemInit(cs);
	setRange(cs, 0 - len * 0.1, len*1.1, min - range * 0.1, max + range * 0.1);

	createCS(cs);
	setlinecolor(color);
	setaspectratio(1, -1);
	setlinestyle(PS_SOLID, 2);
	for (int i = 0; i < len - 1; i++) {
		line(transX(cs, i + 1), transY(cs, data[i]), transX(cs, i + 2), transY(cs, data[i + 1]));
	}
	for (int i = 0; i < len; i++) {
		putpixel(transX(cs, i + 1), transY(cs, data[i]), color);
	}
	//
}


void dynamicPlotInt(CoordinateSystem* cs, QueueInt* queue, int color) {
	int len = getSizeInt(queue);
	int min, max;
	if (len == 0) {
		min = 0;
		max = 100;
	}else if (len==1) {
		min = queue->data[queue->front] - 10;
		max = queue->data[queue->front] + 10;
	}else {
		int p = (queue->front+1)%MAXSIZE;
		min = queue->data[queue->front];
		max = queue->data[queue->front];
		while (p% MAXSIZE != queue->rear) {
			if (queue->data[p ]>max) {
				max = queue->data[p ];
			}
			if (queue->data[p ] < min) {
				min = queue->data[p ];
			}
			p++;
			p %= MAXSIZE;
		}
	}
	if (min == max) {
		min = min - 10;
		max = max + 10;
	}
	float range = max - min;

//	coordinateSystemInit(cs);
	if (len <= 10) {
		setRange(cs, -10, 10, min - range * 0.1, max + range * 0.1);
	}
	else {
		setRange(cs, 0 - len * 0.1, len*1.1, min - range * 0.1, max + range * 0.1);
	}
	BeginBatchDraw();//开始批量画图
	createCS(cs);

	if (len == 0) {
		EndBatchDraw();
		return;
	}

	setlinecolor(color);
	setaspectratio(1, -1);
	setlinestyle(PS_SOLID, 2);
	int i = 0;
	int k = 0;
	
	for (int p = queue->front; (p+1)%MAXSIZE != queue->rear;p++,p%=MAXSIZE,i++) {
		line(transX(cs, i + 1), transY(cs,queue->data[p]), transX(cs, i + 2), transY(cs, queue->data[(p+1)%MAXSIZE]));
		k++;
		if (k == 10) {
//			FlushBatchDraw();
			k = 0;
		}
	}
	EndBatchDraw();
//	i = 0;
//	for (int p = queue->front; p%MAXSIZE != queue->rear; p++, p %= MAXSIZE, i++) {
//		putpixel(transX(cs, i + 1), transY(cs, queue->data[p]), color);
//	}
//	for (int i = 0; i < len; i++) {
//		putpixel(transX(cs, i + 1), transY(cs, data[i]), color);
//	}
}

void addInt(QueueInt* queue, int a) {
	if (insertInt(queue, a)) {
		deleteInt(queue);
		insertInt(queue, a);
	}
}

Finalmente, el código de dibujo

Dibujar código de datos estáticos:

#include <math.h>
#include <windows.h>
#include <stdio.h>
#include <easyx.h>			// 引用图形库头文件
#include <conio.h>
#include "drawCoordinateSystem.h"
#include "queue.h"


int main() {
	CoordinateSystem cs;
	coordinateSystemInit(&cs);
	float a[1001];
	int j = 0;
	for (float i = 0; i < 2 * 3.14; i += 3.14 / 500) {
		a[j++] = 10 * sin(i);
	}
	plotFloat(&cs, a, 1000, RED);
	getchar();
	return 0;
}

Dibujo de código de datos dinámicos:

#include <math.h>
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <easyx.h>			// 引用图形库头文件
#include <conio.h>
#include "drawCoordinateSystem.h"
#include "queue.h"

void fun(void* p) {
	CoordinateSystem cs;
	coordinateSystemInit(&cs);
	while (1) {
		dynamicPlotInt(&cs,&queue,RED);
		Sleep(20);
	}
	_endthread();
}

int main(){
	queueInitInt(&queue);
	_beginthread(fun, 0, NULL);
	float t = 0;
	getchar();
	while (1) {
		if (int(t+1) % 500 == 0) {
			addInt(&queue, 100 * sin(t / 100));
		}else
			addInt(&queue,100*sin(t/100));
		Sleep(10);
		t++;
		printf("%d\n",getSizeInt(&queue));
	}
	return 0;
}

El dibujo dinámico aquí solo escribe el código para dibujar el tipo int, el tipo flotante es básicamente el mismo, solo cópielo, si tiene una necesidad, puede hacerlo usted mismo o comentar o mensaje privado, lo agregaré.

Supongo que te gusta

Origin blog.csdn.net/qq_39545674/article/details/105260116
Recomendado
Clasificación