Orbital elements: Difference between revisions

Content added Content deleted
(Scala contribution added.)
Line 1: Line 1:
{{draft task}}
{{draft task}}

When neglecting the influence of other objects, two celestial bodies orbit one another along a [[wp:conic section|conic]] trajectory. In the orbital plane, the radial equation is thus:
When neglecting the influence of other objects, two celestial bodies orbit one another along a [[wp:conic section|conic]] trajectory. In the orbital plane, the radial equation is thus:


<big> r = L/(1 + e cos(angle)) </big>
&nbsp;<big> r = L/(1 + e cos(angle)) </big>


<big> '''<tt>L</tt>''' </big>, <big> '''e''' </big> and <big> '''angle''' </big> are respectively called ''semi-latus rectum'', ''eccentricity'' and ''true anomaly''. The eccentricity and the true anomaly are two of the six so-called [[wp:orbital elements|orbital elements]] often used to specify an orbit and the position of a point on this orbit.
<big>'''<tt>L</tt>''' </big>, <big> '''e''' </big> and <big> '''angle''' </big> are respectively called ''semi-latus rectum'', ''eccentricity'' and ''true anomaly''. The eccentricity and the true anomaly are two of the six so-called [[wp:orbital elements|orbital elements]] often used to specify an orbit and the position of a point on this orbit.


The four other parameters are the ''semi-major axis'', the ''longitude of the ascending node'', the ''inclination'' and the ''argument of periapsis''. An other parameter, called the ''gravitational parameter'', along with dynamical considerations described further, also allows for the determination of the speed of the orbiting object.
The four other parameters are the ''semi-major axis'', the ''longitude of the ascending node'', the ''inclination'' and the ''argument of periapsis''. An other parameter, called the ''gravitational parameter'', along with dynamical considerations described further, also allows for the determination of the speed of the orbiting object.
Line 11: Line 10:
The semi-major axis is half the distance between [[wp:perihelion and aphelion|perihelion and aphelion]]. It is often noted <big> '''a'''</big>, and it's not too hard to see how it's related to the semi-latus-rectum:
The semi-major axis is half the distance between [[wp:perihelion and aphelion|perihelion and aphelion]]. It is often noted <big> '''a'''</big>, and it's not too hard to see how it's related to the semi-latus-rectum:


<big> a = L/(1 - e<sup>2</sup>) </big>
&nbsp;<big> a = L/(1 - e<sup>2</sup>) </big>


The longitude of the ascending node, the inclination and the argument of the periapsis specify the orientation of the orbiting plane with respect to a reference plane defined with three arbitrarily chosen reference distant stars.
The longitude of the ascending node, the inclination and the argument of the periapsis specify the orientation of the orbiting plane with respect to a reference plane defined with three arbitrarily chosen reference distant stars.
Line 17: Line 16:
The gravitational parameter is the coefficent GM in Newton's gravitational force. It is sometimes noted <tt>µ</tt> and will be chosen as one here for the sake of simplicity:
The gravitational parameter is the coefficent GM in Newton's gravitational force. It is sometimes noted <tt>µ</tt> and will be chosen as one here for the sake of simplicity:


<big> µ = GM = 1 </big>
&nbsp;<big> µ = GM = 1 </big>


As mentioned, dynamical considerations allow for the determination of the speed. They result in the so-called [[wp:vis-viva equation|vis-viva equation]]:
As mentioned, dynamical considerations allow for the determination of the speed. They result in the so-called [[wp:vis-viva equation|vis-viva equation]]:


<big>v<sup>2</sup> = GM(2/r - 1/a)</big>
&nbsp;<big>v<sup>2</sup> = GM(2/r - 1/a)</big>


This only gives the magnitude of the speed. The direction is easily determined since it's tangent to the conic.
This only gives the magnitude of the speed. The direction is easily determined since it's tangent to the conic.


Those parameters allow for the determination of both the position and the speed of the orbiting object in [[wp:cartesian coordinates|cartesian coordinates]], those two vectors constituting the so-called [[wp:orbital state vectors|orbital state vectors]].
Those parameters allow for the determination of both the position and the speed of the orbiting object in [[wp:cartesian coordinates|cartesian coordinates]], those two vectors constituting the so-called [[wp:orbital state vectors|orbital state vectors]].



;Task:
;Task:
Line 131: Line 129:


=={{header|Java}}==
=={{header|Java}}==
{{lines too long|Java}}
{{trans|Kotlin}}
{{trans|Kotlin}}
<lang Java>public class OrbitalElements {
<lang Java>public class OrbitalElements {
Line 278: Line 277:
println("Speed : $speed")
println("Speed : $speed")
}</lang>
}</lang>

{{out}}
{{out}}
<pre>Position : (0.7794228433986797, 0.45000003465368416, 0.0)
<pre>
Position : (0.7794228433986797, 0.45000003465368416, 0.0)
Speed : (-0.5527708409604438, 0.9574270831797618, 0.0)</pre>
Speed : (-0.5527708409604438, 0.9574270831797618, 0.0)
</pre>


