C++:见缝插圆

见缝插圆是基于见缝插针的改良版小程序,只要所建画布当中存在缝隙,就会在其中随机创建一个圆,一共有4中绘画模式,初始状态默认为第1种,只要按下空格就可以切换绘画模式。感兴趣的小伙伴可以基于代码,去做一个修改,比如更改绘画模式,又更改形状,让它可以画正方形、长方形、三角形之类的。
1.运行效果
绘画模式4在这里插入图片描述
绘画模式3在这里插入图片描述
绘画模式2在这里插入图片描述
绘画模式1在这里插入图片描述

2.所用头文件

#include "stdafx.h"
#include <graphics.h>  
#include <conio.h>
#include <stdio.h>
#include <time.h>
#include <math.h>

3.函数声明

void initEasyxWindows(int width, int heigh);//初始化EasyX窗口
void drawCircleMode1(float x, float y, float r);//绘画模式1
void drawCircleMode2(float x, float y, float r);//绘画模式2
void drawCircleMode3(float x, float y, float r);//绘画模式3
void drawCircleMode4(float x, float y, float r);//绘画模式4
bool isTwoCirclesIntersect(float x1, float y1, float r1, float x2, float y2, float r2);//两圆是否相交
float countTwoPointDis(float x1, float y1, float x2, float y2);//两点间的距离
void updateWindows(int width, int heigh);//更新绘画圆的操作
int  creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100]);//创建最大的不相交圆
int  creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100]);//随机创建不相交圆

4.功能实现

void initEasyxWindows(int width, int height)//初始化EasyX窗口
{
	initgraph(width, height);		 // 新开一个窗口
	setbkcolor(RGB(255, 255, 255));  // 背景颜色为白色
	cleardevice();					 // 以背景颜色清空背景
	srand(time(0));					 // 随机种子函数
}

int creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100])//随机创建不相交圆
{
	int  i, isNewCircleOK = 0;
	for (i = 0; i < circleNum; i++)   // 对已有圆遍历
		if (isTwoCirclesIntersect(xArray[i], yArray[i], rArray[i], x, y, r))
			break; // 如果已有圆和新圆相交,跳出循环,此时i<circleNum

	if (i == circleNum)    // 如果上面for语句都不跳出,说明i等于circleNum
		isNewCircleOK = 1; //  这个新生成的圆和已有圆都不相交
	return  isNewCircleOK;
}
int  creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100])
{
	int isNewCircleOK = 0, r = 8, j;
	while (isNewCircleOK == 0 && r < rmax) // 当不ok,并且新圆的半径小于最大半径时
	{
		r++; // 让半径+1
		for (j = 0; j < circleNum; j++) // 对所有旧圆遍历
		{
			if (isTwoCirclesIntersect(xArray[j], yArray[j], rArray[j], x, y, r))
			{
				isNewCircleOK = 1;  //一旦和一个旧圆相交,这时新圆Ok
				break;				//因为新圆半径已经达到最大的情况,这时跳出循环
			}
		}
	}
	return  r;
}
int huode(int *drawMode, int *circleNum)
{
	if (_kbhit()) // 当按键时
	{
		char input = _getch();  // 获得用户按键
		if (input == ' ')		// 空格键
		{
			*circleNum = 0;  // 圆的个数为0,相当于画面清除所有已有的圆圈
			cleardevice();   // 清屏
			*drawMode += 1;  // 进行下一种绘图模式
			if (*drawMode>4) // 如果大于4,重新回到第1种绘图模式
				*drawMode = 1;
		}
	}
	return *drawMode;
}
void updateWindows(int width, int height)
{
	int xArray[1000]; // 数组存储所有圆心的x坐标
	int yArray[1000]; // 数组存储所有圆心的y坐标 
	int rArray[1000]; // 数组存储所有圆的半径 
	int rmin = 8; // 圆的最小半径
	int rmax = 50; // 圆的最大半径
	int circleNum = 0; // 生成的圆的个数
					   
	int isNewCircleOK = 0; // 用于判断新生成的圆是否可以了
	int i, j;
	int drawMode = 1; // 用于设定4种不同的绘制模式,开始设为3

	//新增圆的圆心坐标、半径
	float x = 0;
	float y = 0;
	float r = 0;
	r = rmin; // 新圆的半径开始设为最小半径

	while (circleNum < 1000)
	{
		isNewCircleOK = 0;
		while (isNewCircleOK == 0)
		{
			x = rand() % width; // 新圆的圆心x坐标
			y = rand() % height;// 新圆的圆心y坐标
			huode(&drawMode, &circleNum);
			isNewCircleOK = creatRandCircle(circleNum, x, y, rmin, xArray, yArray, rArray);//调用画随机圆
		}
		isNewCircleOK = 0;
		r = creatBigCircle(rmax, circleNum, x, y, xArray, yArray, rArray);//调用画最大圆
		
		xArray[circleNum] = x; // 把新圆的圆心坐标添加到数组中
		yArray[circleNum] = y; //
		rArray[circleNum] = r; // 把新圆的半径添加到数组中
		circleNum++; // 圆的个数+1

		// 根据不同绘图模式进行绘制		
		if (drawMode == 1)
			drawCircleMode1(x, y, r);
		if (drawMode == 2)
			drawCircleMode2(x, y, r);
		if (drawMode == 3)
			drawCircleMode3(x, y, r);
		if (drawMode == 4)
			drawCircleMode4(x, y, r);

		Sleep(10); // 暂停若干毫秒
	}
}
// 填充黄色圆绘制
void drawCircleMode1(float x, float y, float r)
{
	setlinecolor(RGB(0, 0, 0));
	setfillcolor(RGB(255, 255, 0));
	fillcircle(x, y, r);
}
// 填充随机颜色圆绘制
void drawCircleMode2(float x, float y, float r)
{
	float h = rand() % 360;
	COLORREF  color = HSVtoRGB(h, 0.6, 0.8);
	setlinecolor(RGB(255, 255, 255));
	setfillcolor(color);
	fillcircle(x, y, r);
}
// 填充随机颜色同心圆绘制
void drawCircleMode3(float x, float y, float r)
{
	while (r > 0)
	{
		float h = rand() % 360;
		COLORREF  color = HSVtoRGB(h, 0.6, 0.8);
		setlinecolor(RGB(255, 255, 255));
		setfillcolor(color);
		fillcircle(x, y, r);
		r = r - 5;
	}
}
// 随机颜色同心圆线条绘制
void drawCircleMode4(float x, float y, float r)
{
	while (r > 0)
	{
		float h = rand() % 360;
		COLORREF  color = HSVtoRGB(h, 0.9, 0.8);
		setlinecolor(color);
		circle(x, y, r);
		r = r - 5;
	}
}
float countTwoPointDis(float x1, float y1, float x2, float y2)//两个圆点之间的距离
{
	float result;
	result = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
	return result;
}
bool isTwoCirclesIntersect(float x1, float y1, float r1, float x2, float y2, float r2)//判断是否相交
{
	return  countTwoPointDis(x1, y1, x2, y2) < r1 + r2;
}

5.主函数

int main()
{
	int width = 600; // 窗口宽度
	int height = 600; // 窗口高度
	initEasyxWindows(width, height);
	updateWindows(width, height);//更新绘画
	_getch();	// 等待按键输入
	closegraph();  // 关闭窗口
	return 0;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤独的根号三号程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值