- gavaghangeodesy.zip
- Geodesy
- dist
- Gavaghan.Geodesy.dll
- Gavaghan.Geodesy.Example.exe
- Gavaghan.Geodesy.Example.pdb
- Gavaghan.Geodesy.pdb
- Gavaghan.Geodesy.Example
- Gavaghan.Geodesy.Test
- Gavaghan.Geodesy
- Geodesy.sln
- lib
- nunit.framework.dll
- gavaghan.geodesy.zip
|
/* Gavaghan.Geodesy by Mike Gavaghan
*
* http://www.gavaghan.org/blog/free-source-code/geodesy-library-vincentys-formula/
*
* This code may be freely used and modified on any personal or professional
* project. It comes with no warranty.
*/
using System;
namespace Gavaghan.Geodesy
{
/// <summary>
/// Encapsulation of an Angle. Angles are constructed and serialized in
/// degrees for human convenience, but a conversion to radians is provided
/// for mathematical calculations.
///
/// Angle comparisons are performed in absolute terms - no "wrapping" occurs.
/// In other words, 360 degress != 0 degrees.
/// </summary>
[Serializable]
public struct Angle : IComparable<Angle>
{
/// <summary>Degrees/Radians conversion constant.</summary>
private const double PiOver180 = Math.PI / 180.0;
/// <summary>Angle value in degrees.</summary>
private double mDegrees;
/// <summary>Zero Angle</summary>
static public readonly Angle Zero = new Angle(0);
/// <summary>180 degree Angle</summary>
static public readonly Angle Angle180 = new Angle(180);
/// <summary>
/// Construct a new Angle from a degree measurement.
/// </summary>
/// <param name="degrees">angle measurement</param>
public Angle(double degrees)
{
mDegrees = degrees;
}
/// <summary>
/// Construct a new Angle from degrees and minutes.
/// </summary>
/// <param name="degrees">degree portion of angle measurement</param>
/// <param name="minutes">minutes portion of angle measurement (0 <= minutes < 60)</param>
public Angle(int degrees, double minutes)
{
mDegrees = minutes / 60.0;
mDegrees = (degrees < 0) ? (degrees - mDegrees) : (degrees + mDegrees);
}
/// <summary>
/// Construct a new Angle from degrees, minutes, and seconds.
/// </summary>
/// <param name="degrees">degree portion of angle measurement</param>
/// <param name="minutes">minutes portion of angle measurement (0 <= minutes < 60)</param>
/// <param name="seconds">seconds portion of angle measurement (0 <= seconds < 60)</param>
public Angle(int degrees, int minutes, double seconds)
{
mDegrees = (seconds / 3600.0) + (minutes / 60.0);
mDegrees = (degrees < 0) ? (degrees - mDegrees) : (degrees + mDegrees);
}
/// <summary>
/// Get/set angle measured in degrees.
/// </summary>
public double Degrees
{
get { return mDegrees; }
set { mDegrees = value; }
}
/// <summary>
/// Get/set angle measured in radians.
/// </summary>
public double Radians
{
get { return mDegrees * PiOver180; }
set { mDegrees = value / PiOver180; }
}
/// <summary>
/// Get the absolute value of the angle.
/// </summary>
public Angle Abs()
{
return new Angle(Math.Abs(mDegrees));
}
/// <summary>
/// Compare this angle to another angle.
/// </summary>
/// <param name="other">other angle to compare to.</param>
/// <returns>result according to IComparable contract/></returns>
public int CompareTo(Angle other)
{
return mDegrees.CompareTo(other.mDegrees);
}
/// <summary>
/// Calculate a hash code for the angle.
/// </summary>
/// <returns>hash code</returns>
public override int GetHashCode()
{
return (int) (mDegrees * 1000033);
}
/// <summary>
/// Compare this Angle to another Angle for equality. Angle comparisons
/// are performed in absolute terms - no "wrapping" occurs. In other
/// words, 360 degress != 0 degrees.
/// </summary>
/// <param name="obj">object to compare to</param>
/// <returns>'true' if angles are equal</returns>
public override bool Equals(object obj)
{
if (!(obj is Angle)) return false;
Angle other = (Angle)obj;
return mDegrees == other.mDegrees;
}
/// <summary>
/// Get coordinates as a string.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return mDegrees.ToString();
}
#region Operators
public static Angle operator +(Angle lhs, Angle rhs)
{
return new Angle(lhs.mDegrees + rhs.mDegrees);
}
public static Angle operator -(Angle lhs, Angle rhs)
{
return new Angle(lhs.mDegrees - rhs.mDegrees);
}
public static bool operator >(Angle lhs, Angle rhs)
{
return lhs.mDegrees > rhs.mDegrees;
}
public static bool operator >=(Angle lhs, Angle rhs)
{
return lhs.mDegrees >= rhs.mDegrees;
}
public static bool operator <(Angle lhs, Angle rhs)
{
return lhs.mDegrees < rhs.mDegrees;
}
public static bool operator <=(Angle lhs, Angle rhs)
{
return lhs.mDegrees <= rhs.mDegrees;
}
public static bool operator ==(Angle lhs, Angle rhs)
{
return lhs.mDegrees == rhs.mDegrees;
}
public static bool operator !=(Angle lhs, Angle rhs)
{
return lhs.mDegrees != rhs.mDegrees;
}
/// <summary>
/// Imlplicity cast a double as an Angle measured in degrees.
/// </summary>
/// <param name="degrees">angle in degrees</param>
/// <returns>double cast as an Angle</returns>
public static implicit operator Angle(double degrees)
{
return new Angle(degrees);
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Mike Gavaghan opines on
C# and .Net in his blog
Talk Nerdy To Me[
^]. He is a Microsoft Certified Professional Developer working as a C#/.Net software consultant based in Dallas, Texas.
Since 1992, he has supported clients in diverse businesses including financial services, travel, airlines, and telecom. He has consulted at both mammoth enterprises and small startups (and sees merits and problems in both).
You may also view his profile on
LinkedIn[
^].