net.grelf

## Class Angle

• java.lang.Object
• net.grelf.Angle
• All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable, java.lang.Comparable<Angle>
Direct Known Subclasses:
Dec, RA

public class Angle
extends java.lang.Object
implements java.lang.Cloneable, java.lang.Comparable<Angle>, java.io.Serializable
In java.lang.(Strict)Math you have to keep track of whether an angle is in degrees or radians when you use trigonometrical functions; the present class knows what to do, so you can forget about it! This should reduce the potential for errors of the degrees/radians kind.

Rationale
A continual refrain in Jean Meeus' excellent series of books on astronomical computation is the risk of errors due to the fact that angles are usually given in degrees but trigonometry requires radians. It is vital to keep track of this in programs and ensure that conversions between units happen correctly. There is nothing to tell from a numerical value by itself what the units are supposed to be.
A first defence against radian/degree confusion is to include the unit names in the names of variables. Eg, latitudeDegrees = 45. That helps to keep track of what the units are supposed to be at any point in a calculation but it does not ensure that they are in fact correct.
So for taking a cosine you could write
and the "Degrees" in the variable name helps you to remember to call the function to convert it to radians first. But it does not guarantee that you will do that. Importantly, the compiler cannot detect such an error because whether the toRadians () function is called or not, the argument to cos () is a number and that's all the compiler requires.
In object-oriented languages there is a better remedy: make angles into objects rather than merely numbers. The class definition for Angle can then contain trigonometrical functions that know what units the angle is in and therefore can always do the right thing:
Angle latitude = new Angle (45.0, DEGREES);
x = latitude.cos ();
Now the conversion to, and use of, appropriate units is hidden inside the class/object. We don't need to know whether internally the value is held in degrees or radians (though for performance in intensive geometrical calculations it probably ought to be radians). Provided that the class has been thoroughly (unit-) tested the kind of mistake we were discussing simply cannot occur. (In the example DEGREES is meant to be a constant - in Java it would be an enum.)
Astronomical quantities such as RA and Dec are angles and so they too should be declared as classes: subclasses of Angle.
In the object-oriented language Java (and as far as I know in all commonly used programming languages) this idea has NOT been adopted in the standard library. A Java class called Math has (static) trigonometrical functions taking angles in radians as their arguments. I contend that a much better basis for astronomical computing should declare Angle as outlined above. Angle uses Math internally but any further geometrical programming should only use objects of class Angle. The application programmer should never directly use Math for trigonometry. Inverse functions should be defined as functions (in Java, static methods) creating new Angle objects:
Angle phi = Angle.atan (x);
A further benefit of using Angle as a class, and therefore as a data type, is that where functions take several parameters which would otherwise just be a list of numbers, it then becomes clear that particular ones are angles. That again reduces errors, of the kind where the parameters are written in the wrong order.
Serialized Form
• ### Nested Class Summary

Nested Classes
Modifier and Type Class and Description
class  Angle.Format
static class  Angle.Units
• ### Constructor Summary

Constructors
Constructor and Description
Angle(double value, Angle.Units units)
Angle(double value, double stdErr, Angle.Units units)
• ### Method Summary

All Methods
Modifier and Type Method and Description
static Angle acos(double cos)
Inverse cosine.
Returns new Angle which is the sum of the present one and other.
static Maths.Statistics angleStatistics(Angle... angles)
Calculate the min, max, mean and stdDev (all in degrees) of an array of angles, taking into account periodicity.
static Maths.Statistics angleStatistics(java.util.Collection<Angle> angles)
Calculate the min, max, mean and stdDev (all in degrees) of a set or list of angles, taking into account periodicity.
static Angle asin(double sin)
Inverse sine.
static Angle atan(double tan)
Inverse tangent.
static Angle atan2(double y, double x)
Inverse tangent.
Angle clone()
Returns a new Angle with the same fields.
int compareTo(Angle other)
Implements java.lang.Comparable
double cos()
Cosine.
Angle difference(Angle other)
Similar to subtract but the result is in the range -180..180 degrees.
boolean equals(Angle other, Angle tolerance)
boolean equals(java.lang.Object obj)
double getDegrees()
Get the value in degrees.
double getHours()
Get the value in hours.
double getStdErrDegrees()
Get the standard error in degrees.
double getStdErrHours()
Get the standard error in hours.
Get the standard error in radians.
int hashCode()
Angle in360()
Returns a new Angle whose value lies in range 0..360 degrees (or 0..2pi radians).
Angle multiply(double factor)
Returns a new Angle that is the result of multiplying the current one by a factor.
static Angle parseAngle(java.lang.String s)
Allow all possible formatting of the String.
double sin()
Sine.
Angle subtract(Angle other)
Returns a new Angle which is the result of subtracting other from this.
double tan()
Tangent.
java.lang.String toString()
java.lang.String toString(Angle.Units requiredUnits)
Get a String representing the angle in the required units.
java.lang.String toString(java.lang.String pattern)
Rather like java.text.SimpleDateFormat, this method allows the use of a format string which can be as follows.
• ### Methods inherited from class java.lang.Object

