よく来たな~、新兵ども!
$テン*シー*シー-bootcamp$テン*シー*シー-bootcamp2
 まずはこいつ↑で、iPhoneやiPadのアプリケーションを作るための知識を一から積み上げる事。どんな機材が必要か、どんな知識が必要か、から初めて、C言語、Objective-C言語まで学習してくれい。でないと、心が通じあえん。Bootcamp2は現在更新中ね。
 Webより本が好き~、な人は、

入門本、ドリル本、デバッグ本、データ本!

もよろしく。

「親切すぎるiPhoneアプリ開発の本」のサンプル、Xcode 8(Swift 3.0)対応について
2016.9.16
対応中だけど、もうちょい時間かかりそう。

Apple日本語ドキュメントページ恒例のリンク切れ。ここにリンク貼っておく。

「親切すぎるiPhoneアプリ開発の本」のExample、年明け以降に更新しますが、とりあえずここで連絡。
  29/Autolayout-02 ViewController.swiftの62行目
および、
  29/Autolayout-02-alt-00、29/Autolayout-02-alt-01、29/Autolayout-02-alt-02のViewController.swift 71行目は間違いです。

toItem:self.view, attribute:.Left,

toItem:self.view, attribute:.Leading,
に変更してください。

「親切すぎるiPhoneアプリ開発の本」は、ここにも近日公開予定。↓

10xEng480-32
1 | 2 | 3 | 4 | 5 |最初 次ページ >>
2016年10月30日(日) 04時23分52秒

だってフォーリンラブ

テーマ:物理シミュレーション

 前回予告した通り、重力加速度の話っす。

 

 地球では手から離れた鉄球は、1秒後には9.8m/s、2秒後には19.6m/sと速度を増加させつつ落下する。ただし空気抵抗は考えない。

 

 というのを中学の時に習ったと思いますが、そこで使われる

 

  t秒後の速度 = 9.8t

 

という式で出てくる9.8てのが重力加速度です。

 なので、落下中の鉄球の速度を縦軸、経過時間を横軸に取った折れ線グラフは以下のように描かれます。

 

 

 ちなみにmは距離の単位であるメートル(Meter)、sは時間の単位である秒(Second)です。あと、ここには出ていないけど、質量の単位にはkg:キログラム(kilogram)を使うのが物理でのお約束でMKS単位系と呼ばれてます。

 

 で話を落下中の鉄球に戻すんですが、この鉄球の動きをアニメーションで表現しようと思うと、鉄球の位置を時間経過に合わせて逐次更新しないといけないので、必要となるのは速度じゃなく移動距離になるんですな。

 

  t秒後の速度 = 9.8t

 

ではなく

 

  t秒後の移動距離 = t

 

が知りたいわけですよ。

 

 

 これが固定された速度での移動、例えば速度10m/s固定でのt秒後なら

 

  t秒後の移動距離 = 10t

 

で解決なんですが、今回の場合、経過時間によって速度が変わるんで、この計算式は使えない。

 

 じゃ、どうするかというと、例えば大雑把に1秒ごとに、その時点での速度を使って、1秒間の移動距離を計算し

 

   t秒後から1秒間の移動距離 = t秒後の速度 x 1秒

 

 とし、この移動距離を加算していくという方法なんかがあります。
 

注意)どうやって移動距離を求めたかは後述

 

 見た通り、かなりな誤差が出ますが、これを1秒じゃなく0.5秒に狭めてやると
 

   t秒後の0.5秒間の移動距離 = t秒後の速度 x 0.5秒

 

 

 少し誤差が改善されるわけです。

 で、この0.5秒間隔の移動距離てのは、最初のグラフに当てはめると、速度x時間=縦軸x横軸、すなわち面積で表現されることになるわけです。

 例えば下のグラフなら肌色の領域すべてで、3秒後の移動距離(誤差付き)を表現してることになる。

 

 

 で、間隔を0.5秒じゃなく0.1秒でやるとどうなるかというと

 

 

 となって、どんどんこの時間間隔を小さくしていって、極限まで時間を短くした場合は

 

 

 となり、これって結局

 

  底辺が経過時間で、高さが速度の三角形の面積

 

