# Path: spyce/vector.py
# class Vec3(list):
#     def norm(u):
#         return math.sqrt(u.dot(u))
# 
#     def dot(u, v):
#         """Dot product"""
#         u1, u2, u3 = u
#         v1, v2, v3 = v
#         return math.fsum([u1*v1, u2*v2, u3*v3])
# 
#     def cross(u, v):
#         """Cross product"""
#         u1, u2, u3 = u
#         v1, v2, v3 = v
#         return Vec3([
#             u2*v3 - u3*v2,
#             u3*v1 - u1*v3,
#             u1*v2 - u2*v1,
#         ])
# 
#     def angle(u, v):
#         """Angle formed by two vectors"""
#         r = u.dot(v)/u.norm()/v.norm()
#         r = max(-1, min(1, r))
#         return math.acos(r)
# 
#     def oriented_angle(u, v, normal=None):
#         """Angle formed by two vectors"""
#         if normal is None:
#             normal = Vec3([0, 0, 1])
#         geometric_angle = u.angle(v)
#         if normal.dot(u.cross(v)) < 0:
#             return -geometric_angle
#         else:
#             return geometric_angle
# 
#     def __mul__(u, s):
#         x, y, z = u
#         return Vec3([x*s, y*s, z*s])
# 
#     def __div__(u, s):
#         x, y, z = u
#         return Vec3([x/s, y/s, z/s])
# 
#     def __add__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x+a, y+b, z+c])
# 
#     def __iadd__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x+a, y+b, z+c])
# 
#     def __sub__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x-a, y-b, z-c])
# 
#     def __isub__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x-a, y-b, z-c])
# 
#     def __neg__(u):
#         x, y, z = u
#         return Vec3([-x, -y, -z])
# 
#     def __abs__(u):
#         """Maximum metric (see Chebyshev distance)"""
#         return max(abs(x) for x in u)


import sys
import math
import spyce.orbit_angles
from spyce.vector import Vec3
    from spyce.cext import orbit as cext
        period = float(period)
        mu = primary.gravitational_parameter
        mean_motion = period / (2*math.pi)
        semi_major_axis = (mean_motion**2 * mu)**(1/3)
        eccentricity = abs(apsis/semi_major_axis - 1)

        return cls.from_semi_major_axis(
            primary, semi_major_axis, eccentricity,
            inclination, longitude_of_ascending_node, argument_of_periapsis,
            epoch, mean_anomaly_at_epoch
        )

    # inspired from https://space.stackexchange.com/questions/1904/#1919
    @classmethod
    def from_state(cls, primary, position, velocity, epoch=0):
        """Orbit from position and velocity

        The state is given in a referential centered on the primary.

        Arguments:
        primary:  orbited body, object with a "gravitational_parameter"
        position: position vector of the vessel (m)
        velocity: velocity vector of the vessel (m/s)
        epoch:    time of the position and velocity (s)
        """

        distance = position.norm()
        speed = velocity.norm()
        mu = primary.gravitational_parameter


# Path: spyce/vector.py
# class Vec3(list):
#     def norm(u):
#         return math.sqrt(u.dot(u))
# 
#     def dot(u, v):
#         """Dot product"""
#         u1, u2, u3 = u
#         v1, v2, v3 = v
#         return math.fsum([u1*v1, u2*v2, u3*v3])
# 
#     def cross(u, v):
#         """Cross product"""
#         u1, u2, u3 = u
#         v1, v2, v3 = v
#         return Vec3([
#             u2*v3 - u3*v2,
#             u3*v1 - u1*v3,
#             u1*v2 - u2*v1,
#         ])
# 
#     def angle(u, v):
#         """Angle formed by two vectors"""
#         r = u.dot(v)/u.norm()/v.norm()
#         r = max(-1, min(1, r))
#         return math.acos(r)
# 
#     def oriented_angle(u, v, normal=None):
#         """Angle formed by two vectors"""
#         if normal is None:
#             normal = Vec3([0, 0, 1])
#         geometric_angle = u.angle(v)
#         if normal.dot(u.cross(v)) < 0:
#             return -geometric_angle
#         else:
#             return geometric_angle
# 
#     def __mul__(u, s):
#         x, y, z = u
#         return Vec3([x*s, y*s, z*s])
# 
#     def __div__(u, s):
#         x, y, z = u
#         return Vec3([x/s, y/s, z/s])
# 
#     def __add__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x+a, y+b, z+c])
# 
#     def __iadd__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x+a, y+b, z+c])
# 
#     def __sub__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x-a, y-b, z-c])
# 
#     def __isub__(u, v):
#         x, y, z = u
#         a, b, c = v
#         return Vec3([x-a, y-b, z-c])
# 
#     def __neg__(u):
#         x, y, z = u
#         return Vec3([-x, -y, -z])
# 
#     def __abs__(u):
#         """Maximum metric (see Chebyshev distance)"""
#         return max(abs(x) for x in u)


# Path: spyce/orbit_determination.py
import sys
import math
import spyce.orbit_angles
from spyce.vector import Vec3
    from spyce.cext import orbit as cext

        period = float(period)
        mu = primary.gravitational_parameter
        mean_motion = period / (2*math.pi)
        semi_major_axis = (mean_motion**2 * mu)**(1/3)
        eccentricity = abs(apsis/semi_major_axis - 1)

        return cls.from_semi_major_axis(
            primary, semi_major_axis, eccentricity,
            inclination, longitude_of_ascending_node, argument_of_periapsis,
            epoch, mean_anomaly_at_epoch
        )

    # inspired from https://space.stackexchange.com/questions/1904/#1919
    @classmethod
    def from_state(cls, primary, position, velocity, epoch=0):
        """Orbit from position and velocity

        The state is given in a referential centered on the primary.

        Arguments:
        primary:  orbited body, object with a "gravitational_parameter"
        position: position vector of the vessel (m)
        velocity: velocity vector of the vessel (m/s)
        epoch:    time of the position and velocity (s)
        """

        distance = position.norm()
        speed = velocity.norm()
        mu = primary.gravitational_parameter


        x_axis = Vec3([1, 0, 0])