# 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 math
from spyce.vector import Vec3
        Arguments:
        distance: distance from the focus (m)
        """

        mu = self.primary.gravitational_parameter
        return math.sqrt(mu * (2/distance - 1/self.semi_major_axis))

    def speed_at_true_anomaly(self, true_anomaly):
        """Orbital speed (m/s) at a given true anomaly (rad)"""
        distance = self.distance_at_true_anomaly(true_anomaly)
        return self.speed_at_distance(distance)

    def position_at_true_anomaly(self, true_anomaly):
        """Position vector at a given true anomaly (rad)"""
        distance = self.distance_at_true_anomaly(true_anomaly)
        c = math.cos(true_anomaly)
        s = math.sin(true_anomaly)
        x = [distance*c, distance*s, 0.0]
        x = self.transform * x
        return x

    def velocity_at_true_anomaly(self, true_anomaly):
        """Velocity vector at a given true anomaly (rad)"""
        distance = self.distance_at_true_anomaly(true_anomaly)

        c = math.cos(true_anomaly)
        s = math.sin(true_anomaly)
        e = self.eccentricity

        x = self.semi_latus_rectum*e*s/(1+e*c)**2

# 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_state.py
import math
from spyce.vector import Vec3

        Arguments:
        distance: distance from the focus (m)
        """

        mu = self.primary.gravitational_parameter
        return math.sqrt(mu * (2/distance - 1/self.semi_major_axis))

    def speed_at_true_anomaly(self, true_anomaly):
        """Orbital speed (m/s) at a given true anomaly (rad)"""
        distance = self.distance_at_true_anomaly(true_anomaly)
        return self.speed_at_distance(distance)

    def position_at_true_anomaly(self, true_anomaly):
        """Position vector at a given true anomaly (rad)"""
        distance = self.distance_at_true_anomaly(true_anomaly)
        c = math.cos(true_anomaly)
        s = math.sin(true_anomaly)
        x = [distance*c, distance*s, 0.0]
        x = self.transform * x
        return x

    def velocity_at_true_anomaly(self, true_anomaly):
        """Velocity vector at a given true anomaly (rad)"""
        distance = self.distance_at_true_anomaly(true_anomaly)

        c = math.cos(true_anomaly)
        s = math.sin(true_anomaly)
        e = self.eccentricity

        x = self.semi_latus_rectum*e*s/(1+e*c)**2

        v = Vec3([-distance*s + x*c, distance*c + x*s, 0])