グラフィックス


  1. グラフィックス

     Processing では特に準備をしないでも、2次元や2次元の「グラフィックス」(図形描画)機能を利用できます。文字の描画については文字列の項を参照してください。ここでは2次元のグラフィックについてのみ紹介し、3次元(3D)グラフィックス については別の本で紹介する予定です。
  2. 座標系と基本図形

     Processing では、「グラフィックス」を編集画面とは別のディスプレイウインドウに表示します。ディスプレイウインドウの大きさは size(幅、高さ); で指定し、その位置はウインドウの左上を原点とし、右側をx方向、下側をy方向とする座標で表します。基本図形を描画するメソッドの x,y をこの座標を指定します。
     point(x,y);            //点
      line(x1,y1,x2,y2);     //直線
      rect(x1,y1,x2,y2);    //矩形
      triangle(x1,y1,x2,y2,x3,y3);  //三角
     quad(x1,y1,x2,y2,x3,y3x4,y4); //四角
      ellipse(x1,y1,w,h);   //楕円 w,h は幅と高さ
      arc(x1,y1,w,h,a1,a2); //弧 a1,a2 は開始と終了の角度
     複数の点から構成される折れ線は  beginShape(); と endShape(CLOSE); の間に通過点を vertex(x,y) で指定します。endShape() で CLOSE を指定すると、多角形を閉じます。beginShape() で モード を指定すると、基本図形で面を生成できます。詳しくは Helpメニューの Reference を参照してください
      beginShape();
      vertex(20, 20);
      vertex(40, 20);
      vertex(40, 40);
      vertex(60, 40);
      vertex(60, 60);
      vertex(20, 60);
      endShape(CLOSE);
    実行結果


  3. 色と透明度の表現

     図形には輪郭と内部の色を指定できます。ほとんどの色は、赤、緑、青 (RGB)の3色の強さで表現できます。「RGB」では実際の色との関連がつけにくいため、「HSB」 表色系を利用する場合があります。H(色)、S(彩度)、B(明るさ)の関連は、 Tools メニューも color Selector で見ることができます。Hが中央右の色の棒の高さ、Sが左の彩色された四角の水平、Bが垂直方向の値になります。

     使用する表色系と数字の範囲 colorModeで設定します。値の範囲に小数を指定することもできます。
      colorMode(RGB, 100); //0から100までで RGB の値を指定
      colorMode(RGB, 1.0); //0から1.0までの小数で指定
     colorMode(HSB, 100); //0から100までで HSB の値を指定
      colorMode(HSB, 360, 100, 100); //Hを0から360で、S,Bを 0..100 で表現
     色の値は、colormode にしたがって color 型に変数に設定することができます。
      color c1 = color(204, 153, 0);
      color c2 = #FFCC00;  //16進表現
     実際に描画するときは、背景の色を加味することができます。背景の色を b、描画する色を c としたとき  実際の色を A*c + (1-A)*b (Aの割合で c 、1-A の割合で b)の色で描画します。A=0 のときは背景の色、A=1 のとき図形の色となりますから、A の値が小さいと「透明度」が高くなります。1-A を不透明度(α値、opacity)と呼ぶことがあります。
     このα値を含めて、colorを設定するのに 0xCC006699 のような16進数で表現することもできます。先頭の 0x が16進数字を意味します。色の値は、輪郭線(stroke)、または、塗りつぶし(fill)で設定します。
      //輪郭線
      stroke(gray); //グレイ
    stroke(gray, alpha); //α付
    stroke(value1, value2, value3);//カラーの値
    stroke(value1, value2, value3, alpha);//カラーの値 とα
    stroke(color);//color型で指定
    stroke(color, alpha);//
    stroke(hex);//16進数で指定
    stroke(hex, alpha);//  //塗る色、文字色、  fill(color);//color型で指定
    fill(color, alpha);//  他の形式もstrokeとどうよう
     A(alpha 値)を指定して、二つの目の矩形を描きます。
      int A=150;
      fill(100,0,0);
      rect(0,0,50,50);
      fill(0,200,100,150);
      rect(30,30,50,50);
    実行結果
      A=150               A=50


     二つの色を与えて、指定された度合の色を返すメソッドに lerpColor() があります。lerp は「補間」の意味です。この補間は RGB ではなく、HSBモードのほうがきれいな変化を見ることができます。RGB モードで反対色を補間すると、途中色のない灰色になってしまいます。
    //色の変化
    //lerp(色1、色2、度合); 色1から色2に度合で変化
    size(120,50);
    colorMode(HSB,1.0);
    color from = color(0.0, 1.0, 1.0);
    color to = color(0.3, 0.8, 0.8);
    noStroke();
    for(int i=0;i<50;i++){
      color inter = lerpColor(from, to, i*1.0/50);
      fill(inter);
      rect(10+2*i,20,2,20);
    }
    実行画面


  4. 輪郭線のスタイル

     「輪郭線の太さ」は strokeWeight(太さ) で設定できます。ある程度太い線の場合、折れ曲がり点の形状を strokeJoin(種類)、端点の形状を strokeCap(種類)で指定します。また、smooth() は円や曲線を滑らかに描画します。
      noFill();  //塗りつびしなし
      smooth();  //円や曲線を滑らかに描く
      strokeWeight(10.0); //線の太さ
      strokeJoin(ROUND);  //折れ曲がり点を丸く
      strokeCap(ROUND);   //端点を丸く
      beginShape();
      vertex(35, 20);
      vertex(65, 50);
      vertex(35, 80);
      endShape(); 
     実行結果


  5. 花模様

     グラフィックと数学メソッドを利用して、花模様を描画してみます。基本は角度 atに応じて、長さ r を周期的に変化させています。花の輪郭の座標は、角度 at に対する長さrで定まる極座標です。nNumは花びらの枚数を定めます。at が 0..2π 変化すると、ua の変化は nNum倍になります。
        ua=nNum*at;
        r=abs(ca*sin(ua)+cb*sin(3*ua))+5;//長さ
        xn=xc+(int)(r*cos(at));//x,y座標に戻す
        yn=yc+(int)(r*sin(at));
     r は sin(ua) の基本周期に対し、その3倍の周期でも変化させています。cb はその度合いを定めます。nNum と cb はキーボードの 'n/N' と 'b/B' で増減しています。詳しくは メソッドの項のイベント処理を参照してください。
    //花模様
    int ca=70, cb=10;
    int nNum=5;
    int xc, yc;
    int xp, yp;
    
    void setup() {
    
      double t, at, r, ua;
      xp=xc;
      yp=yc;
      frameRate(10);
      size(200,200);
      xc=width/2;
      yc=height/2;
    }
    
    public void draw() {
    
      int xn, yn, it;
      float t,at,ua,r;
      background(200);
      for (it=0;it<100;it++) {
        t=it/100.0;
        at=2*3.1415*t;
        ua=nNum*at;
        r=abs(ca*sin(ua)+cb*sin(3*ua))+5;//長さ
        xn=xc+(int)(r*cos(at));//x,y座標に戻す
        yn=yc+(int)(r*sin(at));
        line(xp, yp, xn, yn);
        xp=xn;
        yp=yn;
        String st="n="+nNum+" ca="+ca+" cb="+cb;
        text(st,10,190);
      }
    }
    
    void keyPressed(){
      if(key=='n') nNum++;
      if(key=='N') nNum--;
      if(key=='b') cb++;
      if(key=='B') cb--; 
    }
     実行画面 n=2,cb=17


  6. 座標系の変換

     標準では座標の原点は、ウインドウの左上にあります。これを、ウインドウの中央に移動するには、translate(width/2,height/2); というメソッドを利用します。移動後の座標系の座標をp1とすると、元の座標系の座標 p0 は
     p0 = T * p1;
    で計算できます。T は行列(matrix)と呼ばれます。移動後さらに座標系を 角度 a だけ回転させます(rotate(角度))。この移動と回転後の座標は 回転の行列を R すると
     p0' = R * T * p1
    と計算できます。 Q = R * T を先に計算しておきますと、移動・回転後の別の座標 P2 の元の座標系の座標は Q*p2 で計算できます。また、この行列 Q を保存(pushMatrix)しておけば、必要な時に行列を取り出すことで(popMatrix)座標系をもとに戻すことができます。
    //rotate and translate
    size(220, 220);
    colorMode(HSB, 1.0);
    noStroke();
    translate(width/2, height /2);//原点を中央に移動
    int num=12;//棒と円の個数
    int r=360/num;
    fill(0.3, 1.0, 0.0);
    rect(-4, -4, 8, 8);//原点に黒い正方形を描画
    
    for (int j=1;j<=num ;j++) {
      pushMatrix();  //変換行列保存
      rotate(radians(r*j));  //座標軸の回転
      fill(0.3, 1.0, 1.0);
      rect(8, -2, 80, 4);//棒を描画
      translate(80, 0);//棒の先に移動
      //5段階の円を描く
      for (int i=1;i<=5;i++) {
        fill(0.3, 1.0, 0.1+i*0.15);//塗りつぶす色を変更
        int sz=50-i*8;//大きさを変更
        ellipse(0, 0, sz, sz);
      }
      popMatrix(); //変換行列を戻す
    }
    実行画面

  7. 画像ファイルの利用

     jpeg、 ping、gif、tiff などの画像ファイルを読みとり、大きさを指定してディスプレイウインドウに表示することができます。まず、PImage 型の変数 gimage に loadImage() で指定した画像ファイルを読み込みます。この gimage を image(位置,大きさ) でウインドウに表示します。元の画像のサイズは、gimage.width や gimage.height で取得できます。
      PImage gimage=loadImage("friend.gif");
      image(gimage,10,10,50,50);//サイズ指定
      image(gimage,30,80,gimage.width,gimage.height);//原寸のサイズで表示


  8. まとめ

     Processingでは標準でグラフィックスの機能が組み込まれているため、プログラムに慣れていない人でも、グラフィックスを始めることができます。draw() の中で グラフィック処理を行うことでアニメーションも容易に作成できます。また、座標変換の機能は 3Dグラフィックスの基礎となります。