예제 #1
0
        /// <summary>
        /// Checks an array of positions that purportedly correspond to a circular arc, to see
        /// whether the data is directed clockwise or not. No checks are made to confirm that
        /// the data really does correspond to a circular arc.
        /// </summary>
        /// <param name="pts">The positions defining an arc</param>
        /// <param name="center">The position of the centre of the circle that the arc lies on.</param>
        /// <returns>True if the data is ordered clockwise.</returns>
        public static bool IsClockwise(IPointGeometry[] pts, IPointGeometry center)
        {
            // To determine the direction, we must locate two successive
            // vertices that lie in the same quadrant (with respect to the
            // circle center).

            QuadVertex start = new QuadVertex(center, pts[0]);
            QuadVertex end   = null;

            for (int i = 1; i < pts.Length; i++, start = end)
            {
                // Pick up the position at the end of the line segment.
                end = new QuadVertex(center, pts[i]);

                // If both ends of the segment are in the same quadrant,
                // see which one comes first. The result tells us whether
                // the curve is clockwise or not.

                if (start.Quadrant == end.Quadrant)
                {
                    return(start.GetTanAngle() < end.GetTanAngle());
                }
            }

            // Something has gone wrong if we got here!
            Debug.Assert(1 == 2);
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Checks an array of positions that purportedly correspond to a circular arc, to see
        /// whether the data is directed clockwise or not. No checks are made to confirm that
        /// the data really does correspond to a circular curve.
        /// </summary>
        /// <param name="pts">Positions on circular arc</param>
        /// <param name="center">The position of the centre of the circle that the curve lies on</param>
        /// <returns>True if the data is ordered clockwise.</returns>
        public static bool IsClockwise(IPosition[] pts, IPosition center)
        {
            if (pts.Length<2)
                return false;

            // To determine the direction, we must locate two successive
            // vertices that lie in the same quadrant (with respect to the
            // circle centre).

            QuadVertex start = new QuadVertex(center, pts[0]);
            QuadVertex end;

            for (int i=1; i<pts.Length; i++, start=end)
            {
                // Pick up the position at the end of the line segment
                end = new QuadVertex(center, pts[i]);

                // If both ends of the segment are in the same quadrant,
                // see which one comes first. The result tells us whether
                // the curve is clockwise or not.

                if (start.Quadrant == end.Quadrant)
                    return (start.GetTanAngle() < end.GetTanAngle() ? true : false);
            }

            // Something has gone wrong if we got here!
            Debug.Assert(1==2);
            return true;
        }
예제 #3
0
        /// <summary>
        /// Gets the most easterly position for this arc.
        /// </summary>
        /// <returns>The most easterly position</returns>
        internal override IPosition GetEastPoint()
        {
            // If the arc is a complete circle, just work it out the easy way.
            if (IsCircle)
            {
                return(m_Circle.GetEastPoint());
            }

            // Determine where the east point is. It could be either the
            // BC, the EC, or the most easterly point of the circle.

            IPosition start  = First;
            IPosition end    = Second;
            char      choice = (start.X > end.X ? 'S' : choice = 'E');

            // But hold on. If the arc passes from the northeast to southeast
            // quadrant, we want the east point of the circle.

            IPosition  c  = m_Circle.Center;
            QuadVertex vs = new QuadVertex(c, start);
            QuadVertex ve = new QuadVertex(c, end);

            Quadrant qs = vs.Quadrant;
            Quadrant qe = ve.Quadrant;

            // If the BC & EC are in the same quadrant, the only way the
            // circle point can apply is if it goes all the way round.
            if (!(qs == qe && vs.GetTanAngle() < ve.GetTanAngle()))
            {
                // Determine whether the circle point applies.
                switch (qs)
                {
                case Quadrant.NE:
                {
                    choice = 'C';
                    break;
                }

                case Quadrant.SE:
                    break;

                case Quadrant.SW:
                {
                    if (qe == Quadrant.SE)
                    {
                        choice = 'C';
                    }

                    break;
                }

                case Quadrant.NW:
                {
                    if (qe != Quadrant.NE)
                    {
                        choice = 'C';
                    }

                    break;
                }
                }
            }

            if (choice == 'S')
            {
                return(start);
            }
            else if (choice == 'E')
            {
                return(end);
            }

            Debug.Assert(choice == 'C');
            return(m_Circle.GetEastPoint());
        }
        public static IWindow GetExtent(ICircularArcGeometry g)
        {
            // If the curve is a complete circle, just define it the easy way.
            if (g.BC.IsCoincident(g.EC))
                return CircleGeometry.GetExtent(g.Circle);

            IPosition bcp = g.BC;
            IPosition ecp = g.EC;
            IPosition centre = g.Circle.Center;

            // Initialize the window with the start location.
            Window win = new Window(bcp);

            // Expand using the end location
            win.Union(ecp);

            // If the curve is completely within one quadrant, we're done.
            QuadVertex bc = new QuadVertex(centre, bcp);
            QuadVertex ec = new QuadVertex(centre, ecp);

            Quadrant qbc = bc.Quadrant;
            Quadrant qec = ec.Quadrant;

            if (qbc == qec)
            {
                if (g.IsClockwise)
                {
                    if (bc.GetTanAngle() < ec.GetTanAngle())
                        return win;
                }
                else
                {
                    if (ec.GetTanAngle() < bc.GetTanAngle())
                        return win;
                }
            }

            // Get the window of the circle
            IWindow circle = CircleGeometry.GetExtent(g.Circle);

            // If the curve is anticlockwise, switch the quadrants for BC & EC
            if (!g.IsClockwise)
            {
                Quadrant temp = qbc;
                qbc = qec;
                qec = temp;
            }

            // Expand the window, depending on which quadrants the start &
            // end points fall in. The lack of breaks in the inner switches
            // is intentional (e.g. if start & end both fall in Quadrant.NorthEast,
            // the window we want is the complete circle, having checked above
            // for the case where the arc is JUST in Quadrant.NorthEast).

            // Define do-nothing values for the Union's below
            double wx = win.Min.X;
            double wy = win.Min.Y;

            if (qbc==Quadrant.NE)
            {
                switch (qec)
                {
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        goto case Quadrant.NW;
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        goto case Quadrant.SW;
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        goto case Quadrant.SE;
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        break;
                }
            }
            else if (qbc==Quadrant.SE)
            {
                switch (qec)
                {
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        goto case Quadrant.NE;
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        goto case Quadrant.NW;
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        goto case Quadrant.SW;
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        break;
                }
            }
            else if (qbc==Quadrant.SW)
            {
                switch (qec)
                {
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        goto case Quadrant.SE;
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        goto case Quadrant.NE;
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        goto case Quadrant.NW;
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        break;
                }
            }
            else if (qbc==Quadrant.NW)
            {
                switch (qec)
                {
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        goto case Quadrant.SW;
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        goto case Quadrant.SE;
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        goto case Quadrant.NE;
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        break;
                }
            }

            return win;
        }
예제 #5
0
        public static IWindow GetExtent(ICircularArcGeometry g)
        {
            // If the curve is a complete circle, just define it the easy way.
            if (g.BC.IsCoincident(g.EC))
            {
                return(CircleGeometry.GetExtent(g.Circle));
            }

            IPosition bcp    = g.BC;
            IPosition ecp    = g.EC;
            IPosition centre = g.Circle.Center;

            // Initialize the window with the start location.
            Window win = new Window(bcp);

            // Expand using the end location
            win.Union(ecp);

            // If the curve is completely within one quadrant, we're done.
            QuadVertex bc = new QuadVertex(centre, bcp);
            QuadVertex ec = new QuadVertex(centre, ecp);

            Quadrant qbc = bc.Quadrant;
            Quadrant qec = ec.Quadrant;

            if (qbc == qec)
            {
                if (g.IsClockwise)
                {
                    if (bc.GetTanAngle() < ec.GetTanAngle())
                    {
                        return(win);
                    }
                }
                else
                {
                    if (ec.GetTanAngle() < bc.GetTanAngle())
                    {
                        return(win);
                    }
                }
            }

            // Get the window of the circle
            IWindow circle = CircleGeometry.GetExtent(g.Circle);

            // If the curve is anticlockwise, switch the quadrants for BC & EC
            if (!g.IsClockwise)
            {
                Quadrant temp = qbc;
                qbc = qec;
                qec = temp;
            }

            // Expand the window, depending on which quadrants the start &
            // end points fall in. The lack of breaks in the inner switches
            // is intentional (e.g. if start & end both fall in Quadrant.NorthEast,
            // the window we want is the complete circle, having checked above
            // for the case where the arc is JUST in Quadrant.NorthEast).

            // Define do-nothing values for the Union's below
            double wx = win.Min.X;
            double wy = win.Min.Y;

            if (qbc == Quadrant.NE)
            {
                switch (qec)
                {
                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    goto case Quadrant.NW;

                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    goto case Quadrant.SW;

                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    goto case Quadrant.SE;

                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    break;
                }
            }
            else if (qbc == Quadrant.SE)
            {
                switch (qec)
                {
                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    goto case Quadrant.NE;

                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    goto case Quadrant.NW;

                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    goto case Quadrant.SW;

                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    break;
                }
            }
            else if (qbc == Quadrant.SW)
            {
                switch (qec)
                {
                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    goto case Quadrant.SE;

                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    goto case Quadrant.NE;

                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    goto case Quadrant.NW;

                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    break;
                }
            }
            else if (qbc == Quadrant.NW)
            {
                switch (qec)
                {
                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    goto case Quadrant.SW;

                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    goto case Quadrant.SE;

                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    goto case Quadrant.NE;

                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    break;
                }
            }

            return(win);
        }
예제 #6
0
        /// <summary>
        /// Gets the most easterly position for this arc.
        /// </summary>
        /// <returns>The most easterly position</returns>
        internal override IPosition GetEastPoint()
        {
            // If the arc is a complete circle, just work it out the easy way.
            if (IsCircle)
                return m_Circle.GetEastPoint();

            // Determine where the east point is. It could be either the
            // BC, the EC, or the most easterly point of the circle.

            IPosition start = First;
            IPosition end = Second;
            char choice = (start.X > end.X ? 'S' : choice = 'E');

            // But hold on. If the arc passes from the northeast to southeast
            // quadrant, we want the east point of the circle.

            IPosition c = m_Circle.Center;
            QuadVertex vs = new QuadVertex(c, start);
            QuadVertex ve = new QuadVertex(c, end);

            Quadrant qs = vs.Quadrant;
            Quadrant qe = ve.Quadrant;

            // If the BC & EC are in the same quadrant, the only way the
            // circle point can apply is if it goes all the way round.
            if (!(qs==qe && vs.GetTanAngle()<ve.GetTanAngle()))
            {
                // Determine whether the circle point applies.
                switch (qs)
                {
                    case Quadrant.NE:
                    {
                        choice='C';
                        break;
                    }

                    case Quadrant.SE:
                        break;

                    case Quadrant.SW:
                    {
                        if (qe==Quadrant.SE)
                            choice = 'C';

                        break;
                    }

                    case Quadrant.NW:
                    {
                        if (qe!=Quadrant.NE)
                            choice = 'C';

                        break;
                    }
                }
            }

            if (choice=='S')
                return start;
            else if (choice=='E')
                return end;

            Debug.Assert(choice=='C');
            return m_Circle.GetEastPoint();
        }