2011.07.02 | 

あと22日?でテレビのアナログ放送が終了だそうです。
テレビ見ないんでどうでもいい話ですが。こんにちはムーチョです。

さて今日はMac内で隠しフォルダを開く必要に迫られたのでその方法をメモ。


//Terminalで以下のように入力で隠しファイル表示
defaults write com.apple.finder AppleShowAllFiles TRUE

//元に戻す時には、
defaults write com.apple.finder AppleShowAllFiles FALSE

//Finde再起動コマンド
killall Finder

これでFinder内で不可視だったファイルがばっちり表示されますが、なぜかデスクトップにも反映されます。デスクトップはFinderの中ということなんですかね?

そして見えてしまうと隠しファイルの多さにちょっとゲンナリ。
せめて人に渡す際は取り除いておきたいな~。
と思ったら、MacWinZipperというアーカイブソフトはこれらの不可視ファイルを圧縮ファイルに含めないようです。オススメ。
http://www.tida.bz/macwinzipper

2011.06.25 | 

Event.ADDED_TO_STAGEのバグ?というメモを前にしたムーチョです。こんにちは。
暑くて脳細胞が熱暴走しそうですね。というかしてる気がします。
そんな中、ニューロンがヒートアップなことがあったのでメモ。

A:外部SWFをあらかじめ読み込んでおいて、ステージにaddChildしない。

B:Event.ADDED_TO_STAGEを設定したDisplayObjectをaddChildする。


class b extends MovieClip{
	private var a:Loader;
	public function b () {
		addEventListener(Event.ADDED_TO_STAGE, onAdded);
	}
	private function onAdded(e:Event) {
		addChild(a.content);
	}
}

BをステージにaddChildしたときには、当然Event.ADDED_TO_STAGEが発生するんですが、
Bの中にAをaddChildしても、 BでEvent.ADDED_TO_STAGEが発生するんです。
上のようなソースだと
onAddedでaを呼び出してaddChild

Event.ADDED_TO_STAGEが発生

onAddedでaを(以下省略
という現象になります。

さらに不思議なのが無限ループにはならず、ループは1度だけで終了します。
前回と同じく外部SWFってところが地雷原な感じです。

2011.06.17 | 

こんばんはムーチョです。
PC用のサイトをスマートフォンで見る時ってありますか?
私はPCが使える環境ならスマートフォンのブラウザを使ってみることはしないんですが、
目の前にパソコンがありながらも携帯でブラウジングって方も中にはいるでしょう。
また、携帯でブラウジングしなきゃならない時、私は快適なブラウジングはできないもんだと
諦めていますが、快適になるならその方がいいでしょう。

携帯にもちょっと対応したページを作ろうとする時に
マウスとタッチインターフェースの差というのがひとつのネックになってきます。
というわけでタッチインターフェース用の分岐処理を実験してみました。
やっつけやっつけサンプルがこちら。ドラッグで左右にスクロール。

キモな部分だけ抜粋するとこんなソース。要jQuery。


// タッチデバイスかを判別
var isTouch = (document.ontouchstart !== undefined)? true : false;

$('#hoge').bind({
	'touchstart mousedown': function(e) {
		preventDefault(e);
		this.pageX = eventX(e);
		this.pageY = eventY(e);
	},
	'touchmove mousemove': function(e) {
		preventDefault(e);
		var pageXold = this.pageX;
		var pageYold = this.pageY;

		this.pageX = eventX(e);
		this.pageY = eventY(e);
	},
	'touchend mouseup': function(e) {
	}
});

// デフォルトの処理を無効にする
var preventDefault = function(e){
  if(e.preventDefault){
    e.preventDefault();
  }
  else if(window.event){
    window.event.returnValue = false;
  }
}

var eventX = function(e){
	return (isTouch)? event.changedTouches[0].pageX : e.pageX;
}
var eventY = function(e){
	return (isTouch)? event.changedTouches[0].pageY : e.pageY;
}

一応、IE6,7,8、FF3.6,4、Chrome、iPhone、Androidで動作確認。
にしてもこう対応ブラウザが増えると、ひとつのギミックを入れるのに、
どんどん工数が増えてそれはそれで問題な気もしないでもない今日この頃。

2011.06.10 | 

最近暑いですねー。こんばんはムーチョです。節電でがんばってます。
ドロネー三角形分割第3弾です。
前々回前回の続きです。

あれから、kaminalyと試行錯誤を繰り返し、
(主にkaminalyによって)最適化をほどこし、
さらに領域外の分割点も使うように変更しました。

その過程で衝撃の事実が発覚しましたのでご報告。
Cinderのgl::draw()やgl::drawLine()は遅い!
もうムーチョがっかりです。


前回と見た目は一緒ですが、速度は倍ぐらいに(当社比)

さらにちょっと遊んでみました。

画像を読み込んで、ポイントのばらつきをちょっと制御
この時点じゃなんだかよく分かりませんね。


さらに色も画像から引っ張ってみたり。どうでしょう?読めますかね?

ソースはこちらです。よろしければどうぞ。
DelauneayRectApp.cpp
さらにあわせ技でカメラ画像をキャプチャーしたりもしましたが、
それはまたの機会に。ムーチョでした。では皆さんよい週末を。

2011.06.05 | 

前回に引き続きドロネー図行ってみましょう。こんにちは。ムーチョです。
今回は面を塗りつぶします。
前回同様にOpenCVのソースに含まれるサンプルをもとに作成しました。
おおまかな流れはこんな感じです。

1.空のドロネー空間を作成
2.座標をドロネー空間に追加
3.面の座標3点を取得
4.描画

1.2.は前回と全く一緒なので飛ばして3.へ。
さすがはOpenCV!あっさり3点が取れる関数が平然と用意されてるッ!
そこにシビれる!あこがれるゥ!
って展開を思い切り期待していましたが、そんなことはありませんでした・・・。

サンプルをみる限り、線の時とほぼ同じで、
まずは1辺を取り、右隣の接する辺を取得してそれで3点にたどり着くという手法。
そこだけ抜粋するとこんな感じです。


	CvSeqReader  reader;
	cvStartReadSeq( (CvSeq*)(subdiv->edges), &reader, 0 );

// 線の時と同じ形でなぜか総当たり
	for( i = 0; i < total; i++ ){
		CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);
		if( CV_IS_SET_ELEM( edge )){

// 辺から2点を取得
			pt0 = cvSubdiv2DEdgeOrg((CvSubdiv2DEdge)edge);
			pt1 = cvSubdiv2DEdgeDst((CvSubdiv2DEdge)edge);

// 右隣の辺を取得
			t = cvSubdiv2DGetEdge((CvSubdiv2DEdge)edge, CV_NEXT_AROUND_LEFT );
			pt2 = cvSubdiv2DEdgeDst(t);

		}
		CV_NEXT_SEQ_ELEM( elem_size, reader );
	}


