2012年6月29日金曜日

JSXによるガジェット開発 ー時計編ー

ガジェット開発にもJSX

JSXでのプログラミングにもだいぶ慣れてきたので,今回はちょっとしたアプリを作ってみたいと思います.俗に言うガジェットですね.手始めにガジェットの中でも定番と言える,時計を紹介します.

時計を作ろうとして,こちら*1のtimer.jsx(タグ)を見ながらTimerを試し,その勢いでWeb版を開発しました.あまりに簡単で拍子抜けしました.これだけだと面白く無いので,さらに勢いに乗ってアナログ時計も開発しました.

ディジタル時計

あまり解説するような内容はありませんが,強いて言えば,繰り返す内容をまとめた関数を用意してください.上記プログラムでは7行目から15行目です.そして,16行目で関数fを100 [msec]毎に実行するよう設定しています.単純に動作させたいだけならsetIntervalの中に無名関数を定義しても構いません.後で繰り返し動作を止めたい場合は,関数にしておいてください.

「時計は1秒に1回動けば良いので,100[msec]は過剰じゃないか?」と思われるかもしれませんが,実際にはちょっとずつずれる可能性があるので念には念を入れています.・・・と思っていたのですが,こちら*2によるとほとんどずれないみたいですね.

肝心の表示ですが,8行目で時刻を取得し,10〜12行目で時・分・秒に分け,14行目でmainに渡された要素に表示しています.これだけのシンプルな仕組みなので,数字が1桁の場合は左詰めになります.Timerのサンプルということでご容赦ください.

デモです.

アナログ時計

こちらは,あまりにディジタル時計が簡単だったので作成した副産物です.例によって手抜きできるだけシンプルを心がけています.

11行目で繰り返す関数を,変数watchに入れています.書式がディジタルと異なるのは,まだ私がJSXに慣れていないためです.

watch内では,12行目で描画領域をクリアして,14〜17行目で1時から12時の印を描いています.この辺は,前回紹介だけした仮想座標をサポートした描画ライブラリを使用して,描画領域をX, Y共に-1〜1にしています.そして,ディジタル時計同様,19〜23行目で時刻の取得と時・分・秒・ミリ秒への分割を行っています.

さらに,25〜27行目で,表示すべき角度を計算しています.数学的な角度は時計で言う3時から反時計回りなので,その分の調整を行っています.さらに29行目〜33行目で短針・長針・秒針の描画を行っています.

近くにあった時計の秒針が赤でスルスル動くタイプだったので,こちらのプログラムでも赤く,かつ,スルスル動くようにしています.スルスルと動かすため,36行目で動作間隔を100[msec]にしています.

デモです.

github上のソースコード

以下のリンクからソースコードを参照できます.バグがあったらこっそり教えていただけると助かります.

gitigal_watch.html:ディジタル時計を表示するhtmlファイル.

digital_watch.jsx:ディジタル時計のソースコード.

digital_watch.jsx.js:コンパイルされたディジタル時計のコード.ブログに載せる都合上,最終行に var dw = JSX; を追加しています.

analog_watch.html:アナログ時計を表示するhtmlファイル.

analog_watch.jsx:アナログ時計のソースコード.

digital_watch.jsx.js:コンパイルされたアナログ時計のコード.ブログに載せる都合上,最終行に var aw = JSX; を追加しています.

vcanvas.jsx:先日から変更なしですが念のため掲載しておきます.仮想座標をサポートしたグラフィック描画クラス.まだメソッドが揃っていません.

参考にしたサイト

*1:timer.jsx ( タグ ) - Code/JSX - CODE CODIUM.

*2:setIntervalとsetTimeoutを調べた結果余分なことになった - 三等兵

貴重な情報をありがとうございました.

このエントリーをはてなブックマークに追加

2012年6月27日水曜日

GUI版DFT by JSX

やはりグラフが必要

