1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
.. include:: references.txt
.. _working_with_angles:
Working with Angles
-------------------
The angular components of the various coordinate objects are represented
by objects of the |Angle| class. While most likely to be encountered in
the context of coordinate objects, |Angle| objects can also be used on
their own wherever a representation of an angle is needed.
.. _angle-creation:
Creation
^^^^^^^^
The creation of an |Angle| object is quite flexible and supports a wide
variety of input object types and formats. The type of the input angle(s)
can an array, scalar, tuple, string, `~astropy.units.Quantity` or another
|Angle|. This is best illustrated with a number of examples of valid ways
to create an |Angle|::
>>> import numpy as np
>>> from astropy import units as u
>>> from astropy.coordinates import Angle
>>> Angle('10.2345d') # String with 'd' abbreviation for degrees # doctest: +FLOAT_CMP
<Angle 10.2345 deg>
>>> Angle(['10.2345d', '-20d']) # Array of strings
<Angle [ 10.2345,-20. ] deg>
>>> Angle('1:2:30.43 degrees') # Sexagesimal degrees # doctest: +FLOAT_CMP
<Angle 1.0417861111111113 deg>
>>> Angle('1 2 0 hours') # Sexagesimal hours # doctest: +FLOAT_CMP
<Angle 1.0333333333333334 hourangle>
>>> Angle(np.arange(1., 8.), unit=u.deg) # Numpy array from 1..7 in degrees
<Angle [ 1., 2., 3., 4., 5., 6., 7.] deg>
>>> Angle(u'1°2′3″') # Unicode degree, arcmin and arcsec symbols # doctest: +FLOAT_CMP
<Angle 1.0341666666666667 deg>
>>> Angle('1d2m3.4s') # Degree, arcmin, arcsec. # doctest: +FLOAT_CMP
<Angle 1.0342777777777779 deg>
>>> Angle('-1h2m3s') # Hour, minute, second # doctest: +FLOAT_CMP
<Angle -1.0341666666666667 hourangle>
>>> Angle((-1, 2, 3), unit=u.deg) # (degree, arcmin, arcsec) # doctest: +FLOAT_CMP
<Angle -1.0341666666666667 deg>
>>> Angle(10.2345 * u.deg) # From a Quantity object in degrees # doctest: +FLOAT_CMP
<Angle 10.2345 deg>
>>> Angle(Angle(10.2345 * u.deg)) # From another Angle object # doctest: +FLOAT_CMP
<Angle 10.2345 deg>
Representation
^^^^^^^^^^^^^^
The |Angle| object also supports a variety of ways of representing the value
of the angle, both as a floating point number as a string::
>>> a = Angle(1, u.radian)
>>> a
<Angle 1.0 rad>
>>> a.radian
1.0
>>> a.degree # doctest: +FLOAT_CMP
57.29577951308232
>>> a.hour # doctest: +FLOAT_CMP
3.8197186342054885
>>> a.hms # doctest: +FLOAT_CMP
hms_tuple(h=3.0, m=49.0, s=10.987083139758766)
>>> a.dms # doctest: +FLOAT_CMP
dms_tuple(d=57.0, m=17.0, s=44.806247096362313)
>>> a.signed_dms # doctest: +FLOAT_CMP
signed_dms_tuple(sign=1.0, d=57.0, m=17.0, s=44.806247096362313)
>>> (-a).dms # doctest: +FLOAT_CMP
dms_tuple(d=-57.0, m=-17.0, s=-44.806247096362313)
>>> (-a).signed_dms # doctest: +FLOAT_CMP
signed_dms_tuple(sign=-1.0, d=57.0, m=17.0, s=44.806247096362313)
>>> a.arcminute # doctest: +FLOAT_CMP
3437.7467707849396
>>> a.to_string()
u'1rad'
>>> a.to_string(unit=u.degree)
u'57d17m44.8062s'
>>> a.to_string(unit=u.degree, sep=':')
u'57:17:44.8062'
>>> a.to_string(unit=u.degree, sep=('deg', 'm', 's'))
u'57deg17m44.8062s'
>>> a.to_string(unit=u.hour)
u'3h49m10.9871s'
>>> a.to_string(unit=u.hour, decimal=True)
u'3.81972'
Usage
^^^^^
Angles will also behave correctly for appropriate arithmetic operations::
>>> a = Angle(1.0, u.radian)
>>> a + 0.5 * u.radian + 2 * a
<Angle 3.5 rad>
>>> np.sin(a / 2) # doctest: +FLOAT_CMP
<Quantity 0.479425538604203>
>>> a == a
array(True, dtype=bool)
>>> a == (a + a)
array(False, dtype=bool)
|Angle| objects can also be used for creating coordinate objects::
>>> from astropy.coordinates import ICRS
>>> ICRS(Angle(1, u.deg), Angle(0.5, u.deg)) # doctest: +FLOAT_CMP
<ICRS Coordinate: (ra, dec) in deg
( 1., 0.5)>
Wrapping and bounds
^^^^^^^^^^^^^^^^^^^
There are two utility methods that simplify working with angles that should
have bounds. The :meth:`~astropy.coordinates.Angle.wrap_at` method allows
taking an angle or angles and wrapping to be within a single 360 degree slice.
The :meth:`~astropy.coordinates.Angle.is_within_bounds` method returns a
boolean indicating whether an angle or angles is within the specified bounds.
Longitude and Latitude objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|Longitude| and |Latitude| are two specialized subclasses of the |Angle|
class that are used for all of the spherical coordinate classes.
|Longitude| is used to represent values like right ascension, Galactic
longitude, and azimuth (for Equatorial, Galactic, and Alt-Az coordinates,
respectively). |Latitude| is used for declination, Galactic latitude, and
elevation.
Longitude
"""""""""
A |Longitude| object is distinguished from a pure |Angle| by virtue of a
``wrap_angle`` property. The ``wrap_angle`` specifies that all angle values
represented by the object will be in the range::
wrap_angle - 360 * u.deg <= angle(s) < wrap_angle
The default ``wrap_angle`` is 360 deg. Setting ``'wrap_angle=180 * u.deg'``
would instead result in values between -180 and +180 deg. Setting the
``wrap_angle`` attribute of an existing ``Longitude`` object will result in
re-wrapping the angle values in-place. For example::
>>> from astropy.coordinates import Longitude
>>> a = Longitude([-20, 150, 350, 360] * u.deg)
>>> a.degree
array([ 340., 150., 350., 0.])
>>> a.wrap_angle = 180 * u.deg
>>> a.degree
array([ -20., 150., -10., 0.])
Latitude
""""""""
A Latitude object is distinguished from a pure |Angle| by virtue
of being bounded so that::
-90.0 * u.deg <= angle(s) <= +90.0 * u.deg
Any attempt to set a value outside that range will result in a
`ValueError`.
|