Processingでアートを作ってみた

本投稿は TECOTEC Advent Calendar 2022 21日目の記事です。   

 

こんにちは、決済認証システム事業部の酒井です。

今回は、Processingを使ってみた、という内容で執筆させていただきます。

自分はよくコードを記述する際に、ここはこの言語で書くとどんな感じになるだろうか、とよく考えているのですが、新しい言語を習得することやそもそもプログラミングを始めるといったことには、難しいことが多いかと思います。

個人的に、プログラミング入門としてTry&Errorを繰り返して感覚を掴みやすい言語だなと思い、初めに触ってみた言語になります。長らく触っていなかったため、個人的な復習も兼ねて記事を書かせていただきます。

Processingとは

まず、Processingとはなんぞや、というところから書かせていただこうと思います。

Wikiによると、

電子アートとビジュアルデザインのためのプログラミング言語であり、統合開発環境(IDE)である。アーティストによるコンテンツ制作作業のために、詳細な設定を行う関数を排除している。 視覚的なフィードバックが即座に得られるため、初心者がプログラミングを学習するのに適しており、電子スケッチブックの基盤としても利用できる。Java を単純化し、グラフィック機能に特化した言語といえる。

ja.wikipedia.org

とあります。基本的な記述方法はJavaと同様ですが、Eclipseなど他のIDEと比べて導入の部分でつまづくことが少ない印象です。また、「視覚的なフィードバックを即座に得られる」とありますが、これはグラフや図形をアニメーションで即座に実行できるということです。他の言語では、専用のアプリケーションやプラグインをインストールする必要があったりしますが、Processingではそれが一切必要なく、コードを書いて実行ボタンを押すだけなので、視覚的な確認がすぐにできます。まとめると、Processingのメリットとしては

  1. 開発環境を構築しやすいため、コーディングまでの時間が短くすむ
  2. アニメーションによる実行で、視覚的な確認がすぐにできる

大きくこの2点だと個人的には思います。

とりあえず動かしてみる

前段で記載したように、自分の環境に合ったものをインストールするだけになるので、詳細は省きます。

processing.org

自分でも久しく触っていない言語になるので、まずは簡単なものから実行していきたいと思います。

まずはこちら。構文は"line(x1,x2,y1,y2)"で「x1,y1」「y1,y2」が線の端のそれぞれの座標になります。

次はこれ、

描画用ウィンドウのサイズを変更し、その中に座標と大きさを指定して円(楕円)を描きます。

sizeはそのまま横と縦の長さを指定してウィンドウのサイズを変更しています。

円の構文は"ellipse(x,y,width,height)"で、「x,y」が中心となる位置の座標、「width,height」がそれぞれ円の縦と横の長さになります、今回は値が同値なため円となりますが値を変更すれば楕円となります。

とまあこんな感じで今回は以下のサイトを参考に描画とアニメーションを復習していきました。ここの値を変更したらこうなる、こうしたい時はどうやったらいいだろうと、あまりエラーに引っかかることなくスムーズに進めることができました。自分はもうインストール済だったのですが、ここまでで大体1時間かかっていません笑

Processing基礎最速入門 - catch.jp-wiki

本格的な作品の制作に入っていく

Processingでできることはたくさんありますが、今回は「生成的な形」というのをテーマにして作っていこうと思います。Processingでは、「幾何学的模様」というのを、前段で紹介した円や線、四角などの描画を用いて表現することができます。

1つの方法に過ぎませんが、具体的には「ある模様を」「どのようなデザインで」「どのように生成するか」という3つを決めることで、簡単に「生成的な形」というのを作ることができます。

今回は「線を」「それっぽい色で」「ランダムに」生成して作品を作っていきます。

Welcome to Processing! / Processing.org

yoppa org – 生成的な形をつくる – Processing オブジェクト指向プログラミング入門

まずは第一段階

色については深く考えず、PVectorとrandomを使ってある程度の方向を保ったままランダムな方向に円を描いていきます。この時、線の幅を徐々に小さくしていくことで木のような形を生成することができます。また、マウスクリックで描画を何度でも行うことができます。

ソースはこんな感じ

//描画用のクラス
class pathfinder {
  PVector lastLocation;
  PVector location;
  PVector velocity;
  float diameter;
  boolean isFinished;
  pathfinder() {
    location = new PVector(width/2, height);
    lastLocation = new PVector(location.x, location.y);
    velocity = new PVector(0, -10);
    diameter = 19.88400223199278;
    isFinished = false;
  }
  pathfinder(pathfinder parent) {
    location = parent.location.get();
    lastLocation = parent.lastLocation.get();
    velocity = parent.velocity.get();
    diameter = parent.diameter * 0.62;
    isFinished = parent.isFinished;
    parent.diameter = diameter;
  }
  void update() {
    
    if(location.x > -10 & location.x < width + 10 & location.y > -10 & location.y < height + 10) {
      lastLocation.set(location.x, location.y);
      if (diameter > 0.2) {
        count ++;
        PVector bump = new PVector(random(-1, 1), random(-1, 1));
        velocity.normalize();
        bump.mult(0.2);
        velocity.mult(0.8);
        velocity.add(bump);
        velocity.mult(random(5, 10));
        location.add(velocity);
        if (random(0, 1) < 0.12) { // control length
          paths = (pathfinder[]) append(paths, new pathfinder(this));
        }
      } else {
        if(!isFinished) {
          isFinished = true;
          noStroke();
          fill(0, 0, 0, 0);
          ellipse(location.x, location.y, 10, 10);
          stroke(0, 0, 0);
        }
      }
    }
  }
}

pathfinder[] paths;
int num;
static int count;

//初期設定
void setup() {
  size(1100, 800);
  background(250);
  ellipseMode(CENTER);
  stroke(0, 0, 0);
  smooth();
  num = 2;
  count = 0;
  paths = new pathfinder[num];
  for(int i = 0; i < num; i++) paths[i] = new pathfinder();
}

//描画用関数
void draw() {
  for (int i = 0; i < paths.length; i++) {
    PVector loc = paths[i].location;
    PVector lastLoc = paths[i].lastLocation;
    strokeWeight(paths[i].diameter);
    line(lastLoc.x, lastLoc.y, loc.x, loc.y);
    paths[i].update();
  }
}

//マウスクリックでリセット
void mousePressed() {
  background(250);
  count = 0;
  paths = new pathfinder[num];
  for(int i = 0; i < num; i++) paths[i] = new pathfinder();
}


それっぽい色に変えて、線が途切れたタイミングで円を描いてあげるだけでそれっぽい感じにすることができました!


感想

約3年ぶりくらいにProcessingを触ってみました。具体的な内容にはあまり触れませんでしたが、今回は「プログラミング入門言語として」と「コードが書ければデザインもできる」という2点を主に紹介したいと思い執筆しました。ランダム関数を使っているため、全く同じ画像を生成するのはほぼ不可能と言ってもいいと思います。今回のコードをコピペして、デザインを変更するだけで全く違うものを作ることも可能です。個人的にはNFTなどとも絡めても面白いかなと思っています。最後まで読んでいただき、ありがとうございました。

www.tecotec.co.jp