コマンドライン版のDFTがとりあえず完成したのを受け,次はGUI版だと意気込んでみたものの,なかなか時間が取れなくて公開が遅くなってしまいました.数値を表示するだけのDFTは,表示が寂しいとかそう言うレベルではなく,分析結果が全く分かりません.やはりグラフィック表示が必要です.

どこに時間が掛かっていたかと言うと,グラフ表示するための「仮想座標をサポートした描画領域」のクラスを作成したからです.こちらのクラスはまだ完成度が低く公開するには時期尚早ですが,githubには上げておきます.使い方の説明は,その内このブログで公開する予定です.

そんなこんなで,ようやく公開するに耐えるDFTアプリができました.今のところ,分析できる波形が「単純なsin波」「位相が30度ずれたsin波」「矩形波」のみです.もっと色々と機能をつけることもできますが,まずは公開を優先したのでご容赦ください.以下,デモです.分析したい波形のボタンをクリックすると,元波形と周波数成分が表示されます.

デモ

※Blog全体を表示している場合,エラーが出て動作しません.この投稿のみを表示すれば動作します.現在原因究明中.追加:JSXの仕組み上,複数のJSXプログラムを同一ページに配置できません.お手数ですが,この投稿のみを表示した状態でお試しください.追加:無理やり同一ページ内に複数のJSXプログラムを配置するための改造を行いました.

ボタンで元波形を選択してください
Please select an original wave by buttons

元波形
original wave

周波数成分(赤:実部,青:虚部)
Spectrum ( red: real part, blue: imaginary part )

ソースコード

ソースコードを以下に示します.

mainメソッドに,「元波形を表示するcanvasのid」「周波数成分を表示するcanvasのid」「sin(x)ボタンのid」「sin(x+30)ボタンのid」「矩形波ボタンのid」を渡してください.7行目から13行目で,与えられたidを元に,仮想座標をサポートするVCanvasの初期化などを行います.次に15行目でサンプル数(ここでは80)をpに代入します.

19行目から57行目はグラフィック表示のためのdftメソッドの定義です.内容は,描画領域のクリア(20, 21行目),軸などの描画(23〜29行目,40〜47行目),DFT(35〜38行目),グラフ描画(31〜33行目,49〜56行目)などです.

58行目から始まるsinメソッド,63行目から始まるsin2メソッド,68行目から始まるrectangleメソッドは,それぞれ波形を計算し配列waveに代入し,上記dftメソッドを実行します.これらは,その直後(74〜76行目)でそれぞれのボタンが押された際に実行されるメソッドです.無名関数で定義しても良かったのですが,確認のために一度変数に代入しています.

80行目以降のFGクラスはFunctionGeneratorクラスです.色々な波形を生成するメソッドを定義していく予定ですが,今のところ何もできないに等しいです.

GUIアプリを作ってみた感想

JSXを初めて見たときは,「Javaっぽい」と思ったのですが,実際にGUIアプリを組んでみると「Javaより数倍楽」ということに気づきました.描画領域に簡単にアクセスできて,ラッパークラスを簡単に定義できて,intとdoubleを厳密に区別しなくて済む=numberクラスの存在がどれだけ幸せか計り知れません.一方JavaScriptとの比較では,メソッドや変数の型チェックが厳密であることの良さも実感できます.

公開したプログラムは,教材として利用することを想定しているので,他人がカスタマイズすることも考慮に入れています.ですので,ボタンを追加したり削ったりすることも考慮したいのですが,現状のJSXでは引き数の数が定義に基づいて固定されてしまっているので,可変長引数のサポートが望まれます.と言いつつ,Nylonに対応できれば,操作部と計算・表示部の独立性が高くなるので,早くNylon.jsxを開発したいと思います.

総合的に判断して,JSXは今後のシミュレータ教材開発言語として最適です.徐々にノウハウを貯め,ライブラリを充実させ,どんどん授業に使っていこうと思います.

