ProcessingとCraftROBOで、クリスマスカードを作成する

12月 24th, 2011

Processing Advent Calendar 2011(24日目)

ProcessingとCraftROBOで、クリスマスカードを作成する

今回は、Processingでデザインした内容を、CraftROBOに送り、紙を切りぬきます。
本日はクリスマスイブですので、Processingでクリスマスツリーの形を作り、その情報をCraftROBOに送ることで、紙を切ることにしました。

カッティングマシンCraftROBOは、カッターが付いているプリンターです。
通常のプリンターは、インクヘッドが付いており、紙にインクを吹き付けて画像を出力しますが、CraftROBOは、インクヘッドの替わりにカッターがついているため、図形を切り出すことができるのです。

概説

CraftROBOは単純な命令コマンドを送ることで、制御することができます。
そこで、Processingでline()などで線を引く時に、CraftROBOには紙を切る命令コマンドを送れば、Processingの実行画面で出力結果を確認し、そしてCraftROBOで紙を切ることができます。

※なお、若干非公式な操作を行うため、CraftROBOが故障などしても、p5infoは一切の責任を負いません。予めご了承ください。

CraftROBOの準備

まずはCraftROBO CC330-20を用意します。ヨドバシカメラやAmazonなどで購入が可能です。お値段は25000円程度になります。
購入後、PCからCraftROBOを使用できるように、付属のCDなどを使ってセットアップします。(この辺のセットアップ詳細は割愛しますね)

通常のCraftROBOセットアップの他に「Cutting Master2」もインストールしておいてください。

P5CraftRoboの利用

P5CraftRobo.pdeをダウンロード、もしくはコピーします。そしてProcessingを起動し、P5CraftRoboを取り込んでください。

P5CraftRobo.pde

このP5CraftRoboは、Processingの描画命令とCraftROBOのコマンド出力の両方を実行できるクラスになります。
※開発中のため不具合などがあるかもしれません。

P5CraftRoboの仕様

P5CraftRoboにはthisを与えてインスタンス生成を行ってください。
P5CraftRobo.createImage()で画像ファイルを、P5CraftRobo.createPlt()で命令コマンドファイルをそれぞれスケッチのあるフォルダに出力します。 画面サイズはP5CraftRobo.widthとP5CraftRobo.heightを使うと、CraftROBOでカットできる領域におさめることができます。

