首页 > 黑暗科技研究 > 那个点圆圈就会分裂的游戏

那个点圆圈就会分裂的游戏

2013年7月13日 发表评论 阅读评论

题目取得有点随便啊,是吧。。额,算了,谁让游戏本体我找不到了。。如果下次找到了,我就放在下面好了。。

既然如此,我就描述一下那个游戏好了。。【其实我只在好久以前玩过一下那个游戏,具体记得不是很清楚了,错了就原谅我吧,不然的话,就当我"定义"了一个新游戏好了。。】

就是说,一开始有一个正方形里面有一个圆形,圆形的颜色你自己定义,正方形内部非圆形区域颜色为黑,然后你只要点击一下那个圆,它就会分裂成四个半径为一半的圆了,分布在四个角那里,你可以设置这些圆为不同颜色,然后你再点击一下这些圆,它又会继续分裂,无穷无尽。。。大概。。。就是这样一个游戏吧。。。

然后人人网上看到了一个大触画的这个图。。。【盗一下,版权归"萝莉丝?想成为可爱男孩子"所有。。】【到我写这一篇为止我还没弄到那个游戏本体,所以我也不知道这个矩形大图是怎么出来的。。。不过,别在意啦~】


我的第一想法是。。。我勒个去。。。。

然后第二想法是。。。真的有人手动画这个么?

我的第三想法是。。。难道不是编个程就可以生成这幅图了么?

我的第四想法是。。。有了生成这个图的方法,不就可以系统控制鼠标选颜色,点击来用那个游戏生成这个图了么?

我的第五想法是。。。之前说好的台风怎么还没来?连滴雨都没有。。害我今天窝宿舍没事干,然后就花点时间玩一下这个东西咯~

好,下面正文,老规矩,代码在最后,唉,其实说真的,写了一下才发现这个代码。。。加上空行50行多一点。。


其实这个东西要编程生成这幅图一点都不难,而且也不麻烦,真要说麻烦的,估计是我上面那个第四个想法。。

总之,目标就是这一幅"大荡漾"!!!【和上面那一幅类似之处在于都是"紫"。。】

总之思路就是,对于当前一个正方形里面有个圆,那我就找出这个区域内的"主颜色",比如说直接用出现的颜色的众数来弄,然后再找这个区域内(正方形区域或者圆形区域都行)和这个"主颜色"颜色相近的颜色,然后看看这些点的总数占正方形区域面积的比例,如果没有超过指定阈值,说明这个主颜色不足以代表这一块区域,就把这个圆分裂成四个小圆,找到四个小圆对应的正方形区域,然后再迭代上面所说的算法就行了,否则,这个正方形就用这个圆来代替就可以了,颜色自然就是主颜色。

其实实现起来唯一的困难就是"主颜色"怎么选取,因为这种小实验我不想搞那么多乱七八糟的学术性很强的复杂算法,所以一开始第一直觉就是找出RGB三层的众数,然后拼成一个颜色,结果就如下图所示:

显然的RGB三个分开选取的众数最后必然不能代替RGB整体的众数,所以会在小点的地方出现原图根本不存在的颜色,而且很容易理解,这种乱七八糟的错误的点的颜色只会出现在小圆区域,而不会出现在大区域。

反正最后也为了简单起见,就用RGB三层的平均值来代替众数,结果就是颜色虽然和原图会有那么一些偏差,但是不会有偏差太大的颜色出现。。

我有一个搞"颜色学"的专业的舍友,他回头去找他师兄要一个什么"种子生长"的算法,有空研究研究。。虽然这个小玩具里面这样已经足够了。。。


备注:

虽然程序短,但是跑起来还是很费时间的【毕竟matlab嘛~】,所以我为了加快速度,就限制了一下生成的最小圆的尺寸,所以精细度没有最上面那幅图那么精细,但是你只要有主够高的近视度数,或者离屏幕足够远,那效果还是不错的。。。

最后还是花了点时间跑了幅精细度比较高的。。


Code:

IMG = double(imread('IMG_0016.JPG'));
[M N] = size(IMG(:,:,1));
result_image = Click_Image(IMG,floor(M/2),floor(N/2),zeros(M,N,3));
imwrite(uint8(result_image),'result.bmp');

