2011年1月16日日曜日

chaos by collision of balls

ボールの衝突でカオスを体験してみます。
下のキャンバス内で適当にドラッグして放すとキャンバスにボールが投入されます。ボールは(重なっていて分かりませんが)二つあり、ごく僅かだけ位置が異なります。グラフはボール間の距離を対数で表しています。
ボールをいくつか投入して、しばらく眺めてみましょう。









2010年12月31日金曜日

MMDModel on THREE.js

THREE.jsを利用してMMDのモデルデータを表示します。
ここにモデルデータ(.pmd)とテクスチャ(.bmp .png .tga)をアップロードすると、ここで閲覧できます。
動作確認はChromium(10.0.614.0)とChromeで行いました。インスパイア元のTHREE.js demoによると、"webGL"コンテキストはChrome8/9 or Firefox4、"2d"コンテキストはChrome推奨だそうです。
お試しミクさん
追記 : ライトなし版を用意しました。 テクスチャをほとんど使わないモデルならFirefox3でも閲覧できます。こちらからどうぞ。

ソースコードは下記に一式置いてあります。
http://www.yktmt.com/threemmd/

参考ページ
御本尊 : https://github.com/mrdoob/three.js/
MikuMikuDance : http://www.geocities.jp/higuchuu4/
モデルデータ : http://jbbs.livedoor.jp/bbs/read.cgi/music/23040/1219738115/
アップロード : https://github.com/felixge/node-formidable
画像変換 : https://github.com/rsms/node-imagemagick
文字コード変換 : https://github.com/bnoordhuis/node-iconv


2010年12月5日日曜日

Nya on canvas

 Nyanyanyanyanyanyanya! が格好良かったのでcanvasで背景を再現してみました。
CPUを喰うのでこちらに置いておきます。
スクリプトはhtml内に記述してあります。

メモ: rotate() は使うたびに加算されるので逆回転させて戻しておく。
追記: save(),restore()を使うのが正しい作法のようです。

追記: mozTextAlongPath を使うと簡単に書けます。こちらです。
CPU使用率の方はたいして変わりませんでした。


2010年11月24日水曜日

setIntervalのcallbackに引数を渡す

node.jsではcallback関数を文字列で渡しても評価してくれないので、
setIntervalやsetTimeoutのcallbackに引数を渡したいとき
下のように書いても実行してくれません。(エラーも吐かない)
setInterval("funcHoge('" + arg1 + "','" + arg2 + "')", 1000);
//NG
//repeat: 1, callback: 'funcHoge(\'arg1\',\'arg2\')'
また次のように書くとcallbackをdelayなしで一回だけ実行してくれます。
(やっぱりエラー吐かない)
setInterval(funcHoge(arg1,arg2), 1000);
//NG
//repeat: 1, callback: undefined
追記1: 関数オブジェクトを返す関数を使うと大丈夫なようです。
funcHoge(arg1,arg2){
  return function(){
    //arg1,arg2を使った処理
  }
}
setInterval(funcHoge(arg1,arg2), 1000);
//OK
//repeat: 1, callback: [Function]
documentの通りに書きましょう。
http://nodejs.org/api.html#timers-86
追記: 呼称が変だったので直しました。
setInterval(funcHoge, 1000, arg1, arg2);
//OK
//repeat: 1, callback: [Function]
これでもOK
setInterval(function(){ funcHoge(arg1,arg2); }, 1000);
//OK
//repeat: 1, callback: [Function]



writefile with httpClient

メモ: node.jsのhttpClientで取得したファイルを保存する

fs.openは"data"イベントの外に出しておかないと、多数のファイルを取得しようしたときに
"Error: EMFILE, Too many open files"
と怒られます。

追記1: このコードだとon dataハンドラの設定が間に合わずデータを取りこぼします。
下に修正版があります。

//NG
var http = require('http'),
    fs = require('fs'),
    url = require('url');

(function() {
    var target_url = 'http://example.com/download.bin';
    var parsed_url = url.parse(target_url);
    var filepath = parsed_url.pathname.match(/[^\/]+$/)[0];
    var client = http.createClient(80, parsed_url.hostname);
    var request = client.request(
        'GET', 
        parsed_url.pathname, 
        {'host': parsed_url.hostname}
    );
    request.end();
    request.on('response', function (response) {
        if(response.statusCode != 200){
            return;
        }
        fs.writeFile(filepath, new Buffer(0), function (err) {
            if(err){ throw err; }
            fs.open(filepath, 'a', 0666, function (err, fd) {
                response.on('data', function (chunk) {
                    fs.write(fd, chunk, 0, chunk.length, null);
                });
                response.on('end', function(){
                    console.log('saved: ' + filepath);
                });
            });
        });
    });
})();


追記2: hidekiyさんに修正していただきました。
on responseを一通り設定してからrequest.end() を呼ぶと良いようです。
またresponseの度に書き込むのはcreateWriteStreamが適しています。

//OK
var http = require('http'),
    fs = require('fs'),
    url = require('url');

(function () {
    var pre = + new Date();

    var target = url.parse('http://example.com/');
    var filepath = 'download.bin';

    var client = http.createClient(target.port || 80, target.hostname);
    var request = client.request(
        'GET',
        target.pathname,
        {host: target.hostname}
    );
    request.on('response', function (response) {
        console.log('request: on response: ' + response.statusCode);
        if (response.statusCode != 200) {
            console.log('failed');
            return;
        }
        var wstream = fs.createWriteStream(filepath, {
            flags: 'w',
            encoding: null,
            mode: 0666,
        });
        response.on('data', function (chunk) {
            wstream.write(chunk);
        });
        response.on('end', function(){
            wstream.end();
            console.log('response: on end: ' + (new Date() - pre) + 'ms');
        });
    });
    request.end();
})();




2010年11月15日月曜日

fillRect vs putImageData

canvasでのピクセル操作はputImageDataが断然早いようです。
fillRectは位置指定がわかりやすく使いやすいですが、頻繁に描画する場合はputImageDataを使うと表示が軽くなりそうです。
なお、fillRectの実行時間はブラウザによりかなり違いが出るので下のデモでいろいろ試してみてください。


fillRect



putImageData




2010年10月31日日曜日