注意事項:JSXのサンプルなどを見ると,クラス名にApplicationが使われることが多いのですが,ブログ上に複数のJSXプログラムを張り付けると,クラス名が重複してしまい動作しないことがあります.クラス名は面倒でも個別に付けたほうが良さそうです.JSXをコンパイルして作成されたJSは,全てグローバル変数JSXに紐付けられます.よって,複数のJSXプログラムを同一ページ内に配置するとコンフリクトし,最後に読み込んだスクリプトしか実行できなくなります.コンパイル後にJS内の「JSX」を別の単語に置換すれば良いものと思われますが,スマートな解決策を期待したいところです.

github上のソースコード

以下のリンクからGUI版DFTのソースコードを参照できます.バグがあったらこっそり教えていただけると助かります.

dft_gui.html:GUI版DFTのHTMLファイル.

dft_gui.jsx:GUI版DFTの中枢部.

vcanvas.jsx:仮想座標をサポートしたグラフィック描画クラス.まだメソッドが揃っていません.

dftlib.jsx:DFTに関するライブラリ.あまり独立したファイルにする意味が無いのは秘密.

dft_gui.js:dft_gui.jsxをコンパイルして作成されたJS.特に最適化オプションは付けていません.

追記

同一ページ内に複数のJSXプログラムを配置できないことについて追記しました.(2012/6/27)

このエントリーをはてなブックマークに追加

2012年6月15日金曜日

JSXでDFT(改訂版)

DFTの改訂版

以前の記事を書いた際には,まだまだJSXのことがよく分かっておらず,変な記述が多かったのと,一部バグがあったのでソースコードを改訂しました.とりあえずソースをご覧ください.

設計上,変えた箇所はFunctionGeneratorを独立したクラスにしていることです.バグがあったのは,元波形を合成しているところで各サンプルをサンプル数で割っていたのですが,これでは波形の振幅がおかしくなってしまうので,dftメソッド内で割るようにしたことです.

技術的に変わったところは,

  1. 元波形の関数をmainで定義し,その関数を渡して元波形を生成するようにした
  2. 表示が見づらかったので1000倍→intに変換→1/1000倍して見やすくした

などです.dftメソッドがシンプルになったので,インスタンスメソッドにしている意味が無くなりました.現状ではaiとarを一度に返すことができないので別のメソッドで取得していますが,JSXが2つ以上の返り値を返せるようになったらクラスメソッドに変更できます.2つ以上の返り値を返せるようになりませんかね?

DFTの実行結果

実行結果です.多少は見やすくなったと思います.

おわりに

徐々にJSXに慣れてきたので,次はGUIアプリ版のDFTを作りたいと思います.もちろん,グラフ表示も付けたいと思います.その他要望などありましたらコメント欄にお書きください.

ソースコードをgithubのこちらに置いておきます.pを増やしたり,元波形の関数を変更するなどお試しください.

このエントリーをはてなブックマークに追加

JSXの関数あれこれ

関数の定義方法

素のJavaScriptでは,関数を定義する方法が4つありました.それぞれ使いどころが異なるのですが,細かい説明は省略します.以下,2つのパラメータを受け取り,それらの積を返す関数を考えます.

  1. Function foo( x, y ) { return x * y; }
  2. function bar( x, y ) { return x * y; }
  3. baz = function( x, y ) { return x * y; };
  4. qux = new Function( "x", "y", "return x * y;" );

一方,JSXでは以下の方法で関数を定義できます.JavaScriptではクラスの概念があやふやですが,JSXではクラスメソッドとインスタンスメソッドと単なるメソッドに区別されます.以下の中では,1がインスタンスメソッド(インスタンスを作成して「インスタンス名.メソッド名」で呼び出す)で2がクラスメソッド(「クラス名.メソッド名」で呼び出す)です.3〜5が単なるメソッド(メソッド名で呼び出す)です.単なるメソッドは変数に代入する形になるので,変数のスコープ外からは使用できません.また,「->」の表記方法は後になって追加されたので,初期にJSXをセットアップした人はエラーとなってしまいます.その場合はJSXを更新してみてください.

  1. function foo( x: number, y: number ) : number { return x * y }
  2. static function bar( x: number, y: number ) : number { return x * y }
  3. var baz = function( x: number, y: number ) : number { return x * y; };
  4. var qux = ( x: number, y: number ): number -> { return x * y; };
  5. var quux = ( x: number, y: number ): number -> x * y;

