Task: Orbital elements




Go: package main

import (
    "fmt"
    "math"
)

type vector struct{ x, y, z float64 }

func (v vector) add(w vector) vector {
    return vector{v.x + w.x, v.y + w.y, v.z + w.z}
}

func (v vector) mul(m float64) vector {
    return vector{v.x * m, v.y * m, v.z * m}
}

func (v vector) div(d float64) vector {
    return v.mul(1.0 / d)
}

func (v vector) abs() float64 {
    return math.Sqrt(v.x*v.x + v.y*v.y + v.z*v.z)
}

func (v vector) String() string {
    return fmt.Sprintf("(%g, %g, %g)", v.x, v.y, v.z)
}

func orbitalStateVectors(
    semimajorAxis, eccentricity, inclination, longitudeOfAscendingNode,
    argumentOfPeriapsis, trueAnomaly float64) (position vector, speed vector) {

    i := vector{1, 0, 0}
    j := vector{0, 1, 0}
    k := vector{0, 0, 1}

    mulAdd := func(v1, v2 vector, x1, x2 float64) vector {
        return v1.mul(x1).add(v2.mul(x2))
    }

    rotate := func(i, j vector, alpha float64) (vector, vector) {
        return mulAdd(i, j, math.Cos(alpha), math.Sin(alpha)),
            mulAdd(i, j, -math.Sin(alpha), math.Cos(alpha))
    }

    i, j = rotate(i, j, longitudeOfAscendingNode)
    j, _ = rotate(j, k, inclination)
    i, j = rotate(i, j, argumentOfPeriapsis)

    l := 2.0
    if eccentricity != 1.0 {
        l = 1.0 - eccentricity*eccentricity
    }
    l *= semimajorAxis
    c := math.Cos(trueAnomaly)
    s := math.Sin(trueAnomaly)
    r := l / (1.0 + eccentricity*c)
    rprime := s * r * r / l
    position = mulAdd(i, j, c, s).mul(r)
    speed = mulAdd(i, j, rprime*c-r*s, rprime*s+r*c)
    speed = speed.div(speed.abs())
    speed = speed.mul(math.Sqrt(2.0/r - 1.0/semimajorAxis))
    return
}

func main() {
    long := 355.0 / (113.0 * 6.0)
    position, speed := orbitalStateVectors(1.0, 0.1, 0.0, long, 0.0, 0.0)
    fmt.Println("Position :", position)
    fmt.Println("Speed    :", speed)
}


Java: public class OrbitalElements {
    private static class Vector {
        private double x, y, z;
 
        public Vector(double x, double y, double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
 
        public Vector plus(Vector rhs) {
            return new Vector(x + rhs.x, y + rhs.y, z + rhs.z);
        }
 
        public Vector times(double s) {
            return new Vector(s * x, s * y, s * z);
        }
 
        public Vector div(double d) {
            return new Vector(x / d, y / d, z / d);
        }
 
        public double abs() {
            return Math.sqrt(x * x + y * y + z * z);
        }
 
        @Override
        public String toString() {
            return String.format("(%.16f, %.16f, %.16f)", x, y, z);
        }
    }
 
    private static Vector mulAdd(Vector v1, Double x1, Vector v2, Double x2) {
        return v1.times(x1).plus(v2.times(x2));
    }
 
    private static Vector[] rotate(Vector i, Vector j, double alpha) {
        return new Vector[]{
            mulAdd(i, Math.cos(alpha), j, Math.sin(alpha)),
            mulAdd(i, -Math.sin(alpha), j, Math.cos(alpha))
        };
    }
 
    private static Vector[] orbitalStateVectors(
        double semimajorAxis, double eccentricity, 
        double inclination, double longitudeOfAscendingNode, 
        double argumentOfPeriapsis, double trueAnomaly
    ) {
        Vector i = new Vector(1, 0, 0);
        Vector j = new Vector(0, 1, 0);
        Vector k = new Vector(0, 0, 1);
 
        Vector[] p = rotate(i, j, longitudeOfAscendingNode);
        i = p[0];
        j = p[1];
        p = rotate(j, k, inclination);
        j = p[0];
        p = rotate(i, j, argumentOfPeriapsis);
        i = p[0];
        j = p[1];
 
        double l = (eccentricity == 1.0) ? 2.0 : 1.0 - eccentricity * eccentricity;
        l *= semimajorAxis;
        double c = Math.cos(trueAnomaly);
        double s = Math.sin(trueAnomaly);
        double r = l / (1.0 + eccentricity * c);
        double rprime = s * r * r / l;
        Vector position = mulAdd(i, c, j, s).times(r);
        Vector speed = mulAdd(i, rprime * c - r * s, j, rprime * s + r * c);
        speed = speed.div(speed.abs());
        speed = speed.times(Math.sqrt(2.0 / r - 1.0 / semimajorAxis));
 
        return new Vector[]{position, speed};
    }
 
    public static void main(String[] args) {
        Vector[] ps = orbitalStateVectors(1.0, 0.1, 0.0, 355.0 / (113.0 * 6.0), 0.0, 0.0);
        System.out.printf("Position : %s\n", ps[0]);
        System.out.printf("Speed : %s\n", ps[1]);
    }
}