が移動距離なわけじゃーんとなって


  三角形の面積=1/2・底辺・高さ

  底辺=t、高さ=9.8t

 

から

 

  1/2・9.8t・t = 4.9t・t

 

てのが、t秒後の移動距離ってことになるわけです。つまり

 

  t秒後の移動距離 = t

 

の部分は

 

  4.9t

 

というのが答えです。高1で習うはず。

 こうやって「t秒後の速度 = 9.8t」の式から「t秒後の移動距離 = 4.9t・t」という式を導き出しt秒後の移動距離を求める方法を

 

 tに関する速度の式から、tに関する移動距離を解析的に解く

 

といいます。

 これに対し、三角形の面積を見つけるまでにやったように、時間間隔を0.1秒とかにして合計し、誤差付きでt秒後の移動距離を求める方法を

 

 tに関する速度の式からtに関する移動距離を数値的に解く

 

といいます。

 当然、解析的に解けるのがベストなんですが、現実は、そうそう簡単に解ける式は少なく(解けないものもある)て、そういう場合は数値的に解くしか方法がないわけです。

 

 たとえば今回の落下の運動だって、本当なら落下物の形状や質量、速度に応じた空気抵抗が発生することになり、これを考慮した速度変化の式は、調べてみたんですが

 

 

といったものになるようです。

 このtに関する速度の式からtに関する移動距離を解析的に解けるのかというと、う〜ん、どうなんでしょ。解ける人は解けるのかな〜。私は挑む気にもならない。

注意)ちなみに、このレベルを解析的に解く場合、大学で習う微分方程式を使うことになります。

 

 なんですが、数値的にはこの速度の式があれば解けるわけですよ。

 誤差付きだけど、できるだけ時間間隔を小さくして解けば、それなりの解が得られるはず。数秒後の移動距離を計算するのに、上の小難しい計算を何百回と地道に繰り返すことになるけど、それこそコンピュータの得意な仕事なわけで…

 

 この数値的に解く方法を次回から実際に使ってアニメーションしていきます。

 じゃまた。

 

AD
いいね!した人  |  コメント(0)  |  リブログ(0)
最近の画像つき記事
 もっと見る >>
2016年10月24日(月) 00時46分14秒

阿呆定理

テーマ:エウレカ

女子教育「コサイン教えて何になる」

 

 てことは…

 cos側はiが残らないグループ

  cos同士か、sin同士(iの2乗=-1が掛けられる)の掛け合わせ

 

 sin側はiが残るグループ

  cosとsinの掛け合わせ

 

なので

 

 cos(A+B) = cosA・cosB + -1・sinA・sinB

 sin(A+B) = cosA・sinB + sinA・cosB

 

これで、サクッと思い出せるか。

AD
いいね!した人  |  コメント(0)  |  リブログ(0)
2016年10月16日(日) 09時55分39秒

超高校級のMikuMikuDance

テーマ:物理シミュレーション

 前回から続けてthreeStart関数の解説。

 コメントをはぶいて、後に続く4行がカメラの作成と設定っす。

 

 こいつね↓

 

 newが付いてるのでわかると思うけど、最初の1行がカメラオブジェクトの作成。

 THREE.PerspectiveCameraというクラスのオブジェクトです。

 

  camera = new THREE.PerspectiveCamera( 45 , frame.・・・10000 )        

 

 作成されたカメラオブジェクトは、camera = としてるので、以後、変数cameraを使ってカメラオブジェクトにメッセージを送ることができます。これもrendererと同じくvar無しなんだけど、このvarの有無については後述。

 

 var frame =   ← varが付く

 renderer =   ← varが付かないの違いは?

 

 THREE.PerspectiveCamera作成時の付加情報としては

 

  縦側の視野角:     45度

  高さに対する横幅の比: frame.clientWidth / frame.clientHeight

  手前クリップ深度:   1

  奥クリップ深度:    10000

 

てのを送ってます。

 こいつはカメラ越しに見える3D領域と、その光景が投影された2D画面を定義するもので、視野角を広く指定すれば、その分、映り込む3D空間が広がります。

 