関数を関数に渡す

使う機会は限定されますが,JavaScript同様,関数に関数を渡すことが必要な場面があります.例を挙げると,GUIアプリや非同期処理などでコールバック関数を指定する時です.関数を渡す際には,上記3〜5のように一旦変数に代入することも,無名関数を直接記述することもできます.

まずは関数を受け取る側の記述例です.やっていることは単純に,パラメータとして関数と2個の数値を受け取り,受け取った関数にその数値を渡して実行し,実行結果を表示するものです.

次に,上記メソッドに関数を渡して実行する例を示します.上記メソッドはクラスメソッドなのでクラス名が必要です.今回は_Mainクラスに記述されているものとします.

今回は関数の渡し方について記述しました.githubにソースコードを置いておきましたのでご利用ください.

func.jsx

最後になりますが,こちらのページにはお世話になりました.ありがとうございました.

JSX の進化速度が半端ない | ぐるぐる~

このエントリーをはてなブックマークに追加

2012年6月8日金曜日

JSXによるマウスでお絵描き

ようやくソースコードの整理が終わったので,恥ずかしながら公開します.マウスでお絵描きするサンプルプログラムです.ペンの色や太さを変更する機能や,保存機能など全く実装していません.あくまで,マウスの座標を取得したり,Canvasを使うサンプルとして御覧ください.

pen.html

pen.jsx

利用方法ですが,以下のようにJSXファイルをコンパイル(?)してください.

jsx --release --output pen.jsx.js pen.jsx

その後,pen.htmlとpen.jsxjsを同じディレクトリに置いてWebブラウザで開いてください.コンパイルされた後は.jsxファイルやweb.jsxは不要です.当方で試した際には「file://〜」の状態でも動作しました.

デモ

以下の四角の中でマウスをドラッグしてみてください.黒い点が描画されます.一部,四角の領域の位置調整の部分でコンパイルされたjsファイルに変更を加えています.どうしてもこの部分をJSXで記述することができませんでした.未熟です,はい.領域内の座標の取得方法を覚えたので,更新しました.(2012/6/21)

<注意!>Firefoxで動作しなくなっています.2012/6/21に加えた変更によるものです.具体的には,マウスの座標を取得するために,MouseEventのインスタンスのoffsetXとoffsetYプロパティにより値を取得していました.しかし,Firefoxにはこれらのプロパティが存在しないため動作しません.普段はGoogle Chromeを使って作業しているため,チェック漏れがあったことをお詫び申し上げます.(2012/6/29)

その後,FirefoxにはlayerXとlayerYプロパティがあることを調べました.ところが,web.jsにこれらのプロパティが存在しないことが分かり,あろうことかこれらを加えてgithubのJSXツリーにPull Requestを出しました.(若くないけど)若気の至りでした.layer[X,Y]はW3Cに承認されていないプロパティだったのです.

そのことを親切に教えてくださったFuji, Goroさんに感謝します.きっと,Pull Requestを見て「え?今さらこんなコト言ってくる人がいるぞ」という気持ちだったのではないでしょうか.冷静になってlayer[X,Y]が存在しない理由をきちんと考えていれば,こんな恥ずかしい思いはしなくても済んだのに・・・と思っていたら,即座にTwitter上で,マウス座標の取り方を解説しているページを授けていただきました.

