这是以前利用这段代码生成的,原理是导入一张图片,然后基于这张图片进行绘制,为了便于理解,下面的代码会分成两段
(请通过截图保存图片(以后会更新保存图片的功能(届时应该是可以之支持到任意大小的图片)

/*
** filename: circlePacking.cpp
** createtime: 2020-03-08
** author: TheBadZhang
** balabalabala
*/
#include <graphics.h>
#include <ctime>
#include <cstdlib>
#include <cmath>
// #include <conio.h>
int main (int argc, char *argv []) {
const unsigned int minRadius = 1;
const unsigned int maxRadius = 50;
// 最小与最大半径
const unsigned int WW = 800, WH = 600, times = 3000;
// 窗口宽度,窗口高度,圈数
// 在这个程序里,窗口的大小决定了生成图片的大小
// 图片过大或者过小都会被缩小或者放大到窗口大小
int *circleList = new int[3 * times];
// 0 为 x, 1 为 y, 2 为 r, 以此类推
// 存储圈圈数据
unsigned int count = 0;
// 圆圈计数器
srand (time (0));
initgraph (WW, WH, 0);
setfillcolor (WHITE);
int x, y, r, l;
int i;
do {
redo:
x = rand () % WW;
y = rand () % WH;
r = rand () % (maxRadius - minRadius) + 1;
// 取模 防止圆 get 不到 pixel,限定园大小为 1 - 50 px
for (i = 0; i < count; i += 1) {
l = sqrt (pow (x - circleList [3*i + 0], 2) +
pow (y - circleList [3*i + 1], 2))
- circleList [3*i + 2];
// 当前坐标点下的最大半径
// 需遍历每一个圆(照理这里应该有优化,但是我没有做,导致到了后面速度就非常慢了
r = r > l ? l : r;
// 选择半径较小的那一个
}
if (r <= 0) goto redo;
// 如果不合法重新生成
// 也就是圆要是出现在了别的圆里就跳过这个数据
fillellipse (x, y, r, r);
// 画出图形
circleList [count * 3 + 0] = x;
circleList [count * 3 + 1] = y;
circleList [count * 3 + 2] = r;
// 计数值加一
count ++;
// getch ();
} while (count < times);
getch ();
closegraph ();
return 0;
}升级一下,让他可以根据图片画圈圈
/*
** filename: circlePacking.cpp
** createtime: 2020-03-08
** author: TheBadZhang
** balabalabala
*/
#include <graphics.h>
#include <ctime>
#include <cstdlib>
#include <cmath>
// #include <conio.h>
int main (int argc, char *argv []) {
const unsigned int minRadius = 1;
const unsigned int maxRadius = 35;
// 最小与最大半径
const unsigned int WW = 1600, WH = 1000, times = 60000;
// 窗口宽度,窗口高度,圈数
// 在这个程序里,窗口的大小决定了生成图片的大小
// 图片过大或者过小都会被缩小或者放大到窗口大小
int *circleList = new int[3 * times];
// 0 为 x, 1 为 y, 2 为 r, 以此类推
// 存储圈圈数据
unsigned int count = 0;
// 圆圈计数器
srand (time (0));
initgraph (WW, WH, 0);
setfillcolor (WHITE);
// ege_enable_aa (true);
PIMAGE PIC = newimage ();
// 用于生成彩色的 circlepacking
PIMAGE CHECK = newimage (WW, WH);
setfillcolor (WHITE, CHECK);
// getimage (PIC, argv [1], WW, WH);
getimage (PIC, "pic.jpg", WW, WH);
putimage (0, 0, PIC);
// 打印图片,否则背景默认纯黑色,圆圈的空隙处会显得有些难看
// 纯几何图形建议不要输出图片
// 可以使用 blur 函数说不定效果好一点
// blur 函数看来要自己写一个了
int x, y, r, l;
int i;
do {
redo:
x = rand () % WW;
y = rand () % WH;
r = rand () % (maxRadius - minRadius) + 1;
// 取模 防止圆 get 不到 pixel,限定园大小为 1 - 50 px
if (getpixel (x, y, CHECK) == WHITE) goto redo;
for (i = 0; i < count; i += 1) {
l = sqrt (pow (abs (x - circleList [3*i + 0]), 2) +
pow (abs (y - circleList [3*i + 1]), 2))
- circleList [3*i + 2];
// 当前坐标点下的最大半径
// 需遍历每一个圆(照理这里应该有优化,但是我没有做,导致到了后面速度就非常慢了
r = r > l ? l : r;
// 选择半径较小的那一个
}
// if (r <= 0 || pic [x + WW * y] == bgcolor) goto redo;
if (r <= 0) goto redo;
// 如果不合法重新生成
// 也就是圆要是出现在了别的圆里就跳过这个数据
setcolor (getpixel (x, y, PIC));
setfillcolor (getpixel (x, y, PIC));
// circle (x, y, r);
// 手动选择实心还是空心
fillellipse (x, y, r, r);
// 画出图形
circleList [count * 3 + 0] = x;
circleList [count * 3 + 1] = y;
circleList [count * 3 + 2] = r;
// 存入数据
fillellipse (x, y, r, r, CHECK);
// 快速判断圆心是否合规
count += 1;
// 计数值加一
} while (count < times);
// imagefilter_blurring (NULL, 0xFF, 0xFF);
getch ();
closegraph ();
return 0;
}