Help us understand the problem. What is going on with this article?

Processingでクリスマス

普段データ操作とかユーザーインターフェースのプログラムばかり書いていると、たまには仕事とまったく関係ないプログラムを書きたくなりますよね。
そんな訳で今回はProcessingでちょっとクリスマスっぽい絵でも描いてみましょう。

Processingとは

Processingは電子アートとビジュアルデザインのためのプログラミング言語であり、統合開発環境です。
こう書くと少し難しいものに思えるかもしれませんが、プログラムを書くことで絵を描けるくらいに考えてもらっても大丈夫だと思います。
記述したプログラムによる変化が視覚的にすぐにわかるので、データ操作をするようなプログラムよりも実行結果の違いがわかりやすいという特徴があります。

ProcessingはJavaで作られており、プログラムも基本はJavaで記述しますが、モードを追加することでPythonやJavaScriptなどでも記述できます。
自分の興味のあるプログラミング言語でProcessingにトライしてみましょう。

インストールしてみよう

Processingのインストールは下記のページからZIPファイルをダウンロードし、解凍してからWindowsであればProcessing.exeを、MacであればProcessing.appをダブルクリックして実行するだけです。

https://processing.org/download/

Processingを起動すると、下記のようなIDEが表示されます。
ide.png

さっそく何か描いてみましょう。
下記のプログラムをコピーしてIDEに貼り付けて実行してみてください。
実行は左上の三角が書かれているボタンです。

size(300,250);
background(255);
stroke(0);

fill(255);
ellipse(150,160,100,100); // body
line(110,130,70,100); // left arm
line(190,130,230,100); // right arm
ellipse(150,100,60,60); // head
arc(150, 106, 30, 25, -TWO_PI, -PI); // mouth

fill(0);
rectMode(CENTER);
rect(150,65,34,20); // hat
line(125,75,175,75); // brim
ellipse(142,92,5,5); // left eye
ellipse(158,92,5,5); // right eye

noStroke();
fill(255,100,0); 
ellipse(150,102,7,7); // nose

snowman.png
こんなのが出てくれば成功です。
プログラムは単純に各パーツの丸を描いて塗り潰したり線を引いたりしているだけです。
各パーツの数値を変えることで絵が変化するので、色々ためしてみましょう。

サンプルプログラム

今回はProcessingのプログラムの書き方については言及しません。
Processingの書き方やサンプルプログラムはWebで検索するとたくさん出てきます。
サンプルプログラムを写経したり、書き換えて動かしてみることで、プログラムの書き方はすぐに解ると思いますので、サンプルプログラムをたくさん動かしてみることをお勧めします。
ここではいくつかのサンプルプログラムをご紹介します。

イルミネーション

クリスマスなのに部屋が殺風景だと感じたら、PCのディスプレイをクリスマスイルミネーションにしてしまいましょう。
サンプルプログラムの描画領域や円のサイズを調整してディスプレイを華やかにしてみてください。
やっていることは乱数で座標、丸の大きさ、色、透過度を変化させて描画しているだけです。
setup()は最初に1回だけ実行され、draw()は定期的に繰り返し実行されます。

void setup() {
  size(700,400);
  background(0);
  smooth();
}

void draw() {
  float r = random(255);
  float g = random(255);
  float b = random(255);
  float a = random(255);
  float x = random(width);
  float y = random(height);
  float diameter = random(20);

  noStroke();
  fill(r,g,b,a);
  ellipse(x,y,diameter,diameter);
}

illumination.png

フラクタル図形で木を書く

フラクタル図形とは、「図形の部分と全体が自己相似(再帰)になっているもの」です。
フラクタル図形にはいろいろな種類がありますが、ここではクリスマスツリーにちなんで木のようなものを描いてみましょう。

int angle = 110;

void setup() {
  background(255);
  size(600, 600, P2D);

  tree(300, 600, 0.0, radians(0), radians(angle), 200, 10);
  tree(300, 600, 0.0, radians(angle), radians(0), 200, 10);
}

