質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.03%

楕円の軌道上を等速で移動するn個の点の計算について

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 3,833

score 14

楕円の中心点、大きさは以下です。

CENTER_X = 0,
CENTER_Y = 25,
RADIUS_X = 280,
RADIUS_Y = 75

この楕円の軌道上をn個のスプライトを等速で動かしたいです。
スプライトは1個〜15個です。

updateで以下の計算をしています。
float newX = (CENTER_X + cos(m_theta) * RADIUS_X);
float newY = (CENTER_Y + sin(m_theta) * RADIUS_Y);

sprite->setPosition(newX, newY);
m_theta += 100.0f;

加算するm_thetaの算出方法が知りたいです。
スプライト12個の時にm_theta +=100.0fで丁度良い速度になるので、同じ速度を他の個数の時にも再現したく思います。

何卒よろしくお願いします。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+1

数学的な話をするなら,速さv=sqrt((dx/dt)^2+(dy/dt)^2)を求めて,
微分方程式dv/dt=0を解いてm_thetaと時間tの関係式を求めることになると思います.
ただ私も最後まで解けないですし,実用上プログラムに組めるのか,という疑問もあります.
途中まで解いて

方程式ただし
theta式(xr = RADIUS_X, yr = RADIUS_Y)
という式になりました

追記
自己満足ですが,近似を使ってグラフを描いてみました
近似の方法は,ある時点でのθをθn,その時の求めるθの差分をΔθnとします.
また,時間差分はΔtで一定だとします.
Δθnが微小なら,dθ/dt≒Δθn/Δt
θの2階微分はΔθ/Δtの差分をΔtで割ったもの,
すなわち((Δθn/Δt)-(Δθn-1/Δt))/Δt = (Δθn - Δθn-1)/Δt^2
で近似できます(Δθn-1は前回のΔθの計算結果で既知である).
これらを適用すると,
差分方程式という方程式が得られます.
これをΔθnについて解くと,f'(θn)≠0,すなわちsin2θn≠0の場合
近似解sin2θn=0の場合は Δθn=Δθn-1

この結果を使い,θ=0の時から始めて,最初のΔθを設定して順次足しあわせて行きました

θ-t
θ-tΔθ-t(初期Δθ=0.02rad)
Δθ-tこの粗い精度(Δθがθ=0,π,2πで揃わない)でも計算回数が100回単位になります(2π回るのに770回以上).
速く動かそうとすると厳しいですね.
だんだん誤差が大きくなると途中でルートの中がマイナスになるエラーになりますし.

追記2度々の追記すみません.
上の計算の精度は,最初に与えるΔθの値が0に近づくほど上がります.
初期Δθ=0.001radで,θ=πでのΔθの誤差は0.2%以下になりました(π回るまでの計算回数が8000回に達しましたが).
あらかじめこの計算をしておいて,θの配列を作っておく,と言うのはどうでしょうか.
θが0からπ/2までの情報があれば,残りの範囲は比較的単純な計算で求められます.
そのままでは数が多すぎるので,必要に応じて例えば100回ごとの値をピックアップしておきます.
スプライトごとに時間を示すインデックス番号(0からθ配列の最大数-1)と象限の情報(1-4)を入れておいて,
double[] theta;
int i; //インデックス
int quadrant; //象限

//以下メソッド内のイメージ
//インデックスと象限の操作
/*updateでiを一定値増加させたあと*/
if(i >= theta.length){
    i -= theta.length;
    quadrant += 1
    if(quadrant > 4)
        quadrant -= 4;
}