そのページによると,やはりマウス座標の取得方法は混沌としているとのこと.これはものすごく役に立つと思って喜びながら日付を見ると,およそ3年前の記事.どれだけ遅れているんだ俺は.

気をとりなおして解説します.まず,マウスイベントからウィンド座標を取得します.これにはclient[X,Y]プロパティを使います.これだけではスクロールするとずれるので,ウィンドウ座標系内でのノードの座標をgetBoundingClientRect()メソッドによって取得し,引き算します.

具体的なマウス座標の取得方法は以下のとおりです.
var es = e as MouseEvent; // マウスイベントの取得
var ee = es.target as Element; // イベントの発生したノードの取得
var rect = ee.getBoundingClientRect(); // ノードのウィンドウ座標の取得
var x = es.clientX - rect.left; // マウスイベントのウィンドウ座標 - ノードのウィンドウ座標
var y = es.clientY - rect.top; // マウスイベントのウィンドウ座標 - ノードのウィンドウ座標
この記事が誰かの参考になることを祈ってます.

最後になりますが,こちらのページにはお世話になりました.ありがとうございました.

【閲覧注意】JSX で何か作ってみた。 | Big Sky

DOM level 3のマウスイベントにおけるカーソル位置の詳細 | 本の虫

追記

githubにソースコードを置いておきました(2012/6/14)

pen.html

pen.jsx

素のままのデモを実行したい場合はこちらをクリックしてください(2012/6/14)

マウスドラッグによる座標の取得方法を変更しました.(2012/6/21)

Firefoxでの不具合について記述しました.(2012/6/29)

マウスドラッグによる座標の取得方法を変更しました.(2012/6/30)

このエントリーをはてなブックマークに追加

メモ:JSXの配列の扱い

JSXの基本的な文法

JSXはJavaに近い書式です.また,詳しくは知りませんがActionScriptにも近いようです.とは言え,新しい言語と出会った際にやってみる「配列に値を代入して,表示してみる」という簡単なプログラムを作ろうとしても,細かい文法の違いで苦労しました.と言うわけで配列に関する基本的な文法についてメモしておこうと思います.

配列の初期化

最初は,こんな簡単なことでも迷ってしまったので書いておきます.簡単なのは直接値を代入する場合で,以下のプログラムの2行目のように書きます.他の言語のように,「まずは配列を宣言して・・・」と考える場合は同5行目のように書きます.

配列の要素数

配列の要素数ですが,固定ではなく可変のようです.配列の要素数を得るには6, 7, 12行目のようにlengthを使います.配列に追加したい場合は10行目のようにpushメソッドが使えますし,配列同士を結合したい場合は15行目のようにconcatメソッドが使えます.

逆に,配列の要素を減らしたければpopメソッドやshiftメソッドがあります.

配列の内容表示とループ

すでに上のプログラムで用いているように,logメソッドで表示します.全要素の表示は31行目のように単純にtoStringメソッドを用いれば良いのですが,併せて配列の要素数分だけ繰り返すための書式も紹介しておきます.

上記のプログラムを全て一つのファイルにまとめて,以下のように実行できます.今回は仮にarray.jsxというファイル名をつけたものとします.ソースコードをgithubのこちらに置いておきます.

jsx --run array.jsx

だんだんと基本的な書式が分かってきましたが,まだまだ足りないところがあるので,続く予定です.今回はこの辺りで失礼します.

追記

空の配列の作成方法その3を追加しました(2012/6/14)

githubにファイルを置き,リンクを追加しました(2012/6/14)

このエントリーをはてなブックマークに追加

2012年6月7日木曜日

メモ:Macのターミナルの設定

.bashrcの話

このブログを読む方はすでに承知のことと思いますが,Mac OS Xの中枢部はBSD Unixの系統です.なので,ターミナルをひらくと見慣れた画面が開き,いつものコマンドを使うことができます.その割に,ホームディレクトリに.bashrcや.bash_profileが見当たりません.検索してみると,.bash_profileを作ってそこから.bashrcを読み込ませれば良いとのことなので,さっそく指示に従ってみます.