void tree(float posX, float posY, float angle, float forkRight, float forkLeft, float length, int counter) {
  if (counter == 0) {
    return;
  }

  float nextX = posX + length * sin(angle);
  float nextY = posY - length * cos(angle);

  line(posX, posY, nextX, nextY);

  tree(nextX, nextY, angle + forkRight, forkRight, forkLeft, length*0.6, counter - 1);
  tree(nextX, nextY, angle - forkLeft,  forkRight, forkLeft, length*0.6, counter - 1);
}

tree2.png

再帰処理に慣れていないと読みにくいかもしれませんが、同じ形のものを縮小して一定回数繰り返し描画しています。
angleの値を変化させると、木の形が変化するので試してみましょう。
下記は size=80 にした時の描画結果になります。

tree_radian80.png

フラクタル図形で雪の結晶を書く

フラクタル図形の一種にコッホ曲線というのがあります。
線分を3等分し、分割した2点を頂点とする正三角形の作図を無限に繰り返すことによって下記の様な図形が作成できます。
kochCurve.png

このコッホ曲線を正三角形に配置すると、雪の結晶のような図形が出現します。
この図形はコッホ雪片と呼ばれます。

snowFrake.png

以下のサンプルは、コッホ雪片を段階的に作成するプログラムです。
実際に動かしてみてコッホ雪片がどのように作られるのかを見てみましょう。

int depth = -1;

void setup(){
  background(255);
  size(400, 400);
  frameRate(1);
}

void draw() {
  background(255);
  depth++;
  if (depth > 5) {
    depth = 0;
  }

  int border = (int) (width * 0.8);
  int triangleHeight = (int) (border * Math.sin(Math.toRadians(60.0)));

  Point p1 = new Point(width / 2, 10);
  Point p2 = new Point(width / 2 - border / 2, 10 + triangleHeight);
  Point p3 = new Point(width / 2 + border / 2, 10 + triangleHeight);

  drawKochCurve(depth, p1, p2);
  drawKochCurve(depth, p2, p3);
  drawKochCurve(depth, p3, p1);
}

void drawKochCurve(int count, Point p1, Point p2) {
  stroke(0);

  if (count == 0) {
    line(p1.x, p1.y, p2.x, p2.y);
  } else {
    int deltaX = p2.x - p1.x;
    int deltaY = p2.y - p1.y;

    double cosConst = Math.cos(Math.toRadians(30.0));
    int zx = (int)((p1.x + p2.x)/2 + cosConst * (p1.y - p2.y)/3.0);
    int zy = (int)((p1.y + p2.y)/2 + cosConst * (p2.x - p1.x)/3.0);

    Point x = new Point(p1.x + deltaX / 3, p1.y + deltaY / 3);
    Point y = new Point(p1.x + deltaX * 2 / 3, p1.y + deltaY * 2 / 3);
    Point z = new Point(zx, zy);

    drawKochCurve(count - 1, p1, x);
    drawKochCurve(count - 1, x, z);
    drawKochCurve(count - 1, z, y);
    drawKochCurve(count - 1, y, p2);
  }
}

class Point {
  int x;
  int y;

  Point(int x, int y){
    this.x = x;
    this.y = y;
  } 
}

The Nature of Code

ここまでいかがでしたでしょうか。
Processingというものに少しでも興味を持ってもらえたら幸いです。
最後に「The Nature of Code」について紹介させてください。
「The Nature of Code」は物理や数学の法則・公式といった自然界のルールをProcessingを使って記述する方法について書かれた書籍です。
今回紹介したフラクタル図形についても詳しく書かれているので、興味のあるかたはご一読ください。

https://www.amazon.co.jp/Nature-Code-Processingではじめる自然現象のシミュレーション-ダニエル・シフマン/dp/4862462456

英語版であれば、下記のサイトから無料で閲覧することができます。

https://natureofcode.com

それでは皆様、良いクリスマスをお迎えください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした