Пример #1
0
        bool TryMoveBackwardOnPath(GeoLine originLine, GeoPoint origin, Double distance, out GeoPoint final)
        {
            final = null;
            Double distanceMoved = EarthGeo.GetDistance(origin as GeoPoint, originLine.P1 as GeoPoint);

            if (distanceMoved <= distance)
            {
                for (int index = IndexOf(originLine) - 1; index >= 0; index--)
                {
                    if (distanceMoved + this[index].Length >= distance)
                    {
                        final = EarthGeo.GetPoint(this[index].P2 as GeoPoint, Angle.Reverse(this[index].Bearing), distance - distanceMoved);
                        break;
                    }
                    else
                    {
                        distanceMoved += this[index].Length;
                    }
                }
            }
            else
            {
                /** the destination is on the first segment */
                final = EarthGeo.GetPoint(origin, Angle.Reverse(originLine.Bearing), distance);
            }
            return(final != null);
        }
Пример #2
0
        public void Move(Double bearing, Double distance)
        {
            GeoPoint np = EarthGeo.GetPoint(this, bearing, distance);

            Latitude  = np.Latitude;
            Longitude = np.Longitude;
        }
Пример #3
0
        public bool TryGetPointAtDistanceFromEnd(Double distance, out GeoPoint point)
        {
            point = null;

            Double      totalLength = 0;
            GeoLineList list        = new GeoLineList(this);

            list.Reverse();

            for (int index = 0; point == null && index < list.Count; index++)
            {
                GeoLine line      = list[index];
                Double  newLength = totalLength + line.Length;
                if (newLength > distance)
                {
                    Double segLength = distance - totalLength;
                    point = EarthGeo.GetPoint(line.P2 as GeoPoint, Angle.Reverse(line.Bearing), segLength);
                }
                else
                {
                    totalLength = newLength;
                }
            }
            return(point != null);
        }
Пример #4
0
        static GeoLine LineFromCenterAndBearing(GeoPoint centerPoint, Double bearing, Double distance)
        {
            GeoPoint p1 = EarthGeo.GetPoint(centerPoint, Angle.Reverse(bearing), distance / 2);
            GeoPoint p2 = EarthGeo.GetPoint(centerPoint, bearing, distance / 2);

            return(new GeoLine(p1, p2));
        }
Пример #5
0
        void RecalculateAxes()
        {
            MajorAxis = new GeoLine(
                EarthGeo.GetPoint(_center, Angle.Reverse(m_MajorAxisBearing), m_MajorAxisLength / 2),
                EarthGeo.GetPoint(_center, m_MajorAxisBearing, m_MajorAxisLength / 2));

            Double minorAxisBearing = Angle.Add(m_MajorAxisBearing, 90);

            MinorAxis = new GeoLine(
                EarthGeo.GetPoint(_center, Angle.Reverse(minorAxisBearing), m_MinorAxisLength / 2),
                EarthGeo.GetPoint(_center, minorAxisBearing, m_MinorAxisLength / 2));
        }
Пример #6
0
        public GeoPolygon ToGeoPolygon(int sides = 16)
        {
            GeoPointList points    = new GeoPointList();
            Double       angleSize = (360 / (Double)sides);

            for (Double degrees = 0; degrees < 360; degrees += angleSize)
            {
                points.Add(EarthGeo.GetPoint(_center, Radius, degrees));
            }

            GeoPolygon polygon = new GeoPolygon(points);

            return(polygon);
        }
Пример #7
0
        public virtual GeoRectangle GetMinimumBoundingRectangle()
        {
            /** offset minor axis to half the major axis distance in either direction */
            Double   offset = MajorAxis.Length / 2;
            GeoPoint p1     = EarthGeo.GetPoint(MinorAxis.P1 as GeoPoint, MajorAxis.Bearing, offset);
            GeoPoint p2     = EarthGeo.GetPoint(MinorAxis.P2 as GeoPoint, MajorAxis.Bearing, offset);
            GeoPoint p3     = EarthGeo.GetPoint(MinorAxis.P2 as GeoPoint, Angle.Reverse(MajorAxis.Bearing), offset);
            GeoPoint p4     = EarthGeo.GetPoint(MinorAxis.P1 as GeoPoint, Angle.Reverse(MajorAxis.Bearing), offset);

            return(new GeoRectangle(new GeoPointList()
            {
                p1, p2, p3, p4
            }));
        }
Пример #8
0
        void RecalculateFociAndArea()
        {
            //      __________
            //    \/ r1² * r2²
            Double fociDistance = Math.Sqrt(MajorRadius * MajorRadius - MinorRadius * MinorRadius);

            Foci = new GeoPoint[]
            {
                EarthGeo.GetPoint(Center as GeoPoint, Angle.Reverse(MajorAxis.Bearing), fociDistance),
                EarthGeo.GetPoint(Center as GeoPoint, MajorAxis.Bearing, fociDistance)
            };

            Eccentricity = new Line(Foci[0], Center).Length / new Line(Foci[0], MinorAxis.P1).Length;

            Area = Math.PI * MajorRadius * MinorRadius;
        }
