orbital_elements_2.sf 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Orbital_elements
  4. #
  5. func orbital_state_vectors(
  6. semimajor_axis,
  7. eccentricity,
  8. inclination,
  9. longitude_of_ascending_node,
  10. argument_of_periapsis,
  11. true_anomaly
  12. ) {
  13. var (i, j, k) = (
  14. %v(1 0 0),
  15. %v(0 1 0),
  16. %v(0 0 1),
  17. )
  18. func muladd(v1, x1, v2, x2) {
  19. (v1 * x1) + (v2 * x2)
  20. }
  21. func rotate(Ref i, Ref j, α) {
  22. (*i, *j) = (
  23. muladd(*i, +cos(α), *j, sin(α)),
  24. muladd(*i, -sin(α), *j, cos(α)),
  25. )
  26. }
  27. rotate(\i, \j, longitude_of_ascending_node)
  28. rotate(\j, \k, inclination)
  29. rotate(\i, \j, argument_of_periapsis)
  30. var l = (eccentricity == 1 ? 2*semimajor_axis
  31. : semimajor_axis*(1 - eccentricity**2))
  32. var (c, s) = with(true_anomaly) { (.cos, .sin) }
  33. var r = l/(1 + eccentricity*c)
  34. var rprime = (s * r**2 / l)
  35. var position = muladd(i, c, j, s)*r
  36. var speed = muladd(i, rprime*c - r*s, j, rprime*s + r*c)
  37. speed /= speed.abs
  38. speed *= sqrt(2/r - 1/semimajor_axis)
  39. struct Result { position, speed }
  40. Result(position, speed)
  41. }
  42. for args in ([
  43. [1, 0.1, 0, 355/(113*6), 0, 0],
  44. [1, 0.1, Num.pi/18, Num.pi/6, Num.pi/4, 0]
  45. ]) {
  46. var r = orbital_state_vectors(args...)
  47. say "Arguments: #{args}:"
  48. say "Position : #{r.position}"
  49. say "Speed : #{r.speed}\n"
  50. }
  51. var r = orbital_state_vectors(1, 0.1, Num.pi/18, Num.pi/6, Num.pi/4, 0)
  52. assert(r.position[0] =~= 0.23777128398220654779107184959165027147748809404)
  53. assert(r.position[1] =~= 0.860960261697715834668966272382699039216399966872)
  54. assert(r.position[2] =~= 0.110509023572075562109405412890808505271310143909)
  55. assert(r.speed[0] =~= -1.06193301748006004757467368094494935655538772696)
  56. assert(r.speed[1] =~= 0.275850020569249507846452830330085489348356659642)
  57. assert(r.speed[2] =~= 0.135747024865598167166145512759280712986072818844)