まずは.bash_profileです.

続いて.bashrcです.かなり偏った内容なので,各自好きな設定をどうぞ.

.bashrcの2〜4行目は,Java言語のソースコードの文字コードをUTF-8として指定します.5行目はJSXのための設定です.

以下のブログ・記事を参考にしました.ありがとうございました.

■[Mac]Mac - bash入門
UNIX Settings...

追記

javadocのaliasにcharsetの設定を加えました(2012/6/14)

このエントリーをはてなブックマークに追加

2012年6月6日水曜日

JSXでDFT

JSXという言語

JSXという言語が彗星のごとく現れました.この言語を使ってプログラムを書くと,ギンギンに最適化されたJavaScriptに変換できるということで興味を持ちました.ドキュメントを読んでいくと,文法がJavaに近いこととJava並に型チェックにうるさいことなどが分かりました.

これまでMeSHやNylonの開発にJavaScriptを使ってきたのですが,thisが何を指すか不明確であることや,変数のチェックがないことによるエラーに悩まされてきました.そこに現れたのがJSXです.言語仕様はJavaのように窮屈ですが,今後ライブラリやサービスを提供していくにあたり,妙なエラーに悩まされたくないので,まずは試してみることにします.

DFTのソースコード

DFTは,言わずと知れた離散フーリエ変換(Discrete Fourier Transform)です.周波数分析の強い味方です.今回はC言語で書かれたDFTを移植してみます(※FFTではありません).JSXのドキュメントがまだまだ整備されていないので,ちょとしたプログラムでも試行錯誤の連続でした.とりあえずソースをご覧ください.

ドキュメントの探し方が悪いのか,Math系(Math.PI,Math.sin,Math.cos)が見つかりませんでした.「文法がJavaに似ているので同じ書き方だろう」と信じて試したところ動いたのでほっとしてます.

文法的に面倒だと感じたのは,インスタンス変数やインスタンスメソッドの呼び出し時にthisが必須なことでした.まぁ特に大きな問題ではないですね.

困ったのが配列の初期化でした.Java言語でいう「int x[] = new int[10];」を書きたかったのですが,試行錯誤の上断念しました.仕方ないので宣言時に「var ar = [0];」として強引にarを整数の配列として認識させ,このままでは0が邪魔なので,コンストラクタで「this.ar.pop();」して空の配列としています.その内,ドキュメントが整備されると思います.ドキュメントが整備されたら,この書き方を笑ってください.

後は単純に配列とループです.詳しいアルゴリズムは巷の書籍やWebページを参照してください.ループと言えば,Rubyのようなイテレータが楽で良いですね.

DFTの実行結果

実行結果です.今回の例では,func_yによって定められている関数を分析しています.具体的には 3sin(x) + 7cos(3x)を分析しているので,1倍と3倍の周波数の数値がそれぞれ3と7になっているので,きちんと動作していることが分かります.欲を言えばe-17とかが目立つので,printfが欲しいところです.

おわりに

今回はJSXの文法を確認するためにC言語で描かれたDFTを移植してみました.ものすごく恥ずかしいソースコードですが,JSXの文法確認のために公開します.

JSX自体はnode.js上で動作するのでグラフィック環境がありませんが,RhinoなどのJava VM上で動作するのなら,Javaのグラフィック機能を使ってみたいですね.それよりはWebブラウザ上で動作させるのが真っ当なので,今後試してみたいと思います.

今回参考にしたC言語のソースですが,自著であるこの本のものを使用しています.「三井田惇郎,須田宇宙,"数値計算方 第2版", 森北出版株式会社」.宣伝ではなく,参照元を明確にする意味で記しておきます.

最後になりますが,JSXの公開に感謝します.

追記

ソースコードをgithubのこちらに置いておきます(2012/6/14)

このエントリーをはてなブックマークに追加