2013年3月29日 星期五

[筆記]經堯老師的Quartz Composer 4-5



在這個練習中,透過把Pd產生訊號,並以Open Sound Control的通訊格式,將訊號丟到QC中的[Struct Maker]建立資料封包。並藉由[Iterator]及[Iterator Variables]的複製功能,讀取[Structure Index Member]中的資訊,便於重複繪製相同圖形。

步驟一:在Pd中建立一個名為ball1 及ball2的兩組資料結構,每組各有3個索引值,設定為每顆球體不同的x、y、z隨機亂數座標。
(Pd patch)

步驟二:在QC中建立[OSC Receiver]物件來接收Pd產生的訊息,並且資料形態為「Floats」


步驟三:接收到的資料結構


步驟四:[Marco]內的接線圖。

File Download

[筆記]經堯老師的Quartz Composer 4-4



在這一個練習中,要透過建立資料結構來封裝資訊,除了程式更為簡潔外,物件與物件間的接線也更為單純,未來更能因此設計來產生大量圖形。

步驟一:kineme官方網站下載DataToolsGLTools兩個套件,DataTools是用來建立資料結構的;GLTools則是用來產生一些opengl的物件(本範例使用到[GL Line]物件)。

步驟二:把下載下來的檔案解壓縮放置到此路徑下,
/Users/[you]/Library/Graphics/Quartz Composer Patches/

步驟三:[Struct Makers]這物件可以用來封裝訊息,讓多組訊號組在一起,在同時從一出口送出。

(因為我們要控制圓球的位置,所以[Struct Makers]的Number of Inputs 選項為2,一個是x軸,另一個是y軸)

步驟四:透過兩組[LFO]物件產生的訊息,控制圓球的x、y軸位置。


步驟五:兩顆球,所以如下圖所示有2個Members ,並且每個Members 都還有兩個值。

                -------0(X)
(一號球)0--|
                -------1(Y)

                -------0(X)
(二號球)0--|
                -------1(Y)





步驟六:建立一個Marco裡面存放繪製的圖形,並建立[Structure Index Member]把封包的訊息拆解出來,並在[Structure Index Member]物件上按右鍵,選擇Publish Inputs>Structure,讓主場景中的訊息能夠傳遞進Marco內。

步驟七:調整[Structure Index Member]內的index索引值,讓資訊能夠被有效分割傳遞。


File download

2013年3月28日 星期四

[筆記]經堯老師的Quartz Composer 4-3


1.在這個練習裡,我們要製造一個會回彈的球,所以需要用的一個新的函式[feedback]。

步驟一:建立兩個[math]物件

步驟二:在[math]物件上按右鍵Publish Outputs,並命名(我命名為 x_pos及y_pos)


步驟三:這時候[feedback]物件上或多出兩個輸出孔,把他接回[math]物件,並且設定[math]
的參數為:

Operation:*
Operand:0.9

步驟四這時候拖拉圓球,放開滑鼠後,圓球會回彈回中心。
(下圖中[math]物件裡的Operand 值不一樣,x=0.98 y=0.95,因此回彈時會呈現曲線運動)



[筆記]經堯老師的Quartz Composer 4-2

1.[String Truncate],可以控制字串長度。





上圖範例中,當字串為「123 456」時:
  • Maximum Lenght==1以及Length Units==words時,只輸出「1...」。
  • Maximum Lenght==1以及Length Units==Characters時,只輸出「123...」。

2.[Grep]為regular expression正規表示法的物件,功能為用來取代置換字串。

常見的用法:
  • 搜尋字串名稱前加「^」符號,代表只搜尋替換掉行首的名稱。

  • 搜尋字串名稱結尾加「$」符號,代表只搜尋替換掉行尾的名稱。


  • 搜尋字串名稱內為「..」符號,代表搜尋替換掉字串開頭為g、結尾為d的名稱。

更多用法請參閱:


[筆記]經堯老師的Quartz Composer 4-1

