Пример #1
0
        int QuickHullPartition(List <CGPoint> points, int low, int high)
        {
            int fp = CGUtils.LeftFarmostPointFromLine(points[low], points[high], points);

            if (fp == -1)
            {
                return(-1);
            }
            CGPoint from = points[low];

            low++;
            high--;
            points.Swap(low, fp);
            CGPoint pivot = points[low];

            while (low < high)
            {
                while (low < high && !CGUtils.ToLeft(from, pivot, points[high]))
                {
                    high--;
                }
                points[low] = points[high];
                while (low < high && CGUtils.ToLeft(from, pivot, points[high]))
                {
                    low++;
                }
                points[high] = points[low];
            }
            points[low] = pivot;
            return(low);
        }
Пример #2
0
        public static Vertex CreateVertex(CGPoint p)
        {
            if (p == null)
            {
                return(null);
            }
            var ret = new Vertex()
            {
                point = p,
                e     = CGEdge.CreateEdge(p, p.succ),
            };

            if (p.y > p.succ.y && p.y > p.pred.y)
            {
                ret.type = CGUtils.ToLeft(p.pred, p.succ, p) ? Type.Split : Type.Start;
            }
            else if (p.y < p.succ.y && p.y < p.pred.y)
            {
                ret.type = CGUtils.ToLeft(p.pred, p.succ, p) ? Type.Merge : Type.End;
            }
            else
            {
                ret.type = Type.Normal;
            }
            return(ret);
        }
Пример #3
0
        public void QuickHull()
        {
            var            ltl         = CGUtils.LowestThenLeftmost(points);
            var            htr         = CGUtils.HighestThenRightmost(points);
            List <CGPoint> leftPoints  = new List <CGPoint>();
            List <CGPoint> rightPoints = new List <CGPoint>();

            leftPoints.Add(ltl);
            rightPoints.Add(htr);
            for (int i = 0; i < points.Count; i++)
            {
                if (points[i] != ltl && points[i] != htr)
                {
                    if (CGUtils.ToLeft(ltl, htr, points[i]))
                    {
                        leftPoints.Add(points[i]);
                    }
                    else
                    {
                        rightPoints.Add(points[i]);
                    }
                }
            }
            leftPoints.Add(htr);
            rightPoints.Add(ltl);
            QuickHull(leftPoints, 0, leftPoints.Count - 1);
            QuickHull(rightPoints, 0, rightPoints.Count - 1);
        }
Пример #4
0
        public void GrahamScan()
        {
            Reset();
            if (points.Count < 3)
            {
                return;
            }
            CGPoint ltl      = CGUtils.LowestThenLeftmost(points);
            int     ltlIndex = points.FindIndex(o => o == ltl);

            if (ltlIndex > 0)
            {
                CGPoint temp = points[ltlIndex];
                points[ltlIndex] = points[0];
                points[0]        = temp;
            }
            PolarAnglePointCompare compare = new PolarAnglePointCompare()
            {
                piovt = ltl
            };

            points.Sort(1, points.Count - 1, compare);
            Stack <CGPoint> t = new Stack <CGPoint>();
            Stack <CGPoint> s = new Stack <CGPoint>();

            s.Push(points[0]);
            s.Push(points[1]);
            for (int i = points.Count - 1; i > 1; i--)
            {
                t.Push(points[i]);
            }
            while (t.Count != 0)
            {
                var topOfS = s.Pop();
                if (CGUtils.ToLeft(s.Peek(), topOfS, t.Peek()))
                {
                    s.Push(topOfS);
                    s.Push(t.Pop());
                }
            }
            var     last = s.Peek();
            CGPoint curr = null;

            while (s.Count > 0)
            {
                curr           = s.Pop();
                curr.isExtreme = true;
                if (s.Count == 0)
                {
                    break;
                }
                curr.pred = s.Peek();
                s.Peek().succ = curr;
            }
            last.succ = curr;
            curr.pred = last;
        }
Пример #5
0
        bool isTangentPoint(CGPoint from, CGPoint to, bool isLeft)
        {
            bool toIsSingle = to.pred == to && to.succ == to;

            if (toIsSingle)
            {
                return(true);
            }
            bool predIsLeft = CGUtils.ToLeft(from, to, to.pred) == isLeft;
            bool succIsLeft = CGUtils.ToLeft(from, to, to.succ) == isLeft;
            bool toPredAndToSuccAreSameSide = predIsLeft && succIsLeft;

            return(toPredAndToSuccAreSameSide);
        }
Пример #6
0
        public bool ContentIsOnTheRightSideOfPoint()
        {
            CGPoint lowY  = null;
            CGPoint highY = null;

            if (pred.y < succ.y)
            {
                lowY  = pred;
                highY = succ;
            }
            else
            {
                lowY  = succ;
                highY = pred;
            }
            var isLeft = CGUtils.ToLeft(lowY, highY, this);

            return(IsConvex() ? isLeft : !isLeft);
        }
Пример #7
0
        public static float GetRotateAngleInRadians(CGPoint from, CGPoint common, CGPoint to)
        {
            CGPoint fromVector = from - common;
            CGPoint toVector   = to - common;
            float   cos        = CGPoint.Dot(fromVector, toVector) / (fromVector.Length * toVector.Length);

            if (Math.Abs(cos - 1.0) <= epsilon)
            {
                return(0f);
            }
            else if (Math.Abs(cos + 1.0) <= epsilon)
            {
                return((float)(Math.Acos(-1) * (180 / Math.PI)));
            }
            else
            {
                //float rad = (float)Math.Acos(cos);
                //return CGUtils.ToLeft(from, to, common) ? rad : (float)(2 * Math.PI - rad);
                float rad = (float)Math.Acos(cos) * (float)(180 / Math.PI);
                return(CGUtils.ToLeft(from, to, common) ? rad : 360f - rad);
            }
        }
Пример #8
0
        public void JarvisMarch()
        {
            Reset();
            CGPoint ltl  = CGUtils.LowestThenLeftmost(points);
            CGPoint curr = ltl;
            CGPoint next = null;

            do
            {
                curr.isExtreme = true;
                next           = null;
                for (int i = 0; i < points.Count; i++)
                {
                    if (points[i] != curr && (next == null || !CGUtils.ToLeft(curr, next, points[i])))
                    {
                        next = points[i];
                    }
                }
                curr.succ = next;
                next.pred = curr;
                curr      = next;
            } while (ltl != curr);
        }
Пример #9
0
        bool IsTopConvex(CGPoint curr, CGPoint top, CGPoint sec)
        {
            bool left = CGUtils.ToLeft(sec, curr, top);

            return(top.pred == curr ? left : !left);
        }
Пример #10
0
 public bool IsConvex()
 {
     return(!CGUtils.ToLeft(pred, succ, this));
 }
Пример #11
0
 public int Compare(CGPoint x, CGPoint y)
 {
     return(CGUtils.ToLeft(piovt, x, y) ? -1 : 1);
 }