• ベストアンサー

ActionScriptでアナログ時計

ActionScriptでアナログ時計を作ったのですが、いまいちスクリプトの意味が分かりません。 _rootのタイムラインに長針・短針・秒針をまとめたムービークリップを配置し(Y軸に対して水平)、そのムービークリップの1フレーム目に以下のフレームアクションを記入しました。 now = new Date(); theHour = now.getHours(); theMin = now.getMinutes(); theSec = now.getSeconds(); ここまでは現在の時間を取得しているという事が分かりますが、問題は以下です。hour、min、secはそれぞれ短針、長針、秒針のMCの名前です。 hour._rotation = (theHour*30)+(theMin/2)-90; min._rotation = theMin*6-90; sec._rotation = theSec*6-90; この2,3行目については、「分・秒ともに60回で360°を一周するから、一度に6°ずつ動く。それに分または秒を掛けたものがそのMCの角度になる。Y軸に水平になっているから90を引くことで12時のところが起点になる」という理解でよろしいでしょうか。 問題は1行目です。theHourに30を掛けるのは12時間*30°で360°になるからで、その後が分かりません。

質問者が選んだベストアンサー

  • ベストアンサー
noname#35109
noname#35109
回答No.1

なんか,書かれているスクリプトは複雑ですね。 アナログ時計 http://www17.ocn.ne.jp/~wolves/SCHOOL/lecture/lectureS1_4.html このような感じに最初から針を縦に作れば90度引く必要はないと思いますが, なぜ横向きに作るのでしょうかね。よくわかりません。 縦向きに作るとシンプルになりますよ。 this.onEnterFrame = function() { now = new Date(); theHour = myTime.getHours(); theMin = myTime.getMinutes(); theSec = myTime.getSeconds(); hour._rotation = (theHour*30)+(theMin/2)-90; min._rotation = theMin*6-90; sec._rotation = theSec*6-90; } みたいな感じに。 >> 問題は1行目です。 >> theHourに30を掛けるのは12時間*30°で360° >> になるからで、その後が分かりません。 最初に横向きに針を作ったから90度がでてくるので, ちょっと,90度は無視します。 針は縦向きに作ったとしておきます。 hour._rotation = (theHour*30)+(theMin/2); まず1日は12時間ではなく,24時間です hour._rotation = (theHour*30)+(theMin/2); hour._rotation = (24*30)+(theMin/2); hour._rotation = 720+(theMin/2); 1日で720度回転する。つまり360度を2回回転させるわけです。 実際に,時計の長針は1日で2回回転しますよね。 だから,式は合っています。 また,1時間は60分です。 (theMin/2); =(60/2); =(30); 長針は,1時間で 360/12 =30 度 回転しますね。 =(30); は,この 30 です。 hour._rotation = (theHour*30)+(theMin/2); ~例1~ もしちょうど1時だと, hour._rotation = (1*30)+(0/2); hour._rotation = (30)+(0); hour._rotation = 30; と言うことです。 1時間で,長針は 360/12 = 30 度 回転します。 つまり1時の向きに向きます。 ~例2~ 1時30分だと, hour._rotation = (1*30)+(30/2); hour._rotation = (30)+(15); hour._rotation = 45; 実際の時計の長針も,1時30分には45度傾きます。 とこういうことですけど… 90を入れるとややこしいので, 90を入れずに,色々な数字を代入してやると,なるほど,式は合っているとわかると思います。 と言うより,実際の針の動きになるように,定数を入れて行くと書かれてあるような式になるわけです。 数学が苦手なので,ちゃんとした "証明" にはなっていませんが, 考えていたら結局書かれているような式になりますよ。 最初に書いたURLの式は,こんなのです。 _root.Hneedle._rotation = (H*30)+(M*0.5); _root.Mneedle._rotation = M*6; _root.Sneedle._rotation = S*6; 針の名前がちがうので,針の名前を合わせると,こうなります。 hour._rotation = (H*30)+(M*0.5); min.._rotation = M*6; sec._rotation = S*6; ご質問にある式から90を取るとこうです。 hour._rotation = (theHour*30)+(theMin/2); min._rotation = theMin*6; sec._rotation = theSec*6; 考えた人によって書き方は変わります。 でも,書き方が違うだけで同じ式ですね。 現実の針の動きを数式化しているのです。 あまり良い説明だとは思えませんが,一応,自分なりの説明です。

ikehata_shin
質問者

お礼

分かりやすい説明本当にありがとうございました。

その他の回答 (1)

  • DPE
  • ベストアンサー率85% (666/776)
回答No.2