//座標を求めるためのm_thetaを求める
switch(quadrant){
    case 1:
        m_theta = theta[i];
        break;
    case 2:
        m_theta = Math.PI - theta[theta.length - i];
        break;
    case 3:
        m_theta = Math.PI + theta[i];
        break;
    case 4:
        m_theta = 2 * Math.PI - theta[theta.length - i];
        break;
}
このようにm_thetaを求めることができます.
速さはインデックスの変化の速さでコントロールすることができます.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/03 15:13

    凄い!
    数学的で一般式としては上記のように解くと思います。
    角速度一定ならともかく、進む速度一定だと計算が異常に面倒になる気がするので、演出上許す範囲で、楽な方法を選択した方がいいと思います。
    ゲームだとキラキラが回るような演出よくあるけど、どうやってるんですかね・・・フレームワークにないのかな

    キャンセル

  • 2015/03/10 18:22

    いや、凄いですね。
    hpfoonさんが仰るようにゲームでよくあるクルクル回るやつを作ろうとしてるのですが、
    回る点の個数が可変するんで、苦労してるんですよねー。

    キャンセル

  • 2015/03/10 18:48

    このグラフを書くときにθに対応するΔθを求めてそれをθに加えて
    新たなθに対応するΔθを求めて・・・というのを繰り返しているんです.
    この過程で出てきた多数のθやΔθをつないでグラフを書いています.
    そして上記の計算ではΔtは一定として計算しているので,
    この計算で求められた,ある時点のθと次のθに対応する点では,
    どこをとってもほぼ等しい距離になります.
    いわば,楕円軌道を等間隔に細分化していることになります.
    なので,その細分化した軌道を同数ずつに分ければ,スプライトの位置を等間隔に分けられます.
    問題は,θの配列をメモリに置くと相当データ量が大きいということなんですよね・・・
    (javaのfloat型(16ビット=4バイト)で1000個並べただけで4キロバイト・・・)

    キャンセル

0

何点か気になるところがありました。
  1.  タイミングを合わせる処理はどのようにやっているのでしょうか。ループ内の処理負荷でタイミングを合わせるような処理だと、動かすマシンや負荷などの環境が変われば速度も変化してしまいます。
  2.  厳密に言えば、このままだと長い方向に行った時に速くなって、等速ではなくなっています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/02 17:05

    回答ありがとうございます。
    1〜15個のスプライトを楕円状に配置して、横方向にスワイプすると回転する処理を作っています。
    Cocos2d-xで実装していますが、他の簡単な方法でも問題ありません。

    キャンセル

0

等速というのが、軌道上の移動速度なのか、見た目の速度?なのかで変わってきますね・・・
前者と仮定した場合、ちょっとずるいかもですが、
単位時間に進む距離が十分に小さいと仮定した場合、楕円は小さな移動ベクトルの集合と見ることができます。
なので、それらの値をあらかじめテーブルにぶっこんでおき、進んだ分だけ該当のとこの値を抜き出す、みたいな感じにするのはダメでしょうか・・・・・


追記ですが、自分もちょっと考えてみました。x,y,tの関係を考える方式で。
ある時間tにおける座標を(x,y)とし、そこから微小時間での変位を(dx,dy)と置きます。

式① 速度一定の式
イメージ説明式② 楕円の方程式
イメージ説明式③ 楕円の接線の式(ちょっと自信なしw)
イメージ説明①②③からyとdyを消去します。するとこんな式ができました。
式④ xとtの関係式
イメージ説明ただし、
イメージ説明④の両辺を時間tで積分します。
イメージ説明イメージ説明ただし、x0=移動前のx座標、x1=移動後のx座標、t=時間

多分どっか間違ってると思いますが、左辺の積分を解いてやればx1の解が出るような気がします(笑)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/03 11:17

    なるほど。
    参考にさせて頂きます。

    キャンセル

  • 2015/03/05 22:07

    残念ながら式2が違います(分母は2乗です).
    自ずとf(x)も変わってきます.
    これを使うとしたら,このf(x)が楕円の両端で不連続になること,
    点がどの象限にあるかの管理が必要になることに注意が必要ですね

    キャンセル

0

楕円の代わりに、次の形で考えれば、周を長さ N 等分することは簡単です。
http://www.shaku8.com/seika/figkoban0.gif
イメージ説明
ここで求めた各分点の角度から 実際の楕円上の点を計算をしては?

上の図は 次のページからの引用です。
- http://www.shaku8.com/seika/tsubushi1.htm http://www.shaku8.com/seika/tsubushi1.htm

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/10 18:19

    ありがとうございます。
    一番理解しやすい形で実装したいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る