Пример #1
0
        //三点法构造弧段的Segment
        private ISegment MadeArcSeg_3Point(IPoint pPoint1, IPoint pPoint2, IPoint pPoint3)
        {
            IConstructCircularArc pArc = new CircularArcClass();

            pArc.ConstructThreePoints(pPoint1, pPoint2, pPoint3, true);
            return((ISegment)pArc);
        }
Пример #2
0
        //构造圆弧点
        private void button1_Click(object sender, EventArgs e)
        {
            delFeature("point");
            //构造一段圆弧
            IPoint centerPoint = new PointClass();

            centerPoint.PutCoords(10, 0);
            IPoint fromPoint = new PointClass();

            fromPoint.PutCoords(0, 0);
            IPoint toPoint = new PointClass();

            toPoint.PutCoords(0, 20);
            IConstructCircularArc circularArcConstruction = new CircularArcClass();

            circularArcConstruction.ConstructThreePoints(fromPoint, centerPoint, toPoint, false);
            //构造圆弧点
            IConstructMultipoint constructMultipoint = new MultipointClass();

            constructMultipoint.ConstructArcPoints(circularArcConstruction as ICircularArc);
            IPointCollection pointCollection = constructMultipoint as IPointCollection;

            for (int i = 0; i < pointCollection.PointCount; i++)
            {
                addFeature("point", pointCollection.get_Point(i));
            }

            axMapControl1.Refresh();
        }
Пример #3
0
        /// <summary>
        /// 通过开始点和结束点创建半圆弧片段
        /// </summary>
        /// <param name="fromPoint">开始点</param>
        /// <param name="toPoint">结束点</param>
        /// <returns>半圆弧片段</returns>
        public static ISegment CreateHalfCircularArcByTwoPoints(IPoint fromPoint, IPoint toPoint)
        {
            ILine line   = CreateLineByTwoPoints(fromPoint, toPoint);
            ILine normal = new LineClass();

            line.QueryNormal(esriSegmentExtension.esriNoExtension, 0.5, true, (double)(line.Length / 2.0), normal);
            IConstructCircularArc Constructor = new CircularArcClass();

            Constructor.ConstructThreePoints(fromPoint, normal.ToPoint, toPoint, true);
            return((ISegment)Constructor);
        }
Пример #4
0
        //构造交点
        private void button4_Click(object sender, EventArgs e)
        {
            delFeature("point");
            IPoint[] points = new IPoint[4];
            for (int i = 0; i < 4; i++)
            {
                points[i] = new PointClass();
            }

            points[0].PutCoords(15, 10);
            points[1].PutCoords(20, 60);
            points[2].PutCoords(40, 60);
            points[3].PutCoords(45, 10);
            addFeature("point", points[0]);
            addFeature("point", points[1]);
            addFeature("point", points[2]);
            addFeature("point", points[3]);
            //构造Bezier曲线
            IBezierCurveGEN bezierCurve = new BezierCurveClass();

            bezierCurve.PutCoords(ref points);
            IPoint centerPoint = new PointClass();

            centerPoint.PutCoords(30, 30);
            IPoint fromPoint = new PointClass();

            fromPoint.PutCoords(10, 10);
            IPoint toPoint = new PointClass();

            toPoint.PutCoords(50, 10);
            //构造圆弧
            IConstructCircularArc circularArcConstruction = new CircularArcClass();

            circularArcConstruction.ConstructThreePoints(fromPoint, centerPoint, toPoint, false);


            object param0;
            object param1;
            object isTangentPoint;
            IConstructMultipoint constructMultipoint = new MultipointClass();

            constructMultipoint.ConstructIntersection(circularArcConstruction as ISegment, esriSegmentExtension.esriNoExtension, bezierCurve as ISegment, esriSegmentExtension.esriNoExtension, out param0, out param1, out isTangentPoint);
            IMultipoint      multipoint      = constructMultipoint as IMultipoint;
            IPointCollection pointCollection = multipoint as IPointCollection;

            for (int i = 0; i < pointCollection.PointCount; i++)
            {
                addFeature("point", pointCollection.get_Point(i));
            }

            axMapControl1.Extent = multipoint.Envelope;
            axMapControl1.Refresh();
        }
