Exemplo n.º 1
0
        /// <summary>
        /// Renders the geometry for the spans along a leg.
        /// </summary>
        /// <param name="display">The display to draw to</param>
        /// <param name="spans">Information about each observed span</param>
        /// <param name="sections">The geometry that corresponds to each span</param>
        void DrawSpans(ISpatialDisplay display, SpanInfo[] spans, ILineGeometry[] sections)
        {
            Debug.Assert(spans.Length == sections.Length);
            IDrawStyle solidStyle  = EditingController.Current.Style(Color.Magenta);
            IDrawStyle dottedStyle = new DottedStyle(Color.Magenta);

            for (int i = 0; i < spans.Length; i++)
            {
                ILineGeometry geom  = sections[i];
                IDrawStyle    style = (spans[i].HasLine ? solidStyle : dottedStyle);

                if (geom is IClockwiseCircularArcGeometry)
                {
                    style.Render(display, (IClockwiseCircularArcGeometry)geom);
                }
                else
                {
                    style.Render(display, new IPosition[] { geom.Start, geom.End });
                }

                if (spans[i].HasEndPoint)
                {
                    solidStyle.Render(display, geom.End);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Checks whether any intersections occur at positions that do not coincide
        /// with the end points of a line.
        /// </summary>
        /// <param name="line">The line to check. This should be the same line that
        /// was supplied to the <c>IntersectionFinder</c> constructor that created THIS results
        /// object (doing otherwise doesn't make any sense).</param>
        /// <returns>TRUE if any intersection does not coincide with the end points
        /// of the specified line.</returns>
        internal bool IsSplitOn(ILineGeometry line)
        {
            // Get the locations of the line end points.
            IPointGeometry start = line.Start;
            IPointGeometry end   = line.End;

            // Go through each intersection, looking for one that does
            // not correspond to the line ends.

            foreach (IntersectionData d in m_Data)
            {
                IPointGeometry loc1 = new PointGeometry(d.P1);
                if (!start.IsCoincident(loc1) && !end.IsCoincident(loc1))
                {
                    return(true);
                }

                if (d.IsGraze)
                {
                    /*
                     * Huh? This was the original, but it always ended up returning true.
                     *
                     *          IPointGeometry loc2 = PointGeometry.New(d.P2);
                     * if (!start.IsCoincident(loc2) && !end.IsCoincident(loc2))
                     *  return true;
                     *
                     * return true;
                     */
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Obtains the geometry for spans along this leg.
        /// </summary>
        /// <param name="pos">The position for the start of the leg.
        /// <param name="bearing">The bearing of the leg.</param>
        /// <param name="sfac">Scale factor to apply to distances.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition pos, double bearing, double sfac, SpanInfo[] spans)
        {
            var result = new ILineGeometry[spans.Length];

            // A leg with just one span, but no observed distance is due to the fact that the Leg constructor
            // that accepts a span count will always produce an array with at least one span (this covers cul-de-sacs
            // defined only with a central angle). May be better to handle it there.
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = new LineSegmentGeometry(pos, pos);
                return(result);
            }

            double sinBearing = Math.Sin(bearing);
            double cosBearing = Math.Cos(bearing);

            IPosition sPos = pos;
            IPosition ePos = null;

            double edist = 0.0;

            for (int i = 0; i < result.Length; i++, sPos = ePos)
            {
                edist    += (spans[i].ObservedDistance.Meters * sfac);
                ePos      = new Position(pos.X + (edist * sinBearing), pos.Y + (edist * cosBearing));
                result[i] = new LineSegmentGeometry(sPos, ePos);
            }

            return(result);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Does any painting that this dialog does.
        /// </summary>
        /// <param name="display">The display to draw to</param>
        internal void Render(ISpatialDisplay display)
        {
            // Draw the original path (in pale gray)
            IDrawStyle gray = new DrawStyle(Color.LightGray);

            m_pop.Render(display, gray, true);

            // Draw the current path (in magenta).
            PathInfo p = new PathInfo(m_pop.StartPoint, m_pop.EndPoint, GetLegs());

            p.Render(display);

            // Highlight the currently selected line.
            int index = distancesListBox.SelectedIndex;

            if (index >= 0 && index < m_FaceSections.Length)
            {
                IDrawStyle    style = new HighlightStyle();
                ILineGeometry geom  = m_FaceSections[index];
                if (geom is IClockwiseCircularArcGeometry)
                {
                    style.Render(display, (IClockwiseCircularArcGeometry)geom);
                }
                else
                {
                    style.Render(display, new IPosition[] { geom.Start, geom.End });
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Obtains the geometry for spans along an alternate face attached to this leg.
        /// </summary>
        /// <param name="legStart">The position for the start of the leg.
        /// <param name="legEnd">The position for the end of the leg.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition legStart, IPosition legEnd, SpanInfo[] spans)
        {
            var result = new ILineGeometry[spans.Length];

            Debug.Assert(AlternateFace != null);

            // Define the arc that corresponds to the complete leg (the circle should have been
            // already defined when we processed the primary face_.
            Debug.Assert(Circle != null);
            var arc = new CircularArcGeometry(Circle, legStart, legEnd, m_Metrics.IsClockwise);

            // Handle case where the leg is a cul-de-sac with no observed spans on the alternate face
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = arc;
                return(result);
            }

            // Get the required arc length (in meters on the ground)
            double len = arc.Length.Meters;

            // Get the observed arc length (in meters on the ground)
            double obs = AlternateFace.GetTotal();

            // Get the adjustment factor for stretching-compressing the observed distances.
            double factor = len / obs;

            // Define start of first arc.
            IPosition sPos = legStart;
            IPosition ePos = null;

            // Haven't got anywhere yet.
            double totobs = 0.0;

            // Figure out the location of each span
            for (int i = 0; i < result.Length; i++, sPos = ePos)
            {
                if (i == result.Length - 1)
                {
                    ePos = legEnd;
                }
                else
                {
                    // Add on the unscaled distance
                    totobs += spans[i].ObservedDistance.Meters;

                    // Scale to the required length for the overall leg
                    double elen = totobs * factor;

                    // Define the end position.
                    arc.GetPosition(new Length(elen), out ePos);
                }

                result[i] = new CircularArcGeometry(Circle, sPos, ePos, m_Metrics.IsClockwise);
            }

            return(result);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns the context code for a grazing intersection with a line.
        /// </summary>
        /// <param name="loc1">The 1st intersection.</param>
        /// <param name="loc2">The 2nd intersection.</param>
        /// <param name="line">The line the context code is for.</param>
        /// <returns>The context code.</returns>
        static IntersectionType GetContext(IPointGeometry loc1, IPointGeometry loc2, ILineGeometry line)
        {
            // Get the context of the start and end of the graze.
            IntersectionType context1 = GetContext(loc1, line);
            IntersectionType context2 = GetContext(loc2, line);

            if (context1 == IntersectionType.TouchOther)
            {
                if (context2 == IntersectionType.TouchStart)
                {
                    return(IntersectionType.GrazeStart);
                }

                if (context2 == IntersectionType.TouchOther)
                {
                    return(IntersectionType.GrazeOther);
                }

                return(IntersectionType.GrazeEnd);
            }
            else if (context1 == IntersectionType.TouchStart)
            {
                if (context2 == IntersectionType.TouchStart)
                {
                    return(IntersectionType.GrazeTotal);
                }

                if (context2 == IntersectionType.TouchOther)
                {
                    return(IntersectionType.GrazeStart);
                }

                return(IntersectionType.GrazeTotal);
            }

            // context1 == IntersectionType.TounchEnd

            if (context2 == IntersectionType.TouchStart)
            {
                return(IntersectionType.GrazeTotal);
            }

            if (context2 == IntersectionType.TouchOther)
            {
                return(IntersectionType.GrazeEnd);
            }

            return(IntersectionType.GrazeTotal);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Marks intersection data with flags that signify the relationship of these
        /// intersection results to the position of a specific line (presumably the
        /// line that caused the generation of these results).
        /// </summary>
        /// <param name="line">The line to compare with.</param>
        /// <returns>TRUE if any context settings were made. It will be FALSE if there
        /// are no intersections, or these results do not refer to a line.</returns>
        internal bool SetContext(ILineGeometry line)
        {
            // Return if there are no intersections.
            if (m_Data == null || m_Data.Count == 0)
            {
                return(false);
            }

            // Go through each intersected object. For those that are
            // lines, figure out the relationship to the supplied line.
            foreach (IntersectionData d in m_Data)
            {
                d.SetContext(m_IntersectedObject.LineGeometry, line);
            }

            return(true);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Define the relationship that this intersection has to a pair of lines.
        /// </summary>
        /// <param name="line1">The 1st line.</param>
        /// <param name="line2">The 2nd line.</param>
        internal void SetContext(ILineGeometry line1, ILineGeometry line2)
        {
            m_Context1 = 0;
            m_Context2 = 0;

            if (this.IsGraze)
            {
                IPointGeometry loc1 = new PointGeometry(m_X1);
                IPointGeometry loc2 = new PointGeometry(m_X2);
                m_Context1 = GetContext(loc1, loc2, line1);
                m_Context2 = GetContext(loc1, loc2, line2);
            }
            else
            {
                IPointGeometry loc = new PointGeometry(m_X1);
                m_Context1 = GetContext(loc, line1);
                m_Context2 = GetContext(loc, line2);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Returns the context code for a simple intersection with a line.
        /// </summary>
        /// <param name="loc">The location of the intersection.</param>
        /// <param name="line">The line to compare with.</param>
        /// <returns>The context code.</returns>
        static IntersectionType GetContext(IPointGeometry loc, ILineGeometry line)
        {
            IntersectionType context = 0;

            if (loc.IsCoincident(line.Start))
            {
                context |= IntersectionType.TouchStart;
            }

            if (loc.IsCoincident(line.End))
            {
                context |= IntersectionType.TouchEnd;
            }

            if (context == 0)
            {
                context = IntersectionType.TouchOther;
            }

            return(context);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Obtains the geometry for spans along this leg.
        /// </summary>
        /// <param name="bc">The position for the start of the leg.
        /// <param name="bcBearing">The bearing on entry into the leg.</param>
        /// <param name="sfac">Scale factor to apply to distances.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition bc, double bcBearing, double sfac, SpanInfo[] spans)
        {
            // Can't do anything if the leg radius isn't defined
            if (m_Metrics.ObservedRadius == null)
                throw new InvalidOperationException("Cannot create sections for circular leg with undefined radius");

            var result = new ILineGeometry[spans.Length];

            // Use supplied stuff to derive info on the center and EC.
            IPosition center;
            IPosition ec;
            double bearingToBC;
            double ecBearing;
            GetPositions(bc, bcBearing, sfac, out center, out bearingToBC, out ec, out ecBearing);

            // Define the underlying circle
            ICircleGeometry circle = new CircleGeometry(PointGeometry.Create(center), BasicGeom.Distance(center, bc));

            // Handle case where the leg is a cul-de-sac with no observed spans
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = new CircularArcGeometry(circle, bc, ec, m_Metrics.IsClockwise);
                return result;
            }

            /// Initialize scaling factor for distances in cul-de-sacs (ratio of the length calculated from
            /// the CA & Radius, versus the observed distances that were actually specified). For curves that
            /// are not cul-de-sacs, this will be 1.0
            double culFactor = 1.0;
            if (m_Metrics.IsCulDeSac)
            {
                double obsv = PrimaryFace.GetTotal();
                if (obsv > MathConstants.TINY)
                    culFactor = Length.Meters / obsv;
            }

            IPosition sPos = bc;
            IPosition ePos = null;
            bool isClockwise = m_Metrics.IsClockwise;
            double radius = RadiusInMeters;
            double edist = 0.0;

            for (int i = 0; i < result.Length; i++, sPos = ePos)
            {
                // Add on the unscaled distance
                edist += spans[i].ObservedDistance.Meters;

                // Get the angle subtended at the center of the circle. We use
                // unscaled values here, since the scale factors would cancel out.
                // However, we DO apply any cul-de-sac scaling factor, to account
                // for the fact that the distance may be inconsistent with the
                // curve length derived from the CA and radius. For example, it
                // is possible that the calculated curve length=200, although the
                // total of the observed spans is somehow only 100. In that case,
                // if the supplied distance is 50, we actually want to use a
                // value of 50 * (200/100) = 100.

                double angle = (edist * culFactor) / radius;

                // Get the bearing of the point with respect to the center of the circle.

                double bearing;

                if (isClockwise)
                    bearing = bearingToBC + angle;
                else
                    bearing = bearingToBC - angle;

                // Calculate the position using the scaled radius.
                ePos = Geom.Polar(center, bearing, radius * sfac);

                result[i] = new CircularArcGeometry(circle, sPos, ePos, isClockwise);
            }

            return result;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Obtains the geometry for spans along this leg.
        /// </summary>
        /// <param name="bc">The position for the start of the leg.
        /// <param name="bcBearing">The bearing on entry into the leg.</param>
        /// <param name="sfac">Scale factor to apply to distances.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition bc, double bcBearing, double sfac, SpanInfo[] spans)
        {
            // Can't do anything if the leg radius isn't defined
            if (m_Metrics.ObservedRadius == null)
            {
                throw new InvalidOperationException("Cannot create sections for circular leg with undefined radius");
            }

            var result = new ILineGeometry[spans.Length];

            // Use supplied stuff to derive info on the center and EC.
            IPosition center;
            IPosition ec;
            double    bearingToBC;
            double    ecBearing;

            GetPositions(bc, bcBearing, sfac, out center, out bearingToBC, out ec, out ecBearing);

            // Define the underlying circle
            ICircleGeometry circle = new CircleGeometry(PointGeometry.Create(center), BasicGeom.Distance(center, bc));

            // Handle case where the leg is a cul-de-sac with no observed spans
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = new CircularArcGeometry(circle, bc, ec, m_Metrics.IsClockwise);
                return(result);
            }

            /// Initialize scaling factor for distances in cul-de-sacs (ratio of the length calculated from
            /// the CA & Radius, versus the observed distances that were actually specified). For curves that
            /// are not cul-de-sacs, this will be 1.0
            double culFactor = 1.0;

            if (m_Metrics.IsCulDeSac)
            {
                double obsv = PrimaryFace.GetTotal();
                if (obsv > MathConstants.TINY)
                {
                    culFactor = Length.Meters / obsv;
                }
            }

            IPosition sPos        = bc;
            IPosition ePos        = null;
            bool      isClockwise = m_Metrics.IsClockwise;
            double    radius      = RadiusInMeters;
            double    edist       = 0.0;

            for (int i = 0; i < result.Length; i++, sPos = ePos)
            {
                // Add on the unscaled distance
                edist += spans[i].ObservedDistance.Meters;

                // Get the angle subtended at the center of the circle. We use
                // unscaled values here, since the scale factors would cancel out.
                // However, we DO apply any cul-de-sac scaling factor, to account
                // for the fact that the distance may be inconsistent with the
                // curve length derived from the CA and radius. For example, it
                // is possible that the calculated curve length=200, although the
                // total of the observed spans is somehow only 100. In that case,
                // if the supplied distance is 50, we actually want to use a
                // value of 50 * (200/100) = 100.

                double angle = (edist * culFactor) / radius;

                // Get the bearing of the point with respect to the center of the circle.

                double bearing;

                if (isClockwise)
                {
                    bearing = bearingToBC + angle;
                }
                else
                {
                    bearing = bearingToBC - angle;
                }

                // Calculate the position using the scaled radius.
                ePos = Geom.Polar(center, bearing, radius * sfac);

                result[i] = new CircularArcGeometry(circle, sPos, ePos, isClockwise);
            }

            return(result);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Attaches geometry to the spans along a leg.
        /// </summary>
        /// <param name="ctx">The context in which the geometry is being defined.</param>
        /// <param name="spans">Information about each observed span</param>
        /// <param name="sections">The geometry that corresponds to each span</param>
        void AttachGeometry(EditingContext ctx, SpanInfo[] spans, ILineGeometry[] sections)
        {
            Debug.Assert(spans.Length == sections.Length);

            for (int i = 0; i < spans.Length; i++)
            {
                SpanInfo data = spans[i];
                Feature feat = data.CreatedFeature;
                PointFeature endPoint = null;

                if (feat is PointFeature)
                    endPoint = (PointFeature)feat;
                else if (feat is LineFeature)
                    endPoint = (feat as LineFeature).EndPoint;

                if (endPoint != null && endPoint.PointGeometry == null)
                {
                    PointGeometry pg = PointGeometry.Create(sections[i].End);
                    endPoint.ApplyPointGeometry(ctx, pg);
                }
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Obtains the geometry for spans along this leg.
        /// </summary>
        /// <param name="pos">The position for the start of the leg.
        /// <param name="bearing">The bearing of the leg.</param>
        /// <param name="sfac">Scale factor to apply to distances.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition pos, double bearing, double sfac, SpanInfo[] spans)
        {
            var result = new ILineGeometry[spans.Length];

            // A leg with just one span, but no observed distance is due to the fact that the Leg constructor
            // that accepts a span count will always produce an array with at least one span (this covers cul-de-sacs
            // defined only with a central angle). May be better to handle it there.
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = new LineSegmentGeometry(pos, pos);
                return result;
            }

            double sinBearing = Math.Sin(bearing);
            double cosBearing = Math.Cos(bearing);

            IPosition sPos = pos;
            IPosition ePos = null;

            double edist = 0.0;

            for (int i = 0; i < result.Length; i++, sPos=ePos)
            {
                edist += (spans[i].ObservedDistance.Meters * sfac);
                ePos = new Position(pos.X + (edist * sinBearing), pos.Y + (edist * cosBearing));
                result[i] = new LineSegmentGeometry(sPos, ePos);
            }

            return result;
        }
Exemplo n.º 14
0
        /// <summary>
        /// Renders the geometry for the spans along a leg.
        /// </summary>
        /// <param name="display">The display to draw to</param>
        /// <param name="spans">Information about each observed span</param>
        /// <param name="sections">The geometry that corresponds to each span</param>
        void DrawSpans(ISpatialDisplay display, SpanInfo[] spans, ILineGeometry[] sections)
        {
            Debug.Assert(spans.Length == sections.Length);
            IDrawStyle solidStyle = EditingController.Current.Style(Color.Magenta);
            IDrawStyle dottedStyle = new DottedStyle(Color.Magenta);

            for (int i = 0; i < spans.Length; i++)
            {
                ILineGeometry geom = sections[i];
                IDrawStyle style = (spans[i].HasLine ? solidStyle : dottedStyle);

                if (geom is IClockwiseCircularArcGeometry)
                    style.Render(display, (IClockwiseCircularArcGeometry)geom);
                else
                    style.Render(display, new IPosition[] { geom.Start, geom.End });

                if (spans[i].HasEndPoint)
                    solidStyle.Render(display, geom.End);
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Checks whether any intersections occur at positions that do not coincide
        /// with the end points of a line.
        /// </summary>
        /// <param name="line">The line to check. This should be the same line that
        /// was supplied to the <c>IntersectionFinder</c> constructor that created THIS results
        /// object (doing otherwise doesn't make any sense).</param>
        /// <returns>TRUE if any intersection does not coincide with the end points
        /// of the specified line.</returns>
        internal bool IsSplitOn(ILineGeometry line)
        {
            // Get the locations of the line end points.
            IPointGeometry start = line.Start;
            IPointGeometry end = line.End;

            // Go through each intersection, looking for one that does
            // not correspond to the line ends.

            foreach (IntersectionData d in m_Data)
            {
                IPointGeometry loc1 = new PointGeometry(d.P1);
                if (!start.IsCoincident(loc1) && !end.IsCoincident(loc1))
                    return true;

                if (d.IsGraze)
                {
                    /*
                     * Huh? This was the original, but it always ended up returning true.
                     *
                    IPointGeometry loc2 = PointGeometry.New(d.P2);
                    if (!start.IsCoincident(loc2) && !end.IsCoincident(loc2))
                        return true;

                    return true;
                     */
                    return true;
                }
            }

            return false;
        }
Exemplo n.º 16
0
        /// <summary>
        /// Marks intersection data with flags that signify the relationship of these
        /// intersection results to the position of a specific line (presumably the
        /// line that caused the generation of these results).
        /// </summary>
        /// <param name="line">The line to compare with.</param>
        /// <returns>TRUE if any context settings were made. It will be FALSE if there
        /// are no intersections, or these results do not refer to a line.</returns>
        internal bool SetContext(ILineGeometry line)
        {
            // Return if there are no intersections.
            if (m_Data==null || m_Data.Count==0)
                return false;

            // Go through each intersected object. For those that are
            // lines, figure out the relationship to the supplied line.
            foreach (IntersectionData d in m_Data)
            {
                d.SetContext(m_IntersectedObject.LineGeometry, line);
            }

            return true;
        }
Exemplo n.º 17
0
        /// <summary>
        /// Obtains the geometry for spans along an alternate face attached to this leg.
        /// </summary>
        /// <param name="legStart">The position for the start of the leg.
        /// <param name="legEnd">The position for the end of the leg.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition legStart, IPosition legEnd, SpanInfo[] spans)
        {
            var result = new ILineGeometry[spans.Length];

            Debug.Assert(AlternateFace != null);

            // Define the arc that corresponds to the complete leg (the circle should have been
            // already defined when we processed the primary face_.
            Debug.Assert(Circle != null);
            var arc = new CircularArcGeometry(Circle, legStart, legEnd, m_Metrics.IsClockwise);

            // Handle case where the leg is a cul-de-sac with no observed spans on the alternate face
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = arc;
                return result;
            }

            // Get the required arc length (in meters on the ground)
            double len = arc.Length.Meters;

            // Get the observed arc length (in meters on the ground)
            double obs = AlternateFace.GetTotal();

            // Get the adjustment factor for stretching-compressing the observed distances.
            double factor = len / obs;

            // Define start of first arc.
            IPosition sPos = legStart;
            IPosition ePos = null;

            // Haven't got anywhere yet.
            double totobs = 0.0;

            // Figure out the location of each span
            for (int i = 0; i < result.Length; i++, sPos = ePos)
            {
                if (i == result.Length - 1)
                {
                    ePos = legEnd;
                }
                else
                {
                    // Add on the unscaled distance
                    totobs += spans[i].ObservedDistance.Meters;

                    // Scale to the required length for the overall leg
                    double elen = totobs * factor;

                    // Define the end position.
                    arc.GetPosition(new Length(elen), out ePos);
                }

                result[i] = new CircularArcGeometry(Circle, sPos, ePos, m_Metrics.IsClockwise);
            }

            return result;
        }