1.QC常見的多種互動物件,包含[OSC Receiver]、[Mouse]、[Keyboard]、[MIDI Notes Receiver]、[MIDI Controllers Receiver]、[HID]




  • [OSC Receiver],Open Sound Control 訊號接收器,可以接收來自其它軟體的訊號,例如Pd、Processing 、OpenFrameWork等等。 
Example 4-1:Pd 傳遞訊息到QC

QC 中[OSC Receiver]的Port Number 設置為12000時,Pd傳遞的位址也要設成12000。
  • [Mouse],偵測滑鼠輸入。
  • [Keyboard],鍵盤上的訊號,但「shift」、「enter」等按鈕無法偵測。
  • [MIDI Notes Receiver],接收鋼琴類的midi樂器。


  • [MIDI Controllers Receiver],接收滑桿、旋鈕等midi樂器,例如 nano Kontrol

  • [HID],接在mac上的外接控制,如滑鼠、鍵盤、搖桿等。透過此方式,鍵盤的shift、control等按鍵也能被偵測。

2.[timeline] 物件節點新增方式。


按住option鍵點選,增加一個新的影格。按住control 鍵點選,出現調整曲線控制把。

更多功能如下:

Expose this area to see Timeline help.
Double-Click: Edit a key frame or control point coordinates.
[Option]-Click: Add a new key frame to, or remove clicked key frame from, the selected timeline.
[Option]-[Shift]-Click: Add a new key frame onto the curve, preserving the curve's shape.
[Control]-Click: Collapse clicked control point, or both control points if a key frame is clicked.
[Control]-Drag: Expose control points for clicked key frame, or break and reset linear relationship between control points.
[Shift]-Drag: Constrain control point dragging to multiples of 45 degrees angles.




2013年3月26日 星期二

[教學]Puredata 聲音設計 4

本週新物件:
  • [key]
  • [tabread] [tabwrite]
  • [table]
  • [k_piano]
  • [writesf~]
  • [readsf~]
  • [delread~] & [delwrite~]



Example -1



Example -2
w4-2.pd


Example -3
w4-3.pd


Example -4
w4-4.pd

Example -5


Example -6

w4-6.pd

2013年3月23日 星期六

[對照]蝦爸的p5範例-3



蝦爸在本案例中運用了ArrayList這原生的Java功能,來儲存各式類別。在本案例中,隨著表演的進行,可以任意敲擊鍵盤,製造有趣好玩的視覺物件。

ArrayList功能可以用來索引儲存在其中的物件,所以當自定用來繪製圖形的類別後,可以用ArrayList儲存它,並依需求呼叫出來。

使用方法,在Processing的算圖視窗中按下:
鍵盤數字鍵1,產生房子
鍵盤數字鍵2,產生雲朵
鍵盤數字鍵3,產生路燈

Example Download

[Processing code] ↓

C_house h1;
C_cloud c1;
C_light l1;
C_star s1;

ArrayList hgroup;
ArrayList cgroup;
ArrayList lgroup;
ArrayList sgroup;

void setup() {
  size(800, 300, OPENGL);
  h1=new C_house();
  c1=new C_cloud();
  l1=new C_light();
  s1=new C_star();

  sgroup=new ArrayList();
  for (int i=0;i<200;i++) {
    sgroup.add(new C_star());
  }

  hgroup=new ArrayList();
  hgroup.add(new C_house());

  cgroup=new ArrayList();
  cgroup.add(new C_cloud());

  lgroup=new ArrayList();
  lgroup.add(new C_light());
}