=={{header|Perl}}==
=={{header|Perl}}==
Line 346: Line 342:
0, # argument of periapsis
0, # argument of periapsis
0 # true-anomaly
0 # true-anomaly
;
;</lang>
</lang>
{{out}}
{{out}}
<pre>$VAR1 = {
<pre>$VAR1 = {
Line 363: Line 358:


=={{header|Perl 6}}==
=={{header|Perl 6}}==

We'll use the [https://github.com/grondilu/clifford Clifford geometric algebra library] but only for the vector operations.
We'll use the [https://github.com/grondilu/clifford Clifford geometric algebra library] but only for the vector operations.

<lang perl6>sub orbital-state-vectors(
<lang perl6>sub orbital-state-vectors(
Real :$semimajor-axis where * >= 0,
Real :$semimajor-axis where * >= 0,
Line 409: Line 402:
longitude-of-ascending-node => pi/6,
longitude-of-ascending-node => pi/6,
argument-of-periapsis => pi/4,
argument-of-periapsis => pi/4,
true-anomaly => 0;
true-anomaly => 0;</lang>

</lang>
{{out}}
{{out}}
<pre>{position => 0.237771283982207*e0+0.860960261697716*e1+0.110509023572076*e2, speed => -1.06193301748006*e0+0.27585002056925*e1+0.135747024865598*e2}</pre>
<pre>{position => 0.237771283982207*e0+0.860960261697716*e1+0.110509023572076*e2, speed => -1.06193301748006*e0+0.27585002056925*e1+0.135747024865598*e2}</pre>
=={{header|Scala}}==
<lang Scala>import scala.language.existentials


object OrbitalElements extends App {
private val ps = orbitalStateVectors(1.0, 0.1, 0.0, 355.0 / (113.0 * 6.0), 0.0, 0.0)
println(f"Position : ${ps(0)}%s%nSpeed : ${ps(1)}%s")

private def orbitalStateVectors(semimajorAxis: Double,
eccentricity: Double,
inclination: Double,
longitudeOfAscendingNode: Double,
argumentOfPeriapsis: Double,
trueAnomaly: Double) = {

def mulAdd(v1: Vector, x1: Double, v2: Vector, x2: Double) = v1 * x1 + v2 * x2

case class Vector(x: Double, y: Double, z: Double) {
def +(term: Vector) =
Vector(x + term.x, y + term.y, z + term.z)
def *(factor: Double) = Vector(factor * x, factor * y, factor * z)
def /(divisor: Double) = Vector(x / divisor, y / divisor, z / divisor)
def abs: Double = math.sqrt(x * x + y * y + z * z)
override def toString: String = f"($x%.16f, $y%.16f, $z%.16f)"
}

def rotate(i: Vector, j: Vector, alpha: Double) =
Array[Vector](mulAdd(i, math.cos(alpha), j, math.sin(alpha)),
mulAdd(i, -math.sin(alpha), j, math.cos(alpha)))

val p = rotate(Vector(1, 0, 0), Vector(0, 1, 0), longitudeOfAscendingNode)
val p2 = rotate(p(0),
rotate(p(1), Vector(0, 0, 1), inclination)(0),
argumentOfPeriapsis)
val l = semimajorAxis *
(if (eccentricity == 1.0) 2.0 else 1.0 - eccentricity * eccentricity)
val (c, s) = (math.cos(trueAnomaly), math.sin(trueAnomaly))
val r = l / (1.0 + eccentricity * c)
val rprime = s * r * r / l
val speed = mulAdd(p2(0), rprime * c - r * s, p2(1), rprime * s + r * c)
Array[Vector](mulAdd(p(0), c, p2(1), s) * r,
speed / speed.abs * math.sqrt(2.0 / r - 1.0 / semimajorAxis))
}

}</lang>
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/ac17jh2/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/2NQNgj4OQkazxZNvSzcexQ Scastie (remote JVM)].
=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Perl}}
{{trans|Perl}}
Line 472: Line 507:
say '['+r.speed.join(', ')+']'</lang>
say '['+r.speed.join(', ')+']'</lang>
{{out}}
{{out}}
<pre>[0.77942284339868, 0.450000034653684, 0]
<pre>
[0.77942284339868, 0.450000034653684, 0]
[-0.552770840960444, 0.957427083179761, 0]</pre>
[-0.552770840960444, 0.957427083179761, 0]
</pre>


=={{header|zkl}}==
=={{header|zkl}}==
Line 518: Line 551:
).println();</lang>
).println();</lang>
{{out}}
{{out}}
<pre>L(L(0.779423,0.45,0),L(-0.552771,0.957427,0))</pre>
<pre>
L(L(0.779423,0.45,0),L(-0.552771,0.957427,0))
</pre>