网站资讯 news
您现在的位置:首页 > 网站资讯 > Processing中绘制Voronoi(泰森多边形)和水立方
NEWS

新闻资讯

Processing中绘制Voronoi(泰森多边形)和水立方

发布时间:2017/03/16 网站资讯 浏览次数:3817

昆山网站建设

Voronoi最出名的例子就是北京奥运的水立方了。它在自然界中非常常见,比如长颈鹿图案,龟壳图案等。

那么,什么是Voronoi?
我能想到的通俗点的解释是这样的:
想象一个平面(就拿长方形来讲好了),该平面内散落着若干种子点(比如,10个种子),现在对组成这个平面的无数个点喊话:请大家立刻找到离自己最近的种子点认大哥,并以此划分为10个帮派!于是,10个点的voronoi图案形成了。
下图是从百度百科扒的,配色嘛…..

由于“每一点都能找到离自己最近的种子点”这一特性,voronoi在城市规划,气象学,统计学,建筑和结构等方向有很多应用。另外,单纯从美学角度讲,这种先撒种子,再划势力范围的方法能生成或者配合生成很多漂亮图案。
一张桌子:

丹麦BIG的一个建筑概念:

Processing中画voronoi有不少方法,下面这种我把它起名叫“逐像素扫描法”,相对于中垂线法省很多代码。
主要思路:遍历窗口内的每一个像素点,求出该像素点到每个种子点的距离,对这些距离排序,得到最小距离和第二小距离,然后进行比较,如果这两个距离相等则说明该像素点在多边形的边上,对其染色标出;如果不等,则说明该像素点在多边形内,不作处理。遍历完成后就得到了一张染过色的网,表明voronoi的边界。

代码约30行,如下:
int qty=20;
PVector everyPixel;
PVector[]seed=new PVector[qty];
float[]distance=new float[qty];
float min,secmin;
float threshold=1f;

size(600,400);

for(int i=0;i
seed[i]=new PVector(random(width),random(height));
fill(255,255,0);
ellipse(seed[i].x,seed[i].y,5,5);
}

for(int i=0;i
for(int j=0;j
   everyPixel=new PVector(i,j);
   for(int k=0;k
     distance[k]=everyPixel.dist(seed[k]);
   }
   distance=sort(distance);
   min=distance[0];
   secmin=distance[1];

   if(abs(secmin-min)
     stroke(255);
     point(i,j);
   }
}
}


20个种子点是随机生成的,下图是得到的一个结果:

代码注释:
int qty=20;//设20个种子点
PVector everyPixel;//将来会通过把每一像素点的值赋给everyPixel进行遍历。
PVector[]seed=new PVector[qty];//20个种子点的位置
float[]distance=new float[qty]; //像素点到20个种子点的距离
float min,secmin;//最小距离和第二小距离
float threshold=1f;//由于距离是浮点数,在实际执行中,几乎不可能出现两个距离恰好相等的情况,所以使用的是阈值法,距离差小于某个阈值的都算相等

size(600,400);

for(int i=0;i
seed[i]=new PVector(random(width),random(height));//随机出20个点
fill(255,255,0);
ellipse(seed[i].x,seed[i].y,5,5);//画小圈标记这20个点的位置
}

for(int i=0;i
for(int j=0;j
   everyPixel=new PVector(i,j);//像素点信息赋给变量
   for(int k=0;k
     distance[k]=everyPixel.dist(seed[k]);
        //该像素到20个种子的距离,形成一个数组
   distance=sort(distance);  //对该数组排序
   min=distance[0];      //得到最小距离
   secmin=distance[1];   //得到第二小距离

   if(abs(secmin-min)
     stroke(255);     //填充白色,对于point的染色,要用stroke,而不是fill
     point(i,j);       //描点
   }
}
}


如果我们进一步把上面的代码加点颜色的变化就能得到下面这种漂亮一些图案:

如果进一步把代码打包成类,并把生成图案作为材质图贴到立方体上就能得到题图的水立方。
整个过程so easy,颤抖吧,grasshopper  🙂

云风网络是集昆山网站制作,昆山网页设计,昆山网站推广于一体的昆山网络公司,业务涵盖:昆山手机网站制作,昆山网站设计,昆山网络建设,昆山做网站,昆山网站建设,电话:13912673321

相关推荐
点击这里给我发消息 技术咨询
回到顶部