カメラ越しに見える3D領域と、その光景が投影された2D画面

 

 

 こんな感じで、指定する視野角は投影される2D画面の縦側に利用され、横側は高さに対する横幅の比によって決定されます。で、残りの手前クリップ深度、奥クリップ深度で、カメラ越しに切り取る3D領域の前面部と後面部を、カメラの位置からの距離で指定してる。

 興味を持った人は、実際に自分で値を変えて表示がどうなるか試してみるといいでしょう。値を変えるとリアルタイムで画面が変わるページがあったんで、そっちで試してみるのもよし。

 

 ここね↓

 THREE.PerspectiveCamera

 

 次は作ったカメラオブジェクトの位置を指定。

 

         camera.position.set(0, 50, 100);

 

 positionはカメラオブジェクトのプロパティで、3次元空間でのカメラ座標を示す。この3D座標を表現するプロパティ自身もオブジェクトなのでsetメッセージで座標を指定してます。付加情報としてx、y、z座標の順に , で区切って渡してる。

 でもって、カメラはpositionプロパティの位置から、lookAtメッセージで指定される座標(注視点)に向くことになり、カメラ位置から注視点への線が、視線となるわけです。こっちは連想配列でx、y、zキーで座標を指定することになるみたい。

 

        camera.lookAt( {x:0, y:0, z:0 } );  ←注視点の指定

 

 

 じゃ、camera.up.set(0, 1, 0)てのは何だよっていうと、カメラが持つupプロパティの指定ってことになります。upプロパティは2Dの投影画面の上方向が3D空間上ではどっち方向かを指定してるっぽいです。

 positionプロパティと同じクラスのオブジェクトなんでsetメッセージで向きを指定する。カメラは、視線が決まっても、それだけだと視線を軸に360度ぐるぐる回転できるので、向きを固定するための情報が必要なんですな。

 

 

 この場合、与えるx、y、zは座標ではなく方向ってことに注意。

 

 

 これを、例えばcamera.up.set(1, 1, 0)なんかにすると、カメラを斜めに傾けた映像になります。

注意)今回は、y軸に沿って増加方向を指定したんだけど、後で調べたら、この値はカメラ作成時に初期値として設定される値なんで、別にわざわざcamera.up.set(0, 1, 0)を書かなくても問題なかったんだよね。やれやれ。

 

 ちなみに、ここで語っている3D座標は、右手座標系と言われるものです。

 

 右手座標系↓

 

親指を回転軸の正の方向に向け、残る4本の指が向いている方向が正の回転方向という決まりだそうです。

 

 高校の幾何だと圧倒的に右手座標系がメジャーですが、左手系てのもあって、3Dでの位置情報や回転情報は、どっちかに決めて話をしないと、話してる方と聞いてる方でイメージがグチャグチャになるんで注意しましょう。

 

 左手座標系↓


 

 混ぜると危険。 

 

 カメラが終わったら、次はシーンの作成。

 シーンはTHREE.Sceneというクラスのオブジェクトです。

 シーンを作ってからカメラ作ってもいいです。ここらへんは順序関係なし。

 

 

 で、このシーンオブジェクトに光源を配置してるのが

 

 

という処理。

 今回の光源にはTHREE.PointLightというクラスのオブジェクトを使う。

 こいつを作成してシーンに追加してます。光源作成時の付加情報としては

 

光源の色:    FFFFFF

光源の強さ:   2

光源の届く範囲: 300

 