void draw() {

  background(30, 30, 60);
  for (int i=0;i<hgroup.size();i++) {
    ((C_house)hgroup.get(i)).update();
    ((C_house)hgroup.get(i)).graphic();
  }

  for (int i=0;i<cgroup.size();i++) {
    ((C_cloud)cgroup.get(i)).update();
    ((C_cloud)cgroup.get(i)).graphic();
  }

  for (int i=0;i<lgroup.size();i++) {
    ((C_light)lgroup.get(i)).update();
    ((C_light)lgroup.get(i)).graphic();
  }

  for (int i=0;i<sgroup.size();i++) {
    ((C_star)sgroup.get(i)).update();
    ((C_star)sgroup.get(i)).graphic();
  }

  strokeWeight(2);
  stroke(0);
  fill(20, 20, 30);
  rect(0, height-50, width, 50);

  for (int i=0;i<hgroup.size();i++) {
    if (((C_house)hgroup.get(i)).sx<0) {
      hgroup.remove(i);
    }
  }

  for (int i=0;i<cgroup.size();i++) {
    if (((C_cloud)cgroup.get(i)).px[0]<0) {
      cgroup.remove(i);
    }
  }

  for (int i=0;i<lgroup.size();i++) {
    if (((C_light)lgroup.get(i)).px<0) {
      lgroup.remove(i);
    }
  }
}

void keyPressed() {
  if (key=='1') {
    if (hgroup.size()<50) {
      hgroup.add(new C_house());
      for (int i = 0;;)
      {
        if (i >= hgroup.size()-1)
        {
          break;
        }
        if (((C_house)hgroup.get(i)).dis == ((C_house)hgroup.get(hgroup.size()-1)).dis)
        {
          ((C_house)hgroup.get(hgroup.size()-1)).Change_Dis();
          i = 0;
          continue;
        }
        i++;
      }
    }
  }



  else if (key=='2') {
    cgroup.add(new C_cloud());
  }
  else if (key=='3') {
    lgroup.add(new C_light());
  }
  else {
  }
}

class C_star {
  float px;
  float py;
  float c;
  float size;
  float count;
  int flash;

  C_star() {
    px=random(-1*width, width*1.5);
    py=random(-1*height, height);
    size=random(1, 5);
    flash=(int)random(1, 30);
  }
  void graphic() {
    pushMatrix();
    translate(0, 0, -200);
    fill(255, c);
    noStroke();
    ellipse(px, py, size, size);
    popMatrix();
  }

  void update() {

    count++;
    count=count%flash;
    if (count==0) {
      c=random(0, 255);
    }
  }
}

class C_light {
  float px;
  float c;
  boolean dir;
  float size;
  C_light() {
    dir=random(0, 2)>1;
    px=width;
    size=random(100, 150)/100;
  }

  void graphic() {
    pushMatrix();

    stroke(0);
    fill(255);
    translate(px, height-90, -3);

    if (dir==true) {
      rotateY(radians(180));
    }
    else {
      rotateY(radians(0));
    }
    scale(size);
    rect(0, 0, 3, 40);
    noStroke();
    fill(255, 255, 0, c);
    triangle(-15, -15, -30, 40, 0, 40);
    stroke(0);
    rotateZ(radians(-45));
    fill(255);
    rect(0, 0-20, 3, 20);
    popMatrix();
  }

  void update() {
    px--;
    c=random(50, 250);
  }
}

class C_house {
  float sx;
  float sy;
  float w;
  float h;
  int col;
  int row;
  int winnum;
  float win_w;
  float win_h;
  float c;
  float temp_c;
  float dis;
  C_house() {
    w=random(30, 100);
    h=random(50, 200);
    sx=width;
    sy=height-50-h;
    winnum=((int)random(1, 5))*2;
    win_w=w/4;
    win_h=w/4;
    c=255;
    temp_c=random(50, 100);
    dis=(int)(random(1, 50))*(-6);
    //dis = 0;
  }
  void update() {
    sx--;
    if (c>temp_c) {
      c--;
    }
  }

  void graphic() {

    pushMatrix();
    translate(0, -dis*0.4, dis);
    stroke(50);
    strokeWeight(2);
    fill(c, 255-c,255-c);
    rect(sx, sy, w, h);
    //起始點x,起始點y ,起始點x+寬,起始點y+高
    stroke(0);
    for (int i=0;i<winnum;i++) {
      strokeWeight(1);
      fill(c-50, 255);
      col=floor(i/2);
      row=i%2;
      rect(
      sx+row*(win_w*2)+win_w/2, 
      sy+col*(win_h*1.5)+win_h/2, 
      win_w, 
      win_h);
    }
    popMatrix();
  }