finalize, getClass, notify, notifyAll, wait, wait, wait
• ### Field Detail

• #### DEGREE_SYMBOL

public static final char DEGREE_SYMBOL
Constant Field Values

• ### Constructor Detail

• #### Angle

public Angle(double value,
Angle.Units units)
• #### Angle

public Angle(double value,
double stdErr,
Angle.Units units)
• ### Method Detail

• #### getDegrees

public double getDegrees()
Get the value in degrees.
• #### getHours

public double getHours()
Get the value in hours.

• #### getStdErrDegrees

public double getStdErrDegrees()
Get the standard error in degrees.
• #### getStdErrHours

public double getStdErrHours()
Get the standard error in hours.

Get the standard error in radians.
• #### parseAngle

public static Angle parseAngle(java.lang.String s)
throws java.lang.NumberFormatException
Allow all possible formatting of the String. Eg,
123.45678 (decimal degrees if part before point is less than 10000)
123:27:18.3
-123 27 18.3
123d27m18.3s
+1232718.3 (sexagesimal)
023d27m18.3
2d27m18.3
123 27m18.3 (can be any single non-digit separators between sub-fields)
2:07:04.3
but not 274.3 which would have to be 20704.3 to be unambiguous. Leading sign is allowed.
Throws:
java.lang.NumberFormatException
• #### cos

public double cos()
Cosine.
• #### sin

public double sin()
Sine.
• #### tan

public double tan()
Tangent.
• #### acos

public static Angle acos(double cos)
Inverse cosine.
• #### asin

public static Angle asin(double sin)
Inverse sine.
• #### atan

public static Angle atan(double tan)
Inverse tangent.
• #### atan2

public static Angle atan2(double y,
double x)
Inverse tangent.
• #### in360

public Angle in360()
Returns a new Angle whose value lies in range 0..360 degrees (or 0..2pi radians).

Returns new Angle which is the sum of the present one and other. Result is not necessarily in the range 0..360 degrees.
• #### subtract

public Angle subtract(Angle other)
Returns a new Angle which is the result of subtracting other from this. Result is not necessarily in the range 0..360 degrees.
• #### multiply

public Angle multiply(double factor)
Returns a new Angle that is the result of multiplying the current one by a factor. Result is not necessarily in the range 0..360 degrees.
• #### difference

public Angle difference(Angle other)
Similar to subtract but the result is in the range -180..180 degrees.
• #### compareTo

public int compareTo(Angle other)
Implements java.lang.Comparable
Specified by:
compareTo in interface java.lang.Comparable<Angle>
• #### angleStatistics

public static Maths.Statistics angleStatistics(java.util.Collection<Angle> angles)
Calculate the min, max, mean and stdDev (all in degrees) of a set or list of angles, taking into account periodicity. Uses Maths.angleDifference () from a working mean of the first angle. Does NOT use the erroneous method you can find on the web that averages sin and cos and then takes atan2.
• #### angleStatistics

public static Maths.Statistics angleStatistics(Angle... angles)
Calculate the min, max, mean and stdDev (all in degrees) of an array of angles, taking into account periodicity. Uses Maths.angleDifference () from a working mean of the first angle. Does NOT use the erroneous method you can find on the web that averages sin and cos and then takes atan2.
• #### clone

public Angle clone()
throws java.lang.CloneNotSupportedException
Returns a new Angle with the same fields.
Overrides:
clone in class java.lang.Object
Throws:
java.lang.CloneNotSupportedException
• #### toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object
• #### toString

public java.lang.String toString(Angle.Units requiredUnits)
Get a String representing the angle in the required units.
• #### toString

public java.lang.String toString(java.lang.String pattern)
Rather like java.text.SimpleDateFormat, this method allows the use of a format string which can be as follows. Characters in square brackets are optional.
d = degrees, m = minutes, s = seconds, h = hours.
There is no need to use this method for radians because the format is a simple decimal.
[x] means show the relevant units symbol after each part; if present, must come first.
[+] means always show the sign (otherwise only minus will appear.
Duplicated digits mean show a leading zero to make 2 digits if necessary.
Digits after a decimal point indicate how many fractional digits to show.
A decimal point can only appear in the last item (d.dd or m.mm or r.rr, etc).
Examples:
[x][+][d]d [m]m [s]s[.][s]   - any number of trailing s's.
[+][d]d.[d]                  - any number of trailing d's.
[x][+][h]h [m]m.[m]          - any number of trailing m's.

• #### hashCode

public int hashCode()
Overrides:
hashCode in class java.lang.Object
• #### equals

public boolean equals(java.lang.Object obj)
Overrides:
equals in class java.lang.Object
• #### equals

public boolean equals(Angle other,
Angle tolerance)