Пример #5
0
        // 创建弧线
        private IPolyline CreateCirculeArc(IPoint fromPoint, IPoint toPoint, double chordCoef)
        {
            // 如果起点和终点相等,返回一个直线
            if (fromPoint.X == toPoint.X && fromPoint.Y == toPoint.Y)
            {
                object    missing  = Type.Missing;
                IPolyline polyline = new PolylineClass();
                var       pointCol = (IPointCollection)polyline;
                pointCol.AddPoint(fromPoint, missing, missing);
                pointCol.AddPoint(toPoint, missing, missing);
                return(polyline);
            }

            // 根据起止点建立直线A方程,
            // 利用A线上的中点建立与A线垂直的线方程,
            // 利用与中点的距离确定直线A两侧对称点
            double midX = (fromPoint.X + toPoint.X) / 2;
            double midY = (fromPoint.Y + toPoint.Y) / 2;
            double k    = (fromPoint.Y - toPoint.Y) / (fromPoint.X - toPoint.X);                                              // 直线斜率
            double h    = Math.Pow(Math.Pow((fromPoint.Y - toPoint.Y), 2.0) + Math.Pow((fromPoint.X - toPoint.X), 2.0), 0.5); // 直线长
            double h2   = h * chordCoef;                                                                                      // 获得0.1, 0.2, 0.3...倍的直线长
            //double sign = Math.Pow(-1, offsetCount - 1); // 左右对称点符号
            double sign = 1;                                                                                                  // 表示正负号

            if (fromPoint.X > toPoint.X)
            {
                sign = -1;
            }
            else if (fromPoint.X == toPoint.X && fromPoint.Y > toPoint.Y)
            {
                sign = -1;
            }
            double x        = midX + sign * (-1) * chordCoef * h2 * k / Math.Pow(1 + k * k, 0.5); // 求解后的x
            double y        = midY + sign * chordCoef * h2 / Math.Pow(1 + k * k, 0.5);            // 求解后的y
            IPoint arcPoint = new PointClass();

            arcPoint.PutCoords(x, y);
            IConstructCircularArc2 circularArc = new CircularArcClass();

            circularArc.ConstructThreePoints(fromPoint, arcPoint, toPoint, true);
            IPolyline circularPolyline = new PolylineClass();
            var       segementColl     = (ISegmentCollection)circularPolyline;
            var       segment          = (ISegment)circularArc;

            segementColl.AddSegment(segment);

            return(circularPolyline);
        }
Пример #6
0
        public override void OnMouseMove(int Button, int Shift, int X, int Y)
        {
            IPoint pMovePt = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);

            pMovePt = GIS.GraphicEdit.SnapSetting.getSnapPoint(pMovePt);
            if (m_lMouseDownCount == 1)
            {
                m_pLineFeedback.MoveTo(pMovePt);
            }
            else if (m_lMouseDownCount == 2)
            {
                m_bCreated = false;

                IEnvelope pEnv = new EnvelopeClass();
                pEnv.UpperLeft  = m_pFirstPoint;
                pEnv.LowerRight = m_pSecondPoint;

                IConstructCircularArc pEllipArc = new CircularArcClass();
                pEllipArc.ConstructThreePoints(m_pFirstPoint, m_pSecondPoint, pMovePt, true);
                m_pCircleArc = pEllipArc as ICircularArc;
                m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
            }
            DataEditCommon.g_pAxMapControl.Focus();
        }
