うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

Geogebraスキルアップ問題集(003解答)

003

 見本

Geogebraファイル

 

現在時刻の取得

リストオブジェクトtimeを、GetTime[ ]として定義する。timeは、現在時刻を表す元データとなる。

数値オブジェクトnowは、各針の角度を計算するための元となる数値であり、timeの要素のうち時・分・秒のデータを抽出し、現在時刻を「秒」ベースで表示するものである。

now=Element[time, 4] 3600 + Element[time, 3] 60 + Element[time, 2] + Element[time, 1] / 1000

ここで、nowの定義の末尾「+ Element[time, 1] / 1000」は、nowの値にミリ秒を加えるものである。これによって、のちにつくる秒針の動きがなめらかになる。

もしこの部分を書かなければ、時刻データの細かさは整数秒までとなり、秒針の動きも1秒おきにカチコチと動く。

 

各針の先端の点の定義

f:id:usiblog:20160817023816p:plain

図の点Oは、原点(0,0)である。

数値オブジェクトl_{h}, l_{m}, l_{s}は、それぞれ短針、長針、秒針の長さを表すための変数である。適宜調節する。

数値オブジェクトh, m, sは、それぞれ短針、長針、秒針が、半直線Ray[O,(0,1)]を反時計回りに何度回転させた場所にあるかを表すためのものである。なぜ反時計回りを前提に作成するかというと、後に使うRotateコマンドにおける角度が、反時計回りに測定した場合の角度を要求するからである。

それぞれの定義は、以下のようにする。

h=-30now / 3600

m=-6Mod[now, 3600] / 60

s=-6Mod[Mod[now, 3600], 60]

 

以上のオブジェクトを前提として、3点H, M, Sは以下のように定義する。

H=Rotate[(0, l_{h}), h°, O]

M=Rotate[(0, l_{m}), m°, O]

S=Rotate[(0, l_{s}), s°, O]

これでH, M, Sは、timeの時刻データに基づいて、それぞれ短針、長針、秒針の先端を示すことになる。

 

時刻のリアルタイム更新

このままでは、timeの時刻データが更新されないため、時計が動かない。

時計を動かすためには、timeの時刻データを更新する必要がある。

そこで、数値オブジェクトudtを用意して、udtの値が更新されるたびに、timeの値を最新の時刻データに更新するように設定する。

※udtはupdaterの略であるが、名前は何でも良い。

udtは、0〜100を1刻みで、速度1で往復するように設定する。速度が遅すぎると、時刻データの更新間隔が大きく開くことになるため、針の動きがなめらかでなくなる。

※見本において、udtの速度がgoとなっているのは、真偽値goを経由させることで、グラフィックスビュー左下に再生/停止ボタンが表示されるのを回避するためである。

udtは、値が更新されるたびにtimeの値を最新の時刻データに更新するためのオブジェクトである。そのため、udtのOn Update スクリプトには、以下を記述する。

SetValue[time,GetTime[]]

 

仕上げ

変数r、および時計を表す円Circle[O,r]を作成する。

OとH, OとM, OとSをそれぞれ線分で結んで完成。