加工で実現した鼓動するハート形状
ハート型実現公式原理はこのブロガーの記事を参照しています
最近、ドラマ「点火してあなたを温めて」で鼓動するハートの形を見て、とても興奮して自分でも実現したいと思いました。可視化するために処理を使用すると非常に便利です。TouchDesign の方が便利かもしれませんが、もしあなたが慣れていない場合は、処理を使用する必要があります。結局TVシリーズではエフェクトが出せないので、まずはやってみましょう。
私が自作した効果は以下の通りです。
ファイルの内容
パーティクル.pde
パーティクルインターフェイス (自分でテストするのに便利)
interface Particle{
void Caculate(float s, float t) ;
void DrawParticle(float s, float t);
void SetIndext(boolean b);
}
Particle1.pde
パーティクル クラス Particle1 は、Particle インターフェイスを実装します。
class Particle1 implements Particle {
// 坐标
PVector v;
// 计算坐标的各项参数
public float xa, ya1, ya2, ya3, ya4;
// 参数设置函数
public void SetIndext(boolean b) {
if (b) {
xa+=0.001*500+0.3;
ya1+=0.001*500+0.1;
ya3+=0.1;
} else {
xa-=0.001*500+0.3;
ya1-=0.001*500+0.1;
ya3-=0.1;
}
}
// 圆点粒子的坐标
float r;
// 坐标的随机范围
float r1, r2;
// 构造器,初始化成员
public Particle1(float r1, float r2) {
v= new PVector(0, 0);
this.xa = 15;
this.ya1 = 13;
this.ya2 = 5;
this.ya3 = 3;
this.ya4 = 0.1;
this.r = 7;
this.r1 = r1;
this.r2 = r2;
}
// 坐标计算
void Caculate(float s, float t) {
this.v.x=this.xa *s* pow(sin(t), 3)+random(this.r1, width/2);
this.v.y=this.ya1* cos(t) - this.ya2* cos(2 * t) - this.ya3* cos(3 * t) - this.ya4*cos(4 * t);
this.v.y = -this.v.y*s+random(this.r2, height/2);
}
// 粒子绘制
void DrawParticle(float s, float t) {
Caculate(s, t);
fill(162, 56, 72, random(255) );
noStroke();
ellipse(this.v.x, this.v.y, random(r), random(r));
}
// 粒子的销毁
void Destroy() {
}
}
愛.pde
パーティクルを使用してハート型の曲線を描きます。ラブクラスでは、サイズパラメータとパーティクルの座標によって計算されるパラメータを変更することでハートのサイズを変更します
class Love {
// 爱心的大小
float size;
// 弧度,取值范是[0,2*pi]
float t;
// 弧度变化参数
float vt;
// t的最大值,循环的次数
float maxt;
int maxi;
// 初始大小的爱心大小和最大的心形的小
float sizeInit, sizeMax;
// 存放粒子的参数
ArrayList<Particle> ps;
// 粒子坐标的偏离范围
float r1, r2;
//标记变化的flag
boolean flag;
// 构造器初始化参数
public Love(float r1, float r2) {
this.Init();
this.size = 8f;
this.sizeInit = 7f;
this.sizeMax = 10f;
this.r1 = r1;
this.r2 = r2;
InitArrayList();
}
// 构造器初始化参数,可以设置粒子运动动范围的大小
public Love(float r1, float r2, float size, float sizeInit, float sizeMax, float vt) {
Init();
this.r1 = r1;
this.r2 = r2;
this.vt = vt;
this.size = size;
this.sizeInit = sizeInit;
this.sizeMax = sizeMax;
// 初始化各个粒子
InitArrayList();
}
void Init() {
this.t = 0;
this.vt = 0.001;
this.maxt = TWO_PI;
this.maxi = ceil(maxt/vt);
flag = true;
}
void InitArrayList() {
ps = new ArrayList<Particle>();
for (int i=0; i<maxi; i++) {
ps.add(new Particle1(this.r1, this.r2));
}
}
void InitArrayList(int addNum) {
int allNum = addNum + maxi;
ps = new ArrayList<Particle>();
for (int i=0; i<allNum; i++) {
ps.add(new Particle1(this.r1, this.r2));
}
}
// 绘制爱心
void DrawLove() {
for (int i = 0; i<maxi; i++) {
// 创建粒子
Particle pp = ps.get(i);
//Particle pp = new Particle1(this.r1,this.r2);
// 计算粒子坐标并且绘制粒子
pp.DrawParticle(this.size, this.t);
t+=vt;
}
}
// 爱心的运动,即改变大小
// 先绘制后大小变化
void PuTong() {
DrawLove();
Move();
}
void Move() {
if (size<this.sizeInit || size>this.sizeMax) {
this.flag = !this.flag;
}
if (this.flag==true) {
size+=0.4;
} else {
size-=0.4;
}
SetLoveIndex(flag);
}
void SetLoveIndex(boolean f){
for(int i=0;i<maxi;i++){
ps.get(i).SetIndext(f);
}
}
}
ハート.pde
import processing.sound.*; //所用到的库sound
// 操作要播放的音乐文件对象
SoundFile file;
ArrayList<Love> loveList;
// 一颗心
Love love;
Love love1;
//=======================================
void setup() {
// 画布大小
size(1920, 1080);
//背景颜色
background(0, 0, 0);
frameRate(7);
//Init();
loveList = new ArrayList<Love>();
loveList.add(new Love(width/2-30, height/2-40));//测试用
loveList.add(new Love(width/2-10, height/2-10, 7f, 7f, 10f, 0.001));
loveList.add(new Love(width/2-100, height/2-100, 7f, 7f, 10f, 0.001));
// 播放背景音频,背景音频放在data文件夹里
file = new SoundFile(this, "心脏在跳动_耳聆网_[声音ID:11421].wav");
file.loop(); // 循环
file.play(); // 播放
}
//=======================================
void draw() {
// 刷新背景
background(0, 0, 0);
loveList.get(1).PuTong();
loveList.get(2).PuTong();
}
更新する
パラメータを修正して、パーティクルを描画する際に異なる座標のパーティクルを追加することで、ランダムに生成されたパーティクルがあまり中心からずれないように修正しました。Heart.pde を呼び出すときに、愛の複数のインスタンスを宣言する必要はありません。
主なものは粒子座標計算式のパラメータ変数ya4を追加し、粒子を描画する際に乱数の異なる2種類の粒子を描画することで、一部のパラメータも自由に調整できます。
Particle1.pde
// Particle1.pde
class Particle1 implements Particle {
// 坐标
PVector v;
// 计算坐标的各项参数
public float xa, ya1, ya2, ya3;
// 粒子坐标计算公式的一个参数变量ya4
float ya4;
// 参数设置函数
public void SetIndext(boolean b) {
if (b) {
xa+=0.001*500+0.1;
ya1+=0.001*500+0.1;
ya3+=0.1;
} else {
xa-=0.001*500+0.1;
ya1-=0.001*500+0.1;
ya3-=0.1;
}
}
// 圆点粒子的坐标
float r;
// 坐标的随机范围
float r1, r2;
// 构造器,初始化成员
public Particle1(float r1, float r2) {
v= new PVector(0, 0);
this.xa = 15;
this.ya1 = 13;
this.ya2 = 5;
this.ya3 = 3;
//
this.ya4 = 0.1;
//
this.r = 7;
this.r1 = r1;
this.r2 = r2;
}
// 坐标计算
void Caculate(float s, float t) {
this.v.x=this.xa *s* pow(sin(t), 3)+random(this.r1, width/2);
this.v.y=this.ya1* cos(t) - this.ya2* cos(2 * t) - this.ya3* cos(3 * t) - this.ya4*cos(4 * t);
this.v.y = -this.v.y*s+random(this.r2, height/2);
}
// 粒子绘制
void DrawParticle(float s, float t) {
Caculate(s, t);
fill(255, 105, 180, random(200) );
noStroke();
float rr = 50;
float rq = 50;
float rc = 10;
//ellipse(this.v.x, this.v.y, random(r), random(r));
ellipse(random(this.v.x-rc,this.v.x+rc), random(this.v.y-rc,this.v.y+rc), random(r), random(r));
ellipse(random(this.v.x-rq,this.v.x+rq), random(this.v.y-rq,this.v.y+rq), random(r), random(r));
ellipse(random(this.v.x-rr,this.v.x+rr), random(this.v.y-rr,this.v.y+rr), random(r), random(r));
}
}
ハート.pde
import processing.sound.*; //所用到的库sound
// 操作要播放的音乐文件对象
SoundFile file;
//ArrayList<Love> loveList;
Love love;
//=======================================
void setup() {
// 画布大小
size(1920, 1080);
//背景颜色
background(0, 0, 0);
frameRate(3);
//Init();
love = new Love(width/2, height/2, 10f, 9.5f, 10f, 0.01);//测试用
// 播放背景音频
file = new SoundFile(this, "心脏在跳动_耳聆网_[声音ID:11421].wav");
file.loop(); // 循环
file.play(); // 播放
}
//=======================================
void draw() {
// 刷新背景
background(0, 0, 0);
love.PuTong();
}