末尾に付いている -90 は、#1の方がおっしゃるように、針のムービークリップを最初から 12 時の方向(”↑”というような感じで)にして作り、初期配置も 12 時を指すように配置すれば不要です。 -90 の部分は描画上の都合ですので、とりあえず無視して話を進めます。 周知の通り、1日は 24 時間でアナログ時計の文字盤は1周 360°・ 12 時間なので、短針は1日に時計を2周、つまり 24 時間で 720°回ることになります。 これは、” 360°を 12 時間で回る”という同じ動きを1日に2回繰り返しているだけです。 例えばムービークリップを 90°回転した場合と 450°(← 90°+ 360°)回転した場合とでは、450°の回転は1回転多く回っただけで、ムービークリップの向きそのものはどちらも同じです。 時計の短針もこれと同じことです。 例えば昼の3時と夜の3時では、昼の3時は夜の0時から数えると2周目に入っていますが、短針の向き自体は夜の3時と全く同じです。 ここでは” 24 時間で 720°回転”ではなく、アナログ時計の文字盤通り” 12 時間で 360°回転するもの”と考えます。 短針は 360°÷ 12 = 30 で、1時間に 30°傾きます。 12 時の位置を0°とすると、1時ちょうどには1× 30 = 30°、2時ちょうどには2× 30°= 60°・・・となります。 式にすると  時間× 30° です。 ご質問文のスクリプトでは、変数 theHour には getHours メソッドにより現在の時間が入っています。  > hour._rotation = (theHour*30)+(theMin/2)-90; の theHour*30 は、12 時を基点とした時の、ちょうどの時間(例えば1時0分)での短針の位置を求める計算です。 ---------------------------------------------------------------- ところで、アナログ時計の針の動きをよく見てみますと、短針は”1時間ごとに1回だけ、30°傾く”のではありませんよね。 正確には、”1時間かけて 30°傾いていく”のです。  > hour._rotation = (theHour*30)+(theMin/2)-90; の theMin/2 の部分は、この動作を実現させるための補正です。 1時間は 60 分ですから、60 分かけて 30°傾くのなら、1分あたりの傾斜角度は 30 ÷ 60 = 0.5 で 0.5°となります。 これに現在の分を乗算した値がその分での傾斜角度ですが、実際の短針は、その時間ちょうどの位置の分だけ既に傾いていることになります。 例えば1時 20 分ですと、12 時の位置を0°とするならば、1時0分の短針の角度は  1× 30 = 30° です。 ここから更に 20 分間経過した角度だけ傾いているので、20 分後の傾きである 20 × 0.5 を加算します。 従って、短針のムービークリップ” hour ”の傾きは  hour._rotation = ( 1 * 30 ) + ( 20 * 0.5 ); となります。 変数を使って式にしますと、  hour._rotation = ( theHour * 30 ) + ( theMin * 0.5 ); です。 ********************************** プログラミングでは、一般に小数点の付く計算は嫌われます。 コンピュータも人間と同じく、小数の計算はできればない方が処理は軽いですし、ゴチャゴチャと細かい小数点が付くと、変数がオーバーフロー(桁あふれ)を起こして値が破壊されたり、誤差のために原因がよく分からない不具合が発生しやすくなるからです。 0.5 の乗算くらいなら別に大した問題ではありませんけれど、小数を使わずに済むように別の考え方をしてみましょう。 先述のように、短針は1時間= 60 分かけて 30°傾きます。 60 分で 30°傾くならば、例えば 60 分の 1 / 4 にあたる 15 分では何度傾くでしょうか? いろいろな考え方がありますが、ここでは比を使って考えます。 ” 60 分で 30°傾くなら、15 分では何度傾くか?”を比で表しますと、  60 : 30 = 15 : 角度 となります。 比は、”=”を挟んだ内側同士の積と外側同士の積が等しいという性質があります。 つまり、  60 × 角度 = 30 × 15 が成り立ちますから、正攻法で行くなら  角度 = 30 × 15 ÷ 60 です。 しかし、  60 ×角度 = 30 × 15 この式を、”=”を境にしてよく見比べてください。 60 は 30 の2倍にあたります。 30 が2倍になったのであればその相方の 15 は半分にすると、計算の帳尻が合います。 従って求める角度は、15 の 1 / 2 である 7.5°となります。 こんな小学生レベルの方法(^^;)ではなく、もう少し理論的に考えますと。 正攻法の  角度 = 30 × 15 ÷ 60 の式は、先頭から真っ向に計算していくのはあまり得策ではありません。除算を含む計算は分数で表してみると、約分して計算が簡単になったり計算回数を減らせたりすることができるからです。 この式は、 (↓表示フォントによっては位置がズレますがご容赦ください)       30 × 15  角度 = ──────         60 と表すことができます。 30 と 60 で約分が可能で分子の 30 は消えますから、最終的には  角度 = 15 / 2 で、つまり 15 を2で除算したものが求める角度となります。 15 の部分は実際には現在の分(ご質問文のスクリプトでは変数 theMin )で時刻により変化していますが、「 60 ×角度 = 30 × 現在の分」という関係は現在時刻が何分であっても常に成り立ちます。 ですから、現在の分の半分、変数では theMin を2で除算した角度がその分での短針の傾きを表す補正値となるのです。 ・・・とまあ、真面目に考えますと何だかいっぱしの学問のようですね。 基本的には小学校か中学校で習う割合や比の問題ですが、時間や角度という想像しにくい概念なので、少々難しく見えるだけだと思います。 「 theMin / 2 」と「 theMin * 0.5 」は計算結果はどちらも同じで、式の上ではただの表現の違いにしか見えません。 数学では、「 theMin * 0.5 」が「 theMin / 2 」と同じだとひらめくことが解法につながったり、より速く確実に計算できる場合もあります。 しかし今回の例では、なぜ分を2で割るのか、分になぜ 0.5 を掛けるのか、その理由を考えていくと、この結論に至るまでの過程はまるで違います。時には、単なる表現の違いでは済まない場合もあるのです。 (余談ですが、数学はただ正しい答えを求められるようになればいいのではなくて、理論的な考え方やスジの通った考え方を学ぶ学問だと思います。日本の数学教育は考え方を教える面が欠けているような気がします...) もっとも、式を立てた本当の理由は本人にしか分かりません。 比にして考えますと、結果として「分÷2」の式が出てきます。 ですが式を立てた人はこんな回りくどい思考過程を踏んだのではなく、1分あたりの傾斜角度 0.5 を掛ければいいけれど、「 theMin * 0.5 」だと小数になるが「 theMin / 2 」なら結果は同じで小数がなくなるから都合がいいじゃないかと、直感的にひらめいただけなのかもしれません。