要求:1利用数组记录多个圆;
2控制圆圈的最大和最小半径,且圆和圆之间不相交;
3按空格键实现风格变化,分别是黄色,随机色,随机叠加色,随机色圈。
代码:
#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<math.h>
#include<time.h>
float Dist2point(float x1, float y1, float x2, float y2) {
float result1;
result1 = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
return result1;
}
int isTwociclesIntersect(float x1, float y1, float x2, float y2, float r1, float r2) {
if (Dist2point(x1, y1, x2, y2) < r1 + r2) {
return 1;
}
return 0;
}
void DrawCircles1(float x1, float y1, float r) {
setlinecolor(RGB(0, 0, 0));
setfillcolor(RGB(255, 255, 0));
fillcircle(x1, y1, r);
}
void DrawCircles2(float x, float y, float r) {
srand((INT)time(0));
float h = rand() % 360;
COLORREF COLOR = HSVtoRGB(h, 0.6, 0.7);
setfillcolor(COLOR);
fillcircle(x, y, r);
}
void DrawCircles3(float x, float y, float r) {
srand((INT)time(0));
while (r > 0) {
float h = rand() % 360;
COLORREF COLOR = HSVtoRGB(h, 0.6, 0.7);
setfillcolor(COLOR);
fillcircle(x, y, r);
r -= 5;
}
}
void DrawCircles4(float x1, float y1, float r) {
srand((INT)time(0));
while (r> 0) {
float h = rand() % 360;
COLORREF COLOR = HSVtoRGB(h, 0.6, 0.7);
setlinecolor(COLOR);
circle(x1,y1,r);
r -= 5;
}
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
int main()
{
int width = 600, height = 800;
initgraph(width, height);
setbkcolor(RGB(255, 255, 255));
cleardevice();
srand(time(0));
int xarray[1000], yarray[1000], rarray[1000];
int min = 8, max = 50;
float x, y, r;
int circlenum = 0;
int i, j, drawMode = 2;
int isNewcircleok = 0;
while (circlenum < 1000) {
isNewcircleok = 0;
while (isNewcircleok == 0) {
if (kbhit()) {
char input = _getch();
if (input == ' ') {
circlenum = 0;
cleardevice();
drawMode += 1;
}
if (drawMode > 4) {
drawMode = 1;
}
}
x = rand () % width;
y = rand() % height;
r = min;
for ( i = 0; i < circlenum; i++) {
if(isTwociclesIntersect(xarray[i], yarray[i], x, y, rarray[i], r))
break;
}
if (circlenum == i) {
isNewcircleok = 1;
}
}
isNewcircleok = 0;
while (isNewcircleok == 0 && r < max) {
r++;
for ( j= 0; j<circlenum;j++) {
if (isTwociclesIntersect(xarray[j],yarray[j], x, y, rarray[j], r)) {
isNewcircleok = 1;
break;
}
}
}
xarray[i] = x;
yarray[i] = y;
rarray[i] = r;
circlenum++;
if (drawMode == 1)
DrawCircles1(x, y, r);
if (drawMode == 2)
DrawCircles2(x,y, r);
if (drawMode == 3)
DrawCircles3(x, y, r);
if (drawMode == 4)
DrawCircles4(x, y, r);
Sleep(10);
}
_getch();
closegraph();
return 0;
}
简化mian(),写更多分函数,效果一样,用模块的思想去实现:
空模块:
// Charper6.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include"graphics.h"
#include <iostream>
#include "conio.h"
void initEasyxWindows(int width, int heigh);//初始化EasyX窗口
void drawCircleMode1(float x, float y, float r);
void drawCircleMode2(float x, float y, float r);
void drawCircleMode3(float x, float y, float r);
void drawCircleMode4(float x, float y, float r);
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]);//随机创建不相交圆
int main()
{
int width = 600; // 窗口宽度
int height = 600; // 窗口高度
initEasyxWindows(width, height);
updateWindows(width, height);
_getch(); // 等待按键输入
closegraph(); // 关闭窗口
return 0;
//std::cout << "Hello World!\n";
}
void initEasyxWindows(int width, int height)
{
}
/// <summary>
/// 随机创建一个圆,如果与已有的圆都不相交,返回1,否则返回0
/// </summary>
/// <param name="circleNum">已有的圆数量</param>
/// <param name="x">圆心的X坐标</param>
/// <param name="y">圆心的Y坐标</param>
/// <param name="r"></param>
/// <param name="xArray">已有的圆的X数组</param>
/// <param name="yArray">已有的圆的Y数组</param>
/// <param name="rArray">已有的圆的R数组</param>
/// <returns></returns>
int creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100])
{
return 0;
}
int creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100])
{
return 0;
}
void updateWindows(int width, int height)
{
}
void drawCircleMode1(float x, float y, float r)
{
}
void drawCircleMode2(float x, float y, float r)
{
}
void drawCircleMode3(float x, float y, float r)
{
}
void drawCircleMode4(float x, float y, float r)
{
}
float countTwoPointDis(float x1, float y1, float x2, float y2)
{
return 0;
}
bool isTwoCirclesIntersect(float x1, float y1, float r1, float x2, float y2, float r2)
{
return 0;
}
填充后:
// Charper6.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include"graphics.h"
#include <iostream>
#include "conio.h"
void initEasyxWindows(int width, int heigh);//初始化EasyX窗口
void drawCircleMode1(float x, float y, float r);
void drawCircleMode2(float x, float y, float r);
void drawCircleMode3(float x, float y, float r);
void drawCircleMode4(float x, float y, float r);
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]);//随机创建不相交圆
int circleNum;
int main()
{
int width = 600; // 窗口宽度
int height = 600; // 窗口高度
initEasyxWindows(width, height);
updateWindows(width, height);
_getch(); // 等待按键输入
closegraph(); // 关闭窗口
return 0;
//std::cout << "Hello World!\n";
}
void initEasyxWindows(int width, int height)
{
initgraph(width, height); // 新开一个窗口
setbkcolor(RGB(255, 255, 255)); // 背景颜色为白色
cleardevice(); // 以背景颜色清空背景
}
/// <summary>
/// 随机创建一个圆,如果与已有的圆都不相交,返回1,否则返回0
/// </summary>
/// <param name="circleNum">已有的圆数量</param>
/// <param name="x">圆心的X坐标</param>
/// <param name="y">圆心的Y坐标</param>
/// <param name="r"></param>
/// <param name="xArray">已有的圆的X数组</param>
/// <param name="yArray">已有的圆的Y数组</param>
/// <param name="rArray">已有的圆的R数组</param>
/// <returns></returns>
int aj(int drawMode1) {
int drawMode= drawMode1;
if (_kbhit()) // 当按键时
{
char input = _getch(); // 获得用户按键
if (input == ' ') // 空格键
{
circleNum = 0; // 圆的个数为0,相当于画面清除所有已有的圆圈
cleardevice(); // 清屏
drawMode = drawMode + 1; // 进行下一种绘图模式
if (drawMode > 4) // 如果大于4,重新回到第1种绘图模式
drawMode = 1;
}
}
return drawMode;
}
int creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100])
{
int i;
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
return 1;
}
else
return 0;
}
int creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100])
{
int r = 8;
int j = 0;
int isNewCircleOK = 0;
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;
}
void updateWindows(int width, int height)
{
int xArray[1000]; // 数组存储所有圆心的x坐标
int yArray[1000]; // 数组存储所有圆心的y坐标
int rArray[1000]; // 数组存储所有圆的半径
int rmin = 8; // 圆的最小半径
int rmax = 50; // 圆的最大半径
circleNum = 0; // 生成的圆的个数
// float x, y, r; // 新增圆的圆心坐标、半径
int isNewCircleOK = 0; // 用于判断新生成的圆是否可以了
int i, j;
int drawMode = 3; // 用于设定4种不同的绘制模式,开始设为3
float x = 0;
float y = 0;
float r = 0;
// int drawMode = 3;
r = rmin; // 新圆的半径开始设为最小半径
while (circleNum < 1000)
{
isNewCircleOK = 0;
while (isNewCircleOK == 0)
{
x = rand() % width; // 新圆的圆心x坐标
y = rand() % height; // 新圆的圆心y坐标
isNewCircleOK = creatRandCircle(circleNum, x, y, rmin, xArray, yArray, rArray);
}
drawMode = aj(drawMode);
isNewCircleOK = 0;
r = creatBigCircle(rmax, circleNum, x, y, xArray, yArray, rArray);
isNewCircleOK = 1;
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)
{
if (countTwoPointDis(x1, y1, x2, y2) < r1 + r2)
return 1;
return 0;
}
运行结果:
风格1:
风格2:
风格3:
风格4: