Today アクセスカウンター Yesterday アクセスカウンター

ホワット・ア・ワンダフル・ワールド

私は知識に何ものかを付け加え,また他の人々がより多くのものを付け加える手助けをした --- G.H.ハーディ

全記事一覧 << 2008/07 12345678910111213141516171819202122232425262728293031 2008/09 >>

プロフィール

あろは (alohakun)

  • Author:あろは (alohakun)
  • 若槻俊宏 (WAKATSUKI toshihiro)

    連絡先 : alohakun ___at___ gmail.com
    mixi : http://mixi.jp/show_friend.pl?id=182927
    twitter : http://twitter.com/alohakun

    abstract

    プログラミングという人間の知的行為を体系化し,単なる職人芸ではなく,サイエンスにするための研究をしています.

    具体的には,等価変換計算モデルに基づいた,仕様記述からのプログラム合成の研究をしています.

    もっと噛み砕くと,プログラムの正しさをどのように定式化し,どのような枠組みで,どのように変換を進めていけば,正しさを保証したまま,効率的なプログラムを手に入れることができるのか,ということについて研究しています.

    キーワード : equivalent transformation, computation model, programming paradigm, formal specification, program synthesis













    あわせて読みたい


    この日記のはてなブックマーク数


    スカウター : ホワット・ア・ワンダフル・ワールド


    Map









    FC2 BLOG RANKING

FC2カウンター

ブロとも申請フォーム

この人とブロともになる

Rhino で twitter の public_timeline を表示

2008/03/24(月) 06:14:18

とりあえず json 取ってくれば,そのまま JavaScript で eval して読み込めるみたい.


importPackage(java.io);
importPackage(java.net);

function show_public_timeline() {
  var url = new URL('http://twitter.com/statuses/public_timeline.json');
  var stream = new BufferedReader(new InputStreamReader(url.openStream()));
  var line, json = '';
  while(line = stream.readLine()) 
    json += line;  
  stream.close();
  public_timeline = eval(json);
  for(var i in public_timeline) {
    print(i + '\n');
    print('truncated              : ' + public_timeline[i]['truncated'] + '\n');
    print('created_at             : ' + public_timeline[i]['created_at'] + '\n');
    print('source                 : ' + public_timeline[i]['source'] + '\n');
    print('text                   : ' + public_timeline[i]['text'] + '\n');
    print('user/name              : ' + public_timeline[i]['user']['name'] + '\n');
    print('user/screen_name       : ' + public_timeline[i]['user']['screen_name'] + '\n');
    print('user/profile_image_url : ' + public_timeline[i]['user']['profile_image_url'] + '\n');
    print('user/description       : ' + public_timeline[i]['user']['description'] + '\n');
    print('user/location          : ' + public_timeline[i]['user']['location'] + '\n');
    print('user/protected         : ' + public_timeline[i]['user']['protected'] + '\n');
    print('user/url               : ' + public_timeline[i]['user']['url'] + '\n\n');
  }
}

show_public_timeline();


素の JavaScript ならともかく,Rhino 使っちゃってるので,本当は JSON.parse とか使わないとセキュリティ的に非常に不味い (twitter の中の人がその気になって public_timeline の JSON に Rhino のコードを流したら,任意のコードを実行できてしまう) んだけど,java 6 に付属のやつでは使えない感じ.

あと, なぜか readUrl が使えなかった… 面倒だけど,Java の URL パッケージ使って取ってきている.

Rhino の目玉機能の一つである ECMAScript for XML (E4X) も,java 6 の版では削られているし.print も,なぜか Linux 版だと改行されなかったりと,いろいろ微妙です.
JavaScriptTB:0CM:0 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!

ウォークスルー

2008/03/20(木) 22:31:10

物理のかぎしっぽ home > コンピュータ > グラフ・解析ツール >OpenGL習作プログラムの,三次元空間をマウスで移動するウォークスルーモデル,を Rhino + JOGL で書いてみました.

JOGL では Java の GUI コンポーネントをそのまま使えるので,GLUT の描画補助関数などに頼る必要が無いです (なので JOGL の GLUT クラスでは,図形の描画関数しかサポートされていません).


importClass(javax.swing.JFrame);
importClass(javax.swing.Timer);
importPackage(java.awt.event);
importPackage(javax.media.opengl);
importPackage(javax.media.opengl.glu);
importClass(com.sun.opengl.util.GLUT);

var RadToDeg = 0.01753;
var gl;
var glu = new GLU();
var glut = new GLUT();
var objects;

var theta = 0.0;
var V = 0.0;
var t = 0.0;
var ww, hh;

canvas = new GLJPanel();

canvas.addGLEventListener(new GLEventListener({
init: function(drawable) {
gl = drawable.getGL();

gl.glClearColor(1.0, 1.0, 1.0, 0.0);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glEnable(GL.GL_CULL_FACE);
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_LIGHT0);

var red = [0.8, 0.2, 0.2, 1.0 ];
var green = [0.2, 0.8, 0.2, 1.0 ];
var blue = [ 0.2, 0.2, 0.8, 1.0 ];
var yellow = [ 0.8, 0.8, 0.2, 1.0 ];
var ground = [[ 0.6, 0.6, 0.6, 1.0 ], [ 0.3, 0.3, 0.3, 1.0 ]];

objects = gl.glGenLists(1);
gl.glNewList(objects, GL.GL_COMPILE);

gl.glPushMatrix();
gl.glTranslated(0.0, 0.0, -6.0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, red, 0);
glut.glutSolidCube(1.0);
gl.glPopMatrix();

gl.glPushMatrix();
gl.glTranslated(0.0, 0.0, 6.0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, green, 0);
glut.glutSolidCube(1.0);
gl.glPopMatrix();

gl.glPushMatrix();
gl.glTranslated(-6.0, 0.0, 0.0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, blue, 0);
glut.glutSolidCube(1.0);
gl.glPopMatrix();

gl.glPushMatrix();
gl.glTranslated(6.0, 0.0, 0.0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, yellow, 0);
glut.glutSolidCube(1.0);
gl.glPopMatrix();

gl.glBegin(GL.GL_QUADS);
gl.glNormal3d(0.0, 1.0, 0.0);
var i, j;
for (j = -20; j < 20; j++) {
for (i = -20; i < 20; i++) {
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, ground[(i + j) & 1],0);
gl.glVertex3d(i, -0.5, j);
gl.glVertex3d(i, -0.5, j + 1);
gl.glVertex3d(i + 1, -0.5, j + 1);
gl.glVertex3d(i + 1, -0.5, j);
}
}
gl.glEnd();
gl.glEndList();
},

reshape: function(drawable, x, y, width, height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(60.0, width / height, 1.0, 1000.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glTranslatef(0.0, 0.0, -20.0);
ww = width; hh = height;
canvas.repaint();
},

display: function(drawable) {
var lightpos = [ 3.0, 4.0, 5.0, 1.0 ];
var ex = 0.0, ez = 0.0;
var Vx = 0.0, Vz = 0.0;
var r = 0.0;
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
r += theta * t;
if(r < 0) {
Vx = V * Math.sin(Math.abs(r) * RadToDeg);
Vz = V * Math.cos(Math.abs(r) * RadToDeg);
} else {
Vx = -V * Math.sin(Math.abs(r) * RadToDeg);
Vz = V * Math.cos(Math.abs(r) * RadToDeg);
}
ex += Vx * t;
ez += Vz * t;
gl.glRotated(r, 0.0, 1.0, 0.0);
gl.glTranslated(ex, 0.0, ez);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightpos, 0);
gl.glCallList(objects);
},

displayChanged: function(drawable, modeChanged, deviceChanged) {}
}));

canvas.addMouseListener(new MouseListener({
mouseClicked: function(e){},
mouseEntered: function(e){},
mouseExited: function(e){},
mouseReleased: function(e){},
mousePressed: function(e){
var x = e.getX();
var y = e.getY();
if(x < ww/2) theta = -(Math.abs(0.5*ww - x ) / (0.5*ww)) * 2.;
if(x > ww/2) theta = (Math.abs(0.5*ww - x ) / (0.5*ww)) * 2.;
if(y < hh/2) V = Math.abs(0.5*hh - y)/2000;
if(y > hh/2) V = -Math.abs(0.5*hh - y)/3000;
}
}));

frame = new JFrame("Simple Walk Through");
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(canvas);
frame.setVisible(true);

new Timer(1, new ActionListener({
actionPerformed: function(e) {
t+=1;
frame.repaint();
}
})).start();

while(1) {java.lang.Thread.sleep(100000000);}



$ /cygdrive/c/Program\ Files/Java/jdk1.6.0_05/bin/jrunscript.exe walkThrough.js

simplewalkthrough.png





またまた追記 Swing はスレッドセーフなライブラリでは無いので,直接 JFrame などの Swing コンポーネントに非イベントハンドラメソッド (例えば,main スレッドが代表例) から触っては駄目らしいです.SwingUtilities.invokeLater() を使って,同期を取らないと駄目なのだそう.これって顕在化してないだけで,かなりの Java プログラムが問題抱えてそうだなぁ… 恐ろしや.ネット上のサンプルプログラムもほとんど該当しそうだし.

mainメソッドでSwingを書かない訳

Rhino がどういう実装なのかはよくわかりませんが… そもそも main メソッドが無いので.心配な人は,ちゃんと invokeLater で同期を取っておきましょう.
JavaScriptTB:0CM:0 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!

Rhino で OpenGL (JOGL) するサンプル

2008/03/20(木) 15:58:58

「OpenGLを使ってJavaでも3Dを楽しもう」 第3回 プログラムで3Dを表示する を Rhino + JOGL で多少書き直しただけの習作だけど,Rhino も JOGL もあんまりネット上にシンプルなサンプルコード無い感じなので,一応張っておきます.



importClass(javax.swing.JFrame);
importPackage(javax.media.opengl);
importClass(com.sun.opengl.util.GLUT);

var gl;
var glut = new GLUT();

var listener = new GLEventListener({
  init: function(drawable) {
    gl = drawable.getGL();
    gl.glClearColor(0.5, 0.5, 0.5, 0.0);
  },
  reshape: function(drawable, x, y, width, height) {
    ratio = height / width;
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glFrustum(-1.0, 1.0, -ratio, ratio, 5.0, 40.0);
    gl.glMatrixMode(GL.GL_MODELVIEW);
    gl.glLoadIdentity();
    gl.glTranslatef(0.0, 0.0, -20.0);
  },
  display: function(drawable) {
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
    glut.glutWireCube(2.0);
  },
  displayChanged: function(drawable, modeChanged, deviceChanged) {}
});

frame = new JFrame("Simple Cube");
canvas = new GLJPanel();
canvas.addGLEventListener(listener);
frame.add(canvas);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

while(1) {java.lang.Thread.sleep(100000000);}



実行には JOGL + JRE が必要です.Java 6 以上の jrunscript か本家の Rhino で実行できると思います.Rhino は直接 Java の interface を new して implement したり,直接イベントハンドラを関数リテラルで書けるので,C/C++ とか Java よりも簡単に OpenGL が扱えて良いと思います.

追記 : AWT と Swing 混ぜるな危険 !! Swing 使う場合は,GLCanvas の代わりに GLJPanel を使うようです.
JavaScriptTB:0CM:0 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!

JavaScript + Swing で実装した Drag & Drop 画像ビューワ

2008/03/18(火) 21:00:54

Java は標準で Drag & Drop も zip 圧縮も mail 送信もサポートしてる感じなので,以前 tcl/tk で作ろうとして,結局フォルダの zip 圧縮が面倒で途中までしか作ってなかった,ファイルかフォルダを D & D すると zip で固めて GMail に (20 M を越えるファイルは適宜分割して) 投げてくれるような,簡易バックアップユーティリティを簡単に作れそうな気がしたので,まずは習作.Swing の D & D だけ Rhino で書いてみた.

追記 : javax.mail (JavaMail) は標準添付じゃないらしいので,一気にやる気が無くなりました.JavaMail だけならともかく,JavaBeans Activation Framework (JAF) までまるごと必要とか,面倒過ぎる… メールぐらい標準でサポートしておいて欲しいなぁ

Java 6 に同梱されている Rhino の JavaAdapter は,1つのインタフェースの実装のみに機能が制限 された SUN の独自実装に差し替えられているようです.なので,ここらへんのサンプルコードを jrunscript で実行しようとすると JavaAdapter requires two arguments という酷いエラーメッセージが出る.

もともと,Rhino は直接 Java のインタフェースを new して実装できるので,これでは存在価値ゼロですね.


var listener = new DropTargetListener({
dragEnter: function(e) {
...
},

drop: function(e) {
...
},

dragExit: function(e) {},
dragOver: function(e) {},
dropActionChanged: function(e) {}
});


linux で試したら何故か上手く行かなかったので,大学の Windows PC で動かしてみようと思ったら,なぜか SUN の sdlc-esd.sun.com に繋がらないので jdk 1.6 がダウンロードできない.

仕方が無いので本家のRhinoをダウンロードして Java 5 で試して見たら無事に動いたので晒しておきます.

$ java -version
java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing)

$ java -cp rhino1_7R1/js.jar org.mozilla.javascript.tools.shell.Main dnd.js

一応 Java 6 の方でも動くように書いてあります.今回は JavaAdapter 使っても使わなくてもコードの長さはそんなに変わりませんので (JavaAdapter 無しで Java のクラスをどうやって継承したオブジェクトを作るのだろうか ? 全部委譲 + インタフェースの直接実装でがんばるのが,プロトタイプベースの JS way なのかもしれないけど)


