-
Notifications
You must be signed in to change notification settings - Fork 1
/
lib_basis.ks
119 lines (104 loc) · 3.05 KB
/
lib_basis.ks
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Functions for dealing with coordinate axes.
// A basis is a list of 3 normalized vectors that determine the components of other vectors/coordinates.
RUN ONCE lib_util.
// Constants.
GLOBAL K_X is V(1,0,0).
GLOBAL K_Y IS V(0,1,0).
GLOBAL K_Z IS V(0,0,1).
GLOBAL KB_X IS 0.
GLOBAL KB_Y IS 1.
GLOBAL KB_Z IS 2.
// For example, the standard XYZ basis is...
GLOBAL basis_xyz IS LIST(K_X, K_Y, K_Z).
// Maneuvers in KSP use a different coordinate system of (radial, normal, prograde). This ordering is chosen because it aligns with the parameter order of NODE().
// These functions determine the basis of that coordinate system.
GLOBAL KB_RADIAL IS 0.
GLOBAL KB_NORMAL IS 1.
GLOBAL KB_PROGRADE IS 2.
GLOBAL KB_UP IS 0.
GLOBAL KB_NORTH IS 1.
GLOBAL KB_EAST IS 2.
{
LOCAL FUNCTION _wrap {
// Returns maneuver basis -- either for velocity and position vectors, or for an orbital at a time.
PARAMETER f.
PARAMETER s IS ship. // or r
PARAMETER t IS time. // or v
IF s:IsType("Orbitable") {
SET t TO ToTime(t).
RETURN f(RELPOSITIONAT(s, t), VELOCITYAT(s, t):orbit).
}
IF s:IsType("Lexicon") {
SET t TO ToTime(t).
RETURN f(s["r"], s["v"]).
}
RETURN f(s,t).
}
LOCAL FUNCTION _mvr {
PARAMETER r.
PARAMETER v.
RETURN List(
(v + angleaxis(90, VCRS(v,r))):normalized, // Radial
VCRS(v,r):normalized, // Normal
v:normalized // Prograde
).
}
LOCAL FUNCTION _une {
PARAMETER r.
PARAMETER v.
LOCAL n IS VXCL(r, K_Y-r).
RETURN LIST(r:normalized,n:normalized,VCRS(r,n):normalized).
}
GLOBAL basis_mvr IS _wrap@:bind(_mvr@).
GLOBAL basis_une IS _wrap@:bind(_une@).
}
// 'Inverts' a basis: returns a new basis such that basis_transform(new, basis_transform(old, vec)) == vec.
FUNCTION basis_invert {
PARAMETER b. // Basis.
RETURN LIST(
V(b[0]:x, b[1]:x, b[2]:x),
V(b[0]:y, b[1]:y, b[2]:y),
V(b[0]:z, b[1]:z, b[2]:z)
).
}
// Transform XYZ vector to new basis (or back).
FUNCTION basis_transform {
PARAMETER b. // Basis.
PARAMETER vec. // Vector.
PARAMETER invert IS FALSE.
IF invert { SET b TO basis_invert(b). }
RETURN V(vec*b[0],vec*b[1],vec*b[2]).
}
// Converts a node to a radial/normal/prograde vector.
FUNCTION node_to_vector {
PARAMETER n.
RETURN V(n:radialout, n:normal, n:prograde).
}
// Converts a radial/normal/prograde vector to a node. Can reconfigure an existing node.
FUNCTION vector_to_node {
PARAMETER v.
PARAMETER t IS TIME.
PARAMETER n IS FALSE.
IF IsFalse(n) { RETURN NODE(ToSeconds(t),v:x,v:y,v:z). }
RETURN node_update(n,t,v:x,v:y,v:z).
}
// Updates an existing node in-place.
FUNCTION node_update {
PARAMETER nd. PARAMETER t. PARAMETER r. PARAMETER n. PARAMETER p.
SET nd:eta TO ToSeconds(t)-ToSeconds(TIME).
SET nd:radialout TO r.
SET nd:normal TO n.
SET nd:prograde TO p.
RETURN nd.
}
// Copy a node.
FUNCTION node_copy {
PARAMETER src.
PARAMETER dst IS FALSE.
IF IsFalse(dst) { RETURN NODE(src:eta+TIME:Seconds, src:radialout, src:normal, src:prograde). }
SET dst:eta TO src:eta.
SET dst:radialout TO src:radialout.
SET dst:normal TO src:normal.
SET dst:prograde TO src:prograde.
RETURN dst.
}