/
RealDeltaVToChangeApoapsisPrograde.cs
59 lines (47 loc) · 1.58 KB
/
RealDeltaVToChangeApoapsisPrograde.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
* Copyright Lamont Granquist, Sebastien Gaggini and the MechJeb contributors
* SPDX-License-Identifier: LicenseRef-PD-hp OR Unlicense OR CC0-1.0 OR 0BSD OR MIT-0 OR MIT OR LGPL-2.1+
*/
#nullable enable
using System;
using System.Threading;
using MechJebLib.Functions;
using MechJebLib.Primitives;
using MechJebLib.Rootfinding;
namespace MechJebLib.FunctionImpls
{
public static class RealDeltaVToChangeApoapsisPrograde
{
private class Args
{
public double Mu;
public V3 R;
public V3 V;
public double NewApR;
public void Set(double mu, V3 r, V3 v, double newApR)
{
Mu = mu;
R = r;
V = v;
NewApR = newApR;
}
}
private static readonly ThreadLocal<Args> _threadArgs =
new ThreadLocal<Args>(() => new Args());
private static readonly Func<double, object?, double> _f = F;
private static double F(double x, object? o)
{
var args = (Args)o!;
return Astro.ApoapsisFromStateVectors(args.Mu, args.R, args.V.normalized * x) - args.NewApR;
}
public static V3 Run(double mu, V3 r, V3 v, double newApR)
{
if (r.magnitude >= newApR)
return V3.zero;
Args args = _threadArgs.Value;
args.Set(mu, r, v, newApR);
double vfm = BrentRoot.Solve(_f, 0, Astro.EscapeVelocity(mu, r.magnitude) - 1, args);
return vfm * v.normalized - v;
}
}
}