を順に渡してます。色はRGB三原色を16進表記で2文字ずつ並べて6文字の16進数として指定。

 RGB三原色てのは、赤(Red)、緑(Green)、青(Blue)の3色で、この3つの色の強弱を組み合わせると人間が感じとれる色の実用的な範囲は表現できることになる。RGB3色全部最強の明るさにした時は真っ白ね。

 

 

 

 three.jsだと色の強さは0〜255の範囲で強さを指定でき、これを16進表記で書くと0〜FFの範囲ってことになる。

 16進表記てのは、日頃使ってる0〜9の数字に加えて10〜15の数をアルファベットのA〜Fで表記する方法。これだと日頃使ってる数の表記法である10進表記に比べ、0から15までを1文字で表せることになる。

 

 

 なので、10進表記が9の次で桁上げ(位を変える)するのに対し

 

 

 16進表記だと15の次で桁上げ(位を変える)することになる。

 

 

 同じ47という数を書き表してるのに、10進表記と16進表記じゃ全然表記が違うんで注意しましょう。

 なぜにこんな書き方するかというのを語り出すと、なぜに色の強さを0〜255で表現するんだ、0〜100の方がキリがいいじゃんというところから話さないとダメになるんで、詳しくは自分で「2進数 16進数 コンピュータ」あたりでググってください。

 

 とにかく今回のFFFFFFは、赤、緑、青、すべてFF=255の最強値なんで、真っ白の指定ってことになります。

 あと、THREE.PointLightは点光源と言われる光源で、光源の位置から放射状に光が広がります。電球をイメージすればいいでしょう。

 色の他には、光の強さと、その届く範囲を指定してます。

 

 ちなみに太陽光は平行光源に分類されて、それ専用の光源クラスもある。

 太陽も点光源ちゃ点光源だけど、地球との距離があまりに離れてるのでほぼ平行になるて話は小学生の理科で習ったはず。これをまじめに位置計算して点光源として指定してもめんどくさいだけでメリットない(というか計算誤差が大きくなりすぎてしまうのか?)ってんで、太陽を表現する時は平行光源オブジェクトを使うみたい。

 

 とにかく光源オブジェクトを作ったら、カメラと同じくpositionプロパティを設定して位置を決めてシーンに登録。

 シーンへのオブジェクトの登録は、登録したいオブジェクトを付加情報に指定したaddメッセージを使います。

 

        light.position.set( 100, 60, 80 )  ←位置決め

        scene.add(light)         ←登録

 

 その次の

 

         arrengeObjects()

 

はarrengeObjectsという関数の呼び出しで、この関数で、立方体と球体を作成してシーンに追加してます。

 

 

 別関数にしたのは、今後、この関数を変更していろいろ実験する予定だから。

 関数名のarrengeObjectsは適当に決めた。

 立方体と球体、どちらもTHREE.Meshというクラスのオブジェクトです。

 THREE.Meshてのは複数の3角形平面で構成された多面体で、この3角形平面の配置を定義しているのが

 

 THREE.CubeGeometry:立方体を表現する複数の3角形平面配置情報クラス

 THREE.SphereGeometry:球体を 〃

 

のオブジェクトっす。THREE.CubeGeometryの場合は付加情報として、立方体の大きさをx、y、zの順に指定。

 THREE.SphereGeometryの場合は付加情報として

 

 半径:   20

 横分割数: 20分割

 縦分割数: 20分割

 

を順に指定。分割数にあんまり小さい値を指定するとガタガタの球になります。

 THREE.Meshオブジェクト作成時は、この配置情報のオブジェクトと、多面体に光が当たった時にどう表示されるかの設定を表現した

 

 THREE.MeshLambertMaterial:素材情報クラス

 

のオブジェクトを付加情報として渡します。

 THREE.MeshLambertMaterialは、例えば木の素材、ガラスの素材、それぞれが持つ固有のざらつきや滑らかさ、反射特性を表現するもんです。

 細かく調整することで金属っぽくしたり、紙、プラスティックぽくできます。

 今回は単純に色だけ指定してあとはお任せする。いろいろな設定があるんで連想配列での指定になってますな。colorキーで色を指定してます。

 

 こうやって作成したTHREE.Meshオブジェクトは、シーンに登録することで、画面に表示されます。光源オブジェクトと同じくaddメッセージ使います。

 

        scene.add(cube);   ←立方体オブジェクトの登録

   ・・・

        scene.add(sphere);  ←球体オブジェクトの登録

 

 ここでいよいよvarを付けるつけないの違いが出てきます。例えば変数

 

  scene

 

にはthreeStart関数でシーンオブジェクトを割り当ててるんですが、もしこれを

 

        scene = new THREE.Scene();

 

じゃなく

 

        var scene = new THREE.Scene();

 