Пример #7
0
        private ISegmentCollection createSegments(Cell cell, BoostVoronoi bv, ArcConstructionMethods method, ISpatialReference spatialReference)
        {
            List <Cell>   cells    = bv.Cells;
            List <Edge>   edges    = bv.Edges;
            List <Vertex> vertices = bv.Vertices;

            IPoint previousEndPoint = null;

            ISegmentCollection segmentCollection = new PolygonClass()
            {
                SpatialReference = spatialReference
            };

            // As per boost documentation, edges are returned in counter clockwise (CCW) rotation.
            //  voronoi_edge_type* next()	Returns the pointer to the CCW next edge within the corresponding Voronoi cell.  Edges not necessarily share a common vertex (e.g. infinite edges).
            for (int i = cell.EdgesIndex.Count - 1; i >= 0; i--)
            {
                Edge edge = edges[cell.EdgesIndex[i]];


                //If the vertex index equals -1, it means the edge is infinite. It is impossible to print the coordinates.
                if (!edge.IsFinite && edge.End < 0)
                {
                    // this is the ending portion of a pair of infinite edges, file the previous edge with Start >= 0
                    Edge previous = null;
                    for (int k = i + 1; k < cell.EdgesIndex.Count; k++)
                    {
                        previous = edges[cell.EdgesIndex[k]];
                        if (previous.End >= 0)
                        {
                            break;
                        }
                        previous = null;
                    }
                    if (previous == null)
                    {
                        for (int k = 0; k < i; k++)
                        {
                            previous = edges[cell.EdgesIndex[k]];
                            if (previous.End >= 0)
                            {
                                break;
                            }
                            previous = null;
                        }
                    }
                    if (previous == null)
                    {
                        throw new Exception("No outbound infinite edge could be found");
                    }

                    //Add a straight line segment
                    Vertex start     = vertices[previous.End];
                    IPoint FromPoint = new PointClass()
                    {
                        X = start.X, Y = start.Y, SpatialReference = spatialReference
                    };
                    Vertex end     = vertices[edge.Start];
                    IPoint ToPoint = new PointClass()
                    {
                        X = end.X, Y = end.Y, SpatialReference = spatialReference
                    };

                    segmentCollection.AddSegment(new LineClass()
                    {
                        FromPoint = FromPoint, ToPoint = ToPoint, SpatialReference = spatialReference
                    });
                    previousEndPoint = ToPoint;
                }
                else if (edge.IsFinite)
                {
                    Vertex start     = vertices[edge.End];
                    IPoint FromPoint = new PointClass()
                    {
                        X = start.X, Y = start.Y, SpatialReference = spatialReference
                    };
                    if (previousEndPoint != null)
                    {
                        if ((Math.Abs(previousEndPoint.X - FromPoint.X) > 0.05 || Math.Abs(previousEndPoint.X - FromPoint.X) > 0.05))
                        {
                            throw new Exception("Significant change between last end point and current start point");
                        }
                        else
                        {
                            FromPoint = previousEndPoint;
                        }
                    }
                    Vertex end     = vertices[edge.Start];
                    IPoint ToPoint = new PointClass()
                    {
                        X = end.X, Y = end.Y, SpatialReference = spatialReference
                    };

                    if (method == ArcConstructionMethods.Straight || edge.IsLinear)
                    {
                        segmentCollection.AddSegment(new LineClass()
                        {
                            FromPoint = FromPoint, ToPoint = ToPoint, SpatialReference = spatialReference
                        });
                        previousEndPoint = ToPoint;
                    }
                    else
                    {
                        // We need three points, use start, end, mid-point between focus and directrix
                        Cell twinCell = cells[edges[edge.Twin].Cell];


                        VPoint pointSite; VSegment lineSite;
                        if (cell.ContainsPoint && twinCell.ContainsSegment)
                        {
                            pointSite = bv.RetrieveInputPoint(cell);
                            lineSite  = bv.RetrieveInputSegment(twinCell);
                        }
                        else if (cell.ContainsSegment && twinCell.ContainsPoint)
                        {
                            pointSite = bv.RetrieveInputPoint(twinCell);
                            lineSite  = bv.RetrieveInputSegment(cell);
                        }

                        else
                        {
                            throw new Exception("Invalid edge, curves should only be present between a point and a line");
                        }

                        double scaleFactor = Convert.ToDouble(bv.ScaleFactor);
                        IPoint aoPointSite = new Point()
                        {
                            X = Convert.ToDouble(pointSite.X) / scaleFactor,
                            Y = Convert.ToDouble(pointSite.Y) / scaleFactor,
                            SpatialReference = spatialReference
                        };

                        ISegment aoLineSite = new LineClass()
                        {
                            FromPoint = new PointClass()
                            {
                                X = Convert.ToDouble(lineSite.Start.X) / scaleFactor,
                                Y = Convert.ToDouble(lineSite.Start.Y) / scaleFactor,
                                SpatialReference = spatialReference
                            },
                            ToPoint = new PointClass()
                            {
                                X = Convert.ToDouble(lineSite.End.X) / scaleFactor,
                                Y = Convert.ToDouble(lineSite.End.Y) / scaleFactor,
                                SpatialReference = spatialReference
                            },
                            SpatialReference = spatialReference
                        };


                        if (method == ArcConstructionMethods.Approximate)
                        {
                            List <Vertex> sampledVerticed = null;
                            try
                            {
                                sampledVerticed = bv.SampleCurvedEdge(edge, aoLineSite.Length / 10);
                            }
                            catch (FocusOnDirectixException e)
                            {
                                //Log any exception here is required
                                sampledVerticed = new List <Vertex>()
                                {
                                    start, end
                                };
                            }
                            catch (UnsolvableVertexException e)
                            {
                                sampledVerticed = new List <Vertex>()
                                {
                                    start, end
                                };
                            }

                            sampledVerticed.Reverse();
                            List <IPoint> discretizedEdge = sampledVerticed.Select(
                                p => new Point()
                            {
                                X = p.X, Y = p.Y
                            }
                                ).ToList <IPoint>();

                            IPoint prev = discretizedEdge[0];
                            foreach (IPoint v in discretizedEdge.Skip(1))
                            {
                                segmentCollection.AddSegment(new LineClass()
                                {
                                    FromPoint = new Point()
                                    {
                                        X = prev.X, Y = prev.Y, SpatialReference = spatialReference
                                    },
                                    ToPoint = new Point()
                                    {
                                        X = v.X, Y = v.Y, SpatialReference = spatialReference
                                    },
                                    SpatialReference = spatialReference
                                });
                                prev = v;
                            }
                            previousEndPoint = discretizedEdge.Last();
                        }
                        else if (method == ArcConstructionMethods.Circular)
                        {
                            IPoint nearPoint = ((IProximityOperator)aoLineSite).ReturnNearestPoint(aoPointSite, esriSegmentExtension.esriNoExtension);
                            IPoint midpoint  = new PointClass()
                            {
                                X = (nearPoint.X + aoPointSite.X) / 2,
                                Y = (nearPoint.Y + aoPointSite.Y) / 2,
                                SpatialReference = spatialReference
                            };

                            IConstructCircularArc constArc = new CircularArcClass()
                            {
                                SpatialReference = spatialReference
                            };
                            constArc.ConstructThreePoints(FromPoint, midpoint, ToPoint, false);
                            ICircularArc arc = (ICircularArc)constArc;

                            if (!arc.IsMinor)
                            {
                                constArc = new CircularArcClass()
                                {
                                    SpatialReference = spatialReference
                                };
                                constArc.ConstructEndPointsRadius(FromPoint, ToPoint, !arc.IsCounterClockwise, arc.Radius, true);
                                arc = (ICircularArc)constArc;
                            }
                            segmentCollection.AddSegment((ISegment)arc);
                            previousEndPoint = arc.ToPoint;
                        }
                        else if (method == ArcConstructionMethods.Ellipse)
                        {
                            IPoint nearPoint = ((IProximityOperator)aoLineSite).ReturnNearestPoint(aoPointSite, esriSegmentExtension.esriExtendTangents);
                            nearPoint.SpatialReference = spatialReference;

                            ILine lineToFocus = new LineClass()
                            {
                                FromPoint = nearPoint, ToPoint = aoPointSite, SpatialReference = spatialReference
                            };
                            ILine semiMajor = new LineClass()
                            {
                                SpatialReference = spatialReference
                            };
                            lineToFocus.QueryTangent(esriSegmentExtension.esriExtendTangentAtTo, 1, true, 100 * lineToFocus.Length, semiMajor);

                            IPoint center = new PointClass()
                            {
                                X = (semiMajor.FromPoint.X + semiMajor.ToPoint.X) / 2,
                                Y = (semiMajor.FromPoint.Y + semiMajor.ToPoint.Y) / 2,
                                SpatialReference = spatialReference
                            };

                            double minor_length = Math.Sqrt(
                                Math.Pow(distance(semiMajor.FromPoint, ToPoint) + distance(semiMajor.ToPoint, ToPoint), 2)
                                - Math.Pow(semiMajor.Length, 2));

                            IEllipticArc arc = new EllipticArcClass()
                            {
                                SpatialReference = spatialReference
                            };
                            double rotation = lineToFocus.Angle;
                            double from     = GetAngle(center, FromPoint);

                            arc.PutCoords(false, center, FromPoint, ToPoint, rotation, minor_length / semiMajor.Length, esriArcOrientation.esriArcMinor);

                            segmentCollection.AddSegment((ISegment)arc);
                            previousEndPoint = arc.ToPoint;
                        }
                    }
                }
            }
            return(segmentCollection);
        }
