- ベストアンサー
複雑過ぎて頭がこんがらがっています
これは画像を衛星のように動かすプログラムです。 まずソースコードを貼り付けます。 <html> <head> <title>Satellite pictures</title> <script language="JavaScript"><!-- iList = ["img0","img1","img2","img3","img4","img5"]; cx = 100; // 回転の中心X座標 cy = 100; // 回転の中心Y座標 cnt = 0; rx = 100; // 回転半径(横) ry = 50; // 回転半径(縦) function rotZIMG(){ for (i=0; i<iList.length; i++){ n = (i * (360 / iList.length) + cnt++) * Math.PI / 180; y = cy - Math.cos(n) * ry; z = 100 - Math.cos(n) * 50; // 画像表示サイズと兼用 document.images[iList[i]].style.pixelLeft = cx + Math.sin(n) * rx; document.images[iList[i]].style.pixelTop = y; document.images[iList[i]].style.zIndex = z; document.images[iList[i]].style.width = z / 1.5; document.images[iList[i]].style.height = z / 2; } } // --></script> </head> <body onload="setInterval('rotZIMG()',100)"> <div style="color:#ff00ff;font-size:18pt">Satellite pictures</div> <br> <br> <img src="image/circle.gif" style="position:absolute;top:60px;left:80px;z-index:100;"> <img src="image/0.jpg" name="img0" style="position:absolute;"> <img src="image/1.jpg" name="img1" style="position:absolute;"> <img src="image/2.jpg" name="img2" style="position:absolute;"> <img src="image/3.jpg" name="img3" style="position:absolute;"> <img src="image/4.jpg" name="img4" style="position:absolute;"> <img src="image/5.jpg" name="img5" style="position:absolute;"> </body> </html> まず画像が奥に行くに従って小さくなるので画像が3Dに見えるように錯覚を起こしてしまいいる。まずは画像の動きですよね。 3Dの回転というのを見るのが初めてなので凄く難しい。 横と縦に回転して、実際に画像がどう動いているのかがよく分かりません。 ただ、画像が小さくなるのはどこでやっているか分かりました。 document.images[iList[i]].style.width = z / 1.5; document.images[iList[i]].style.height = z / 2; ここですよね。でも奥に行くに従って徐々に小さくなるのには別のソースコードが必要ですよね。 それはどこに書いてあるのでしょうか。 問題は次の式です。 z = 100 - Math.cos(n) * 50; 100は横の回転半径で50は縦の回転半径の数値なんですかね。 因みに、知識不足なんですけどz-indexって何を意味してるんですかね。 辞書調べても載ってなかったので分かる方教えて下さい。 初歩的な知識も含めて、このソースコードを分かりやすく解説してくれる方、お待ちしております。 どうぞ宜しくお願い致します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
さて~俺か~^^; rx = 100; // 回転半径(横) ry = 50; // 回転半径(縦) y = cy - Math.cos(n) * ry; document.images[iList[i]].style.pixelLeft = cx + Math.sin(n) * rx; document.images[iList[i]].style.pixelTop = y; y軸に対してはry、x軸に対してはrxが乗算されています この場合、 ry=100 /2; と考えると、x軸の長さも、y軸の長さも同じ正円になります そしてy軸のながさを半分にします つまり、横につぶれた円を創造できるでしょう? z = 100 - Math.cos(n) * 50 このコサインは、最小で-1。最高で1の値を示します なので 100 - (-1*50) = 100-(-50) = 150 100 - (1*50) = 50 ということで範囲が算定できます >円の中心を100ずらしているという部分ですが、これは楕円軌道で回転する円でいいのでしょうか。 zとxの変化を見れば、正円の軌道を描きますが、このプログラムでは z値は、文字の大きさに使われていて、座標をあらわす計算には使われていません なので、距離が変化していますが、図の表示順とその大きさに使われています 何故上手く奥に画像が行った際に縮小されるのでしょうか。 座標系には、左手座標系と右手座標系があります t_netbugさんが示した参考URLに目を通しましょう! >何故上手く奥に画像が行った際に縮小されるのでしょうか。 プログラムのz値の変化を alert('z='+z);//この行をプログラムに追加する のようにして、z値の変化を観察してみましょう~!時間がかかるけどね >自分のレベルの差が天と地もある事に・・・ 貴方が気づいていないだけで、ここの板にも、向こうの板にも、私から見て天と地の差もある人達が ゴロゴロいます。とくに私にとって「神様」的存在の人も、困った時にこちらの板にも降臨してきてくれます^^; ちょっと天につばを吐いているように見えましたよ。だから自分の尊敬する人に、あぁ~なんてことを! と思ったり・・・。^^; 回答者の方は、ただ質問に答えるのではなく、質問者に上達してほしいと思うからこそ、遠まわしに教えてたり コードだけ示したり、丁寧に教えていたりと努力してくれるのです。(まじ人それぞれ表現の仕方は違いまが。) なので、回答者の方に指摘されたら、それに応えるのが質問者のマナーだと思います。 応えるというのは、お礼の返事を書くのではなく、コードで示す!です。成長した成果が見たいのです! 私も、ここで大変お世話になりました。なので上級者の方にはお礼ができないので、質問者の方に 答えられるときは、自分なりに考えて調べて答えています。これが結構自分の勉強になります。 ちなみに私はプロではありません。分類でいうと(そんなのあるか?)サンデープログラマです。 趣味の範囲ですね~。ちなみに自分の中で基準があります。そのプログラムを作ったら面白いのか? とそれを作るとしたら30分で作れるか?です。 ちなみに3Dの字がくるくる下から上に回転するプログラムで40分でした。 ちょっとプログラム的には、汚いし、みんなで笑っていることでしょう~!
その他の回答 (4)
そうそう自分のレベルって測る基準がわかりませんね。 自分的には、10段階表記で、下から2くらいかなぁ~なんて思ってます! マジ! 上には凄い人達が・・・・。
お礼
再度のレスを頂き、ありがとうございます。 できれば、補足質問に答えてもらえたら大変有り難かったのですが、無理でしたか。 話は変わりますが、この前紹介して頂いたURLでTAGというサイトに行きました。 あそことここでより多くの回答が貰えると喜びましたが、大きな間違いでした。 そのおかげで1つ教訓を覚えましたが。 俺はこの質問に書かれているソースコードも読み取れません。 _pipi_さんが10段階で下から2なのだとしたら、自分はマイナス10ぐらいでしょうか。 この質問をTAGの掲示板にも書きたい思いで一杯です。 そうすれば、もしかしたら私が理解できるくらいのレベルで解説を書いてくれる人がいるかもしれない。 勿論、いないかもしれない。 自分はいない確率の方が高いと考えていますがね。 このプログラムを理解するために、私は何をすべきなのでしょうかね。
まぁ~まぁ~ということで、息抜きに。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <title>Mojiga kuru2</title> <body> <p>文字列の表示</p> </body> <script type="text/javascript"> //@cc_on var str = '1文字が1メラメラだとすると、これは3ボウボウとかになるのかな~?まぁ~世の中いろいろな人がいるから、な~な~で良かったり。'; var strLen = str.length; var cha = [], c; var sinTbl = []; var cosTbl = []; var i, max; var cnt =0; r = 200; x2d = 400; y2d =400; var rd = Math.PI / 180; for (i = 0; i < 361; i++) { sinTbl[i] = Math.sin( i * rd ); cosTbl[i] = Math.cos( i * rd ); } for (i = 0; i < strLen; i++) { c = document.createElement('p'); c.style.position = 'absolute'; c.style.fontSize = '10px'; c.appendChild( document.createTextNode( str.substr(i, 1) ) ); cha[i] = document.body.appendChild( c ); } function kaiten(){ var t; for(i = 0; i < strLen; i++){ t=i*720/strLen; with(cha[i].style){ var z = zahyo( sin( t + cnt) * r, -100-i*5+cnt, cos( t + cnt) * r); top = z.y + 'px'; left = z.x + 'px'; fontSize = z.f+'px'; /*@if(1) filter = 'alpha(opacity='+ z.o+ ')'; @else @*/ MozOpacity = (z.o / 100); opacity = (z.o/ 100);/*@end@*/ } } cnt+=1; if(cnt>700) cnt =0; } function sin(n){ return sinTbl[ ((360 + n) % 360)|0 ];} function cos(n){ return cosTbl[ ((360 + n) % 360)|0 ];} function zahyo(x,y,z){ var k = (600-z) /400; var x = x2d - x / k; var y = y2d - y / k; var f = 40-k*10; var o = 100-k*30; return {'x':x, 'y':y, 'z':z, 'f':f, 'o':o } } setInterval( kaiten, 20); </script>
お礼
一言圧巻です。 自分の実力の無さをまざまざと知り、ちょっと鬱入ってます。 上のソースコード動かしてみました。お見事です。 何かもう軽々しく_pipi_さんと呼べませんね。 自分は途轍もない人と出逢い、歓喜してます。 まず、自分はまだまだプログラミング言語を知らなさ過ぎる事を実感しました。 自分は所詮ホームページに飾りつけする程度だと思っていましたが、これはアッと驚く出来事です。 今自分がテキストにしている題名を少しはさんでみました。 今使ってるテキストなんて……。 困りました。もっと勉強しないとドンドン遅れていくような気がする。
- t_netbug
- ベストアンサー率34% (15/44)
難しく考えすぎているような…。 この関数で行っている式はプロジェクション座標からスクリーン座標変換を行った結果、算出された式だと思えば良いかな~と。 pipi様の回答が一番分かりやすいデスね・・・。 cosの特性をうまく使って遠近感を演出しているにすぎないって事ですね。 蛇足となりますが、3Dプログラミング用の数式、考え方などはここに書かれてました。 http://www.c3.club.kyutech.ac.jp/gamewiki/index.php?3D%BA%C2%C9%B8%CA%D1%B4%B9 高校3年までの数学知識で理解できると思います。
お礼
レスを頂き、ありがとうございます。 そうですか。悲しい事に意味が全然分かりません。 泣けてきますね。 プロとアマだとこうも差の開きがでるものですかね。 プロレベルまで辿り着こうなんて思ってもいませんが、でも、こうも力量の差を見せつけられると正直凹みますね。 それと、3Dプログラミング用のサイトを紹介してもらい、大変感謝しています。 いつか役に立ててみせますので……。
さてさて、遅ればせながら自分なりに噛み砕いて説明してみます。 頭の中でダブっていたら読み飛ばして下さい。 サイン・コサイン・タンジェントなんて三角形に使うもの!と思わないで 円の描画に使う程度だと気楽に考えましょう。 r^2=y^2-x^2 この式だと、xに対して2つのyの値が導き出され、円の図であれば、 +側なのか-側なのか面倒です。 そこで、原点を中心にして考えます。 角度と距離(r)でxとyを求めようとするのが次式です y=cos(角度*PI/180)*r x=sin(角度*PI/180)*r 角度は、マイナスでもプラスでも360度を超えてもOK! でも面倒なので 角度=(角度+360)%360; にして、360で割って余りを使うことで、ループ内で使うのであれば常に 正の値にの角度で使えます(初期値が-360以下だとだめですが) (座標系なんて、右回りでも左回りでも上でも下でも関係ないでしょう?! 回転してればどうせ見た目同じだし^^;) (計算に時間のかかる関数なのであらかじめテーブルにして計算しておいて 使う方法とかもあります。) たとえば三角形を描くときに3点の座標を求めます for(i=0;i<361;i+=360/3){ ここにiを角度にして座標計算・・ } 衛星が回るようにするのであれば、360/3の、「3」を衛星の数にします ここではiList.lengthですね >3Dに見えるように錯覚・・ あなたが考えたとおりこれは、ただの横につぶれた楕円軌道を描くだけです そして問題の一つが、zIndexですね スタイルシートで定義するときは z-index ですが、スクリプトで使うときはzIndexとします これと似たようなものにbackground-colorもあります。これもスクリプトで使うときは backgroundColorです ようは'-'をとり、次の文字は大文字にする。そんな程度で覚えて置いてください。 zIndexは画像が重なって表示されたときに、手前に表示させるか、奥に表示させるかに使われます なので z = 100 - Math.cos(n) * 50 が50~150の範囲で奥行きを変化させます。 ここでの100は、横の回転半径ではありません。 円の中心を100だけ奥にずらしている?と考えればOK! >奥に行くに従って徐々に小さくなるのには別のソースコードが必要 これは、必要ありません。これはあくまで楕円軌道です。 奥(上)に行った図の、高さと幅をzで割って、小さく見せているだけです。 もし、3Dで計算するならyの値にzの値が関連してくるはずです。 以下みたいな~(あくまでも気楽に考えてね。プログラムの文法ならエラーだから) 2Dx = 3Dx - (1/3Dz); 2Dy = 3Dy - (1/3Dz); document.images[iList[i]].style.pixelTop = y; これはストレートな記述なので、しつこいようですが楕円軌道です
お礼
_pipi_さん、またお逢いできて嬉しい限りです。 今の時点で脳みそはパッパラパーとでも言うのでしょうか。 今回はお礼&補足説明をお願いするかもしれません。 横に潰れた楕円軌道ですか。まずこういうモノを身近では初めて見たので多少困惑しています。 まず rx = 100; // 回転半径(横) ry = 50; // 回転半径(縦) の部分ですが、このコメントが難解です。 これだと横と縦に回転しているように読み取ってしまいます。 これは一体何が言いたいのでしょうか。 次に z = 100 - Math.cos(n) * 50 が50~150の範囲で奥行きを変化させます。 ここでの100は、横の回転半径ではありません。 円の中心を100だけ奥にずらしている?と考えればOK! 何故50~150と断定できるのでしょうか。 後、円の中心を100ずらしているという部分ですが、これは楕円軌道で回転する円でいいのでしょうか。 最後に document.images[iList[i]].style.width = z / 1.5; document.images[iList[i]].style.height = z / 2; についてですが、これで奥に画像が行く際に画像を縮小させるのでしょうが、何故上手く奥に画像が行った際に縮小されるのでしょうか。 これならば、画像が前方にある時点で縮小される恐れは無いのですか。 質問は以上です。 今、_pipi_さんと自分のレベルの差が天と地もある事に驚かされています。 いやはや凄い人だったんですね。 改めてお訊きしますが、_pipi_はプロの方なのですか。 それとも、この程度のプログラムなんかヘッチャラなんでしょうか。 そうだとしたら、脱帽ですね。 またのレス、期待してますね。
お礼
まず、1つお詫びをしなければなりません。 これを読む前に新しい方を先に読んでしまいお礼を書いてしまいました。 ちゃんと質問に答えてくれたのに、大変申し訳ありません。 それと、_pipi_さんが指摘してくれたアドバイスを読んで、また1つ勉強させてもらいました。 どうしても他力本願になってしまうのが、私の悪い癖です。 t_netbugさんが貼り付けてくれた参考URLをもう1度じっくり見てみます。 最後に1つだけ質問させて下さい。 何故プログラム作成の時間に制限をするのでしょうか。 プロならば納期内という時間的制限があります。だから、少しでも早くやるというのなら話は分かりますが、プロではない_pipi_さんには制限というものが存在しないですよね。 そこを敢えて自分を追い詰めるような制限を作るのには何かしら理由があると思うのですが。 別に答えたくなければ、それでも一向に構いません。でしゃばり過ぎている面もあるので。 TAGというサイトを知る事ができたのも、それ以上に_pipi_さんと知り合えた事にも感謝しています。 前のお礼の内容に少し触れますが、もし私がTAGの方にも同じ内容の質問、いわゆるマルチポストをしたら、_pipi_さんは失望されるでしょうね。 おそらく、今回の質問に対してはこの辺でそろそろ謎解きを終わらせる時期だと私は感じています。 しかも、ここからは自分の力だけで解決できるのがBetterなのではないか、と思っています。