P5CraftROBOをnewで作成した後は、P5CraftRoboが持つProcessing互換の描画命令を呼び出すことで、P5CraftRobo.createPlt()実行時に、命令コマンドファイルを出力することができます。
現在実装されている互換描画命令は下記のとおりです。

  • line()
  • rect()
  • ellipse()
  • arc()
  • beginShape()
  • vertex()
  • endShape()
  • 例えば下記のようにコーディングします。

    P5CraftRobo p5cr;
     
    void setup() {
      p5cr = new P5CraftRobo(this);
      size(P5CraftRobo.width, P5CraftRobo.height);
     
      //  線を切る
      for (int x = 50; x < width - 50; x += 10) {
        p5cr.line(x, 50, x, height - 50);
      }
     
      p5cr.createImage();
      p5cr.createPlt();
    }

    すると、次の様な画像となります。

    pltファイルを使ってCraftROBOで紙を切る

    CraftROBO付属の「Cutting Master 2 for CraftROBO」を起動します。そして「ファイル」→「ジョブの追加」、もしくは作成した.pltファイルをドラッグアンドドロップし、ジョブに追加します。
    その後、CraftROBOに紙をセットしたら、先ほど追加したジョブをクリックし、「送信」をクリックすることで、CraftROBOが動きだします。

    あとは、カットが完了するのを待つだけです。

    先ほどの、複数の縦線を切るコードで作ったpltファイルをCraftROBOに送って紙を切った後、円筒形にまとめたところ、このようなものができました。

    クリスマスツリーを切る

    クリスマスツリーは下記のプログラムで作成しています。

    float halfHeight;  //  画面の縦幅の半分
     
    final int STAR_OUTER_RADIUS = 80;        //  星の中心から外側までの距離
    final int STAR_INNER_RADIUS = 40;        //  星の中心から内側までの距離
    final int STAR_REMAIN_OFFSET = 3;        //  星を完全に切らない場合の残す量(角度)
    final int STAR_CENTER_POSITION_X = 100;  //  星の中心の位置
     
    final int TREE_FIRST_POSITION_X = 200;   //  もみの木の最初の線の地位
    final int TREE_FIRST_LINE_LENGTH = 100;  //  もみの木の最初の線の長さ
    final int TREE_INTERVAL = 40;            //  もみの木の線の間隔
    final float TREE_LENGTH_RATIO = 1.2;     //  もみの木の線の増加割合
     
    final int TRUNK_FIRST_POSITION_X = 480;  //  幹の最初の線の位置
    final int TRUNK_LENGTH = 180;            //  幹の線の長さ
    final int TRUNK_INTERVAL = 100;          //  幹の線の間隔
     
    P5CraftRobo p5cr;
     
    void setup() {
      p5cr = new P5CraftRobo(this);
      size(P5CraftRobo.width, P5CraftRobo.height);
      halfHeight = height / 2;
     
      //  星
      int plotCounter = 0;         //  描画している星の頂点番号(凹み部分も頂点としてカウント)
      int[] remainIndex = {2, 8};  //  完全に切断しない頂点番号
      boolean outerFlag = true;    //  line()について、星の外側が基点になっていることを表すフラグ
     
      for(int i = 180; i < 540; i += 36){
        int baseRadius = outerFlag ? STAR_OUTER_RADIUS: STAR_INNER_RADIUS;  //  基点の中央からの距離
        int destRadius = outerFlag ? STAR_INNER_RADIUS: STAR_OUTER_RADIUS;  //  目的点の中央からの距離
     
        //  完全に切断しない場合には、plotOffsetを設定する。
        int baseOffset = isInArray(remainIndex, plotCounter) ? STAR_REMAIN_OFFSET : 0;
        int destOffset =  isInArray(remainIndex, i + plotCounter) ? STAR_REMAIN_OFFSET : 0;
     
        //  線を描画
        float baseX = cos(radians(i + baseOffset)) * baseRadius + STAR_CENTER_POSITION_X;
        float baseY = sin(radians(i + baseOffset)) * baseRadius + halfHeight;
        float destX = cos(radians(i + 36 - destOffset)) * destRadius + STAR_CENTER_POSITION_X;
        float destY = sin(radians(i + 36 - destOffset)) * destRadius + halfHeight;
        p5cr.line(baseX, baseY, destX, destY);
     
        outerFlag = !outerFlag;
        plotCounter++;
      }
     
      //  もみの木
      float halfLength = TREE_FIRST_LINE_LENGTH / 2;
      float halfInterval = TREE_INTERVAL / 2;
      for(int i = 0; i < 7; i++){
        p5cr.line(TREE_FIRST_POSITION_X + i * TREE_INTERVAL, halfHeight - halfLength,
                  TREE_FIRST_POSITION_X + i * TREE_INTERVAL, halfHeight + halfLength);
        p5cr.line(TREE_FIRST_POSITION_X + halfInterval + i * TREE_INTERVAL, halfHeight - halfLength,
                  TREE_FIRST_POSITION_X + halfInterval + i * TREE_INTERVAL, halfHeight + halfLength);
        halfLength *= TREE_LENGTH_RATIO;
      }
     
      //  幹
      float halfTrunkLength = TRUNK_LENGTH / 2;
      p5cr.line(TRUNK_FIRST_POSITION_X, halfHeight - halfTrunkLength, 
                TRUNK_FIRST_POSITION_X, halfHeight + halfTrunkLength);
      p5cr.line(TRUNK_FIRST_POSITION_X + TRUNK_INTERVAL, halfHeight - halfTrunkLength, 
                TRUNK_FIRST_POSITION_X + TRUNK_INTERVAL, halfHeight + halfTrunkLength);
     
      p5cr.createImage();  //  画像を出力する
      p5cr.createPlt();    //  CraftROBO用ファイルを出力する
    }
     
     
    //  指定配列内に、指定値があるかどうかを返す関数
    boolean isInArray(int[] ar, int target){
      int count = ar.length;
      for(int i = 0; i < count; i++){
        if(ar[i] == target){
          return true;
        }
      }
      return false;
    }

    山折り、谷折りを交互に行うことで、クリスマスツリーの完成です。


    また、 ProcessingAdventCalendarの1日目で作った、ハート形などを、CraftROBOで切ってみました。

    このように、ProcessingとCraftROBOを連携させることで、幾何学模様やたくさんの繰り返しの図形などを簡単に作り出すことができます。
    サンタクロースへのお願い事はもう決まりましたか?
    今年のクリスマスプレゼントはCraftROBOというのはいかがでしょうか?


    なお、P5CraftROBOはライブリなどにすると、便利になりますが、今回は時間の関係で割愛しました。

    Tags: , ,
    Posted in Processing Advent Calendar2011 | No Comments »

    Comments

    Leave a Reply

     Comment Form