见缝插圆是基于见缝插针的改良版小程序,只要所建画布当中存在缝隙,就会在其中随机创建一个圆,一共有4中绘画模式,初始状态默认为第1种,只要按下空格就可以切换绘画模式。感兴趣的小伙伴可以基于代码,去做一个修改,比如更改绘画模式,又更改形状,让它可以画正方形、长方形、三角形之类的。
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;
}