  void Change_Dis()
  {
    dis=(int)(random(1, 50))*(-6);
  }
  void Change_Dis(float Enter_Dis)
  {
    dis = Enter_Dis;
  }
}

class C_cloud {
  float [] px;
  float [] py;
  float [] sx;
  float [] sy;
  int num;
  float dis;
  float c;

  C_cloud() {
    num=(int)random(3, 15);
    px=new float[num];
    py=new float[num];
    sx=new float[num];
    sy=new float[num];
    dis=(random(1, 50))*(-1);
    c=255+(dis*2);
    for (int i=0;i<num;i++) {

      if (i<=0) {
        px[0]=width;
        py[0]=random(10, 60);
      }
      else {
        px[i]=px[i-1]+random(-20, 20);
        py[i]=py[i-1]+random(-5, 5);
      }
      sx[i]=random(10, 40);
      sy[i]=random(10, 20);
    }
  }

  void graphic() {
    pushMatrix();
    translate(0, 0, dis);
    noStroke();
    fill(c);
    for (int i=0;i<num;i++) {
      ellipse(px[i], py[i], sx[i], sy[i]);
    }
    popMatrix();
  }

  void update() {
    for (int i=0;i<num;i++) {
      px[i]=px[i]-1;
    }
  }
}


[Pd code] ↓



同場加映:以Pd撰寫的相同程式,並加上與聲響互動的功能,當發出聲響時,會有對應的視覺造型產生。

Pd Example

2013年3月21日 星期四

[筆記]經堯老師的Quartz Composer 3-4


主程式下載

自定物件下載
(拖拉時會顯示出藍色背景)
1.我們可以透過自定物件,來完成程式的封裝,並且之後只要透過Patch Library,便可呼叫出自定物件,在本範例中[k_debug]物件,是一個能夠在Viewer視窗顯示出訊息,並且可以透過滑鼠拖拉,更改位置(如上圖)

2.請把自定物件[k_debug]放到路徑 Machintosh〉User〉User name〉Library〉Graphics〉Quartz Composer Patches 資料夾中。



3.透過Patch Library 即可呼叫出自定物件

(在Filter 輸入k_debug)
4.主程式

(把[LFO]物間的訊息傳遞到[k_debug]物件內)
5.只要框選程式,並且點選畫布icon bar上的Add to Library即可建立自定物件
([k_debug] patch 圖)

6.未來要編輯自定物件可以透過在Patch Librart按右鍵,選擇Edit即可。



[筆記]經堯老師的Quartz Composer 3-3


(跟隨滑鼠移動的資訊列)
1.如上圖所示,在這一個範例中,我們要試著完成一個簡單的互動案例,在Viewer中當按下滑鼠左鍵拖拉時,資訊列會跟著滑鼠移動,並且座標位置會顯示在資訊列上。為了要完成此範例,必須用到一個新的物件[interaction](造型為紫色圓角,並且有個互動的輸出孔),該物件能夠傳遞滑鼠在Viewer上的行為。
(輸出孔必須跟互動物件連線,才能產生作用)
2.第一步,建立一個自製Marco 物件[mouse point]以及[Interaction]物件。

(主場景圖)

3.為了把[mouse point] 的資訊跟[interaction]物間作互動,必須透過Insert Input Splitter把[mouse point]內的[Billboard]物件的X Position、Y Position、Interaction 分裂出,再把這三個資訊跟[sphere]物件共享。

(在[Billboard]物件上按右鍵,便會彈跳出選單)


(並且透過Publish Inputs,將X Position、Y Position、Interaction 資訊傳出。)

([mouse point],內部接線圖)


4.細部參數

([Images With String] Parameters)
([Images With String] Settings)
([String Printer] Settings )
([String Subrange] Parameters)