processing1.5 Pickingライブラリの穴 ~noFill()は使わないほうがいい?~
Post date: Jul 13, 2013 2:24:38 AM
先に結論をいうと、picker使う時はnoFill()使わないほうが良さそうってことである。
発端は、作っているあるプログラムでpickerライブラリがgetしても-1しか返さない(割り当てが無効になっている)というバグにあたった事による。pickingライブラリは線line(というかstroke系は全部ダメだった気がする)を取れなかったりして前につらい目を見たが、問題はそこではなさそう。
そこで、こんなプログラムを組んでみた。
import picking.*;
Picker picker;
void setup(){
size(640,480);
picker=new Picker(this);
}
void draw(){
background(0);
picker.start(1);
fill(255,0,0);
rect(100,100,100,100);
picker.start(2);
fill(0,255,0);
rect();
picker.start(3);
Rect rect=new Rect();
rect.draw();
picker.start(4);
Rect2 rect2[]={new Rect2(300,300),new Rect2(350,300),new Rect2(300,350),new Rect2(350,350)};
for(Rect2 tmp:rect2){
fill(255,255,0);
tmp.draw();
}
picker.start(5);
ArrayList<Rect2> rect3=new ArrayList<Rect2>();
rect3.add(new Rect2(500,100));
rect3.add(new Rect2(550,100));
rect3.add(new Rect2(500,150));
rect3.add(new Rect2(550,150));
for(int i=0,n=rect3.size();i<n;i++){
fill(255,0,255);
rect3.get(i).draw();
}
picker.stop();
fill(255);
text(picker.get(mouseX,mouseY),10,10);
}
void rect(){
rect(100,300,100,100);
}
class Rect{
void draw(){
fill(0,0,255);
rect(300,100,100,100);
}
}
class Rect2{
int x,y;
Rect2(int x,int y){
this.x=x;
this.y=y;
}
void draw(){
rect(x,y,50,50);
}
}
このプログラムは、
1. 関数を通してもちゃんとpickingライブラリが動くかどうか
2. クラスを通してもちゃんとpickingライブラリが動くかどうか
3. クラスの配列に通してもちゃんと動くかどうか
4. クラスのリストに通してもちゃんと動くかどうか
を検証している。実行結果は画面左上にpicker.get(mouseX,mouseY)の値を表示している。
しかし、このプログラムではおかしな挙動はなかった。ちゃんと関数を通っても割り当ては有効なようである。
そこで、バグの存在しているプログラムを見ていると、「noFill();」の記述があった。もしやと思い、picker.start(4)の場所(黄色の四角)の記述を次のように変更してみた。
picker.start(4);
Rect2 rect2[]={new Rect2(300,300),new Rect2(350,300),new Rect2(300,350),new Rect2(350,350)};
for(Rect2 tmp:rect2){
fill(255,255,0);
tmp.draw();
noFill();
}
このようにするとnoFill以降の部分でpicker.get()をとっても-1しか返さなくなってしまう。
しかし、次の四角形では割り当てが有効なため、picker.start()すれば割り当てが有効になるようだ。
つまりpicker使っている所ではnoFill()あんまり使わないほうがいいよ、ってことだと思う。
とりあえずpickingライブラリの中身を逆コンパイルしてみてたがようわからんかったorz
Bufferクラス内でcurrent_colorのバックアップとしてold_current_colorとかを用意して、
setCurrentId()の中でold_current_color=current_color=paramInt;
fill()内でcurrent_color=old_current_color;
とすれば行けそうな気がするがどうなんだろうね。今度やってみる。