/// <summary> /// Creates a new instance of the <see cref="GreatCircleSegment"/> struct with the given points defininf it. /// </summary> /// <param name="start">The start coordinate of the segment.</param> /// <param name="end">The end coordinate of the segment.</param> public GreatCircleSegment(SphereCoordinate start, SphereCoordinate end) { Start = start; End = end; BaseCircle = new GreatCircle(start, end); Length = CalculateArcLength(start, end); }
/// <summary> /// Checks whether the given <see cref="GreatCircleSegment"/> intersects with this <see cref="GreatCicle"/>. /// The point of intersection can then be found in the out-Parameter. /// </summary> /// <param name="arc">The arc segment to be checked.</param> /// <param name="intersection">The point of intersection, if they intersect.</param> /// <returns>Whether the <see cref="GreatCircleSegment"/> intersects this <see cref="GreatCircle"/> or not.</returns> public bool Intersects(GreatCircleSegment arc, out SphereCoordinate intersection) { intersection = default(SphereCoordinate); CartesianVector possibleIntersection; if (!Intersects(arc.BaseCircle, out possibleIntersection)) { return(false); } if (arc.IsOnArc(possibleIntersection)) { intersection = possibleIntersection; return(true); } if (arc.IsOnArc(-possibleIntersection)) { intersection = -possibleIntersection; return(true); } return(false); }
/// <summary> /// Checks whether the given <see cref="GreatCircleSegment"/> intersects with this one. /// The point of intersection can then be found in the out-Parameter. /// </summary> /// <param name="other">The arc segment to be checked.</param> /// <param name="intersection">The point of intersection, if they intersect.</param> /// <returns>Whether the two <see cref="GreatCircleSegment"/>s intersect or not.</returns> public bool Intersects(GreatCircleSegment other, out SphereCoordinate intersection) { // http://www.boeing-727.com/Data/fly%20odds/distance.html intersection = default(SphereCoordinate); if (Length.IsAlmostEqualTo(0) || other.Length.IsAlmostEqualTo(0)) { return(false); } CartesianVector possibleIntersection1; if (!BaseCircle.Intersects(other.BaseCircle, out possibleIntersection1)) { return(false); } var possibleIntersection2 = -possibleIntersection1; if (IsOnArc(possibleIntersection1) && other.IsOnArc(possibleIntersection1)) { intersection = possibleIntersection1; return(true); } if (IsOnArc(possibleIntersection2) && other.IsOnArc(possibleIntersection2)) { intersection = possibleIntersection2; return(true); } return(false); }
/// <summary> /// Creates a new instance of the <see cref="GreatCircleSegment"/> struct with the given points defining it. /// </summary> /// <param name="baseCircle">The <see cref="GreatCircle"/> that this segment is part of.</param> /// <param name="start">The start coordinate of the segment.</param> /// <param name="end">The end coordinate of the segment.</param> public GreatCircleSegment(GreatCircle baseCircle, SphereCoordinate start, SphereCoordinate end) : this(start, end) { if (!baseCircle.IsOnCircle(start) || !baseCircle.IsOnCircle(end)) throw new ArgumentOutOfRangeException("Start and End have to be on the baseCircle."); BaseCircle = baseCircle; }
/// <summary> /// Calculates the length of a Great Circle segment between the two <see cref="SphereCoordinate"/>s. /// Coordinates must have the same radius. /// </summary> /// <param name="start">One point of the arc.</param> /// <param name="end">Other point of the arc.</param> /// <returns>The length of the Great Circle segment between the two <see cref="SphereCoordinate"/>s.</returns> public static double CalculateArcLength(SphereCoordinate start, SphereCoordinate end) { // http://www.had2know.com/academics/great-circle-distance-sphere-2-points.html var cartesianLength = ((CartesianVector)start - end).Length; return(2 * Math.Asin(cartesianLength / 2)); }
/// <summary> /// Checks whether a given <see cref="SphereCoordinate"/> is on this arc. /// </summary> /// <param name="sphereCoordinate">The <see cref="SphereCoordinate"/> to test.</param> /// <returns>Whether the coordinate is on this arc.</returns> public bool IsOnArc(SphereCoordinate sphereCoordinate) { // http://www.boeing-727.com/Data/fly%20odds/distance.html Step 1.7 var startToCoord = CalculateArcLength(Start, sphereCoordinate); var endToCoord = CalculateArcLength(End, sphereCoordinate); return((Length - startToCoord - endToCoord).IsAlmostEqualTo(0)); }
/// <summary> /// Creates a new instance of the <see cref="GreatCircleSegment"/> struct with the given points defining it. /// </summary> /// <param name="baseCircle">The <see cref="GreatCircle"/> that this segment is part of.</param> /// <param name="start">The start coordinate of the segment.</param> /// <param name="end">The end coordinate of the segment.</param> public GreatCircleSegment(GreatCircle baseCircle, SphereCoordinate start, SphereCoordinate end) : this(start, end) { if (!baseCircle.IsOnCircle(start) || !baseCircle.IsOnCircle(end)) { throw new ArgumentOutOfRangeException("Start and End have to be on the baseCircle."); } BaseCircle = baseCircle; }
private static void Main(string[] args) { var start1 = new SphereCoordinate(0.5 * Math.PI, -0.25 * Math.PI); Console.WriteLine((CartesianVector)start1); var end1 = new SphereCoordinate(0.5 * Math.PI, 0.25 * Math.PI); Console.WriteLine((CartesianVector)end1); var start2 = new SphereCoordinate(0.25 * Math.PI, 0); Console.WriteLine((CartesianVector)start2); var end2 = new SphereCoordinate(0.75 * Math.PI, 0); Console.WriteLine((CartesianVector)end2); var arc1 = new GreatCircleSegment(start1, end1); var arc2 = new GreatCircleSegment(start2, end2); Console.WriteLine(); Console.WriteLine(arc1.Midpoint); Console.WriteLine(new CartesianVector(0, 0, 1)); Console.WriteLine((SphereCoordinate)arc1.Midpoint); Console.WriteLine((SphereCoordinate)new CartesianVector(0, 0, 1)); Console.WriteLine((CartesianVector)(SphereCoordinate)arc1.Midpoint); Console.WriteLine(); SphereCoordinate intersection; Console.WriteLine(arc1.Intersects(arc2, out intersection) + " " + intersection + " " + (CartesianVector)intersection); Console.WriteLine(); var quarterSpherePoly = new VoronoiCell(new SphereCoordinate(0, 0), new SphereCoordinate(0.5 * Math.PI, 0), new SphereCoordinate(0.5 * Math.PI, 0.5 * Math.PI), new SphereCoordinate(0.5 * Math.PI, Math.PI)); Console.WriteLine("Area of quarter sphere Polygon: " + quarterSpherePoly.Area); Console.WriteLine("Area of whole sphere: " + 4 * Math.PI); Console.WriteLine("Area of quarter sphere: " + Math.PI); Console.WriteLine(); Console.WriteLine(Math.Acos(new CartesianVector(0, 1, 0).DotProduct(new SphereCoordinate(Math.PI / 2, 0)))); Console.WriteLine(Math.Acos(new CartesianVector(0, 1, 0).DotProduct(new SphereCoordinate(Math.PI / 2, -Math.PI / 2)))); Console.WriteLine(Math.Acos(new CartesianVector(0, 1, 0).DotProduct(new SphereCoordinate(Math.PI / 2, 0)))); Console.WriteLine(Math.Acos(new CartesianVector(0, 1, 0).DotProduct(new SphereCoordinate(Math.PI / 2, -Math.PI / 2)))); Console.WriteLine(); Console.WriteLine(Math.Acos(new CartesianVector(1, 1, 0).AsUnitVector.DotProduct(new SphereCoordinate(Math.PI / 2, 0)))); Console.WriteLine(Math.Acos(new CartesianVector(1, 1, 0).AsUnitVector.DotProduct(new SphereCoordinate(Math.PI / 4, -Math.PI / 2)))); Console.WriteLine(); Console.WriteLine(Math.Acos(new CartesianVector(0, 1, 0).DotProduct(new CartesianVector(1, 1, 0).AsUnitVector))); Console.WriteLine(Math.PI / 4); Console.ReadLine(); }
/// <summary> /// Returns the tangent vector of this <see cref="GreatCircleSegement"/>'s underlaying <see cref="GreatCircle"/> in the given point, that points in the specified direction. /// </summary> /// <param name="point">The point on the underlaying <see cref="GreatCircle"/> that the tangent is wanted for.</param> /// <param name="direction">The vector specifying in which direction the tangent vector will point.</param> /// <returns>The tangent vector pointing in the right direction.</returns> public CartesianVector GetTangentAt(SphereCoordinate point, CartesianVector direction) { return BaseCircle.GetTangentAt(point, direction); }
/// <summary> /// Creates a new instance of the <see cref="VoronoiCell"/> class with the given center and sides. /// </summary> /// <param name="center">The point used as center for Voronoi calculations. Assumed to be inside.</param> /// <param name="firstPart">The <see cref="GreatCircle"/> that makes the first part of the Polygon.</param> public VoronoiCell(SphereCoordinate center, GreatCircle firstPart) { Center = center; FirstPart = firstPart; }
/// <summary> /// Checks whether the given <see cref="SphereCoordinate"/> is within this <see cref="VoronoiCell"/>. /// </summary> /// <param name="sphereCoordinate">The <see cref="SphereCoordinate"/> to check.</param> /// <returns>Whether the given <see cref="SphereCoordinate"/> is within this <see cref="VoronoiCell"/>.</returns> public bool IsInside(SphereCoordinate sphereCoordinate) { var centerToPoint = new GreatCircleSegment(Center, sphereCoordinate); // Check if any sides intersect with the arc from Center to point. SphereCoordinate _; if (startCorner == null) return FirstPart.Intersects(centerToPoint, out _); else foreach (var corner in Corners) if (corner.ToNext.Intersects(centerToPoint, out _)) return false; return true; }
public VoronoiPoint(SphereCoordinate point, bool calculated = false, VoronoiCell polygon = null) { Point = point; Calculated = calculated; Polygon = polygon; }
public Corner(SphereCoordinate point) { Point = point; }
/// <summary> /// Returns one possible tangent vector of this <see cref="GreatCircleSegement"/>'s underlaying <see cref="GreatCircle"/> in the given point, the other is antipodal to it. /// </summary> /// <param name="point">The point on the underlaying <see cref="GreatCircle"/> that the tangent is wanted for.</param> /// <returns>One possible tangent vector.</returns> public CartesianVector GetTangentAt(SphereCoordinate point) { return(BaseCircle.GetTangentAt(point)); }
/// <summary> /// Calculates the length of a Great Circle segment between the two <see cref="SphereCoordinate"/>s. /// Coordinates must have the same radius. /// </summary> /// <param name="start">One point of the arc.</param> /// <param name="end">Other point of the arc.</param> /// <returns>The length of the Great Circle segment between the two <see cref="SphereCoordinate"/>s.</returns> public static double CalculateArcLength(SphereCoordinate start, SphereCoordinate end) { // http://www.had2know.com/academics/great-circle-distance-sphere-2-points.html var cartesianLength = ((CartesianVector)start - end).Length; return 2 * Math.Asin(cartesianLength / 2); }
/// <summary> /// Checks whether a given <see cref="SphereCoordinate"/> is on this great circle. /// </summary> /// <param name="sphereCoordinate">The <see cref="SphereCoordinate"/> to test.</param> /// <returns>Whether the coordinate is on this great circle.</returns> public bool IsOnCircle(SphereCoordinate sphereCoordinate) { // DotProduct of (unit) vectors is 0 when they're in a 90° angle. return(DefinitionVector.DotProduct(sphereCoordinate).IsAlmostEqualTo(0)); }
/// <summary> /// Checks whether a given <see cref="SphereCoordinate"/> is on this arc. /// </summary> /// <param name="sphereCoordinate">The <see cref="SphereCoordinate"/> to test.</param> /// <returns>Whether the coordinate is on this arc.</returns> public bool IsOnArc(SphereCoordinate sphereCoordinate) { // http://www.boeing-727.com/Data/fly%20odds/distance.html Step 1.7 var startToCoord = CalculateArcLength(Start, sphereCoordinate); var endToCoord = CalculateArcLength(End, sphereCoordinate); return (Length - startToCoord - endToCoord).IsAlmostEqualTo(0); }
/// <summary> /// Checks whether the given <see cref="GreatCircleSegment"/> intersects with this one. /// The point of intersection can then be found in the out-Parameter. /// </summary> /// <param name="other">The arc segment to be checked.</param> /// <param name="intersection">The point of intersection, if they intersect.</param> /// <returns>Whether the two <see cref="GreatCircleSegment"/>s intersect or not.</returns> public bool Intersects(GreatCircleSegment other, out SphereCoordinate intersection) { // http://www.boeing-727.com/Data/fly%20odds/distance.html intersection = default(SphereCoordinate); if (Length.IsAlmostEqualTo(0) || other.Length.IsAlmostEqualTo(0)) return false; CartesianVector possibleIntersection1; if (!BaseCircle.Intersects(other.BaseCircle, out possibleIntersection1)) return false; var possibleIntersection2 = -possibleIntersection1; if (IsOnArc(possibleIntersection1) && other.IsOnArc(possibleIntersection1)) { intersection = possibleIntersection1; return true; } if (IsOnArc(possibleIntersection2) && other.IsOnArc(possibleIntersection2)) { intersection = possibleIntersection2; return true; } return false; }
/// <summary> /// Checks whether the given <see cref="GreatCircleSegment"/> intersects with this <see cref="GreatCicle"/>. /// The point of intersection can then be found in the out-Parameter. /// </summary> /// <param name="arc">The arc segment to be checked.</param> /// <param name="intersection">The point of intersection, if they intersect.</param> /// <returns>Whether the <see cref="GreatCircleSegment"/> intersects this <see cref="GreatCircle"/> or not.</returns> public bool Intersects(GreatCircleSegment arc, out SphereCoordinate intersection) { intersection = default(SphereCoordinate); CartesianVector possibleIntersection; if (!Intersects(arc.BaseCircle, out possibleIntersection)) return false; if (arc.IsOnArc(possibleIntersection)) { intersection = possibleIntersection; return true; } if (arc.IsOnArc(-possibleIntersection)) { intersection = -possibleIntersection; return true; } return false; }
/// <summary> /// Checks whether a given <see cref="SphereCoordinate"/> is on this great circle. /// </summary> /// <param name="sphereCoordinate">The <see cref="SphereCoordinate"/> to test.</param> /// <returns>Whether the coordinate is on this great circle.</returns> public bool IsOnCircle(SphereCoordinate sphereCoordinate) { // DotProduct of (unit) vectors is 0 when they're in a 90° angle. return DefinitionVector.DotProduct(sphereCoordinate).IsAlmostEqualTo(0); }