としていると、画面には何も表示されないことになります。

 なぜかと言うと、関数内での初登場時varをつけてる変数は、その関数から戻るときに破棄される決まりだからです。

 例えば、今回threeStart関数で用意した変数frameは初登場時にvarをつけてるので、別の関数(仮にanother関数とする)で、同じように初登場時にvarをつけた変数frameを用意しても、これはthreeStart関数側のframeとは別物となります。

 

 

 じゃあ、関数内で初登場時にvarをつけなかった変数はどうなるかというと、関数外で用意されているものとみなされます。

 こいつを一般にグローバル変数といいます。関数内限定で用意する方はローカル変数という。

 

 こんな感じ↓

注意)ただし、varを付けることができるのは、関数内初登場時の 変数名 = ・・・ といった処理や、初登場時にvarを付けた変数名だけを記述する処理 var 変数名; の場合のみ。いずれも変数宣言(後述)を意味する。

 

 なので、さっきのようにthreeStart関数内で作った変数sceneの前にvarをつけると、このsceneは他の関数で利用できなくなっちゃうんですな。

 

注意)この場合、関数外に明示的に「var scene;」と書いてないし、関数内初登場時のvar無しの scene = ・・・ といった記述もなくなるので、sceneなんて変数は存在しないというエラーになる。

 

 この仕組みがないと、関数内だけで一時的に使いたい変数に対しても、いちいち「この変数別の場所で使ってなかったよな、使ってる変数の値、勝手に変えちゃまずいよな」と確認する必要がでてきて、非常にめんどうくさくなる。

 非常に役立つ仕組みなんだけど、varを付ける付けないで、こういったトラップにもなるんで気をつけましょう。

 あと、グローバル変数は変数tのように、いちいち関数外に並べておく方が、はっきりしてわかりやすいです。これを変数宣言ていいますが、今回はわざと省略してみますた。JavaScriptちゃんはこれでもガッツで動く。

 

 変数宣言

  var t;

 

 初期値の設定付き変数宣言

  var t = 0;

 

 ということでvarの説明も終わってあとひといき。

 addの後は、cube、sphereのpostionプロパティに座標を指定して、sphereをcubeのちょっと上に配置してます。ちなみに、three.jsが用意してくれてるTHREE.CubeGeometryやTHREE.SphereGeometryはpostionで指定された位置が、自身の中央位置を示していると解釈して移動します。

 

 

 arrengeObjects関数の後に呼び出しているloop関数は、Web画面への表示を支持する処理。Web画面表示中はアニメーションさせるために繰り返し呼び出す必要がある処理群なんで、独立した関数にしてます。名前は何でもいいけど、繰り返しって事がわかりやすいようにloopて名前にしてる。

 

 

 このうち、THREE.WebGLRendererオブジェクトにシーンとカメラオブジェクトを付加情報としたrenderメッセージを送ってるところが、Webブラウザの画面に3D空間を描画した2D画面が表示させる処理。

 

        renderer.render(scene, camera); ←cameraでsceneを撮って表示せよ!

 

 renderer、scene、cameraはすべてグローバル変数なんで、threeStart関数で設定した各オブジェクトを指し示してます。

 renderメッセージを送る前にやっているcubeのrotationプロパティへの設定は回転量の指定。このプロパティもオブジェクトで、setメッセージでx、y、zの順にそれぞれの軸の回転量を渡すことで設定される。

 

        cube.rotation.set(0, 0, t/100)

 

 今回ならz軸に対して、t/100ラジアンの回転を指定してることになる。

 ラジアン単位が0〜2π(π:3.14)で0〜360度を表現する角度の単位てのは高校で習います。2Dや3Dの回転では、サイン・コサイン・タンジェントが大活躍するんでラジアン単位を使うのが基本となっとります。

 サイン・コサイン・タンジェントについては、いずれ使うんでその時に。

 

 ここで使ってる変数tはWebに画面が表示されている間は、回転量を保持する必要があり、ローカル変数にして関数が呼び出されて戻るたびに毎回作成・破棄されちゃ困るんで、グローバル変数として変数宣言してます。一番最初の値を0とするために = 0 としてる。

 

    var t = 0; ←こいつね
    function loop() {

 

でloop関数内で

 

        t++;

 

とやってるので、tはloop関数を呼び出すたびに1増えます。++は変数の値を1つ増やす処理。他の書き方として

 

  t = t + 1;

 

というのもあります。これはまず = の右側の計算が行われて、その結果を = で結ばれた左側の変数に設定するという意味。

 省略記法として

 

  t  += 1;

 

てのもあります。

 結果、loop関数が呼ばれるたびに、cubeはz軸に対して

 

  1/100、2/100、3/100、・・・、呼び出された回数/100

 

ラジアンの回転を与えられることになる。

 画面の動きから考えてloop関数が繰り返し呼ばれていることになるけど、この仕組みはloop関数の最後に、windowという変数が示すオブジェクトに送っているrequestAnimationFrameメッセージで実現してます。

 

        window.requestAnimationFrame(loop)

 

 変数windowは、これまでの説明でグローバル変数だというのはわかると思うけど、これはJavaScript側で用意された変数で、現在JavaScriptが動作中のWeb画面を持つウィンドウを表現したオブジェクトを示してます。

 注意)同じようにthreeStart関数の初っぱなで使ってる、変数documentもJavaScript側で用意された変数です。こっちは前回説明したとおり。

 

 そのウィンドウに対して、付加情報にloopを指定したrequestAnimationFrameメッセージを送ることで、「ウィンドウさんは、次のアニメーションのための画像更新のタイミングが来たらloop関数を呼び出してね」という指定になる。

 試しに // を使ってコメントにしたらアニメーションが止まります。

 

        //  window.requestAnimationFrame(loop);

 

 だいたい1/60秒たつと呼び出されるみたいなんで

 

  (1/100ラジアン) / (1/60秒)

 

