Source code for hscmap.vec3

import math
from dataclasses import dataclass
from typing import List, Tuple, TypedDict, Union

from .angle import Angle


class SkyCooerdDict(TypedDict):
    ''':meta private:'''

    ra: float
    dec: float


[docs] @dataclass class SkyCoord: ''' This class represents a position on the celestial sphere. The position is represented by right ascension and declination. ''' ra: Angle dec: Angle def as_dict(self) -> SkyCooerdDict: ''':meta private:''' return {'ra': self.ra.radian, 'dec': self.dec.radian}
[docs] def as_vec3(self) -> 'Vec3': ''' Convert the position to a :class:`Vec3`. ''' return Vec3( math.cos(self.ra.radian) * math.cos(self.dec.radian), math.sin(self.ra.radian) * math.cos(self.dec.radian), math.sin(self.dec.radian), )
[docs] @classmethod def from_degree(cls, ra: float, dec: float) -> 'SkyCoord': return cls(Angle.from_degree(ra), Angle.from_degree(dec))
[docs] @classmethod def from_radian(cls, ra: float, dec: float) -> 'SkyCoord': return cls(Angle.from_radian(ra), Angle.from_radian(dec))
[docs] @classmethod def from_vec3(cls, vec: 'Vec3') -> 'SkyCoord': vec = vec.normalize() ra = math.atan2(vec.y, vec.x) dec = math.asin(vec.z) return cls(Angle.from_radian(ra), Angle.from_radian(dec))
[docs] @dataclass class Vec3: ''' This class represents a 3D vector. Operator overloading is implemented for addition, subtraction, multiplication, division, negation, and absolute value. :: a = Vec3(1, 2, 3) b = Vec3(4, 5, 6) c = a + b # c = Vec3(5, 7, 9) d = a - b # d = Vec3(-3, -3, -3) e = a * 2 # e = Vec3(2, 4, 6) f = 2 * a # f = Vec3(2, 4, 6) g = a / 2 # g = Vec3(0.5, 1, 1.5) h = -a # h = Vec3(-1, -2, -3) i = abs(a) # i = 3.7416573867739413 ''' x: float y: float z: float def __add__(self, other: 'Vec3') -> 'Vec3': return Vec3(self.x + other.x, self.y + other.y, self.z + other.z) def __sub__(self, other: 'Vec3') -> 'Vec3': return Vec3(self.x - other.x, self.y - other.y, self.z - other.z) def __mul__(self, other: float) -> 'Vec3': return Vec3(self.x * other, self.y * other, self.z * other) def __rmul__(self, other: float) -> 'Vec3': return Vec3(self.x * other, self.y * other, self.z * other) def __truediv__(self, other: float) -> 'Vec3': return Vec3(self.x / other, self.y / other, self.z / other) def __neg__(self) -> 'Vec3': return Vec3(-self.x, -self.y, -self.z) def __abs__(self) -> float: return math.sqrt(self.x**2 + self.y**2 + self.z**2)
[docs] def normalize(self) -> 'Vec3': ''' Return a normalized vector. ''' return self / abs(self)
[docs] def dot(self, other: 'Vec3') -> float: ''' Return the dot product of this vector and `other`. ''' return self.x * other.x + self.y * other.y + self.z * other.z
[docs] def cross(self, other: 'Vec3') -> 'Vec3': ''' Return the cross product of this vector and `other`. ''' return Vec3( self.y * other.z - self.z * other.y, self.z * other.x - self.x * other.z, self.x * other.y - self.y * other.x, )
[docs] def angle(self, other: 'Vec3') -> Angle: ''' Return the angle between this vector and `other`. ''' return Angle(math.acos(self.dot(other) / (abs(self) * abs(other))))
[docs] def as_tuple(self) -> Tuple[float, float, float]: return (self.x, self.y, self.z)
[docs] def as_list(self) -> List[float]: return [self.x, self.y, self.z]
SkyCoordOrVec3 = Union[SkyCoord, Vec3]
[docs] def as_vec3(position: SkyCoordOrVec3): ''' Convert `position` to a :class:`Vec3`. ''' if isinstance(position, SkyCoord): return position.as_vec3() return position
[docs] def as_sky_coord(position: SkyCoordOrVec3): ''' Convert `position` to a :class:`SkyCoord`. ''' if isinstance(position, Vec3): return SkyCoord.from_vec3(position) return position