用EasyX图形库编写动态彩色万花尺程序(c语言)

用EasyX图形库编写动态彩色万花尺程序(c语言)

在EasyX看到别人写的万花尺程序,想起来小时候玩的,就动手改进增加了一些效果。参考程序连接(侵删):万花尺_慢羊羊
我的效果如下,输入数据:【300 180 100】【450 320 141】
输出效果:
在这里插入图片描述
输入数据:【86 30 42】【86 38 12】【300 180 100】【600 400 140】
输出效果:
在这里插入图片描述
由于代码简单,就不多解释,值得注意的是:代码运行环境是VS2019 EasyX20200109,其他版本没试过,,如果代码提示参数类型有错误,可以设置 项目——属性——配置属性——高级——字符集——将Unicode设置为未设置 即可。附上代码:

//********************************************************************//
// 程序名称:万花尺程序
// 编译环境:VS2019,EasyX_20200315(beta)
//

#include <graphics.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <iostream>
#include<mmsystem.h>
#pragma comment(lib,"WINMM.LIB")
#define PI 3.1415926536				//π的近似值
#define WIN_X 1200					//绘图窗口尺寸X轴
#define WIN_Y 700					//绘图窗口尺寸Y轴
void CurrentTime(char*);			//读取电脑时间函数

int color[15] = {		//颜色数组
		GREEN,			//	0x00AA00	绿
		LIGHTMAGENTA,	//	0xFF55FF	亮紫
		BLUE,			//	0xAA0000	蓝
		RED,			//	0x0000AA	红
		YELLOW,			//	0x55FFFF	黄
		LIGHTGRAY,		//  0xAAAAAA	浅灰
		MAGENTA,		//	0xAA00AA	紫
		LIGHTCYAN,		//	0xFFFF55	亮青
		WHITE,			//	0xFFFFFF	白
		LIGHTGREEN,		//	0x55FF55	亮绿
		BROWN,			//	0x0055AA	棕
		LIGHTRED,		//	0x5555FF	亮红
		CYAN,			//	0xAAAA00	青
		DARKGRAY,		//	0x555555	深灰
		LIGHTBLUE		//	0xFF5555	亮蓝
};

///主程序///
*******************************************************************/

