0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Processingで万華鏡を作ってみた

Posted at

高井です。

夏といえば夏休み。夏休みといえば自由研究。
自由研究気分で万華鏡を作ってみます。

使う言語はこちらで紹介したProcessingです。

やってみよう!!!

万華鏡の仕組み

参考サイト1

ニコン キッズアイランド「万華鏡のしくみを学ぼう」
https://www.jp.nikon.com/company/corporate/sp/kids/kaleidoscope/

まさに夏休みの自由研究でできそうな工作が紹介されています。
透明な筒にビーズを入れて周りを鏡で三角形に囲むことで、簡単な万華鏡が作れるみたいです。

参考サイト2

ナゾロジー「万華鏡はどうやって美しい幾何学模様を作るのか?秘密は三角形の角度!」
https://nazology.net/archives/130704

パンダの絵が鏡映しになっているイメージ図が分かりやすいです。
鏡は三角形が好ましいみたいです。

プログラミング方針

上記2サイトを踏まえ、ざっくりした方針を決めました↓
・ビーズクラスを作る
・位置や色が異なるビーズオブジェクトを大量に作る
・三角形のエリアに、大量生成したビーズを描画する
・隣にはそれを左右反転した三角形を、上下には上下反転した三角形を描画する

先駆者

なんと先駆者がいました!
https://github.com/abekzk/kaleidoscope

こちらのソースコードを参考にさせていただきました。

万華鏡作ってみた

ということでできたのがこちらです。

※録画の都合でカクカクしています…すみません

ソースコード

main.pde

Ball[] balls = new Ball[50]; // ビーズ50個
Mirror[] mirrors = new Mirror[6]; // 鏡6枚
PGraphics texture; // 鏡に反射させる、元の絵(ビーズを描画するエリア)

void setup(){
 size(600, 600, P2D);
 
 // ビーズ初期化
 for(int i = 0; i < 50; i++){
   balls[i] = new Ball();
 }
 
 // テクスチャ初期化
 texture = createGraphics(600, 600);
 
 // 鏡初期化
 for(int i = 0; i < 6; i++){
  mirrors[i] = new Mirror(i, texture);
 }
}

void draw(){
 background(0);
 
 // ビーズを描画する(元の絵になる)
 drawTexture();
  
 // 元の絵を反射した鏡を描画する 
 for(Mirror mirror:mirrors){
  mirror.display();
 }
 
 // 録画のためこのフレームを保存
 saveFrame("frames/####.png");
}

// 毎フレーム、ビーズ描画
void drawTexture(){
 texture.beginDraw();
 
 texture.background(255);
 
 // ビーズをゆっくり回転させる
 texture.translate(texture.width / 2, texture.height / 2);
 texture.rotate(radians(millis()) / 50 % 360);
 
 for(Ball ball:balls){
  texture.shape(ball.shape, ball.x - texture.width / 2, ball.y - texture.height / 2);
 }
 
 texture.endDraw();
}

Ball.pde

// ビーズクラス
class Ball {
 PShape shape; // 形(丸、三角形、四角形)
 int x;
 int y;
 int size;
 color c;
 
 Ball(){
  // 位置、サイズ、色をランダム生成
  this.x = int(random(600));
  this.y = int(random(600));
  this.size = int(random(30, 60));
  this.c = color(int(random(256)), int(random(256)), int(random(256)), int(random(256)));
  
  // 形をランダム生成
  int type = int(random(3));
  if(type == 0){
   shape = createShape(ELLIPSE, 0, 0, size, size);
  }else if(type == 1){
   shape = createShape(RECT, 0, 0, size, size); 
  }else if(type == 2){
    shape = createShape(TRIANGLE, 0, 0, size, 0, size/2, size);
  }
  
  shape.setFill(c);
  shape.setStroke(false);
 }
}

Mirror.pde

// 鏡クラス
class Mirror{
  PShape pShape; //描画する三角形
  
  Mirror(int mirrorNum, PGraphics texture){
   int r = 150;                                       // 鏡のサイズ
   int rad = 90 + 60 * mirrorNum;                     // 鏡の角度
   int  x = int(width / 2 + r * cos(radians(rad)));   // 鏡のx座標
   int  y = int(height / 2 + r * sin(radians(rad)));  // 鏡のy座標
   
   textureMode(NORMAL);
   pShape = createShape();
   pShape.beginShape();
   
   // 三角形に元の絵を貼り付ける設定
   pShape.texture(texture);
   
   // 三角形の縁をグレーで描画
   pShape.stroke(200);
   
   // 三角形の頂点の座標を描画する
   for(int i = 0; i < 3; i++){
    float theta = radians(60 * mirrorNum - 90 + 120 * i);
    float thetaTexture = radians(-90 + 120 * i);
    
    if(mirrorNum % 2 == 1){
      // 奇数枚目ならテクスチャをそのまま貼り付ける
      pShape.vertex(x + r * cos(theta), y + r * sin(theta), (cos(thetaTexture) + 1) * 0.5, (sin(thetaTexture) + 1) * 0.5);
    }else{
      // 偶数枚目ならテクスチャを反転して貼り付ける
      pShape.vertex(x + r * cos(theta), y + r * sin(theta), 1 - (cos(thetaTexture) + 1) * 0.5, (sin(thetaTexture) + 1) * 0.5);
    }
   } 
   
   pShape.endShape(CLOSE);
  }
  
  // 毎フレーム、三角形を描画する
  void display(){
   shape(pShape); 
  }
}

ポイント

こだわりポイント
・半透明のビーズ(カワイイ)
・最終的に記事にするので、ソースコードを簡潔に書く

今後の改良ポイント簡潔なソースコードのため断念したこと
・ビーズをぼんやり光らせたい(より"万華鏡"感ある見た目の研究)
・ハートとか星型とか、ビーズの形を増やしたい
・鏡が6枚しかないので、敷き詰めたい

以上、高井でした:art:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?