最後の更新は次の時刻以降のはず. Time-stamp: "2003/09/05 Fri 18:11 hig"
円を書くのにも, sin, cos を使いますが, i-appli の java では, sin, cos 関数はないので, 値を覚えておくしかありません.
また, 覚えておくと言っても, double 型がないので, sin q=x/100000 のような分数だと思って, 整数 x を覚えることにします. これに演算をするときは, 順序をよく考えなくてはいけません. int の間の演算では, ( 10 * 100 ) / 1000=1000/1000=1, 10 * (100 / 1000) = 10 * 0 = 0 です. 一般に, オーバーフローしない範囲で, 割り算は最後に1回だけ行う, ようにするのがいいでしょう.
/* double の扱い. sin, cos の作成 hig Time-stamp: "2003/01/20 Mon 22:01 hig" */ import com.nttdocomo.ui.*; import com.nttdocomo.util.*; public class CanvasTable1 extends IApplication { /** 起動するときに呼ばれる メソッド. 必須. */ public void start(){ CircleCanvas cc=new CircleCanvas(); Display.setCurrent(cc); Timer ti=new Timer(); int interval=100; ti.setTime(interval); // interval ミリ秒で発生するタイマー ti.setRepeat(true); // 繰り返し発生するタイマー ti.setListener(cc); // クラス cc の timerExpired を使用. ti.start(); // カウントダウン開始. 一時停止は, ti.stop(); } } class CircleCanvas extends Canvas implements TimerListener{ CircleCanvas(){ if( getWidth() > getHeight() ){ radius=getHeight()/2; } else { radius=getWidth()/2; } } public void paint(Graphics g){ // g.lock();//画面をいったん固定(ダブルバッファリング) // 下の unlock とペアでアンコメントしてみよう. g.clearRect(0,0,getWidth(),getHeight());// 画面を消す for(int i=0; i < period ; i++){ /* (x1,y1) と (x2,y2) の間に線分をひく */ g.drawLine( radius + (radius * sin[ theta%period ]) /magfactor,//x1 radius - (radius * cos[ theta%period ]) /magfactor,//y1 radius + (radius * sin[ (theta+1)%period ]) /magfactor,//x2 radius - (radius * cos[ (theta+1)%period ]) /magfactor//y2 ); /* g.drawLine( radius + radius * (sin[ i%period ] /magfactor) ,//x1 radius - radius * (cos[ i%period ] /magfactor) ,//y1 radius + radius * (sin[ (i+1)%period ] /magfactor),//x2 radius - radius * (cos[ (i+1)%period ] /magfactor) //y2 ); だとどうなるかな */ } g.fillRect(radius + (radius * cos[ theta%period ]) / magfactor, radius - (radius * sin[ theta%period ]) / magfactor, 4,4); // g.unlock(true);//画面を再度表示(ダブルバッファリング終了) } /** Timer が 0 になったとき呼ばれるメソッド implements TimerListner を宣言したらこれが必要 */ public void timerExpired(Timer source){ theta=(theta+1) % period; // 角度を進め repaint(); // paint() を再度呼び出す. } int radius; /** 2pi に相当する 度 */ private final int period=360; private final int magfactor=100000; // 100000.0*sin(n度) を長さ 360 の整数配列にしたもの // 本当は, sin の始め90個から sin, cos すべてを簡単に計算できるはず. private final int sin[]={ 0,1745,3489,5233,6975,8715,10452,12186,13917,15643, 17364,19080,20791,22495,24192,25881,27563,29237,30901,32556, 34202,35836,37460,39073,40673,42261,43837,45399,46947,48480, 49999,51503,52991,54463,55919,57357,58778,60181,61566,62932, 64278,65605,66913,68199,69465,70710,71933,73135,74314,75470, 76604,77714,78801,79863,80901,81915,82903,83867,84804,85716, 86602,87461,88294,89100,89879,90630,91354,92050,92718,93358, 93969,94551,95105,95630,96126,96592,97029,97437,97814,98162, 98480,98768,99026,99254,99452,99619,99756,99862,99939,99984, 100000,99984,99939,99862,99756,99619,99452,99254,99026,98768, 98480,98162,97814,97437,97029,96592,96126,95630,95105,94551, 93969,93358,92718,92050,91354,90630,89879,89100,88294,87461, 86602,85716,84804,83867,82903,81915,80901,79863,78801,77714, 76604,75470,74314,73135,71933,70710,69465,68199,66913,65605, 64278,62932,61566,60181,58778,57357,55919,54463,52991,51503, 49999,48480,46947,45399,43837,42261,40673,39073,37460,35836, 34202,32556,30901,29237,27563,25881,24192,22495,20791,19080, 17364,15643,13917,12186,10452,8715,6975,5233,3489,1745, 0,-1745,-3489,-5233,-6975,-8715,-10452,-12186,-13917,-15643, -17364,-19080,-20791,-22495,-24192,-25881,-27563,-29237,-30901,-32556, -34202,-35836,-37460,-39073,-40673,-42261,-43837,-45399,-46947,-48480, -50000,-51503,-52991,-54463,-55919,-57357,-58778,-60181,-61566,-62932, -64278,-65605,-66913,-68199,-69465,-70710,-71933,-73135,-74314,-75470, -76604,-77714,-78801,-79863,-80901,-81915,-82903,-83867,-84804,-85716, -86602,-87461,-88294,-89100,-89879,-90630,-91354,-92050,-92718,-93358, -93969,-94551,-95105,-95630,-96126,-96592,-97029,-97437,-97814,-98162, -98480,-98768,-99026,-99254,-99452,-99619,-99756,-99862,-99939,-99984, -100000,-99984,-99939,-99862,-99756,-99619,-99452,-99254,-99026,-98768, -98480,-98162,-97814,-97437,-97029,-96592,-96126,-95630,-95105,-94551, -93969,-93358,-92718,-92050,-91354,-90630,-89879,-89100,-88294,-87461, -86602,-85716,-84804,-83867,-82903,-81915,-80901,-79863,-78801,-77714, -76604,-75470,-74314,-73135,-71933,-70710,-69465,-68199,-66913,-65605, -64278,-62932,-61566,-60181,-58778,-57357,-55919,-54463,-52991,-51503, -50000,-48480,-46947,-45399,-43837,-42261,-40673,-39073,-37460,-35836, -34202,-32556,-30901,-29237,-27563,-25881,-24192,-22495,-20791,-19080, -17364,-15643,-13917,-12186,-10452,-8715,-6975,-5233,-3489,-1745}; // 100000.0*cos(n度) を長さ 360 の整数配列にしたもの private final int cos[]={ 100000,99984,99939,99862,99756,99619,99452,99254,99026,98768, 98480,98162,97814,97437,97029,96592,96126,95630,95105,94551, 93969,93358,92718,92050,91354,90630,89879,89100,88294,87461, 86602,85716,84804,83867,82903,81915,80901,79863,78801,77714, 76604,75470,74314,73135,71933,70710,69465,68199,66913,65605, 64278,62932,61566,60181,58778,57357,55919,54463,52991,51503, 50000,48480,46947,45399,43837,42261,40673,39073,37460,35836, 34202,32556,30901,29237,27563,25881,24192,22495,20791,19080, 17364,15643,13917,12186,10452,8715,6975,5233,3489,1745, 0,-1745,-3489,-5233,-6975,-8715,-10452,-12186,-13917,-15643, -17364,-19080,-20791,-22495,-24192,-25881,-27563,-29237,-30901,-32556, -34202,-35836,-37460,-39073,-40673,-42261,-43837,-45399,-46947,-48480, -49999,-51503,-52991,-54463,-55919,-57357,-58778,-60181,-61566,-62932, -64278,-65605,-66913,-68199,-69465,-70710,-71933,-73135,-74314,-75470, -76604,-77714,-78801,-79863,-80901,-81915,-82903,-83867,-84804,-85716, -86602,-87461,-88294,-89100,-89879,-90630,-91354,-92050,-92718,-93358, -93969,-94551,-95105,-95630,-96126,-96592,-97029,-97437,-97814,-98162, -98480,-98768,-99026,-99254,-99452,-99619,-99756,-99862,-99939,-99984, -100000,-99984,-99939,-99862,-99756,-99619,-99452,-99254,-99026,-98768, -98480,-98162,-97814,-97437,-97029,-96592,-96126,-95630,-95105,-94551, -93969,-93358,-92718,-92050,-91354,-90630,-89879,-89100,-88294,-87461, -86602,-85716,-84804,-83867,-82903,-81915,-80901,-79863,-78801,-77714, -76604,-75470,-74314,-73135,-71933,-70710,-69465,-68199,-66913,-65605, -64278,-62932,-61566,-60181,-58778,-57357,-55919,-54463,-52991,-51503, -50000,-48480,-46947,-45399,-43837,-42261,-40673,-39073,-37460,-35836, -34202,-32556,-30901,-29237,-27563,-25881,-24192,-22495,-20791,-19080, -17364,-15643,-13917,-12186,-10452,-8715,-6975,-5233,-3489,-1745, 0,1745,3489,5233,6975,8715,10452,12186,13917,15643, 17364,19080,20791,22495,24192,25881,27563,29237,30901,32556, 34202,35836,37460,39073,40673,42261,43837,45399,46947,48480, 50000,51503,52991,54463,55919,57357,58778,60181,61566,62932, 64278,65605,66913,68199,69465,70710,71933,73135,74314,75470, 76604,77714,78801,79863,80901,81915,82903,83867,84804,85716, 86602,87461,88294,89100,89879,90630,91354,92050,92718,93358, 93969,94551,95105,95630,96126,96592,97029,97437,97814,98162, 98480,98768,99026,99254,99452,99619,99756,99862,99939,99984}; int radius; int theta=0; }
ここで, この配列 sin, cos は, J2SE の プログラム で作りました.
penguin15% javac TrigTable.java penguin15% java TrigTable > tableなどとするんですね.
ちなみに, 標準でない MathFP というクラスライブラリを使うと, もう少し楽に小数を扱えます. 樋口による解説
アナログ時計を作ろう. 世の中のアナログ時計って, 日時の表示があったり, 文字盤に絵が描いてあったり, 月齢計があったり, n時0分には楽隊が出てきて演奏したりするよね :)
ここでデジタル時計の例. クラス Calendar の API は, CLDC のドキュメントの中にあります./* 日時の扱い. hig Time-stamp: "2002/11/27 Wed 22:23" */ import com.nttdocomo.ui.*; import java.util.*;// Calendar を使う import com.nttdocomo.util.*; // Timerを使う public class DigitalClock1 extends IApplication { /** 起動するときに呼ばれる メソッド. 必須. */ public void start(){ ClockCanvas cc=new ClockCanvas(); Display.setCurrent(cc); Timer ti=new Timer(); ti.setTime(1000); // 1000ミリ秒で発生するタイマー ti.setRepeat(true); // 繰り返し発生するタイマー ti.setListener(cc); // クラス cc の timerExpired を使用. ti.start(); // カウントダウン開始. 一時停止は, ti.stop(); } } class ClockCanvas extends Canvas implements TimerListener{ public void paint(Graphics g){ Calendar c = Calendar.getInstance(); g.clearRect(0,0,getWidth(),getHeight());// 画面を消す g.drawString( c.get(Calendar.HOUR) + "時" + c.get(Calendar.MINUTE) + "ふん" + c.get(Calendar.SECOND) + "秒くらいだよん" , 0,getHeight()/2); } public void timerExpired(Timer source){ repaint(); // paint() を再度呼び出す. } }