/// <summary> /// Indicates whether this instance and a specified object are equal. /// </summary> /// <param name="obj">Another object to compare to.</param> /// <returns><c>true</c> if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, <c>false</c>.</returns> public override Boolean Equals(Object obj) { if (ReferenceEquals(null, obj)) { return(false); } if (ReferenceEquals(this, obj)) { return(true); } Coordinate otherCoordinate = obj as Coordinate; if (otherCoordinate != null) { return(this.x == otherCoordinate.x && this.y == otherCoordinate.y && this.z == otherCoordinate.z); } CoordinateVector otherVector = obj as CoordinateVector; if (otherVector != null) { return(this.x == otherVector.X && this.y == otherVector.Y && this.z == otherVector.Z); } return(false); }
/// <summary> /// Indicates whether this instance and a specified other <see cref="CoordinateVector" /> are equal. /// </summary> /// <param name="other">Another <see cref="CoordinateVector" /> to compare to.</param> /// <returns><c>true</c> if <paramref name="other" /> and this instance represent the same value; otherwise, <c>false</c>.</returns> public Boolean Equals(CoordinateVector other) { if (ReferenceEquals(other, null)) { return(false); } return(this.x == other.X && this.y == other.Y && this.z == other.Z); }
/// <summary> /// Determines whether the specified coordinate vectors are equal. /// </summary> /// <param name="first">The first coordinate vector.</param> /// <param name="second">The second coordinate vector.</param> /// <returns><c>true</c> if the two coordinate vectors are considered equal at the specified precision; otherwise, <c>false</c>.</returns> public Boolean AreEqual(CoordinateVector first, CoordinateVector second) { if (ReferenceEquals(first, null) && ReferenceEquals(second, null)) { return(true); } if (ReferenceEquals(first, null) || ReferenceEquals(second, null)) { return(false); } return(this.AreEqual(first.X, second.X) && this.AreEqual(first.Y, second.Y) && this.AreEqual(first.Z, second.Z)); }
/// <summary> /// Computes the cross product of two vectors. /// </summary> /// <param name="first">The first vector.</param> /// <param name="second">The second vector.</param> /// <returns>The cross product of two vectors.</returns> /// <exception cref="System.ArgumentNullException"> /// The first vector is null. /// or /// The second vector is null. /// </exception> public static CoordinateVector CrossProduct(CoordinateVector first, CoordinateVector second) { if (ReferenceEquals(first, null)) { throw new ArgumentNullException(nameof(first)); } if (ReferenceEquals(second, null)) { throw new ArgumentNullException(nameof(second)); } return(new CoordinateVector(first.y * second.z - first.z * second.y, first.z * second.x - first.x * second.z, first.x * second.y - first.y * second.x)); }
/// <summary> /// Indicates whether this instance and a specified other <see cref="CoordinateVector" /> are equal. /// </summary> /// <param name="other">Another <see cref="CoordinateVector" /> to compare to.</param> /// <returns><c>true</c> if <paramref name="other" /> and this instance represent the same value; otherwise, <c>false</c>.</returns> public Boolean Equals(CoordinateVector other) { if (ReferenceEquals(other, null)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } return(this.x == other.x && this.y == other.y && this.z == other.z); }
/// <summary> /// Computes the perp dot product of two vectors. /// </summary> /// <param name="first">The first vector.</param> /// <param name="second">The second vector.</param> /// <returns>The perp dot product of two vectors.</returns> /// <exception cref="System.ArgumentNullException"> /// The first vector is null. /// or /// The second vector is null. /// </exception> public static Double PerpDotProduct(CoordinateVector first, CoordinateVector second) { if (ReferenceEquals(first, null)) { throw new ArgumentNullException(nameof(first)); } if (ReferenceEquals(second, null)) { throw new ArgumentNullException(nameof(second)); } return(first.x * second.y - first.y * second.x); }
/// <summary> /// Computes the distance between two vectors. /// </summary> /// <param name="first">The first vector.</param> /// <param name="second">The second vector.</param> /// <returns>The distance between the two vectors.</returns> /// <exception cref="System.ArgumentNullException"> /// The first vector is null. /// or /// The second vector is null. /// </exception> public static Double Distance(CoordinateVector first, CoordinateVector second) { if (ReferenceEquals(first, null)) { throw new ArgumentNullException(nameof(first)); } if (ReferenceEquals(second, null)) { throw new ArgumentNullException(nameof(second)); } Double x = first.x - second.x; Double y = first.y - second.y; Double z = first.z - second.z; return(Math.Sqrt(x * x + y * y + z * z)); }
/// <summary> /// Rounds the specified list of coordinate vectors to match the precision model. /// </summary> /// <param name="vectors">The list of vectors.</param> /// <returns>The list of precise coordinate vectors.</returns> /// <exception cref="System.ArgumentNullException">The collection of vectors is null.</exception> public IReadOnlyList <CoordinateVector> MakePrecise(IReadOnlyList <CoordinateVector> vectors) { if (vectors == null) { throw new ArgumentNullException(nameof(vectors)); } if (this.ModelType == PrecisionModelType.Floating) { return(vectors); } CoordinateVector[] preciseVectors = new CoordinateVector[vectors.Count]; if (this.ModelType == PrecisionModelType.Fixed) { for (Int32 index = 0; index < vectors.Count; index++) { if (vectors[index] == null) { continue; } preciseVectors[index] = new CoordinateVector(Math.Floor((vectors[index].X * this.Scale) + 0.5) / this.Scale, Math.Floor((vectors[index].Y * this.Scale) + 0.5) / this.Scale, Math.Floor((vectors[index].Z * this.Scale) + 0.5) / this.Scale); } } else { for (Int32 index = 0; index < vectors.Count; index++) { if (vectors[index] == null) { continue; } preciseVectors[index] = new CoordinateVector((Single)vectors[index].X, (Single)vectors[index].Y, (Single)vectors[index].Z); } } return(preciseVectors); }
/// <summary> /// Determines whether the two vectors are perpendicular. /// </summary> /// <param name="first">The first vector.</param> /// <param name="second">The second vector.</param> /// <param name="precision">The precision model.</param> /// <returns><c>true</c> if the two vectors are perpendicular; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException"> /// The first vector is null. /// or /// The second vector is null. /// </exception> public static Boolean IsPerpendicular(CoordinateVector first, CoordinateVector second, PrecisionModel precision) { if (ReferenceEquals(first, null)) { throw new ArgumentNullException(nameof(first)); } if (ReferenceEquals(second, null)) { throw new ArgumentNullException(nameof(second)); } if (precision == null) { precision = PrecisionModel.Default; } return(first.x * second.x + first.y * second.y + first.z * second.z <= precision.Tolerance(first, second)); }
/// <summary> /// Determines whether the two vectors are parallel. /// </summary> /// <param name="first">The first vector.</param> /// <param name="second">The second vector.</param> /// <param name="precision">The precision model.</param> /// <returns><c>true</c> if the two vectors are parallel; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException"> /// The first vector is null. /// or /// The second vector is null. /// </exception> public static Boolean IsParallel(CoordinateVector first, CoordinateVector second, PrecisionModel precision) { if (ReferenceEquals(first, null)) { throw new ArgumentNullException(nameof(first)); } if (ReferenceEquals(second, null)) { throw new ArgumentNullException(nameof(second)); } if (precision == null) { precision = PrecisionModel.Default; } return(Math.Abs(first.x * second.y - first.y * second.x) <= precision.Tolerance(first, second) && Math.Abs(first.x * second.z - first.z * second.z) <= precision.Tolerance(first, second)); }
/// <summary> /// Rounds the specified coordinate vector to match the precision model. /// </summary> /// <param name="vector">The coordinate vector.</param> /// <returns>The precise coordinate vector.</returns> public CoordinateVector MakePrecise(CoordinateVector vector) { if (vector == null) { return(null); } switch (this.ModelType) { case PrecisionModelType.FloatingSingle: return(new CoordinateVector((Single)vector.X, (Single)vector.Y, (Single)vector.Z)); case PrecisionModelType.Fixed: return(new CoordinateVector(Math.Floor((vector.X * this.Scale) + 0.5) / this.Scale, Math.Floor((vector.Y * this.Scale) + 0.5) / this.Scale, Math.Floor((vector.Z * this.Scale) + 0.5) / this.Scale)); default: return(vector); } }
/// <summary> /// Determines whether the two vectors are perpendicular. /// </summary> /// <param name="first">The first vector.</param> /// <param name="second">The second vector.</param> /// <returns><c>true</c> if the two vectors are perpendicular; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException"> /// The first vector is null. /// or /// The second vector is null. /// </exception> public static Boolean IsPerpendicular(CoordinateVector first, CoordinateVector second) { return(IsPerpendicular(first, second, PrecisionModel.Default)); }
/// <summary> /// Determines whether the two vectors are parallel. /// </summary> /// <param name="first">The first vector.</param> /// <param name="second">The second vector.</param> /// <returns><c>true</c> if the two vectors are parallel; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException"> /// The first vector is null. /// or /// The second vector is null. /// </exception> public static Boolean IsParallel(CoordinateVector first, CoordinateVector second) { return(IsParallel(first, second, PrecisionModel.Default)); }