見出し画像

ChatGPTを使って自作ペンプロッタでジェネラティブアートを作る

自作したペンプロッタでジェネラティブアートをやりたいと思っていたのですが、プログラミングについての知識が少なすぎて行き詰まっていたので、ChatGPTを使用してみることにしました。
ChatGPTは有料版のGPT-4を使用しました。元にしたプログラムはこの記事のものです。

まずは、円を書くプログラムを作りたかったのですが、GPTにペンプロッタの仕様を伝えるのに一個ずつ入力するのが面倒だったので、
「以下のコードを参考にして、Arduinoでペンプロッタを制御し、円を描くプログラムを作成してください。」
として、その下に元のプログラムを貼り付けました。
雑なやり方ですが、これだけでピン番号もXY軸はステッピングモータで、ペンの上げ下げはサーボモータを使用していることもきちんと理解してくれました。優秀なやつです。

#include <Servo.h>
#include <AccelStepper.h>

// Servo
const int penZUp = 30;
const int penZDown = 90;
const int penServoPin = 6;
int LineDelay = 0.1;
Servo penServo;

// StepMotor
AccelStepper stepperX(1, 3, 2);
AccelStepper stepperY(1, 9, 8);

// Canvas size
int posX = 1000;
int posY = 1000;

// Circle parameters
float radius = 200; // Set the desired circle radius
float angle = 0;
const float angleStep = 1;

void setup() {
  stepperX.setMaxSpeed(3000); // Increase the maximum speed
  stepperX.setAcceleration(2000); // Increase the acceleration
  stepperY.setMaxSpeed(3000); // Increase the maximum speed
  stepperY.setAcceleration(2000); // Increase the acceleration

  penServo.attach(penServoPin);
  penServo.write(penZUp);
  delay(100);
}

void loop() {
  drawCircle();
}

// Raises pen
void penUp() {
  penServo.write(penZUp);
  delay(LineDelay);
}

// Lowers pen
void penDown() {
  penServo.write(penZDown);
  delay(LineDelay);
}

void drawCircle() {
  float centerX = posX / 2;
  float centerY = posY / 2;

  penUp();
  stepperX.moveTo(centerX + radius);
  stepperY.moveTo(centerY);
  stepperX.runToPosition();
  stepperY.runToPosition();

  penDown();

  for (angle = 0; angle <= 360; angle += angleStep) {
    float newX = centerX + radius * cos(radians(angle));
    float newY = centerY + radius * sin(radians(angle));
    stepperX.moveTo(newX);
    stepperY.moveTo(newY);

    stepperX.runToPosition();
    stepperY.runToPosition();
  }

  penUp();
  delay(10000); // Wait for 10 seconds before starting the next circle
}


これで円を書くことができたので、このコードを改変していくことにしました。パラメータを手入力で修正しながら、以下のようにプロンプトを書いていきました。
「円の半径を小さくしながら、3回繰り返して書いてください」
「円を5回書くたびに、円の中心を描画範囲内でランダムに選びなおしてください。」
「描画範囲がはみ出してもいいので、中心がもっとばらけるようにして、半径も5回ごとにランダムで100から400の間で変わるようにして」
「直径が描画範囲内ちょうどにおさまるようにしてください。」など

出来上がった結果はこんな感じです。

描画中の様子

出力した結果はこれです。円が切れていたり、少し歪んでいたりと完璧ではないですが、ランダムな図形をペンプロッタに描かせることができました。

出力されたGenerative Art

本当は他にも色々試したのですが、「描画範囲いっぱいにランダムな複雑な模様を描いて」とか、「アルファベットのAを描いて」とかのプロンプトでは途中で書くのをやめたり、デタラメだったりで上手くいきませんでした。抽象的な命令を読み解いて具体的な形にするのはまだ難しいのかもしれません。プロンプト次第かもしれませんが。
自分がクリエイティブコーディングをやる時みたいに、まず単純な物を作って、それとfor()やramdom()を組み合わせて徐々に条件を増やしていくやり方なら割とうまくいきました。

ChatGPTの活用の仕方についてはあまり分かっていなかったのですが、今回実際使ってみたことで少しだけ理解できた気がします。人間側で企画や仕様を決めてコーディングはAIに任せるようなやり方が進んでいくのかなとも感じました。

楽しかったので、また何か作ってみたいと思います。