見出し画像

立体視ができる画像を作る. by Processing


立体視(ステレオグラム)ってご存知ですか?

平面画像を見るときの焦点を意図的にずらすことによって立体的に見ることができる方法です。

実際は魔法の類です。

立体視には平行法と交差法という2つの方法があります。

絵でいうとこんな感じです。

平行法は遠くを見る、交差法は近くを見る(寄り目)といった感じです。

2つの方法は立体的に見える画像の前後(奥行き)が逆になります。

2つの目と少しの脳があれば見ることができると思うので、詳しいやり方はググってください。

早速今回作った画像を見てみましょう。

上部の赤い円が重なるように焦点をずらしてください。

見えましたか?円錐っぽいものが見えたら正解です。

平行法で見た場合は手前に浮き上がって見えます。交差法はその逆。

コードも貼っておきます。

ArrayList<PVector>pos;
color[] col;

void setup() {
 size(600, 600);
 pixelDensity(2);
 colorMode(HSB, 360, 100, 100, 100);
 noLoop();
 //posに数値を追加
 addP();
}

void draw() {
 background(0);
 //左側を描画
 form(0);

 //右側を描画
 push();
 translate(width/2, 0);
 form(1);
 pop();

 //焦点を合わせるための円
 stroke(0);
 fill(0, 100, 100);
 circle(width*0.25, 20, 20);
 circle(width*0.75, 20, 20);
 
 save("stereogram.png");
}

void addP() {
 pos = new ArrayList<PVector>();
 int c = 100;  //一列に配置する四角形の数
 float w = width/c;  //ひとつひとつの四角形の一辺の長さ

 //タイル状に配置する
 for (int j=0; j<c; j++) {
   for (int i=0; i<c/2; i++) {
     pos.add(new PVector(i*w, j*w, w));
   }
 }

 col = new color[pos.size()];
 for (int i=0; i<col.length; i++) {
   col[i] = color(random(100, 300), 80, 80);
 }
}

void form(int t) {
 int cc = 0;  //左右の描画の色を揃えるためのカウント

 //拡張forループ
 for (PVector p : pos) {
   //それぞれの座標から中心までの距離
   float d = dist(p.x, p.y, width/4, height/2);
   //距離の最大値
   float maxd =width/4;
   //ずらす大きさ
   float sft = map(d, 0, maxd, 20, 0);
   //中心からの距離がwidth/4より大きい場合は適応されない
   if (d > maxd) {
     sft = 0;
   }

   fill(col[cc]);
   noStroke();
   //tを使って、右側は左にずれ、左側は右にずれるようにする
   if (t == 0)rect(p.x+sft, p.y, p.z, p.z);
   else rect(p.x-sft, p.y, p.z, p.z);

   cc ++;
 }
}

コメントで書いたので細かい説明は省きますが何か質問があれば聞いてください。

作るときのポイントとしては…

・左右に2つの画像を並べる。

・立体的(手前)に見せたい部分を元の位置から2つの画像の中心をにずらす。(平行法の場合)

・ずらす方向は左右方向にずらす(目が左右についているので)。上下に目がついている場合は上下にずらす。

・画像が大きいと平行法で見ることが難しい。

多分この辺を意識したらできると思います。

何か作ったらぜひシェアしてください!

最後まで読んでいただき、ありがとうございます。

Happy coding!!!!

応援してくださる方!いつでもサポート受け付けてます!