このページが同様の資料を探している他の誰かによって見つけられた場合に備えて、ここに返信をドロップしたかった。
以下は、AdobeのAfter Effectsソフトウェアで「式」として記述されているため、別のアプリ(cinema 4d)用のPythonバージョンがありますが、javascriptishです。考え方は同じです。任意の精度に達するまで、ニュートン法を繰り返し実行します。
私はこのコードを模範的または意味のある効率的なものとして投稿しているのではなく、特定のタスクを達成するために期限に作成したコードを投稿していることに注意してください(つまり、ケプラーの法則に従って惑星を焦点の周りに移動し、正確に実行します)。私たちは生計を立てるためのコードを書かないので、批評のためにこれを投稿することもありません。クイック&ダーティは締め切りに間に合うものです。
After Effectsでは、「式」コードはアニメーションの1フレームごとに1回実行されます。これは、グローバルデータを簡単にアドレス指定できないため、多くのアルゴリズムを実装するときに実行できることを制限します(ケプラー運動の他のアルゴリズムは、相互に更新された速度ベクトルを使用します。これは、使用できなかったアプローチです)。コードが残す結果は、その瞬間のオブジェクトの[x、y]位置(内部的には、これはフレーム番号です)であり、コードは、上のオブジェクトレイヤーの位置要素にアタッチされることを目的としています。タイムライン。
このコードは、http://www.jgiesen.de/kepler/kepler.htmlにある資料から発展したものであり、次の人のためにここで提供されています。
pi = Math.PI;
function EccAnom(ec,am,dp,_maxiter) {
// ec=eccentricity, am=mean anomaly,
// dp=number of decimal places
pi=Math.PI;
i=0;
delta=Math.pow(10,-dp);
var E, F;
// some attempt to optimize prediction
if (ec<0.8) {
E=am;
} else {
E= am + Math.sin(am);
}
F = E - ec*Math.sin(E) - am;
while ((Math.abs(F)>delta) && (i<_maxiter)) {
E = E - F/(1.0-(ec* Math.cos(E) ));
F = E - ec * Math.sin(E) - am;
i = i + 1;
}
return Math.round(E*Math.pow(10,dp))/Math.pow(10,dp);
}
function TrueAnom(ec,E,dp) {
S=Math.sin(E);
C=Math.cos(E);
fak=Math.sqrt(1.0-ec^2);
phi = 2.0 * Math.atan(Math.sqrt((1.0+ec)/(1.0-ec))*Math.tan(E/2.0));
return Math.round(phi*Math.pow(10,dp))/Math.pow(10,dp);
}
function MeanAnom(time,_period) {
curr_frame = timeToFrames(time);
if (curr_frame <= _period) {
frames_done = curr_frame;
if (frames_done < 1) frames_done = 1;
} else {
frames_done = curr_frame % _period;
}
_fractime = (frames_done * 1.0 ) / _period;
mean_temp = (2.0*Math.PI) * (-1.0 * _fractime);
return mean_temp;
}
//==============================
// a=semimajor axis, ec=eccentricity, E=eccentric anomaly
// delta = delta digits to exit, period = per., in frames
//----------------------------------------------------------
_eccen = 0.9;
_delta = 14;
_maxiter = 1000;
_period = 300;
_semi_a = 70.0;
_semi_b = _semi_a * Math.sqrt(1.0-_eccen^2);
_meananom = MeanAnom(time,_period);
_eccentricanomaly = EccAnom(_eccen,_meananom,_delta,_maxiter);
_trueanomaly = TrueAnom(_eccen,_eccentricanomaly,_delta);
r = _semi_a * (1.0 - _eccen^2) / (1.0 + (_eccen*Math.cos(_trueanomaly)));
x = r * Math.cos(_trueanomaly);
y = r * Math.sin(_trueanomaly);
_foc=_semi_a*_eccen;
[1460+x+_foc,540+y];