/// <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>
        /// 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;
        }
Example #3
0
        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();
        }
Example #4
0
        /// <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;
        }
Example #5
0
 /// <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;
 }
Example #6
0
 public Corner(SphereCoordinate point)
 {
     Point = point;
 }
 public VoronoiPoint(SphereCoordinate point, bool calculated = false, VoronoiCell polygon = null)
 {
     Point = point;
     Calculated = calculated;
     Polygon = polygon;
 }
        /// <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>
        /// 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>
 /// 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);
 }
Example #12
0
 /// <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);
 }
Example #13
0
        /// <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;
        }