Пример #9
0
        public override bool Intersects(GeoLine line, out GeoPoint intersection1, out GeoPoint intersection2, out int intersections)
        {
            intersection1 = new GeoPoint(float.NaN, float.NaN);
            intersection2 = new GeoPoint(float.NaN, float.NaN);

            const Double increment = .1;

            bool     intersects = false;
            GeoPoint p          = line.P1.Clone() as GeoPoint;

            do
            {
                if (this.Contains(p))
                {
                    intersects = true;
                    break;
                }

                p = EarthGeo.GetPoint(p, line.Bearing, increment);
            } while(EarthGeo.GetDistance(line.P1 as GeoPoint, p) < line.Length);

            intersections = 0;
            if (intersects)
            {
                Double degy   = EarthGeo.DegreesPerMeterAtLatitude(_center.Latitude);
                Double degx   = EarthGeo.DegreesPerMeterAtLongitude(_center.Longitude);
                Double radius = Radius * Math.Max(degx, degy);

                Double dx, dy, A, B, C, det, t;

                dx = line.P2.X - line.P1.X;
                dy = line.P2.Y - line.P1.Y;

                A = dx * dx + dy * dy;
                B = 2 * (dx * (line.P1.X - Center.X) + dy * (line.P1.Y - Center.Y));
                C = (line.P1.X - Center.X) * (line.P1.X - Center.X) + (line.P1.Y - Center.Y) * (line.P1.Y - Center.Y) - radius * radius;

                det = B * B - 4 * A * C;

                if ((A <= 0.00000001) || (det < 0))
                {
                    // No real solutions.
                    intersection1 = new GeoPoint(float.NaN, float.NaN);
                    intersection2 = new GeoPoint(float.NaN, float.NaN);
                }
                else if (det == 0)
                {
                    // One solution.
                    t             = -B / (2 * A);
                    intersection1 = new GeoPoint(line.P1.X + t * dx, line.P1.Y + t * dy);
                    intersection2 = new GeoPoint(float.NaN, float.NaN);
                    intersections = 1;
                }
                else
                {
                    // Two solutions.
                    t             = (float)((-B + Math.Sqrt(det)) / (2 * A));
                    intersection1 = new GeoPoint(line.P1.X + t * dx, line.P1.Y + t * dy);
                    t             = (float)((-B - Math.Sqrt(det)) / (2 * A));
                    intersection2 = new GeoPoint(line.P1.X + t * dx, line.P1.Y + t * dy);
                    intersections = 2;
                }
            }
            return(intersects);
        }
Пример #10
0
        public bool Contains(GeoPoint point, Double rayLength = DEFAULT_RAY_LENGTH)
        {
            /** Use Ray-Casting Algorithm to determine if point lies within polygon */

            Double rayBearing = EarthGeo.North;
            float  insides    = 0;
            float  outsides   = 0;

            int minimumRays = 4;

            bool majority = false;

            /**
             * We will cast at least two rays and keep casting till we get a majority of
             * one or the other, or we go in a circle.
             */
            do
            {
                /**
                 * Step One:
                 *   Create a ray from our point extending outwards
                 */
                GeoPoint endPoint = EarthGeo.GetPoint(point, rayBearing, rayLength);
                GeoLine  ray      = new GeoLine(point, endPoint);

                /**
                 * Step 2
                 *   Draw line from our point in any direction (we will use North)
                 *   and count the intersections
                 */
                Double intersections = 0;
                foreach (GeoLine line in Lines)
                {
                    if (ray.Intersects(line))
                    {
                        intersections++;
                    }
                }

                /** if the intersections are even, the point is outside... if odd, it's inside */
                bool inside = (intersections % 2) != 0;

                if (inside)
                {
                    insides++;
                }
                else
                {
                    outsides++;
                }

                rayBearing = Angle.Add(rayBearing, 95);

                if (insides + outsides >= minimumRays)
                {
                    majority = insides > outsides * 2 || outsides > insides * 2;
                }
            }while(majority == false && !(insides + outsides >= 360 / 5));

            return(insides > outsides);
        }
Пример #11
0
 public GeoPoint GetPointAt(Double bearing, Double distance)
 {
     return(EarthGeo.GetPoint(this, bearing, distance));
 }
Пример #12
0
        public override void Move(Double bearing, Double distance)
        {
            GeoPoint newCenter = EarthGeo.GetPoint(GeoCenter, bearing, distance);

            Move(newCenter);
        }