importPackage(Packages.javax.swing);
importPackage(java.awt);
importPackage(java.awt.event);
importPackage(java.awt.datatransfer);
importPackage(java.awt.dnd);
importPackage(java.util);

var frame = new JFrame('Prease Drag & Drop Image File Here!');
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);

var listener = new DropTargetListener({
dragEnter: function(e) {
e.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
},

drop: function(e) {
if (e.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) {
e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
var trans = e.getTransferable();
if(e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
var l = trans.getTransferData(DataFlavor.javaFileListFlavor);
var fileName = l.get(0).getAbsolutePath();
print(fileName + ' droped.');
dndLabel.setIcon(new ImageIcon(fileName));
frame.pack();
e.dropComplete(true);
} else {
print('DataFlavor.javaFileListFlavor is not supported.\n');
e.dropComplete(false);
}
} else {
e.dropComplete(false);
}
},

dragExit: function(e) {},
dragOver: function(e) {},
dropActionChanged: function(e) {}
});

var dndLabel = new JLabel();
// JLabel コンポーネントに DropTargetListener リスナーを登録
new DropTarget(dndLabel, DnDConstants.ACTION_COPY_OR_MOVE, listener, true);
frame.add(dndLabel);
frame.setVisible(true);
// Rhino ではスクリプトの終了と同時に全スレッドが強制的に殺されてしまうため
while(1) {java.lang.Thread.sleep(1000);}


やってることはほとんど Java と同じなんですけど,だいぶ雰囲気違いますね.

ちなみに,Rhino の本家版は,Continuation オブジェクトとか,いろいろ面白そうな機能もいろいろある感じです (Java 6 に同梱版はだいぶ機能が削られてる)
JavaScriptTB:0CM:0 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!

JVM の上でコンパイルされて実行される JavaScript スクリプトをコンパイルして実行する JavaScript スクリプト

2008/03/18(火) 02:15:24

Java 6 に付いてくる Rhino は,コンパイラが付いてないんだけど,Compilable インタフェースには compile なんてメソッドがあるじゃん,と思ったんだけど.パースするだけで,バイトコードか何か中間形式はダンプできないのか… なので実用性は無いですが.


importPackage(java.io);
importClass(javax.script.ScriptEngineManager);

function main(arguments{
  if(!arguments[0]return;
  var buffer = new BufferedReader(
                 new InputStreamReader(
                   new FileInputStream(arguments[0])));
  var script = "";
  while(l=buffer.readLine()) {
    script += l + '\n'
  }
  buffer.close();
  
  var manager = new ScriptEngineManager();
  var engine = manager.getEngineByName("js");
  var compiledScript = engine.compile(script);
  
  compiledScript.eval();
}

main(arguments);



~/work/java/rhino$ ~/jdk1.6.0_05/bin/jrunscript -l js jsc.js T.js

そもそも,パースして中間形式を作ることを,JavaScript の世界ではコンパイルと言うらしい.普通の意味(?) でのコンパイラは,オプティマイザと言うらしい.確かに,現在のスクリプト言語のほとんどは load 時に構文木作るのと同時に簡単な最適化までするから,コンパイラとインタプリタという用語の境目はほとんど無くなりつつある (意味を強調するために「最適化コンパイラ」という用語は昔から使れてるけど).

これは本来,Java 側からスクリプト側にアクセスするためのキャッシュフレームワーク (C から gauche にアクセスできる libgauche みたいなもの) 毎回文字列からパースしてるとコストがかかるので,構文木(か何か中間形式)をキャッシュしておく.それぞれの束縛はengine.createBindings() で作る bindings に put("x", "10") とかして,eval の評価環境を変更できる (つまり,Java 側のオブジェクトをスクリプトに受け渡すことができる).

なので,スクリプトからスクリプトにアクセスしてもしょうがないのですが (そんな面倒なことしなくても,普通にアクセスできる) まぁ,スクリプトを生成するスクリプトみたいな,メタプログラミング時には役に立つことがあるかもしれません.Rhino JavaScript は変数に型書かなくても,右辺の式で勝手に型推論してくれる感じなので素晴らしいと思います (普通のスクリプト言語 (?) みたいにメソッドを動的にサーチして結合してるのかもしれませんが,Rhino はわりと速いらしいので,ちゃんと静的に解決している気がします.調べてない)
JavaScriptTB:0CM:0 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!

最近のコメント

リンク

このブログをリンクに追加する

最近のトラックバック

人生の残り日数

日本人男性の平均寿命は 28700日.

RSSフィード

カテゴリー