int main()
{
	int circle_num=1;//不擦除绘图次数
	int R=300;		// 外部静圆半径
	int r=180;		// 内部动圆半径
	int dr=100;		// 内部动圆上的作图点到圆心的距离
	HWND hwnd = initgraph(WIN_X, WIN_Y);	// 创建绘图窗口
	setorigin(WIN_X / 2, WIN_Y / 2);		// 设定圆心坐标
	//绘图窗口名字
	SetWindowText(hwnd, "万花尺");
	//mciSendString(TEXT("open H:\\我曾-隔壁老樊.mp3 alias mysong"), NULL, 0, NULL);//插入音频文件
	//mciSendString(TEXT("play mysong"), NULL, 0, NULL);
begin:
	// 获取用户输入
	char input_pre[30];//存储用户输入的数组
	bool flag;//反馈用户在输入窗口点击 “确认”键还是“取消”键
	flag=InputBox(input_pre,30,"大圆(R<350)_小圆(r<R)_动点的尺寸(△r<r):",
		"请按顺序输入参数:","300 180 100",0,0,false);
	if (flag == false)//防止误按“取消”键
	{
		flag=_getch();
		R = 300;
		r = 180;
		dr = 100;
	}
	sscanf_s(input_pre, "%d %d %d", &R,&r,&dr);
	/**********************************************************************************************************/
	// 求执行次数( )
	int m = R, n = r;
	int tmp;
	while (n != 0)//求最小公约数,即可求得绘图周期
	{
		tmp = m % n;
		m = n;
		n = tmp;
	}
	double maxdegree = (double)r / m * 2 * PI;//绘图周期
///
	//显示输入参数
	char RR[10], rr[10], drr[10],CIRcle_num[10];
	//清空前次的输入
	for(int W_y=5;W_y <= 105;W_y += 25)
	{
		outtextxy(5 - WIN_X / 2, W_y - WIN_Y / 2, "         ");
	}
	sprintf_s(RR, "R=%d",R);
	sprintf_s(rr, "r=%d", r);
	sprintf_s(drr, "△r=%d", dr);
	sprintf_s(CIRcle_num, "CIR=%d", (circle_num+2)/3);
	settextstyle(18, 0, _T("宋体"));
	settextcolor(GREEN);
	outtextxy(5-WIN_X / 2, 5-WIN_Y / 2,RR);
	outtextxy(5 - WIN_X / 2, 30 - WIN_Y / 2, rr);
	outtextxy(5 - WIN_X / 2, 55 - WIN_Y / 2, drr);
	outtextxy(5 - WIN_X / 2, 80 - WIN_Y / 2, CIRcle_num);
	//
	int maxnum; //旋转绘图的个数
	maxnum = (int)round(162.0 * (R - 50.0) / (maxdegree * (300 - 50.0)));//根据图形复杂度和绘图尺寸调整旋转绘图个数
	if (maxnum < 4) maxnum = 1;
	else if (maxnum > 11) maxnum = 11;//限制绘图最大和最小个数,避免太密集

	//输出绘图个数
	char MAXnum[10];
	sprintf_s(MAXnum, "N=%d", maxnum);
	outtextxy(5 - WIN_X / 2, 105 - WIN_Y / 2, MAXnum);

	/*/******************************//****************************************///
	// 绘图
	int x, y;
	int D_FLAG = 0;//旋转的次数
	int x0, y0;
	double add = 0.003;		//每点增量
	int delay_time;//延时参数
	//根据绘图像素数调整绘图速度(延时时长)

	delay_time =(int)round( 100*5.0 * add );
	if (delay_time > 500) delay_time = 500;//避免延时过长
	for (double degree = 0; degree < maxdegree; degree += add)
	{
		x = (int)round(dr * cos(degree * (double(R) / r - 1)) + ((double)R - r) * cos(degree)); //圆内旋线公式 ,x坐标
		y = (int)round(dr * sin(degree * (double(R) / r - 1)) - ((double)R - r) * sin(degree));
		putpixel(x, y, color[circle_num - 1]);
		//根据绘图像素数调整绘图速度(延时时长)
		for (int us = 0;us < delay_time;us++)
			for (int i = 0;i < 50000;i++);
	}
	旋转一定角度绘图,为了美观//
	
	//for循环使得每次旋转2.5度,
	for (D_FLAG=1;D_FLAG < maxnum;D_FLAG++)
	{
		if (D_FLAG == (maxnum-1))
			add = 0.003;
		else add = 0.02;
		for (double degree = 0; degree < maxdegree; degree += add)
		{
			x0 = (int)round(dr * cos(degree * (double(R) / r - 1)) + ((double)R - r) * cos(degree));
			y0 = (int)round(dr * sin(degree * (double(R) / r - 1)) - ((double)R - r) * sin(degree));
			x = (int)round(x0 * cos(PI / 72 * D_FLAG) - y0 * sin(-PI / 72 * D_FLAG));		//逆时针旋转2.5度
			y = (int)round(x0 * sin(-PI / 72 * D_FLAG) + y0 * cos(PI / 72 * D_FLAG));
			if (D_FLAG == (maxnum - 1))//设置最后一次绘图颜色和绘图速度,与其他不同
			{
				putpixel(x, y, color[circle_num +1]);
				for (int us = 0;us < delay_time;us++)
					for (int i = 0;i < 50000;i++);
			}
			else {
				putpixel(x, y, color[circle_num]);
				for (int us = 0;us < delay_time;us++)
					for (int i = 0;i < 100000;i++);
			}	
		}	
	}
	/绘图完成

	///用户操作//******************************************************/
	IMAGE img;//截图,方便保存
	getimage(&img, -WIN_X / 2, -WIN_Y / 2, WIN_X , WIN_Y );

	outtextxy(5 - WIN_X / 2,  WIN_Y / 2-30, _T("按空格键继续,按s或S保存图像,按c或C重新绘制,按 ESC 退出"));

	// 重新开始,或退出程序
	char c = _getch();	
	if (c == 's'||c=='S') /'s'||'S'键为保存图片到D:盘
	{
		char tim1[50] = "D:\\万花尺",tim2[30],tim3[10]=".png";
		CurrentTime(tim2);		//获取时间并以字符类型放入tim1
		
		strcat_s(tim1,50,tim2);
		strcat_s(tim1,50, tim3);
		saveimage(tim1,&img);//保存图片,以时间命名图片
	contin:	//防止误按 s 键
		settextcolor(LIGHTCYAN);
		outtextxy(5 - WIN_X / 2, 130 - WIN_Y / 2, "图片保存完成!");
		outtextxy(5 - WIN_X / 2, 155 - WIN_Y / 2, "按相应键继续..");
		c = _getch();
		settextcolor(GREEN);
		outtextxy(5 - WIN_X / 2, 130 - WIN_Y / 2, "              ");//清空字样
		outtextxy(5 - WIN_X / 2, 155 - WIN_Y / 2, "              ");
		if (c == 's' || c == 'S') goto contin;

	}
	switch (c) {
	case 0x1b:					//ESC键退出程序
		closegraph();//退出绘图程序
		return 0;
		break;
	case 0x20:					//空格键键,在原窗口继续绘图
		circle_num+=3;
		if (circle_num > 15) circle_num = 1;
		//清除提示位置
		outtextxy(5 - WIN_X / 2, WIN_Y / 2 - 30, _T("                                                         "));
		goto begin;
		break;
	case 'c':
	case 'C':					//'c'||'C'键关闭原绘图窗口,并新建绘图窗口
	{
		circle_num = 1;
		closegraph();
		HWND hwnd = initgraph(WIN_X, WIN_Y);	// 创建绘图窗口
		setorigin(WIN_X / 2, WIN_Y / 2);	// 设定圆心坐标
		goto begin;
		break;
	}
	default://其他键,退出程序
		break;


	}
	
	return 0;
}

///*****************************************
/读取计算机本地时间函数//
void CurrentTime(char* TIM)
{
	time_t tt;
	time(&tt);
	struct tm t;
	localtime_s(&t, &tt);
	char tttt[30];
	sprintf_s(tttt, "%d_%02d_%02d_%02d_%02d_%02d",
		t.tm_year + 1900,
		t.tm_mon + 1,
		t.tm_mday,
		t.tm_hour,
		t.tm_min,
		t.tm_sec);
	strcpy_s(TIM, strlen(tttt) + 1,tttt);
}

/*****************************************************/
/*******************************************************/

谢谢阅览,如有侵权,还请联系。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值