這是我參與8月更文挑戰的第8天,活動詳情查看: 8月更文挑戰java
該效果其實核心思想是將多「層」的心形煙進行組合,首先咱們來定義其中一 「層」 的心形煙的實現代碼。markdown
class Heart{
float seed = random(10,1000);
float offset = random(TWO_PI);
float ff = random(0.5,2.5);
float sw = random(0.8,1.8);
float part = 0.1+0.5*pow(random(1),2.0);
float rf = random(0.5,1.15);
float d = random(10,120);
int m = 500; ///< 500 個點
OpenSimplexNoise noise = new OpenSimplexNoise(); ///< 噪聲,用於擾動心形
float R = 150;
float xh(float p){
return R/15.0*16*pow(sin(p),3);
}
float yh(float p){
return R/15.0*(-13*cos(p) +5*cos(2*p) + 2*cos(3*p) + cos(4*p));
}
void show(float q){
for(int i=0;i<m;i++){
float p = 1.0*i/m;
float theta = offset + part*TWO_PI*i/m;
float rad = 1.3f;
int per = 2;
float xx = rf*xh(theta) + pow(p,3.0f)*d*(float)noise.eval(seed + rad*cos(TWO_PI*(per*p-q)),rad*sin(TWO_PI*(per*p-q)));
float yy = rf*yh(theta) + pow(p,3.0f)*d*(float)noise.eval(2*seed + rad*cos(TWO_PI*(per*p-q)),rad*sin(TWO_PI*(per*p-q)));
strokeWeight(sw);
stroke(255,ff*18*sin(PI*p));
point(xx,yy);
}
}
}
複製代碼
其中關鍵的代碼(以下所示)表明的公式能夠繪製出心形(將 360° 分紅了 m 份,而後每一個位置放置一個點,只要劃分的足夠細,就能夠看起來像是一個完整的 ♥)app
float R = 150;
float xh(float p){
return R/15.0*16*pow(sin(p),3);
}
float yh(float p){
return R/15.0*(-13*cos(p) +5*cos(2*p) + 2*cos(3*p) + cos(4*p));
}
複製代碼
簡化後對應函數示意圖以下所示dom
而後經過疊加 Simplex 噪聲的隨機擾動,咱們就能夠模擬出煙塵的效果。函數
自此基礎上,接着咱們構造多層(本例爲 250 層)的心形煙塵,並將它們疊加起來一層一層繪製工具
float t, c;
int samplesPerFrame = 5;
int numFrames = 100;
float shutterAngle = .6;
int n = 250; ///< 250 層 ♥
Heart[] array = new Heart[n];
void setup(){
size(600,600,P3D);
for(int i=0;i<n;i++){
array[i] = new Heart();
}
}
void show(){
background(0);
push();
translate(width/2,height/2);
for(int i=0;i<n;i++){
array[i].show(t);
}
pop();
}
void draw() {
t = mouseX*1.0/width;
c = mouseY*1.0/height;
if (mousePressed)
println(c);
frameCount = 0;
show();
/// @note 保存序列 gif,後期可用 gifsicle 合成真正的 gif
// saveFrame("fr###.gif");
}
void keyPressed(){
if(key == 'r' || key == 'R'){
recording = !recording;
println("recording:" + recording);
}
}
複製代碼
最後附上 OpenSimplexNoise.pde(因爲代碼過長,爲了避免影響閱讀,因此上傳到百度網盤),關於噪聲的詳解能夠看我以前寫的一篇ShaderJoy —— 噪聲之美,你們一塊兒 「噪」 起來 【GLSL】oop
連接:pan.baidu.com/s/1uKqedakx… 提取碼:u8ru post
gifsicle 下載連接:www.lcdf.org/gifsicle/ ui
下載安裝完成以後,打開命令行工具,執行如下命令(默認各幀的命名模式爲 fr*.gif) ,最終生成 anim.gif,各幀的延遲爲 10 / 100 surl
gifsicle --delay=10 --loop fr*.gif > anim.gif
複製代碼
gifsicle 支持的更加複雜的命令行請參見其官方手冊