2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
7 package gov
.nasa
.worldwind
.geom
;
9 import gov
.nasa
.worldwind
.*;
12 * Represents a geometric angle. Instances of <code>Angle</code> are immutable. An <code>Angle</code> can be obtained
13 * through the factory methods <code>fromDegrees</code> and <code>fromRadians</code>.
16 * @version $Id: Angle.java 1645 2007-04-27 00:16:09Z tgaskins $
18 public class Angle
implements Comparable
<Angle
>
21 * Represents an angle of zero degrees
23 public final static Angle ZERO
= Angle
.fromDegrees(0);
26 * Represents a right angle of positive 90 degrees
28 public final static Angle POS90
= Angle
.fromDegrees(90);
31 * Represents a right angle of negative 90 degrees
33 public final static Angle NEG90
= Angle
.fromDegrees(-90);
36 * Represents an angle of positive 180 degrees
38 public final static Angle POS180
= Angle
.fromDegrees(180);
41 * Represents an angle of negative 180 degrees
43 public final static Angle NEG180
= Angle
.fromDegrees(-180);
46 * Represents an angle of positive 360 degrees
48 public final static Angle POS360
= Angle
.fromDegrees(360);
50 private final static double DEGREES_TO_RADIANS
= Math
.PI
/ 180d
;
51 private final static double RADIANS_TO_DEGREES
= 180d
/ Math
.PI
;
54 * Obtains an <code>Angle</code> from a specified number of degrees.
56 * @param degrees the size in degrees of the <code>Angle</code> to be obtained
57 * @return a new <code>Angle</code>, whose size in degrees is given by <code>degrees</code>
59 public static Angle
fromDegrees(double degrees
)
61 return new Angle(degrees
, DEGREES_TO_RADIANS
* degrees
);
65 * Obtains an <code>Angle</code> from a specified number of radians.
67 * @param radians the size in radians of the <code>Angle</code> to be obtained
68 * @return a new <code>Angle</code>, whose size in radians is given by <code>radians</code>
70 public static Angle
fromRadians(double radians
)
72 return new Angle(RADIANS_TO_DEGREES
* radians
, radians
);
75 private static final double PIOver2
= Math
.PI
/ 2;
77 public static Angle
fromDegreesLatitude(double degrees
)
79 degrees
= degrees
< -90 ?
-90 : degrees
> 90 ?
90 : degrees
;
80 double radians
= DEGREES_TO_RADIANS
* degrees
;
81 radians
= radians
< -PIOver2 ?
-PIOver2
: radians
> PIOver2 ? PIOver2
: radians
;
83 return new Angle(degrees
, radians
);
86 public static Angle
fromRadiansLatitude(double radians
)
88 radians
= radians
< -PIOver2 ?
-PIOver2
: radians
> PIOver2 ? PIOver2
: radians
;
89 double degrees
= RADIANS_TO_DEGREES
* radians
;
90 degrees
= degrees
< -90 ?
-90 : degrees
> 90 ?
90 : degrees
;
92 return new Angle(degrees
, radians
);
95 public static Angle
fromDegreesLongitude(double degrees
)
97 degrees
= degrees
< -180 ?
-180 : degrees
> 180 ?
180 : degrees
;
98 double radians
= DEGREES_TO_RADIANS
* degrees
;
99 radians
= radians
< -Math
.PI ?
-Math
.PI
: radians
> Math
.PI ? Math
.PI
: radians
;
101 return new Angle(degrees
, radians
);
104 public static Angle
fromRadiansLongitude(double radians
)
106 radians
= radians
< -Math
.PI ?
-Math
.PI
: radians
> Math
.PI ? Math
.PI
: radians
;
107 double degrees
= RADIANS_TO_DEGREES
* radians
;
108 degrees
= degrees
< -180 ?
-180 : degrees
> 180 ?
180 : degrees
;
110 return new Angle(degrees
, radians
);
114 * Obtains an <code>Angle</code> from rectangular coordinates.
116 * @param x the abscissa coordinate
117 * @param y the ordinate coordinate
118 * @return a new <code>Angle</code>, whose size is determined from <code>x</code> and <code>y</code>
120 public static Angle
fromXY(double x
, double y
)
122 double radians
= Math
.atan2(y
, x
);
123 return new Angle(RADIANS_TO_DEGREES
* radians
, radians
);
126 public final double degrees
;
127 public final double radians
;
129 public Angle(Angle angle
)
131 this.degrees
= angle
.degrees
;
132 this.radians
= angle
.radians
;
135 // private Angle(double degrees)
137 // this.degrees = degrees;
138 // this.radians = DEGREES_TO_RADIANS * this.degrees;
141 private Angle(double degrees
, double radians
)
143 this.degrees
= degrees
;
144 this.radians
= radians
;
148 * Retrieves the size of this <code>Angle</code> in degrees. This method may be faster than first obtaining the
149 * radians and then converting to degrees.
151 * @return the size of this <code>Angle</code> in degrees
153 public final double getDegrees()
159 * Retrieves the size of this <code>Angle</code> in radians. This may be useful for <code>java.lang.Math</code>
160 * functions, which generally take radians as trigonometric arguments. This method may be faster that first
161 * obtaining the degrees and then converting to radians.
163 * @return the size of this <code>Angle</code> in radians.
165 public final double getRadians()
171 * Obtains the sum of these two <code>Angle</code>s. Does not accept a null argument. This method is commutative, so
172 * <code>a.add(b)</code> and <code>b.add(a)</code> are equivalent. Neither this <code>Angle</code> nor
173 * <code>angle</code> is changed, instead the result is returned as a new <code>Angle</code>.
175 * @param angle the <code>Angle</code> to add to this one.
176 * @return an <code>Angle</code> whose size is the total of this <code>Angle</code>s and <code>angle</code>s size
177 * @throws IllegalArgumentException if <code>angle</code> is null
179 public final Angle
add(Angle angle
)
183 String message
= WorldWind
.retrieveErrMsg("nullValue.AngleIsNull");
184 WorldWind
.logger().log(java
.util
.logging
.Level
.FINE
, message
);
185 throw new IllegalArgumentException(message
);
188 return Angle
.fromDegrees(this.degrees
+ angle
.degrees
);
192 * Obtains the difference of these two <code>Angle</code>s. Does not accept a null argument. This method is not
193 * commutative. Neither this <code>Angle</code> nor <code>angle</code> is changed, instead the result is returned as
194 * a new <code>Angle</code>.
196 * @param angle the <code>Angle</code> to subtract from this <code>Angle</code>
197 * @return a new <code>Angle</code> correpsonding to this <code>Angle</code>'s size minus <code>angle</code>'s size
198 * @throws IllegalArgumentException if <code>angle</code> is null
200 public final Angle
subtract(Angle angle
)
204 String message
= WorldWind
.retrieveErrMsg("nullValue.AngleIsNull");
205 WorldWind
.logger().log(java
.util
.logging
.Level
.FINE
, message
);
206 throw new IllegalArgumentException(message
);
209 return Angle
.fromDegrees(this.degrees
- angle
.degrees
);
213 * Multiplies this <code>Angle</code> by <code>multiplier</code>. This <code>Angle</code> remains unchanged. The
214 * result is returned as a new <code>Angle</code>.
216 * @param multiplier a scalar by which this <code>Angle</code> is multiplied
217 * @return a new <code>Angle</code> whose size equals this <code>Angle</code>'s size multiplied by
218 * <code>multiplier</code>
220 public final Angle
multiply(double multiplier
)
222 return Angle
.fromDegrees(this.degrees
* multiplier
);
226 * Divides this <code>Angle</code> by another angle. This <code>Angle</code> remains unchanged, instead the
227 * resulting value in degrees is returned.
229 * @param angle the <code>Angle</code> by which to divide
230 * @return this <code>Angle</code>'s degrees divided by <code>angle</code>'s degrees
231 * @throws IllegalArgumentException if <code>angle</code> is null
233 public final double divide(Angle angle
)
237 String message
= WorldWind
.retrieveErrMsg("nullValue.AngleIsNull");
238 WorldWind
.logger().log(java
.util
.logging
.Level
.FINE
, message
);
239 throw new IllegalArgumentException(message
);
242 return this.degrees
/ angle
.degrees
;
245 public final Angle
addDegrees(double degrees
)
246 { //Tom: this method is not used, should we delete it? (13th Dec 06)
247 return Angle
.fromDegrees(this.degrees
+ degrees
);
250 public final Angle
subtractDegrees(double degrees
)
251 { //Tom: this method is not used, should we delete it? (13th Dec 06)
252 return Angle
.fromDegrees(this.degrees
- degrees
);
256 * Divides this <code>Angle</code> by <code>divisor</code>. This <code>Angle</code> remains unchanged. The result is
257 * returned as a new <code>Angle</code>. Behaviour is undefined if <code>divisor</code> equals zero.
259 * @param divisor the number to be divided by
260 * @return a new <code>Angle</code> equivalent to this <code>Angle</code> divided by <code>divisor</code>
262 public final Angle
divide(double divisor
)
264 return Angle
.fromDegrees(this.degrees
/ divisor
);
267 public final Angle
addRadians(double radians
)
269 return Angle
.fromRadians(this.radians
+ radians
);
272 public final Angle
subtractRadians(double radians
)
274 return Angle
.fromRadians(this.radians
- radians
);
278 * Obtains the sine of this <code>Angle</code>.
280 * @return the trigonometric sine of this <code>Angle</code>
282 public final double sin()
284 return Math
.sin(this.radians
);
287 public final double sinHalfAngle()
288 { //Tom: this method is not used, should we delete it? (13th Dec 06)
289 return Math
.sin(0.5 * this.radians
);
292 public static Angle
asin(double sine
)
293 { //Tom: this method is not used, should we delete it? (13th Dec 06)
294 return Angle
.fromRadians(Math
.asin(sine
));
298 * Obtains the cosine of this <code>Angle</code>
300 * @return the trigonometric cosine of this <code>Angle</code>
302 public final double cos()
304 return Math
.cos(this.radians
);
307 public final double cosHalfAngle()
308 { //Tom: this method is not used, should we delete it? (13th Dec 06)
309 return Math
.cos(0.5 * this.radians
);
312 public static Angle
acos(double cosine
)
313 { //Tom: this method is not used, should we delete it? (13th Dec 06)
314 return Angle
.fromRadians(Math
.acos(cosine
));
318 * Obtains the tangent of half of this <code>Angle</code>.
320 * @return the trigonometric tangent of half of this <code>Angle</code>
322 public final double tanHalfAngle()
324 return Math
.tan(0.5 * this.radians
);
327 public static Angle
atan(double tan
)
328 { //Tom: this method is not used, should we delete it? (13th Dec 06)
329 return Angle
.fromRadians(Math
.atan(tan
));
333 * Obtains the average of two <code>Angle</code>s. This method is commutative, so <code>midAngle(m, n)</code> and
334 * <code>midAngle(n, m)</code> are equivalent.
336 * @param a1 the first <code>Angle</code>
337 * @param a2 the second <code>Angle</code>
338 * @return the average of <code>a1</code> and <code>a2</code> throws IllegalArgumentException if either angle is
341 public static Angle
midAngle(Angle a1
, Angle a2
)
343 if (a1
== null || a2
== null)
345 String message
= WorldWind
.retrieveErrMsg("nullValue.AngleIsNull");
346 WorldWind
.logger().log(java
.util
.logging
.Level
.FINE
, message
);
347 throw new IllegalArgumentException(message
);
350 return Angle
.fromDegrees(0.5 * (a1
.degrees
+ a2
.degrees
));
354 * Obtains the average of three <code>Angle</code>s. The order of parameters does not matter.
356 * @param a the first <code>Angle</code>
357 * @param b the second <code>Angle</code>
358 * @return the average of <code>a1</code>, <code>a2</code> and <code>a3</code>
359 * @throws IllegalArgumentException if <code>a</code> or <code>b</code> is null
361 public static Angle
average(Angle a
, Angle b
)
363 if (a
== null || b
== null)
365 String message
= WorldWind
.retrieveErrMsg("nullValue.AngleIsNull");
366 WorldWind
.logger().log(java
.util
.logging
.Level
.FINE
, message
);
367 throw new IllegalArgumentException(message
);
370 return Angle
.fromDegrees(0.5 * (a
.degrees
+ b
.degrees
));
374 * Obtains the average of three <code>Angle</code>s. The order of parameters does not matter.
376 * @param a the first <code>Angle</code>
377 * @param b the second <code>Angle</code>
378 * @param c the third <code>Angle</code>
379 * @return the average of <code>a1</code>, <code>a2</code> and <code>a3</code>
380 * @throws IllegalArgumentException if <code>a</code>, <code>b</code> or <code>c</code> is null
382 public static Angle
average(Angle a
, Angle b
, Angle c
)
384 if (a
== null || b
== null || c
== null)
386 String message
= WorldWind
.retrieveErrMsg("nullValue.AngleIsNull");
387 WorldWind
.logger().log(java
.util
.logging
.Level
.FINE
, message
);
388 throw new IllegalArgumentException(message
);
391 return Angle
.fromDegrees((a
.degrees
+ b
.degrees
+ c
.degrees
) / 3);
395 * Compares this <code>Angle</code> with <code>angle</code> for order. Returns a negative integer if this is the
396 * smaller <code>Angle</code>, a positive integer if this is the larger, and zero if both <code>Angle</code>s are
399 * @param angle the <code>Angle</code> to compare against
400 * @return -1 if this <code>Angle</code> is smaller, 0 if both are equal and +1 if this <code>Angle</code> is
402 * @throws IllegalArgumentException if <code>angle</code> is null
404 public final int compareTo(Angle angle
)
408 String msg
= WorldWind
.retrieveErrMsg("nullValue.AngleIsNull");
409 WorldWind
.logger().log(java
.util
.logging
.Level
.FINE
, msg
);
410 throw new IllegalArgumentException(msg
);
413 if (this.degrees
< angle
.degrees
)
416 if (this.degrees
> angle
.degrees
)
423 * Obtains a <code>String</code> representation of this <code>Angle</code>.
425 * @return the value of this <code>Angle</code> in degrees and as a <code>String</code>
428 public final String
toString()
430 return Double
.toString(this.degrees
) + '\u00B0';
434 * Obtains the amount of memory this <code>Angle</code> consumes.
436 * @return the memory footprint of this <code>Angle</code> in bytes.
438 public long getSizeInBytes()
443 public boolean equals(Object o
)
447 if (o
== null || getClass() != o
.getClass())
450 Angle angle
= (Angle
) o
;
452 if (angle
.degrees
!= this.degrees
)
458 public int hashCode()
460 long temp
= degrees
!= +0.0d ? Double
.doubleToLongBits(degrees
) : 0L;
461 return (int) (temp ^
(temp
>>> 32));