基于Processing的noise随机数做出炫酷的图片

编程入门 行业动态 更新时间:2024-10-23 07:20:51

基于Processing的noise<a href=https://www.elefans.com/category/jswz/34/1766016.html style=随机数做出炫酷的图片"/>

基于Processing的noise随机数做出炫酷的图片

内容

  • 前置知识
    • 一维noise函数
    • 二维noise函数
  • 制作思路
  • 代码

一维noise函数

其 x x x的取值范围是负无穷到正无穷,且函数本身关于 y y y轴对称。返回值是一个 [ 0 , 1 ] [0,1] [0,1]之间的数。
需要注意的是, [ 0 , 1 ] [0,1] [0,1]中的每个数出现概率并不相同,其结果类似于正态分布,越接近 0.5 0.5 0.5的数出现概率越大,越接近 0 , 1 0,1 0,1的数出现概率越低。

与random随机数的区别

randow随机数生成的数是均匀分布的,而noise随机数的生成值是接近正态分布的,且noise随机数的值是“确定“的,同一次运行中,调用 10 10 10次noise(233),每次的返回值都是相同的。

一些性质

  • noise生成的随机数看起来比较“自然”。
  • 连续取值时,间隔越小,生成的数起伏越小,间隔越大,生成的数起伏越大。

二维noise函数



如果把值当成高度,分的再细一点的话,就能得到类似于自然中群山的样子。

如果贴一个模型,再加上光影…
实际上,很多游戏中的山都是基于noise生成的。

noise函数的应用

noise函数得到的随机数,比较“自然”,所以基于它绘制的内容比较有特点。


那么这张图片是怎么生成的呢?

如果我们在二维noise上画一个圆,并且把得到的值当作一个新的圆的半径:

然后我们让在noise函数中的圆向右平移,并把得到的圆绘制在另一个图中,并且也向右平移…

最终就能得到这种图了。

代码-变量
float centerX, centerY, offsetX, offsetY, inc, r, rd;
int segNumber;

c e n t e r X , c e n t e r Y centerX,centerY centerX,centerY是在绘制图中,圆的中心坐标
o f f s e t X , o f f s e t Y offsetX, offsetY offsetX,offsetY是在noise函数图中,圆的坐标。
s e g N u m b e r segNumber segNumber把圆分成几个点
i n c inc inc是在noise函数图中圆的半径
r , r d r,rd r,rd是在绘制图中圆的半径

代码-setup部分
void setup() 
{size(1920, 1080);background(0);noFill();colorMode(HSB);centerX = 0; centerY = height / 2;offsetX = offsetY = 0; inc = 0.725; segNumber = 500;r = 0; rd = 350;
}
beginShape();
//通过vertex(x,y)函数画几个节点
endShape(CLOSE);

这个函数负责把在两个函数之间绘制的节点依次连接起来,从而形成一个封闭图形。

代码-怎么绘制一个圆

我们知道单位圆方程 x 2 + y 2 = 1 x^2 + y^2=1 x2+y2=1
以及 c o s 2 ( α ) + s i n 2 ( α ) = 1 cos^2(\alpha)+sin^2(\alpha)=1 cos2(α)+sin2(α)=1

我们借助 c o s 2 ( α ) + s i n 2 ( α ) = 1 cos^2(\alpha)+sin^2(\alpha)=1 cos2(α)+sin2(α)=1这个方程,
对于每个点 ( c o s ( α ) , s i n ( α ) ) (cos(\alpha),sin(\alpha)) (cos(α),sin(α)),它们都在 x 2 + y 2 = 1 x^2 + y^2=1 x2+y2=1这个圆上。

所以我们枚举在 [ 0 , 2 π ] [0,2\pi] [0,2π]中枚举 α \alpha α,就得到了所有单位圆中点的坐标。然后我们把所有坐标都乘上一个数 i n c inc inc,就得到了任意半径的圆了。

代码-draw部分
void draw() 
{stroke((frameCount * 0.05) % 255, 180, 255, 64);beginShape();//画圆for(int i = 0; i < segNumber; i++) {float angel = TWO_PI * i / segNumber;PVector p = new PVector(cos(angel), sin(angel));float radius = r + rd * noise(offsetX + p.x * inc, offsetY + p.y * inc);p.mult(radius);vertex(p.x + centerX, p.y + centerY);}endShape(CLOSE);float offset = 0.00385;//平移offsetX += offset; offsetY += offset;centerX += 1;if(centerX > width) {centerX = 0;background(0);}
}

经过很多次尝试,我发现了最影响图形的的两个参数:

  • i n c inc inc:即noise函数中圆的半径,这个很好理解,在noise中画的圆的大小越大,那么它所得到的值范围就越大,且起伏就越明显,绘制出来的图形棱角就比较多。相反, i n c inc inc值越小,画出来的图形就越"圆润"。
  • o f f s e t offset offset:即在noise函数中每次平移的距离。值越小,noise值变化的就越小,表现出来的结果就是重叠效果越明显;值越大,noise变化就越大,表现出来的结果就是画的圆比较分散。

代码

float centerX, centerY, offsetX, offsetY, inc, r, rd;
int segNumber;void setup() 
{size(1920, 1080);background(0);noFill();colorMode(HSB);centerX = 0; centerY = height / 2;offsetX = offsetY = 0; inc = 1; segNumber = 500;r = 0; rd = 350;
}void draw() 
{stroke((frameCount * 0.05) % 255, 180, 255, 64);beginShape();for(int i = 0; i < segNumber; i++) {float angel = TWO_PI * i / segNumber;PVector p = new PVector(cos(angel), sin(angel));float radius = r + rd * noise(offsetX + p.x * inc, offsetY + p.y * inc);p.mult(radius);vertex(p.x + centerX, p.y + centerY);}endShape(CLOSE);float offset = 0.006;offsetX += offset; offsetY += offset;centerX += 1;if(centerX > width) {centerX = 0;background(0);}
}

参考内容:

更多推荐

基于Processing的noise随机数做出炫酷的图片

本文发布于:2024-02-11 20:15:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1683201.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:随机数   图片   Processing   noise

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!