Processing中制作沙粒溶解动画:智慧从乌合之众中涌现
processing吧
全部回复
仅看楼主
level 6
Prezi_暗流 楼主
在博客上花费数小时憋出一篇文章却没人看,心情很失落。
发到这里来找存在感~~貌似这里人气也不是很高,这贴应该不会沉得快~~
发图
镇楼
,后面代码就是这个效果:
2014年05月26日 08点05分 1
level 6
求编码
2014年05月26日 09点05分 4
level 6
Prezi_暗流 楼主
Processing能够以相对简单的方式对很多元胞自动机进行模拟,此外它还内置了一些例子。比如file/examples/topics/cellularautomata/game of life 就是很简单的一个,它把画布切割成网状格,每个格子只有两种状态:“生”和“死”,而这种状态由环绕着它的八个格子的生死状态来决定,只有当八个格子中有两个或三个“生格子”的时候,该格子才能“生”,大于三个,则因“拥挤”而死,小于两个,则因“孤独”而死。遵循着这个原则,画布上所有格子不断进化,生生死死,最后得到一个相对较稳定的状态。这个模型说起来也是对生活中很多现象的抽象化表达。
题图的砂堆模型,应用的是另一种元胞自动机的规则,叫做blockcellularautomaton,可以译作分块式元胞自动机,就是把所有元胞按照位置分为若干个均匀的“块”,每一各块内部的元胞根据规则作出相应活动;紧接着下一步把元胞重新划块,重新块内作用;再分块,再作用,周而复始,不断变化。这在模拟物理运动时非常好用(这几句看不懂没关系,继续往下看)。
Margolusneighborhood就是这个分块式模型里最简单的模型。把平面内所有元胞按照2*2分割成块(如绿线所示分割),计算块内四个元胞的相互作用并更新状态;然后错一行一列重新进行分割(如蓝线),块内相互作用并更新元胞状态;再按绿线分割;再按蓝线分割;如此往复。
2014年05月26日 11点05分 6
level 6
Prezi_暗流 楼主
把每一块内的四个元胞替换成沙粒和空隙,并应用沙堆规则,就能相当逼真地模拟沙堆自然塌陷的效果,这里运用的沙堆规则如下:
只有一种情况会出现“阻塞”效果,如下。这种情况下,会按概率p和1-p出现两种结果。
2014年05月26日 11点05分 7
level 6
Prezi_暗流 楼主
题图的代码及注释如下,这个例子里每个像素点就是一个元胞。
boolean jump; //一个让块的分割线在蓝线和绿线之间来回切换的参数
boolean p1,p2,p3,p4; //每个块内四个元胞的状态,p1代表左上,p2右上,p3左下,p4右下
BlockquadCube; //后面写了一个类叫做Block,主要内容就是块内四个元胞如何根据现有的状态更新状态
boolean[]status=newboolean[4]; //建个数组储存四个元胞状态
PFontyahei; //声明字体
void setup(){
size(400,300);
background(0);
frameRate(30); //画布的帧率,通过这个参数可以控制坍塌的速度
yahei=createFont("MSYHBD.TTF",160);
//写这句之前你需要先在c盘font文件夹里找到雅黑字体并拖到当前代码窗口里
textFont(yahei); //使用字体
fill(255); //字体填充色
text("节操",50,200); //写字
}
void draw(){
if(jump==false){ //false时使用绿线的方法分割,true时使用蓝线方法切割
for(int i=0;i<width-1;i+=2){ //每一列
for(intj=0;j<height-1;j+=2){ //每一行
if(get(i,j)==color(255)){p1=true;}else{p1=false;} //根据每个像素点的颜色求得其状态
if(get(i+1,j)==color(255)){p2=true;}else{p2=false;}
if(get(i,j+1)==color(255)){p3=true;}else{p3=false;}
if(get(i+1,j+1)==color(255)){p4=true;}else{p4=false;}
quadCube=new Block(p1,p2,p3,p4); //四个状态导入到类里运算
status=quadCube.output(); //得到更新后的状态
if(status[0]==true){set(i,j,color(255));}else{set(i,j,color(0));} //根据状态给每个像素点上色
if(status[1]==true){set(i+1,j,color(255));}else{set(i+1,j,color(0));}
if(status[2]==true){set(i,j+1,color(255));}else{set(i,j+1,color(0));}
if(status[3]==true){set(i+1,j+1,color(255));}else{set(i+1,j+1,color(0));}
}
}
jump=true; //切换下状态,下一帧里按照蓝线切割了
}else{
//按照蓝线切割
for(int i=1;i<width-1;i+=2){ //每一列
for(intj=1;j<height-1;j+=2){ //每一行
if(get(i,j)==color(255)){p1=true;}else{p1=false;}
if(get(i+1,j)==color(255)){p2=true;}else{p2=false;}
if(get(i,j+1)==color(255)){p3=true;}else{p3=false;}
if(get(i+1,j+1)==color(255)){p4=true;}else{p4=false;}
quadCube=new Block(p1,p2,p3,p4);
status=quadCube.output();
if(status[0]==true){set(i,j,color(255));}else{set(i,j,color(0));}
if(status[1]==true){set(i+1,j,color(255));}else{set(i+1,j,color(0));}
if(status[2]==true){set(i,j+1,color(255));}else{set(i,j+1,color(0));}
if(status[3]==true){set(i+1,j+1,color(255));}else{set(i+1,j+1,color(0));}
}
}
jump=false; //切换回绿线
}
}
//下面是专门计算状态的类,看着挺长,实际上就是用if 和 else if对上面那个沙堆规则图进行了代码化表达
class Block {
boolean s1, s2, s3, s4;
float possibility=35f; //这里的f是用来声明35是个浮点数而不是整数,有35的概率“阻塞”
boolean result[]=new boolean[4];
Block(boolean i1, boolean i2, boolean i3,boolean i4) {
if(i1==false && i2==false && i3==false &&i4==false) {
s1=false;
s2=false;
s3=false;
s4=false;
}
else if(i3==true && i4==true) {
s1=i1;
s2=i2;
s3=i3;
s4=i4;
}
else if(i1==true && i2==true && i3==false &&i4==true) {
s1=false;
s2=true;
s3=true;
s4=true;
}
else if(i1==true && i2==true && i3==true &&i4==false) {
s1=true;
s2=false;
s3=true;
s4=true;
}
else if(i1==true && i2==false && i3==true &&i4==false) {
s1=false;
s2=false;
s3=true;
s4=true;
}
else if(i1==false && i2==true && i3==false &&i4==true) {
s1=false;
s2=false;
s3=true;
s4=true;
}
else if(i1==true && i2==true && i3==false &&i4==false) {
float odd=random(100);
if (odd
s1=true;
s2=true;
s3=false;
s4=false;
}
else {
s1=false;
s2=false;
s3=true;
s4=true;
}
}
else if(i1==true) {
s1=false;
s2=false;
s3=true;
s4=false;
}
else if(i2==true) {
s1=false;
s2=false;
s3=false;
s4=true;
}
else {
s1=i1;
s2=i2;
s3=i3;
s4=i4;
}
}
boolean[] output() { //这里返回数组的写法要多留心下,我写错了好多回
boolean[]result= {
s1, s2, s3, s4
};
returnresult;
}
}
这段代码里溶解的是汉字,换成图片等同样能收到不错的视觉效果。
2014年05月26日 11点05分 8
回复 落小笛 :我也有错 操
2014年12月20日 01点12分
敢问如何把文字换成图片呢?自己摸索了一晚上 还是无解...谢谢了
2015年03月05日 15点03分
@wenna22 这么长时间了,把文字换成图片会了没?教教我啊
2015年08月24日 08点08分
我 也是字体申明错误,咋整?
2015年12月19日 05点12分
level 6
Prezi_暗流 楼主
我的新浪微博是@Prezi_暗流,欢迎关注:-)
2014年05月26日 11点05分 9
level 6
楼主 我完全没看懂
2014年05月26日 13点05分 10
level 5
写的很好
2014年05月28日 07点05分 11
level 6
Mark,好文章!
2014年06月02日 02点06分 12
level 1
好文章,学习……话说楼主的博客是啥
2014年06月03日 09点06分 13
level 4
已粉
2014年06月04日 10点06分 14
level 9
加精啊
2014年06月26日 03点06分 16
level 5
好贴当顶!!
2014年06月26日 16点06分 17
level 1
粘贴过去怎么运行不了
2014年06月27日 01点06分 18
Block后面加个空格变成Block quadCube, 不知道为何空格消失了。
2014年06月27日 14点06分
level 2
float r=0;
int backR;
int backG;
int backB;
void setup()
{
size(800,800);
rectMode(CENTER);
backR=int(random(0,255));
backG=int(random(0,255));//<>//
backB=int(random(0,255));
background(backR,backG,backB);
//
}
void draw()
{
fill(backR,backG,backB,50);
rect(width/2,height/2,width,height);
translate(mouseX,mouseY);
rotate(r);
fill(255);
rect(0,0,100,100);
r=r+0.05;
}
求各位学长们给我解释一下这个代码,谢谢~~
2014年06月28日 04点06分 19
现在还需要解释吗。。。过了大半年了。。估计应该是我有问题问你了。哈哈 rectMode()函数是什么意思?
2015年01月05日 10点01分
回复 tl4011196 :设置方形函数rect的定位模式
2015年04月14日 07点04分
level 10
不是学计机所以着实搞不懂出了什么问题,我是拿来主义,见谅,请指正
2014年07月02日 06点07分 20
这个问题怪我,但更怪傻×新浪博客,这篇文章是我从自己新浪博客上复制过来的,每当在新浪博客上发表博文时,只要遇到小于号就吞代码。 解决方法也很简单,把上面那行 if(odd 补全成 if (odd<possibility) { 就可以了。
2014年07月02日 07点07分
倒数第三行也少了个空格....应该是return result 前面也回复了另一个缺失空格的问题,新浪太差劲了~~
2014年07月02日 08点07分
感激楼主的耐心解答~!给你一个赞![大拇指]
2014年07月02日 08点07分
这只是简单的语法错误,少写了一个小括号,一个中括号,这个估计是暗流复制时候的问题
2015年01月05日 14点01分
level 1
好厉害……从微博fo过来的路过……
2014年10月09日 03点10分 21
level 1
先顶了 LZ这个做的还是很牛B的!!!学习了
2014年12月05日 12点12分 22
level 1
帮楼主加了一下空格。。。。。。。。
先找到c盘的WINDOWS文件夹,打开,再找到Fonts文件夹,进去找到 微软雅黑Bold(TrueType)
这个文件,托至processing内,如果有对话框,就选确定。
boolean jump; //一个让块的分割线在蓝线和绿线之间来回切换的参数
boolean p1,p2,p3,p4; //每个块内四个元胞的状态,p1代表左上,p2右上,p3左下,p4右下
Block quadCube; //后面写了一个类叫做Block,主要内容就是块内四个元胞如何根据现
//有的状态更新状态
boolean[]status=new boolean[4]; //建个数组储存四个元胞状态
PFont yahei; //声明字体
void setup(){
size(400,300);
background(0);
frameRate(30); //画布的帧率,通过这个参数可以控制坍塌的速度
yahei=createFont("MSYHBD.TTF",160);
//写这句之前你需要先在c盘font文件夹里找到雅黑字体并拖到当前代码窗口里
textFont(yahei); //使用字体
fill(255); //字体填充色
text("节操",50,200); //写字
}
void draw(){
if(jump==false){ //false时使用绿线的方法分割,true时使用蓝线方法切割
for(int i=0;i<width-1;i+=2){ //每一列
for(int j=0;j<height-1;j+=2){ //每一行
if(get(i,j)==color(255)){p1=true;}else{p1=false;} //根据每个像素点的颜色求得其状态
if(get(i+1,j)==color(255)){p2=true;}else{p2=false;}
if(get(i,j+1)==color(255)){p3=true;}else{p3=false;}
if(get(i+1,j+1)==color(255)){p4=true;}else{p4=false;}
quadCube=new Block(p1,p2,p3,p4); //四个状态导入到类里运算
status=quadCube.output(); //得到更新后的状态
if(status[0]==true){set(i,j,color(255));}else{set(i,j,color(0));} //根据状态给每个像素点上色
if(status[1]==true){set(i+1,j,color(255));}else{set(i+1,j,color(0));}
if(status[2]==true){set(i,j+1,color(255));}else{set(i,j+1,color(0));}
if(status[3]==true){set(i+1,j+1,color(255));}else{set(i+1,j+1,color(0));}
}
}
jump=true; //切换下状态,下一帧里按照蓝线切割了
}else{
//按照蓝线切割
for(int i=1;i<width-1;i+=2){ //每一列
for(int j=1;j<height-1;j+=2){ //每一行
if(get(i,j)==color(255)){p1=true;}else{p1=false;}
if(get(i+1,j)==color(255)){p2=true;}else{p2=false;}
if(get(i,j+1)==color(255)){p3=true;}else{p3=false;}
if(get(i+1,j+1)==color(255)){p4=true;}else{p4=false;}
quadCube=new Block(p1,p2,p3,p4);
status=quadCube.output();
if(status[0]==true){set(i,j,color(255));}else{set(i,j,color(0));}
if(status[1]==true){set(i+1,j,color(255));}else{set(i+1,j,color(0));}
if(status[2]==true){set(i,j+1,color(255));}else{set(i,j+1,color(0));}
if(status[3]==true){set(i+1,j+1,color(255));}else{set(i+1,j+1,color(0));}
}
}
jump=false; //切换回绿线
}
}
//下面是专门计算状态的类,看着挺长,实际上就是用if 和 else if对上面那个沙堆规
//则图进行了代码化表达
class Block {
boolean s1, s2, s3, s4;
float possibility=35f; //这里的f是用来声明35是个浮点数而不是整数,有
//35的概率“阻塞”
boolean result[]=new boolean[4];
Block(boolean i1, boolean i2, boolean i3,boolean i4) {
if(i1==false && i2==false && i3==false &&i4==false) {
s1=false;
s2=false;
s3=false;
s4=false;
}
else if(i3==true && i4==true) {
s1=i1;
s2=i2;
s3=i3;
s4=i4;
}
else if(i1==true && i2==true && i3==false &&i4==true) {
s1=false;
s2=true;
s3=true;
s4=true;
}
else if(i1==true && i2==true && i3==true &&i4==false) {
s1=true;
s2=false;
s3=true;
s4=true;
}
else if(i1==true && i2==false && i3==true &&i4==false) {
s1=false;
s2=false;
s3=true;
s4=true;
}
else if(i1==false && i2==true && i3==false &&i4==true) {
s1=false;
s2=false;
s3=true;
s4=true;
}
else if(i1==true && i2==true && i3==false &&i4==false) {
float odd=random(100);
if (odd<possibility){
s1=true;
s2=true;
s3=false;
s4=false;
}
else {
s1=false;
s2=false;
s3=true;
s4=true;
}
}
else if(i1==true) {
s1=false;
s2=false;
s3=true;
s4=false;
}
else if(i2==true) {
s1=false;
s2=false;
s3=false;
s4=true;
}
else {
s1=i1;
s2=i2;
s3=i3;
s4=i4;
}
}
boolean[] output() { //这里返回数组的写法要多留心下,我写错了好多回
boolean[]result= {
s1, s2, s3, s4
};
return result;
}
}
2014年12月06日 13点12分 23
把字体拖进去这个在Mac里怎么操作呢?
2015年06月09日 06点06分
level 1
帮楼主加了一下空格。。。。。。。。
先找到c盘的WINDOWS文件夹,打开,再找到Fonts文件夹,进去找到 微软雅黑Bold(TrueType)
这个文件,托至processing内,如果有对话框,就选确定。
boolean jump; //一个让块的分割线在蓝线和绿线之间来回切换的参数
boolean p1,p2,p3,p4; //每个块内四个元胞的状态,p1代表左上,p2右上,p3左下,p4右下
Block quadCube; //后面写了一个类叫做Block,主要内容就是块内四个元胞如何根据现
//有的状态更新状态
boolean[]status=new boolean[4]; //建个数组储存四个元胞状态
PFont yahei; //声明字体
void setup(){
size(400,300);
background(0);
frameRate(30); //画布的帧率,通过这个参数可以控制坍塌的速度
yahei=createFont("MSYHBD.TTF",160);
//写这句之前你需要先在c盘font文件夹里找到雅黑字体并拖到当前代码窗口里
textFont(yahei); //使用字体
fill(255); //字体填充色
text("节操",50,200); //写字
}
void draw(){
if(jump==false){ //false时使用绿线的方法分割,true时使用蓝线方法切割
for(int i=0;i<width-1;i+=2){ //每一列
for(int j=0;j<height-1;j+=2){ //每一行
if(get(i,j)==color(255)){p1=true;}else{p1=false;} //根据每个像素点的颜色求得其状态
if(get(i+1,j)==color(255)){p2=true;}else{p2=false;}
if(get(i,j+1)==color(255)){p3=true;}else{p3=false;}
if(get(i+1,j+1)==color(255)){p4=true;}else{p4=false;}
quadCube=new Block(p1,p2,p3,p4); //四个状态导入到类里运算
status=quadCube.output(); //得到更新后的状态
if(status[0]==true){set(i,j,color(255));}else{set(i,j,color(0));} //根据状态给每个像素点上色
if(status[1]==true){set(i+1,j,color(255));}else{set(i+1,j,color(0));}
if(status[2]==true){set(i,j+1,color(255));}else{set(i,j+1,color(0));}
if(status[3]==true){set(i+1,j+1,color(255));}else{set(i+1,j+1,color(0));}
}
}
jump=true; //切换下状态,下一帧里按照蓝线切割了
}else{
//按照蓝线切割
for(int i=1;i<width-1;i+=2){ //每一列
for(int j=1;j<height-1;j+=2){ //每一行
if(get(i,j)==color(255)){p1=true;}else{p1=false;}
if(get(i+1,j)==color(255)){p2=true;}else{p2=false;}
if(get(i,j+1)==color(255)){p3=true;}else{p3=false;}
if(get(i+1,j+1)==color(255)){p4=true;}else{p4=false;}
quadCube=new Block(p1,p2,p3,p4);
status=quadCube.output();
if(status[0]==true){set(i,j,color(255));}else{set(i,j,color(0));}
if(status[1]==true){set(i+1,j,color(255));}else{set(i+1,j,color(0));}
if(status[2]==true){set(i,j+1,color(255));}else{set(i,j+1,color(0));}
if(status[3]==true){set(i+1,j+1,color(255));}else{set(i+1,j+1,color(0));}
}
}
jump=false; //切换回绿线
}
}
//下面是专门计算状态的类,看着挺长,实际上就是用if 和 else if对上面那个沙堆规
//则图进行了代码化表达
class Block {
boolean s1, s2, s3, s4;
float possibility=35f; //这里的f是用来声明35是个浮点数而不是整数,有
//35的概率“阻塞”
boolean result[]=new boolean[4];
Block(boolean i1, boolean i2, boolean i3,boolean i4) {
if(i1==false && i2==false && i3==false &&i4==false) {
s1=false;
s2=false;
s3=false;
s4=false;
}
else if(i3==true && i4==true) {
s1=i1;
s2=i2;
s3=i3;
s4=i4;
}
else if(i1==true && i2==true && i3==false &&i4==true) {
s1=false;
s2=true;
s3=true;
s4=true;
}
else if(i1==true && i2==true && i3==true &&i4==false) {
s1=true;
s2=false;
s3=true;
s4=true;
}
else if(i1==true && i2==false && i3==true &&i4==false) {
s1=false;
s2=false;
s3=true;
s4=true;
}
else if(i1==false && i2==true && i3==false &&i4==true) {
s1=false;
s2=false;
s3=true;
s4=true;
}
else if(i1==true && i2==true && i3==false &&i4==false) {
float odd=random(100);
if (odd<possibility){
s1=true;
s2=true;
s3=false;
s4=false;
}
else {
s1=false;
s2=false;
s3=true;
s4=true;
}
}
else if(i1==true) {
s1=false;
s2=false;
s3=true;
s4=false;
}
else if(i2==true) {
s1=false;
s2=false;
s3=false;
s4=true;
}
else {
s1=i1;
s2=i2;
s3=i3;
s4=i4;
}
}
boolean[] output() { //这里返回数组的写法要多留心下,我写错了好多回
boolean[]result= {
s1, s2, s3, s4
};
return result;
}
}
2014年12月06日 13点12分 24
感谢[爱心]
2014年12月18日 08点12分
回复 Prezi_暗流 : boolean[]status=newboolean[4]; //建个数组储存四个元胞状态 到这里为什么会出现:Cannot find anything named "newboolean"呢?
2015年01月05日 15点01分
@sombrade new boolean 少个空格 就是建个boolean类型的包含四个元素的数组
2015年04月02日 12点04分
1 2 3 尾页