//
//Angle class -- copyright 2001, Information Disciplines, Inc.
// This class supports operations on plane angles.
public class Angle{
double value; // normalized radians
// For compatibility with the Java Math library and other software,
// range is (-pi,pi] not [0,2pi), enforced by the following function:
void normalize()
{final double twoPi = Math.PI + Math.PI;
while (value <= -Math.PI) value += twoPi;
while (value > Math.PI) value -= twoPi;
}
// Constructors
// ------------
public Angle(final double rad) {value = rad; normalize();}
public Angle() {this(0.0);}
public Angle(final Angle theta) {this(theta.value);}
public Angle(final int deg, // Degrees, minutes, seconds
final int min, // (Signs should agree
final int sec) // for conventional notation.)
{double seconds = sec + 60 * (min + 60 * deg);
value = seconds * Math.PI / 648000.0;
normalize();
}
public Angle(final int deg, final int min) {this(deg,min,0);}
// Accessors
// ---------
public double toDegrees() {return 180.0 * (value / Math.PI);}
public double toRadians() {return value;}
// If the following functions are used often, performance can be improved
// by caching the results -- See IDI Date class for example.
public short degrees() {return (short)(toDegrees());}
public short minutes()
{long result = ((long)(Math.abs(toDegrees()) * 60.0) % 60);
return (short) (value >=0 ? result : -result);
}
public short seconds()
{long result = ((long)(Math.round(Math.abs(toDegrees()) * 3600.0)) % 60);
return (short) (value >=0 ? result : -result);
}
// Trigonometric functions (for notational consistency and to hide internal
// ----------------------- representation. User can use other old functions
// by extracting value with toRadians() accessor)
public double cos() {return Math.cos (value);}
public double sin() {return Math.sin (value);}
public double tan() {return Math.tan (value);}
public static Angle arccos(final double x) {return new Angle(Math.acos(x));}
public static Angle arcsin(final double x) {return new Angle(Math.asin(x));}
public static Angle arctan(final double y,
final double x) {return new Angle(Math.atan2(y,x));}
public static Angle arctan(final double y) {return new Angle(arctan(y,1.0));}
// Conversion functions
// --------------------
public String toString()
{final String degreeSymbol = "\370";
return (value < 0 ? "-" : "")
+ Math.abs(degrees()) + degreeSymbol
+ Math.abs(minutes()) + '\''
+ Math.abs(seconds()) + '\"';}
// Relational operators
// --------------------
// WARNING: Floating point equality test is undependable
// Ordering is ambiguous and not transitive, due to normalization.
public boolean equals(final Angle rs) {return value == rs.value;}
public boolean lessThan(final Angle rs) {return value < rs.value;}
public boolean greaterThan(final Angle rs) {return value > rs.value;}
// Operators follow the standard additive pattern
// ---------
public Angle addSet(final Angle rs)
{value+=rs.value; normalize(); return this;}
public Angle subSet (final Angle rs)
{value-=rs.value; normalize(); return this;}
public Angle mpySet(final double rs)
{value*=rs; normalize(); return this;}
public Angle divSet (final double rs)
{value/=rs; normalize(); return this;}
public Angle minus () {return new Angle(-value);}
public Angle add(final Angle rs) {return new Angle(this).addSet(rs);}
public Angle sub(final Angle rs) {return new Angle(this).subSet(rs);}
public Angle mpy(final double rs) {return new Angle(this).mpySet(rs);}
public Angle div(final double rs) {return new Angle(this).divSet(rs);}
public double div(final Angle rs) {return value / rs.value;}
// The following two functions support standard Java contracts, but are
// not necessary, since easier-to-use equivalents appear above.
public boolean equals(final Object rs)
{return rs instanceof Angle && value ==((Angle) rs).value;}
public int compareTo(Object obj)
{Angle theta = (Angle) obj;
return lessThan(theta) ? -1
: greaterThan(theta) ? 1
: 0;
}
}
//