の速度で回転することになる。なので

 

   t++

 

 

   t = t + 3

 

とかすると、1/60秒ごとに3/100ラジアンづつ回転することになって「そんな、通常の3倍の速度で回転している」ってことになるよ。

 

        renderer.clear()
 

は画面の消去。前の画面を消してから新しい画面を描いてる。なんか省略しても大丈夫っぽいけど、一応やってる。

 

 以上で、これからやる物理シミュレーションの舞台についての基礎的な話はおしまい。

 次回は、いよいよ物理シミュレーション自体の基礎的なお話。

 やっとだよ。

 扱うのは、お約束の重力加速度だ!

 

 ま、それは置いといて、three.jsのサンプルにMikuMikuDanceのローダーがあったんで、そのご紹介。

 試しに別のmmdファイルを指定してみたら動きましたわ〜。

 

 名前自体もネタバレ指定にされてる○刃696ちゃん。

  キャラ名 MMDモデル

 でググれば見つかると思われ。

 解凍してできたフォルダをまるごと

  three.js-master/examples/models/mmd/

に置いて、その中にある拡張子が.pmxのファイルを

  three.js-master/examples/webgl_loader_mmd.html

  var modelFile

に指定すれば踊る。

  var modelFile = 'models/mmd/追加フォルダ名/MMDファイル名.pmx';

て感じ。

 

 すごいっす。

 Clothシミュレーションや、頂点モーフ、IKなんかも自前でやってるっぽい。

 じゃまた。

 

 three.jsのオブジェクトの公式説明自体は以下です。

 

 例)PerspectiveCamera

 

AD
いいね!した人  |  コメント(0)  |  リブログ(0)
1 | 2 | 3 | 4 | 5 |最初 次ページ >>

AD

Ameba人気のブログ

Amebaトピックス

      ランキング

      • 総合
      • 新登場
      • 急上昇
      • トレンド

      ブログをはじめる

      たくさんの芸能人・有名人が
      書いているAmebaブログを
      無料で簡単にはじめることができます。

      公式トップブロガーへ応募

      多くの方にご紹介したいブログを
      執筆する方を「公式トップブロガー」
      として認定しております。

      芸能人・有名人ブログを開設

      Amebaブログでは、芸能人・有名人ブログを
      ご希望される著名人の方/事務所様を
      随時募集しております。