待受時計を作ろう --- aka double の無い世界の暮らし方

[目次|前回|次回|携帯Javaのページ|ローカルドキュメント]
Time-stamp: "2004/11/03 Wed 11:51 hig"

double のない世界の暮らし方

楕円弧を描きたい!

Canvas に, (楕)円(弧)をを描くことを考えましょう. DoJa3.0(505i)以降のiアプリ, およびMIDPの場合には, drawArc というメソッドが用意されているのでこれを使えばいいです. しかし, DoJa3.0 未満の場合や, 楕円弧以外の, x,y 座標が sin, cos で表わされる曲線(例: 極方程式 r=sin(5θ) で表わされる曲線)などは, sin, cos を使って細かい折れ線として描くことになります. また, バイオリズム曲線など, sin, cos が必要な場合があります.

三角関数がない!

しかし, iアプリ/Vアプリ/EZアプリの従う J2ME CLDC1.0 には, sin, cos 関数はありません. そこで, 数表をおぼえておくか, Taylor 級数で計算することになります.

double もない!

さらに, 数表をおぼえておく, Taylor 展開で計算するといっても J2ME CLDC1.0 には, double/float 型がないので, 工夫が必要です. sin q=x/100000 のような分数だと思って, 整数 x をおぼえることにします. このように表現された実数に演算をするときは, 順序をよく考えなくてはいけません. int の間の演算では, ( 10 * 100 ) / 1000=1000/1000=1, 10 * (100 / 1000) = 10 * 0 = 0 です. 一般に, オーバーフローしない範囲で, 割り算は最後に1回だけ行う, ようにするのがいいでしょう.

サンプルArcSample.javaを参照してみましょう. ここで, この配列 sin, cos は, J2SE の TrigTable.java で作りました.

penguin15% javac TrigTable.java
penguin15% java TrigTable > table 
などとするのでした.

キャリア独自拡張を使う手はある…

キャリア独自拡張として, 固定小数点が提供されています. たとえば, au の KDDI Profile Phase3 の com.jblend.graphics.util.Calc, com.jblend.graphics.m3d.Point3D, Vodafone の com.j_phone.amuse.j3d.Util3D, com.j_phone.amuse.j3d.Vector3D, NTT DoCoMo の DoJa2.0 の com.nttdocomo.opt.ui.j3d.Math, com.nttdocomo.opt.ui.j3d.Vector3D などです. また, CLDC1.1 では, double 型がサポートされるそうです. また, J2ME CLDC1.0 に(すなわち,iアプリ/Vアプリ/EZアプリ共通に) 固定小数点クラスを追加するクラスライブラリ MathFP というものが存在します. 樋口はもっぱらこちらを使っています. 樋口による解説

ただし, Vアプリ,EZアプリの場合, これらの独自拡張は FixedPoint オブジェクトに対する sin, cos などのメソッドを持っています. しかし, これらは J2ME Wireless Toolkit の中からは使用できず, compiler や preverifier をコマンドラインで使用しなければなりません. EZアプリの場合は, KJXツールが使ってもいいです. Vアプリ/EZアプリの場合, MIDP Builder を使ってもいいです.

ここでは, これらの独自拡張を使わない例を示してみます. 各自, 独自拡張を利用した例もやってみてもいいです.

課題

デジタル時計のサンプルClockSample.java と, 三角関数の使い方を参照して, アナログ時計を作ろう. 世の中のアナログ時計って, 日時の表示があったり, 文字盤に絵が描いてあったり, 月齢計があったり, n時0分には楽隊が出てきて演奏したりするよね :) クラス Calendar の API は, CLDC のドキュメントの中にあります.

待受アプリの作り方

前回のマルチスレッドのサンプルを待受化した 例 ResidentSample.javaを示しています. 以前に使用した画像 pose0.gif/png, pose1.gif/png が必要です.

iアプリ

DoJa 2.0(504i)以降でサポートされます. IApplication でなく MApplication を継承したクラスを作ります. ADF設定で, MyConcierge を Yes にします. プログラマの責任で, 活性化状態 ⇒ 非活性化状態 ⇒ 休止状態 の遷移を, それぞれ, MApplication クラスの void deactivate() , void sleep() メソッドで行います. 待受に関わるイベントを, MApplication クラスの void processSystemEvent(int type, int param) メソッドで拾えます.

Vアプリ

ADFオプション設定で, MIDlet-Resident を Y とするだけです. com.j_phone.system.DeviceControl クラスのオブジェクトに, MailListener, ScheduleAlarmListener, TelephonyListener を登録することで, 待受中に発生したイベントを拾えます.

EZアプリ

待受アプリとするための設定は特にありません. Phase2.5以降でのみ, com.kddi.matiuke.EventManager のオブジェクトに, AlarmEventListener, CallEventListener, CMailEventListener, EMailEventListener を登録することで, 待受中に発生したイベントを拾えます.

課題

時計のアプリを待受アプリにしよう.