作者: 张小三
作者博客: https://thebadzhang.github.io/
何为Circle Pakcing?
就差不多是上面的东西吧……只不过上面做了一点处理,如果按照定义的话,就应该是一堆相切的圆。只不过放到图形学里面就不一定是大小相同的了,可以根据需求和效果调整大小,
算法实现
用一个vector存储圆,每次生成新的圆就遍历一遍,直到生成的圆没有与任何圆相交(我的实现里面没有保证每个圆都要相切,但是,当圆的数量达到一定程度了,所有圆也就都相切了。具体也可以看代码的实现。
编译
代码在VS2017 19.11 with xege_for_windows 上编译通过
首先需要在电脑上配置xege,然后编译……
代码: (注意, 下方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#include <graphics.h> #include <ctime> #include <cstdlib> #include <cmath> #include <vector> #include <iostream> #include <fstream> struct Circle{ int x, y, r; }; int main () { const int R = 255, G = 255, B = 255; // 背景色 ////////////////////////////// 最小半径?这注释是啥? const int radius = 50; // 最大半径 const int WW = 800, WH = 600, times = 3000; // 窗口宽度,窗口高度,圈数 // 在这个程序里,窗口的大小决定了生成图片的大小 std::vector <Circle> CircleList; int count = 0; // 圆圈计数器 srand (time (nullptr)); initgraph (WW, WH); do { int x = rand () % WW; int y = rand () % WH; int r = rand () % radius; // 取模 防止圆 get 不到 pixel,限定园大小为 50 px for (auto a : CircleList) { int l = sqrt (pow (abs (x - a.x), 2) + pow (abs (y - a.y), 2) ) - a.r; // 当前坐标点下的最大半径 // 需遍历每一个圆(照理这里应该有优化,但是我没有做,导致到了后面速度就非常慢了 r = r > l ? l : r; // 选择半径较小的那一个 if (r <= 0) break; // 如果不合法跳过这次循环(外面 while 的那个) // 也就是圆要是出现在了别的圆里就跳过这个数据 } // circle (x, y, r); // 手动选择实心还是空心 fillellipse (x, y, r, r); // 画出图形 CircleList.push_back ({x,y,r}); count += 1; // 计数值加一 } while (count <= times); closegraph (); return 0; } |
近期评论