|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectnet.grelf.Angle
public class Angle
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
x = cos (toRadians (latitudeDegrees))
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.
| Nested Class Summary | |
|---|---|
static class |
Angle.Units
|
| Field Summary | |
|---|---|
static char |
DEGREE_SYMBOL
|
static double |
FOUR_PI
|
static double |
TWO_PI
|
protected MeasuredValue |
valueRadians
|
| Constructor Summary | |
|---|---|
Angle(double value,
Angle.Units units)
|
|
Angle(double value,
double stdErr,
Angle.Units units)
|
|
| Method Summary | |
|---|---|
static Angle |
acos(double cos)
Inverse cosine. |
Angle |
add(Angle other)
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 th 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(java.lang.Object obj)
|
double |
getDegrees()
Get the value in degrees. |
double |
getHours()
Get the value in hours. |
double |
getRadians()
Get the value in radians. |
double |
getStdErrDegrees()
Get the standard error in degrees. |
double |
getStdErrHours()
Get the standard error in hours. |
double |
getStdErrRadians()
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()
Units are radians. |
java.lang.String |
toString(Angle.Units requiredUnits)
Get a String representing the angle in the required units. |
| Methods inherited from class java.lang.Object |
|---|
finalize, getClass, notify, notifyAll, wait, wait, wait |
| Field Detail |
|---|
public static final double TWO_PI
public static final double FOUR_PI
public static final char DEGREE_SYMBOL
protected MeasuredValue valueRadians
| Constructor Detail |
|---|
public Angle(double value,
Angle.Units units)
public Angle(double value,
double stdErr,
Angle.Units units)
| Method Detail |
|---|
public double getDegrees()
public double getHours()
public double getRadians()
public double getStdErrDegrees()
public double getStdErrHours()
public double getStdErrRadians()
public static Angle parseAngle(java.lang.String s)
throws java.lang.NumberFormatException
java.lang.NumberFormatExceptionpublic double cos()
public double sin()
public double tan()
public static Angle acos(double cos)
public static Angle asin(double sin)
public static Angle atan(double tan)
public static Angle atan2(double y,
double x)
public Angle in360()
public Angle add(Angle other)
public Angle subtract(Angle other)
public Angle multiply(double factor)
public Angle difference(Angle other)
public int compareTo(Angle other)
compareTo in interface java.lang.Comparable<Angle>public static Maths.Statistics angleStatistics(java.util.Collection<Angle> angles)
public static Maths.Statistics angleStatistics(Angle... angles)
public Angle clone()
clone in class java.lang.Objectpublic java.lang.String toString()
toString in class java.lang.Objectpublic java.lang.String toString(Angle.Units requiredUnits)
public int hashCode()
hashCode in class java.lang.Objectpublic boolean equals(java.lang.Object obj)
equals in class java.lang.Object
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||