発射体の動き-矢印


13

2Dゲームでは、飛行中の矢印の軌跡を描きたいだけです。以下のコードでは、軌道(放物線)は正しく見えますが、角度(または回転)または矢印は正しくありません。

float g = -9.8f;
float x = (launchVelocity * time);
float y = (launchVelocity * time) + (0.5f * g * (float)Math.Pow(time, 2));
float angle = (float)Math.Tanh(y / x);

私は何が欠けていますか?ありがとう。


3
スクリーンショットが役立つ場合があります
doppelgreener

回答:


10

Arctanh双曲線の正接を与えます!私の知る限り、あなたの放物線は双曲線ではありません。

しかし、良いニュースがあります。放物線の接線を見つけるのが簡単です。方程式は

x = s・t => t = x / s; y = s・t + g / 2・t²=> y = x + g / 2・x²/s²

sはどこにありますかlaunchVelocity。矢印の勾配は次のとおりです。

∂y/∂y= g /(2s²)・x + 1

Arctan必要に応じて安全に使用できます。

物理学に関する追加情報:

シミュレートするおおよその軌道は、矢印の重心に適用されます。「位置」(x、y)と言うとき、重心の位置について話します。矢印の重心は中点からわずかに前方にあり、矢印を描く場合はそれを考慮する必要があります。

矢の慣性運動量(巨大なバリスタを発射している場合は大きく変化する可能性があります)を考慮しておらず、矢の流体力学を考慮していないことに注意してください。弓矢の飛行は放物線の経路をたどりません!


ありがとう、Fxlll。矢印の物理学に適用される式を取得できるアイデアはありますか?
マーティン

![∂ y /∂ x = g /(2s²)· x + 1] [2]ですが、いずれにしても、私は以下のより良いアプローチをお勧めすると思います。1つには、xコンポーネントとyコンポーネントの分離について説明しなかったため、これは任意の45度の角度にハードコードされており、launchVelocityは実際にはlaunchVelocityではなく、xとyの両方のコンポーネント
Dov

慣性モーメントを簡単に計算できます。これらはロッド用に2つあり、1つはその重心の周りの回転用で、もう1つはロッドの軸の周りの回転用です。重ね合わせの原理は慣性モーメントに適用されるため、矢印は羽、体、先端の3つの部分に分割できます。
FxIII

1
問題は、唯一の運動量は角度の変化によるものであるということです(放物線の2倍の導出は定数項だけであることがわかります)。もう1つは、バックフェザーによる回転が原因です。ここで、羽の抗力と摩擦は、運動エネルギーを回転に変換し、矢印を減速させますが、ジャイロ効果を追加します。これは軌道に影響し、モデル化するのは非常に困難です
FxIII

とにかく、フェザー設定で運動量を速度に関連付けることができれば、すべてを完全な積分で計算できますが、運動方程式の閉形式ができるかどうかはわかりません(つまり、積分アルゴリズムを得ることができますが、パラメトリック方程式)。
FxIII

4

任意の時点での矢印の角度が必要です。角度を計算するために、接線があることを思い出しました。しかし、ここであなたの思考がうまくいかなくなったのです:

  1. 必要なのはデルタy /デルタxです。これは、勾配が変化率(他の回答の1つで言及されている)であるためです。xは、dxではなく、ある瞬間の位置にすぎないことに注意してください。

それでは、空気の摩擦を無視すると、矢印のx速度は一定になります。

まず、速度をx成分とy成分に分解します。45度または60度の角度で撮影できます。したがって、launchVelocityと角度が必要です。これはスカラーではありません。

第二に、すべてをフロートではなくダブルとして計算します。あなたは、丸め誤差があなたを殺さないときを知るほど数値的に洗練されていないので、試みないでください。いずれにせよ、それは素晴らしい時間の節約にはなりません。

第三に、Math.powを使用しないでください。これは遅く、整数の累乗の乗算ほど正確ではありません。また、Hornerのフォームを使用することで時間を大幅に節約できます(以下を参照)

final double DEG2RAD = Math.PI/180;
double ang = launchAngle * DEG2RAD;
double v0x = launchVelocity * cos(ang); // initial velocity in x
double v0y = launchVelocity * sin(ang); // initial velocity in y

double x = (v0x * time);
// double y = (v0y * time) + (0.5 * g * (float)Math.Pow(time, 2));
double y = (0.5 * g * time + v0y) * time

パフォーマンスに必死な場合は、0.5 * gを事前計算することもできますが、上記のコードを使用すると、狂ったことを何もせずに、そこから90%の方法で処理できます。必要に応じてこれを1000万回行うベンチマークは、確か​​に膨大な時間ではなく、割合的にはかなり大きいです-Javaではライブラリが非常に遅い

したがって、矢印が進むべき角度が必要な場合は、

atan(dy/dx)

この場合、dxは定数であるため機能します。しかし、一般に、dxはゼロになる可能性があるため、通常は以下を使用します。

atan2(dy, dx)

これは、このジョブ専用に設計された機能です。

しかし、私が言ったように、Javaのライブラリ関数はひどく遅いので、この場合、上記の@FxIIIで言及されていないように、それを行うより良い方法があります。

水平速度が常にv0xで、垂直速度が次の場合:

double vy = v0y - 0.5 * g * time;

あなたのデルタは:vx、vy

角度は必要ありません。矢印を描くには、名目上は次のようなものを使用します。

plot(x、y、x + vx、y + vy);

何を描いているのかわかりませんので、(JOGLを使用しているように)回転させるために角度が必要な場合は、角度を使用してください。

ATAN2はラジアンを返すため、openglを使用して角度を度に戻すことを忘れないでください。

final double RAD2DEG = 180 / Math.PI;
double ang = Math.atan2(vy,vx); // don't forget, vy first!!!
double deg = ang * RAD2DEG;

2

Tanh()(双曲線正接)はパラメーターとして角度を取りますが、側面の比率を与えました。

本当に必要なのは、双曲線アークタンジェントを使用することです。これは、辺の比率をパラメーターとして取り、角度を返します。(これに関する命名は、「atanh」、「atanh2」、「arctanh」、または他の同様のものである可能性があります。異なる数学ライブラリ間で大きく異なるようです)


いいえは双曲線何もしたくない
ドブ

ああ、あなたは絶対に正しい。私はすぐに「基本的な三角法の使用法」エラーに気づき、彼が使用していた関数が彼の残りのアプローチでは完全に間違っていることを見落としました。
トレバーパウエル

Tan()は角度を取ります。Atanは、三角形の辺の比(sin / cos)を取ります。
3Dave
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.