その3点からTriMeshを作成して塗りつぶし。
とりあえずアルファ10%で塗ってみたところ、あれ?


これはこれでありか?いやいや。

という訳で塗れてない面やら何度も塗ってる面やらバラバラ。
サンプルをよくよく見直してみると、1辺から二つの面を取得してました。
という訳で以下を追加してたところ・・・


// 基準にしてる辺を反転
			e = cvSubdiv2DRotateEdge( (CvSubdiv2DEdge)edge, 2 );
// 辺から2点を取得
			pt0 = cvSubdiv2DEdgeOrg(e);
			pt1 = cvSubdiv2DEdgeDst(e);
// 反転させた辺の右隣の辺を取得
			t = cvSubdiv2DGetEdge(e, CV_NEXT_AROUND_LEFT );
			pt2 = cvSubdiv2DEdgeDst(t);



均質にはなったが、なんか濃いです・・・。

当然ながら辺総当たりなので、面1つにたいして辺が3つあるため
3倍塗ってるご様子。
どうもサンプルソースもそれっぽい。
そこでやや強引ですが、重複を削除することを決意。
C++初心者のムーチョはここでハマりまくり。

単純にソート&ユニーク化は効果なし・・・。

ソート時に比較しやすいように座標で持つのをあきらめ、
前回追加してたflagを3点のIDとして持った構造体に変更。
アンド、ID(int)3点の大小でソートできるように比較関数を用意。

比較関数がコンパイル時にエラーはきまくり。クラスにすることで回避。

と思ったのもつかの間、それ用に定義した構造体を渡すと、比較関数がエラー。
構造体をあきらめ、配列にするもエラー。C++の配列ってホント使いにくい。

vectorにしたら無事動くがややもっさり。
やっぱり構造体的なものの方がいいのか?と
省力化を兼ねてCinderが元々持ってるVec3iに3点のIDを格納しちゃえと変更。

再びエラーで動かなくなる。Vec3iをVec3fに変更。
もうかなりやけっぱち。後々わかりにくくなりそうだけど、エコですよ。エコ。

これでどうにか動くように。vectorを使ってた時より少し速くもなりました。
基本がないってつらいですね。



// まずは並べ替え
	polys.sort(comparePolyKey());

// 重複を削除
	list<Vec3f>::iterator last_it = unique(polys.begin(), polys.end());
	polys.erase(last_it, polys.end());

// 並べ替え用のクラス
class comparePolyKey {
public:
	bool operator()(const Vec3f&#038; left, const Vec3f&#038; right)
	{
		return (left.x < right.x)
		 || (left.x == right.x &#038;& left.y < right.y)
		 || (left.x == right.x &#038;& left.y == right.y &#038;& left.z < right.z);
	}
};


そんなこんなでようやくキレイに塗れました。

ぱっと見が退屈なのが非常に残念。

おまけにソートとユニーク化をかける前より高速化したので、
面倒でしたがこちらの方がいいですね。
そもそも3倍まわさないようにしたいのですが、
どう書くのがいいのか思いつかず・・・。
かなりいっぱいいっぱいなドロネー図でした。

さらに画像を解析して分割・塗りつぶしをしようと思っていましたが、
リアルタイムでは処理落ちしそうです。