Пример #8
0
        public override void OnMouseMove(int Button, int Shift, int X, int Y)
        {
            IPoint pMovePt = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
            pMovePt = GIS.GraphicEdit.SnapSetting.getSnapPoint(pMovePt);
            if (m_lMouseDownCount == 1)
            {
                m_pLineFeedback.MoveTo(pMovePt);
            }
            else if (m_lMouseDownCount == 2)
            {
                m_bCreated = false;

                IEnvelope pEnv = new EnvelopeClass();
                pEnv.UpperLeft = m_pFirstPoint;
                pEnv.LowerRight = m_pSecondPoint;

                IConstructCircularArc pEllipArc = new CircularArcClass();
                pEllipArc.ConstructThreePoints(m_pFirstPoint, m_pSecondPoint, pMovePt, true);
                m_pCircleArc = pEllipArc as ICircularArc;
                m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
            }
            DataEditCommon.g_pAxMapControl.Focus();
        }
Пример #9
0
        private ISegmentCollection createSegments(Cell cell,BoostVoronoi bv,ArcConstructionMethods method,ISpatialReference spatialReference)
        {
            List<Cell> cells = bv.Cells;
            List<Edge> edges = bv.Edges;
            List<Vertex> vertices = bv.Vertices;

            IPoint previousEndPoint = null;

            ISegmentCollection segmentCollection = new PolygonClass() { SpatialReference = spatialReference };
            // As per boost documentation, edges are returned in counter clockwise (CCW) rotation.
            //  voronoi_edge_type* next()	Returns the pointer to the CCW next edge within the corresponding Voronoi cell.  Edges not necessarily share a common vertex (e.g. infinite edges).
            for (int i = cell.EdgesIndex.Count - 1; i >= 0; i--)
            {
                Edge edge = edges[cell.EdgesIndex[i]];

                //If the vertex index equals -1, it means the edge is infinite. It is impossible to print the coordinates.
                if (!edge.IsFinite && edge.End < 0)
                {
                    // this is the ending portion of a pair of infinite edges, file the previous edge with Start >= 0
                    Edge previous = null;
                    for (int k = i + 1; k < cell.EdgesIndex.Count; k++)
                    {
                        previous = edges[cell.EdgesIndex[k]];
                        if (previous.End >= 0)
                            break;
                        previous = null;
                    }
                    if (previous == null)
                    {
                        for (int k = 0; k < i; k++)
                        {
                            previous = edges[cell.EdgesIndex[k]];
                            if (previous.End >= 0)
                                break;
                            previous = null;
                        }
                    }
                    if (previous == null)
                        throw new Exception("No outbound infinite edge could be found");

                    //Add a straight line segment
                    Vertex start = vertices[previous.End];
                    IPoint FromPoint = new PointClass() { X = start.X, Y = start.Y, SpatialReference = spatialReference };
                    Vertex end = vertices[edge.Start];
                    IPoint ToPoint = new PointClass() { X = end.X, Y = end.Y, SpatialReference = spatialReference };

                    segmentCollection.AddSegment(new LineClass() { FromPoint = FromPoint, ToPoint = ToPoint, SpatialReference = spatialReference });
                    previousEndPoint = ToPoint;
                }
                else if (edge.IsFinite)
                {
                    Vertex start = vertices[edge.End];
                    IPoint FromPoint = new PointClass() { X = start.X, Y = start.Y, SpatialReference = spatialReference };
                    if (previousEndPoint != null)
                    {
                        if ((Math.Abs(previousEndPoint.X - FromPoint.X) > 0.05 || Math.Abs(previousEndPoint.X - FromPoint.X) > 0.05))
                            throw new Exception("Significant change between last end point and current start point");
                        else
                            FromPoint = previousEndPoint;
                    }
                    Vertex end = vertices[edge.Start];
                    IPoint ToPoint = new PointClass() { X = end.X, Y = end.Y, SpatialReference = spatialReference };

                    if (method == ArcConstructionMethods.Straight || edge.IsLinear)
                    {
                        segmentCollection.AddSegment(new LineClass() { FromPoint = FromPoint, ToPoint = ToPoint, SpatialReference = spatialReference });
                        previousEndPoint = ToPoint;
                    }
                    else
                    {
                        // We need three points, use start, end, mid-point between focus and directrix
                        Cell twinCell = cells[edges[edge.Twin].Cell];

                        VPoint pointSite; VSegment lineSite;
                        if (cell.ContainsPoint && twinCell.ContainsSegment)
                        {
                            pointSite = bv.RetrieveInputPoint(cell);
                            lineSite = bv.RetrieveInputSegment(twinCell);
                        }
                        else if (cell.ContainsSegment && twinCell.ContainsPoint)
                        {
                            pointSite = bv.RetrieveInputPoint(twinCell);
                            lineSite = bv.RetrieveInputSegment(cell);
                        }

                        else
                        {
                            throw new Exception("Invalid edge, curves should only be present between a point and a line");
                        }

                        double scaleFactor = Convert.ToDouble(bv.ScaleFactor);
                        IPoint aoPointSite = new Point()
                        {
                                X = Convert.ToDouble(pointSite.X) / scaleFactor,
                                Y = Convert.ToDouble(pointSite.Y) / scaleFactor,
                                SpatialReference = spatialReference
                        };

                        ISegment aoLineSite = new LineClass()
                        {
                            FromPoint = new PointClass()
                            {
                                    X = Convert.ToDouble(lineSite.Start.X) / scaleFactor,
                                    Y = Convert.ToDouble(lineSite.Start.Y) / scaleFactor,
                                    SpatialReference = spatialReference
                            },
                            ToPoint = new PointClass()
                            {
                                    X = Convert.ToDouble(lineSite.End.X) / scaleFactor,
                                    Y = Convert.ToDouble(lineSite.End.Y) / scaleFactor,
                                    SpatialReference = spatialReference
                            },
                            SpatialReference = spatialReference
                        };

                        if (method == ArcConstructionMethods.Approximate)
                        {
                            List<Vertex> sampledVerticed = null;
                            try
                            {
                                sampledVerticed = bv.SampleCurvedEdge(edge, aoLineSite.Length / 10);

                            }
                            catch (FocusOnDirectixException e)
                            {
                                //Log any exception here is required
                                sampledVerticed = new List<Vertex>() { start, end };
                            }
                            catch (UnsolvableVertexException e)
                            {
                                sampledVerticed = new List<Vertex>() { start, end };
                            }

                            sampledVerticed.Reverse();
                            List<IPoint> discretizedEdge = sampledVerticed.Select(
                                p => new Point() { X = p.X, Y = p.Y }
                            ).ToList<IPoint>();

                            IPoint prev = discretizedEdge[0];
                            foreach (IPoint v in discretizedEdge.Skip(1))
                            {
                                segmentCollection.AddSegment(new LineClass()
                                {
                                    FromPoint = new Point() { X = prev.X, Y = prev.Y, SpatialReference = spatialReference },
                                    ToPoint = new Point() { X = v.X, Y = v.Y, SpatialReference = spatialReference },
                                    SpatialReference = spatialReference
                                });
                                prev = v;
                            }
                            previousEndPoint = discretizedEdge.Last();
                        }
                        else if (method == ArcConstructionMethods.Circular)
                        {
                            IPoint nearPoint = ((IProximityOperator)aoLineSite).ReturnNearestPoint(aoPointSite, esriSegmentExtension.esriNoExtension);
                            IPoint midpoint = new PointClass()
                            {
                                X = (nearPoint.X + aoPointSite.X) / 2,
                                Y = (nearPoint.Y + aoPointSite.Y) / 2,
                                SpatialReference = spatialReference
                            };

                            IConstructCircularArc constArc = new CircularArcClass() { SpatialReference = spatialReference };
                            constArc.ConstructThreePoints(FromPoint, midpoint, ToPoint, false);
                            ICircularArc arc = (ICircularArc)constArc;

                            if (!arc.IsMinor)
                            {
                                constArc = new CircularArcClass() { SpatialReference = spatialReference };
                                constArc.ConstructEndPointsRadius(FromPoint, ToPoint, !arc.IsCounterClockwise, arc.Radius, true);
                                arc = (ICircularArc)constArc;
                            }
                            segmentCollection.AddSegment((ISegment)arc);
                            previousEndPoint = arc.ToPoint;
                        }
                        else if (method == ArcConstructionMethods.Ellipse)
                        {
                            IPoint nearPoint = ((IProximityOperator)aoLineSite).ReturnNearestPoint(aoPointSite, esriSegmentExtension.esriExtendTangents);
                            nearPoint.SpatialReference = spatialReference;

                            ILine lineToFocus = new LineClass() { FromPoint = nearPoint, ToPoint = aoPointSite, SpatialReference = spatialReference };
                            ILine semiMajor = new LineClass() { SpatialReference = spatialReference };
                            lineToFocus.QueryTangent(esriSegmentExtension.esriExtendTangentAtTo, 1, true, 100 * lineToFocus.Length, semiMajor);

                            IPoint center = new PointClass()
                            {
                                X = (semiMajor.FromPoint.X + semiMajor.ToPoint.X) / 2,
                                Y = (semiMajor.FromPoint.Y + semiMajor.ToPoint.Y) / 2,
                                SpatialReference = spatialReference
                            };

                            double minor_length = Math.Sqrt(
                                        Math.Pow(distance(semiMajor.FromPoint, ToPoint) + distance(semiMajor.ToPoint, ToPoint), 2)
                                        - Math.Pow(semiMajor.Length, 2));

                            IEllipticArc arc = new EllipticArcClass() { SpatialReference = spatialReference };
                            double rotation = lineToFocus.Angle;
                            double from = GetAngle(center, FromPoint);

                            arc.PutCoords(false, center, FromPoint, ToPoint, rotation, minor_length / semiMajor.Length, esriArcOrientation.esriArcMinor);

                            segmentCollection.AddSegment((ISegment)arc);
                            previousEndPoint = arc.ToPoint;

                        }
                    }
                }
            }
            return segmentCollection;
        }