function  result_image = Click_Image(img,x,y,result_image)
rate_thred_hold = 0.75;%提高可以增加分裂的数目
[m n] = size(img(:,:,1));
r = floor(m/2);
rgb = GetMainColorRGB(img);
circle_idx = GetCircle_Idx(m);
color_idx = find_similar_color(img,rgb);

%限制圆的最小尺寸和最大尺寸
if (sum(color_idx(:))/m/n < rate_thred_hold && m>40) || m > size(result_image,1)/10
    sub_img = img(1:floor(m/2),1:floor(m/2),:);
    result_image = Click_Image(sub_img,x-r/2,y-r/2,result_image);

    sub_img = img(1:floor(m/2),floor(m/2)+1:floor(m/2)*2,:);
    result_image = Click_Image(sub_img,x+r/2,y-r/2,result_image);

    sub_img = img(floor(m/2)+1:floor(m/2)*2,1:floor(m/2),:);
    result_image = Click_Image(sub_img,x-r/2,y+r/2,result_image);

    sub_img = img(floor(m/2)+1:floor(m/2)*2,floor(m/2)+1:floor(m/2)*2,:);
    result_image = Click_Image(sub_img,x+r/2,y+r/2,result_image);
else
    for i = 1 : m
        for j = 1 : m
            if(circle_idx(i,j))
                result_image(floor(y-r+i),floor(x-r+j),:) = rgb;
            end
        end
    end
    figure(1);
    imshow(uint8(result_image));drawnow;
end

function idx = find_similar_color(sub_image,rgb)
thred = 20;
[m n] = size(sub_image(:,:,1));
diff_img = abs(sub_image - repmat(rgb,m,n));
idx = (diff_img(:,:,1)<thred ) & (diff_img(:,:,1)<thred) & (diff_img(:,:,1)<thred);

function rgb = GetMainColorRGB(img)
rgb = zeros(1,3);
for i = 1 : 3
    rgb(i) = mean(mean(img(:,:,i)));
end
rgb = reshape(rgb,1,1,3);

function z = GetCircle_Idx(m)
[x y] = meshgrid(linspace(-1,1,m),linspace(-1,1,m));
z = (x.^2+y.^2)<=1;

【完】

本文内容遵从CC版权协议,转载请注明出自http://www.kylen314.com

  • 密集恐惧症者直接给跪了

    • 你不说我不怎么觉得,你这么一说。。。突然觉得。。。。好像有点。。【应该把图缩小一倍可能效果好一些~

  • changeling

    正在熬夜观摩。。。真是给跪研究僧和研究僧之间的差距怎么就这么大呢前几天开始学mma又刚去现场仰望了下wolfram本尊回来就翻到这个博客了 应该找到你说的那个“游戏”了http://koalastothemax.com/

    • changeling

      更加有趣的玩法应该是像这个网站里面做的一样鼠标点击之后逐渐呈现出一幅有意义的图像然后为什么这次用的是MATLAB呢希望有mma的

      • 没人说过这个博客不能写matlab啊。。不过看日期,好像是很久远之前的东西了。。那时还没有写mma的想法。。【其实现在也没有2333这个网址的游戏不能设置颜色?我如果画工好。。我也想这么玩2333MMA的话好像完全可以做一个这个游戏诶。。Graphics+MousePosition

        • changeling

          我知道 我之前也用过MATLAB的只是看前后都是mma这里忽然冒出来MATLAB故有此一问那个网站的游戏应该是一个javascript的一个库的demo应该是没有提供自定义图片的(话说我拿网址搜的时候谷歌自动提示的就是custom 说明估计很多人想弄这个的)其实用来把妹不错,编好以后打个包发给妹子

          • 啊咧?原来我理解错这个游戏了?原来是把所有圆分裂到最小可以看到一张图片啊。。。。我一直以为像最上面那副大触画的一样可以自己创作呢。。

          • 那个网站的话,直接把JS代码扒下来,自己改图片!!

  • 赞脑洞~受启发自己也做了一个~http://www.frozenc.com/demo/,顺便求互换友链~

  • O(∩_∩)O!

    代码太罗嗦