ランダムウォーク2
先日のランダムウォークを改良しました。
gotutiyan.hatenablog.com
方向ベクトルを斜めにして、軌跡を点線に。さらに円の内部を動く色付きのものと、円の外を動く白色のものに分けてみました。
ランダムウォークをもう少し改良〜
— string s="ごつちやん"; (@gotutiyan_kapi) October 6, 2018
コードと解説は以下からhttps://t.co/kwZ3QfGVEE#processing#creativecoding pic.twitter.com/VCX6Ciwwuz
白いものは画面外に出たとき、もしくは円の中に入ったときに、強制的に引き戻す方向に変えさせます。
色付きのものは、円を出ようとしたときに、強制的に引き戻す方向に変えさせます。
引き戻す方向は案外簡単に設定できて、引き戻す条件に合致した瞬間のx,y座標をX,Yとおけば、「出て行く」動きを引き戻すなら、X,Yそれぞれの反対の符号を持つdir[ ]を、「入りこむ」動きを引き戻すなら、X,Yそれぞれと同じ符号を持つ dir[ ]を足せば良いです。
また、軌跡を表す線を点線にしましたが、これは軌跡を格納している配列において、「5で割った余りが0,1,2となるような添字の時だけline()を引く」ということをしています。
つまり、3ピクセル描いて2ピクセル描かない、をひたすら繰り返します。
コードはprocessingで、以下の通りです。
RandomWalk2 random10_color[]=new RandomWalk2[100]; RandomWalk2 random10_white[]=new RandomWalk2[200]; void setup() { size(600,600,P2D); for (int i=0; i<random10_color.length; i++)random10_color[i]=new RandomWalk2(0); for (int i=0; i<random10_white.length; i++)random10_white[i]=new RandomWalk2(1); } void draw() { background(0); translate(width/2, height/2); noFill(); ellipse(0, 0, 500, 500); for (int i=0; i<random10_color.length; i++)random10_color[i].move(); for (int i=0; i<random10_white.length; i++)random10_white[i].move(); } class RandomWalk2 { PVector now; PVector dir[]=new PVector[4]; PVector diff; ArrayList<PVector> prev=new ArrayList<PVector>(); int changeDir; float c; float radius=250; int mode=0; //0なら円内部の色付き、1なら円外部の白 RandomWalk2(int emode) { mode=emode; if (mode==0)now=new PVector(0, 0); else now=new PVector(random(width)-width/2, random(height)-height/2); dir[0]=new PVector(1, 1); //方向ベクトルたち dir[1]=new PVector(-1, -1); dir[2]=new PVector(1, -1); dir[3]=new PVector(-1, 1); diff=new PVector(1, 1); changeDir=(int)random(30, 50); c=random(360); } void move() { if (mode==0) { if (dist(0, 0, now.x, now.y)>radius) { //色つきのが円の外に出ない if (now.x<0&&now.y<0)diff=dir[0]; if (now.x>0&&now.y>0)diff=dir[1]; if (now.x<0&&now.y>0)diff=dir[2]; if (now.x>0&&now.y<0)diff=dir[3]; } } else { if (dist(0, 0, now.x, now.y)<radius) { //白いのが円の中に入らない if (now.x>0&&now.y>0)diff=dir[0]; if (now.x<0&&now.y<0)diff=dir[1]; if (now.x>0&&now.y<0)diff=dir[2]; if (now.x<0&&now.y>0)diff=dir[3]; } if (now.x<-width/2)diff=dir[0];//白が画面の外に出ない if (now.x>width/2)diff=dir[1]; if (now.y<-height/2)diff=dir[3]; if (now.y>height/2)diff=dir[2]; } if (frameCount%changeDir==0) { //フレームごとでの方向変更 int x=(int)random(0, 4); diff=dir[x]; } prev.add(new PVector(now.x, now.y)); while (prev.size()>100)prev.remove(0); now.add(diff); if (mode==0) { //円の色 colorMode(HSB,360,100,100,100); fill(c, 100, 100,100); } else { colorMode(RGB); fill(255); } noStroke(); ellipse(now.x, now.y, 10, 10); //円の描画 colorMode(HSB); if (mode==0) { //線の色 colorMode(HSB); stroke(c, 100, 100, 100); } else { colorMode(RGB); stroke(255); } for (int i=1; i<prev.size(); i++) { //線を描く if (i%5==0||i%5==1||i%5==2)line(prev.get(i).x, prev.get(i).y, prev.get(i-1).x, prev.get(i-1).y); } } };