- ベストアンサー
sinとcosを使って10度毎に線を追加させたい
Flash初心者です。 バージョンは5を使っています。 水平方向に一本線を書いておき、一方は固定、一方はsinとcosを使って0度から360度までの間で10度毎に座標を取り、新しく線を追加したいと思っています。 円周運動というのでしょうか? 本を読んでいてもよく分からないので、教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
#1&2です。 あぁ,説明不足でした。 deg は勝手に決めた変数なので,何処にもないと思います。というかあっては困ります。 Flash は普通の場合,変数を宣言しなくて良いので,自分が作るときには好き勝手で良いですけど, 他の人が見るとわかりにくいですよね。 #2の下のスクリプトを例にして,仮に,回転を 10度 だとすると, if文内は, if (time2>=time1+(1+i)*spd && ★10*i<360 && ★10*i>-360) { i++; duplicateMovieClip (_root.line0, "line"+i, i); _root["line"+i]._x = pos0_x+(_root.line0._width/2)*Math.cos(★10*i*Math.PI/180); _root["line"+i]._y = pos0_y+(_root.line0._width/2)*Math.sin(★10*i*Math.PI/180); _root["line"+i]._rotation = ★10*i; } (★は目印のために勝手に入れました) みたいになります。 これだと「やっぱり 10度 はやめて,20度 にしよう。」とか思ったとき, 全ての 10 を見つけだして 20 に変更するのは大変面倒です。 うかつに 10 → 20 みたいに置換をして, もし 110 みたいな数があったときそれまで 120 に置換されてしまったりしてグチャグチャになりなす。 それで,何度も使い回しをされる数は,変数に持たせておいてスクリプトを書いているのです。 同じ,#2の下のスクリプトで言うと,少なくとも最初の onClipEvent (load) { // 角度の設定(可変) ★deg = 10; // スピードの設定 単位ミリ秒(可変) ★spd = 500; // line0 の左端の座標を求める ★pos0_x = _root.line0._x-(_root.line0._width/2); // (_root.line0_width/2) ★pos0_y = _root.line0._y; // 変数 i の初期値設定 ★i = 0; // 変数 time1にタイマーをセット ★time1 = getTimer(); } の★の付いた,deg,spd,pos0_x,pos0_y,i ,time1は全部勝手に決めた変数です。 >> 直角三角形を回転させると三角錐になり、長方形を回転させると、円柱に、… と書かれていますが,いわゆる 3D に当たるものですよね。 Flash は 2D なので,その点はかなり難しいです。 私はActionScript自体は,簡単なものであれば,たいてい大丈夫なのですが,『数学』が非常に苦手です。 平面上の sin cos tan あたりなら,高校1年くらいに,一応やりましたからなんとかなるのですが, 立体になったり, cot や log など出てきたらさっぱりわからないのです。 Flash で3Dになると,どうしてもその辺が出てくるのでお手上げです。 以前,質問にあったものではココ↓が参考になるかもしれません。 上と下は同じ物ですが, 教えて!goo なら http://oshiete1.goo.ne.jp/kotaeru.php3?q=1446117 OKWave なら http://okwave.jp/kotaeru.php3?q=1446117 #2の方の回答が参考になるかもしれません。 (私は数学が苦手なので#1で沈没しております。) この質問者の方はそもそも何を質問されているかと言うと, 「正六面体の回転を作る」 http://hfm-kenchan.com//Lesson/flash16.htm 「ActionScriptによる3D描画」 http://blog.dawgsdk.org/weblog/archives/410041 みたいなのの,もっとシンプルなものの作り方を質問されているわけです。 他の人のサンプルや解説があるのはわかったのですが, それを改造して答えるのはイヤだったので,一から考えると,頭ボカンになって,#1の回答でごまかしたのです。 でも今,検索してみるとここにシンプルな例がありました。 「Fake Three-Dimensions 02」 http://kei.serio.jp/flash/ornament/Fake3D_02.html このURLでも回答しておいた方が良かったかもしれません。 でもFlash5では,このmoveTo とか lineTo で線を引けませんでした… すみません,あまり参考にはならない引用だったかもしれません。 でも,数学的にはこのように考えるようです。 また,アルファをかけて残像を作るとなると,moveTo とか lineTo ではなく 線のムービークリップを使った方がやりやすいとは思います。 >> 直角三角形を回転させると三角錐になり、 >> 長方形を回転させると、円柱に、 >> 真ん中が開いている場合はドーナツの円柱になるというアニメーションが作りたかったのです。 >> 残像を残して回転させて、Stopボタンを押したら、 >> その場所から一定角度ごとに図形の軌跡を残すというものを目標にしています。 書かれている内容はよくわかりますし,画像のイメージもなんとなく湧きます。 でも,私は数学が苦手で,この辺になると,お手上げです…
その他の回答 (2)
#1です。 すみません。#1でのスクリプトですが,1箇所大きなミスがありました。 // 変数 i を1プラスする i++; という部分ですが, if 文の中に入れないと, i が無茶苦茶にカウントアップされてしまい,とんでもないことになってしまうものでした。 以下のように訂正します。 ------------------------------------------ // このムービークリップが表示されたとき onClipEvent (load) { // 角度の設定(可変) deg = 10; // 変数 i の初期値設定 i = 0; // 変数 time1にタイマーをセット time1 = getTimer(); } // 1フレーム進む時間ごとに1回以下を実行 onClipEvent (enterFrame) { // 変数 time2 にタイマーをセット time2 = getTimer(); // time2>=time1+100(ミリ秒)のとき // かつ 角度が360度を超えないとき if (time2>=time1+100 && deg*i<360 && deg*i>-360 ) { // 変数 i を1プラスする i++; // line0 を line(1~?)というインスタンス名で複製 duplicateMovieClip (_root.line0, "line"+i, i); // 複製した line? を回転 _root["line"+i]._rotation = deg*i; // time1 に time2 の値をセット time1 = time2; } } ----------------------------------------- お詫びと言っては変ですけど,sinとcosも考えてみました。 考えてみると,そんなに難しくはありませんでした。ややこしいですけど。 ただ,やはりちょっと限定が付きます。 上のスクリプトだと線の位置や角度や長さなどは全く自由ですが, sinとcosを使った場合でなるべく簡単なスクリプトにしようと思うと, 制限ができてしまいます。 制限とは線の角度です。 最初に引く線を真横に引いてください。 縦や斜めなどの線では以下のスクリプトはそのまま使えません。 あと,一端も左限定です。 書いた横線の左端を基準にsinとcosで移動させ, そして回転させるアニメーションのスクリプトです。 まず,任意の長さで太さの線を横向きに引きます。 それをムービークリップにします。 そのときそのムービークリップの基準点が線の真ん中あたりにあることを確認してください。 今回はそのままで行きます。 基準点が線の真ん中あたりにあることを確認したら,そのムービークリップにインスタンス名を付けてください。 今回のスクリプトも前回同様,『line0』というインスタンス名を付けた物で説明します。 『line0』というインスタンス名の線のムービークリップができたら, その『line0』とは別のスクリプトを書くムービークリップを用意します。 前回と同じく,ステージ外に小さな四角い塗りを書いて,その塗りをムービークリップにしてください。 その,スクリプト用のムービークリップに以下のようなスクリプトを書けば, 『line0』が『line1』,『line2』… と複製され,複製されたムービークリップをsin,cosで移動,そして回転するというスクリプトになります。 コピペ可↓。 ////////////////////////////////////////////////////////////////////// // このムービークリップが表示されたとき onClipEvent (load) { // 角度の設定(可変) deg = 10; // スピードの設定 単位ミリ秒(可変) spd = 500; // line0 の左端の座標を求める pos0_x = _root.line0._x-(_root.line0._width/2); // (_root.line0_width/2) pos0_y = _root.line0._y; // 変数 i の初期値設定 i = 0; // 変数 time1にタイマーをセット time1 = getTimer(); } // 1フレーム進む時間ごとに1回以下を実行 onClipEvent (enterFrame) { // 変数 time2 にタイマーをセット time2 = getTimer(); // time2>= time2>=time1+(1+i)*spd のとき // かつ 角度が360度を超えないとき if (time2>=time1+(1+i)*spd && deg*i<360 && deg*i>-360) { // 変数 i を1プラスする i++; // line0 を line(1~?)というインスタンス名で複製 duplicateMovieClip (_root.line0, "line"+i, i); // 複製した line(1~?) を移動 _root["line"+i]._x = pos0_x+(_root.line0._width/2)*Math.cos(deg*i*Math.PI/180); _root["line"+i]._y = pos0_y+(_root.line0._width/2)*Math.sin(deg*i*Math.PI/180); // 複製した line? を回転 _root["line"+i]._rotation = deg*i; } } ////////////////////////////////////////////////////////////////////// 前回の分だと, スピード調整の部分がややこしいところにあったので, 可変の部分はすべて最初に持って行きました。 // 角度の設定(可変) deg = 10; // スピードの設定 単位ミリ秒(可変) spd = 500; カスタマイズするのは,この2行だけです。 あと,変更点は,時間の計算方法です。 前回のだと,相対的に毎回100ミリ秒みたいなのを設定して算出していたので,誤差が大きかったです。 今回は time1 time2 とを絶対的に比較しているので誤差は少ないと思います。 少ないと言っても, enterFrame で計算させていますから,フレームレート以上のスピードは出ません。 Maxがフレームレート(デフォルトでは12フレーム/秒)です。 またそれに近づけるだけ誤差は増えます。 Flash MX以上だと,setInterval が使えてもっと誤差は少なくできるのですが, Flash5ではこれがないので,カウンターを自作するしかないため,誤差が大きくなります。 Math.cos(deg*i*Math.PI/180) これが,cosを度で表す方法です。 汎用的に書くと Math.cos(度*Math.PI/180) です。 sinとcosは radian ですので,こうやってdegree を radian に変換して使います。 以上のような感じでどうでしょうか? 本当にこのようなスクリプトを使うのであったら,絶対上の方のスクリプトの方が良いですよ。 下の cos や sin は他で使うかもしれない向学のためと考えると参考にはなるかもしれませんけど。
むむむむ… 疑問… >> sinとcosを使って0度から360度まで… まず最初の疑問がsinとcosを使う理由です。 sinとcosは使おうと思えば,使うことも可能ですが,この場合普通はは登場しないのではないでしょうか。 sinとcosは座標を求めるときに使います。 書かれている感じだと x座標とy座標を算出する必要性が感じられませんが。 大筋は,『線の複製を作成』→『複製を回転』で良いのではないでしょうか。 sin,cosを使うと, 『線の一端の座標を求める』 →『線の複製を作成』 →『複製の座標をsin,cosから算出』 →『複製を移動』 →『複製を回転』 みたいになり,使えばまわりくどくてややこしくなりますよ。 結局,『線の複製を作成』や『複製を回転』はどっちにしてもしないとならないわけで,これを回避する手段にもなりません。 また,その座標も作りたい物によって変わってくるので,汎用的なスクリプトがおそらく作れません。 「ステージの大きさが400×400pxで,回転の中心をステージの中央にする場合。」 とかいう限定された回答しかしにくくなります。 次の疑問ですが,36本の線を一気に引いてしまうのか, アニメーションで1本ずつ引くのかがわかりませんでした。 でも, >> 円周運動というのでしょうか? と書かれていますから,運動=アニメーション と考えることにしました。 以下の例は sinやcosを使わず,一定時間ごとに10度間隔で線を引く方法です。 ステージの大きさや線の太さや長さは,どうでも良いです。 ======================================= まずステージ上に適当な線を引きます。 その線を選択→「挿入」→「シンボルに変換」よりムービークリップにします。 その線にインスタンス名を付けてください。 ここでは『line0』というインスタンス名を付けておきます。 次にその『line0』を右クリック→「同じ位置で編集」より,線を編集します。 編集に入ると + 印が見えると思います。それが,このムービークリップの基準点です。 描いた線のどちらか一方の端を,+ 印に合わせるように移動させてください。 これでムービークリップの基準点と線の一端が一致します。 この点を中心にムービークリップを回転させれば良いわけです。 「編集」→「ムービーの編集」でムービーの編集に戻ります。 線『line0』の位置を修正して良い位置に持って行ってください。 次にステージ外など見えない場所に,適当に小さな四角でも描いてそれをムービークリップにしてください。 これはActionScriptを書くためのムービークリップです。 特にインスタンス名は必要ありません。 このムービークリップに,『線の複製を作成』→『複製を回転』というスクリプトを書きます。 コピペ可能です。 ----------------------------------- // このムービークリップが表示されたとき onClipEvent (load) { // 角度の設定(可変) deg = 10; // 変数 i の初期値設定 i = 0; // 変数 time1にタイマーをセット time1 = getTimer(); } // 1フレーム進む時間ごとに1回以下を実行 onClipEvent (enterFrame) { // 変数 time2 にタイマーをセット time2 = getTimer(); // 変数 i を1プラスする i++; // time2>=time1+100(ミリ秒)のとき // かつ 角度が360度を超えないとき if (time2>=time1+100 && deg*i<360 && deg*i>-360 ) { // line0 を line(1~?)というインスタンス名で複製 duplicateMovieClip (_root.line0, "line"+i, i); // 複製した line? を回転 _root["line"+i]._rotation = deg*i; // time1 に time2 の値をセット time1 = time2; } } ----------------------------------- 変数 deg は10(度)にしていますが,変えても使えます。 正の数では右回り,負の数にすれば左回りになります。 if (time2>=time1+100 &&… の 100 の値を変えれば線が増える速さが変わります。 単位はミリ秒で,100 = 0.1秒 にしていますが,1000にすれば1秒ごとに線が追加されるスクリプトになります。 他は特に変える場所はないと思います。 普通のムービークリップであれば, そのムービークリップを非表示にしたいフレームで,そのムービークリップ自体を消してしまえば良いので,消すのは簡単ですが, 上のようにスクリプトで複製されたムービークリップはスクリプトで消さないと消えません。 もしくは,複製を特定のムービークリップの中に作って,そのムービークリップごと全てを削除するかです。 もし,複製されたムービークリップをスクリプト消したい場合は, 以下のように書いて消してください。 ----------------------------------- on (release) { // 変数 j が 36 になるまで for (j=1; j<36; j++) { // _root.line(1~?)を消す removeMovieClip (_root["line"+j]); } } ----------------------------------- 一応,これはボタンのスクリプトですが, あるフレームに来たとき,線を消したい場合は 1行目の 「on (release) {」 と最終行の 「}」 を取れば,タイムラインのスクリプトとしても使えます。 どうしてもsin,cosが必要な場合,ウンウン唸って考えてみても良いですが, 以上のような感じでどうでしょうか?
お礼
本当にご丁寧な回答、ありがとうございます。 実は、アクションスクリプトも今回が初挑戦でして、「deg」が一覧に無いよぉ・・・と独り言を言いながら挑戦している次第です。 完成にはまだ時間がかかりそうですが、ご教授いただいたとおりに最後まで頑張ってみます。出来たら必ずご報告させていただきます。 実は、ExcelのVBAでsinとcosを使って座標を求め、そこから中心点に向かって線を引くというマクロを書きました。同じことがFlashでもできるはず・・・と思い投稿したのですが、アプリケーションが違えば、考え方が違うのは当然ですよね。 Excelの世界に入り込んでいる最中に質問したので、質問も的を得ているようでそうでない書き方だったと思います。それにもかかわらず、こんなに丁寧なご回答をいただき、心から感謝しております。 直角三角形を回転させると三角錐になり、長方形を回転させると、円柱に、真ん中が開いている場合はドーナツの円柱になるというアニメーションが作りたかったのです。残像を残して回転させて、Stopボタンを押したら、その場所から一定角度ごとに図形の軌跡を残すというものを目標にしています。 ご教授いただいたスクリプトにたくさんのヒントが隠されていると思いますので、最後まで頑張ります。 是非、また報告させてください。 宜しくお願い致します。