Esempio n. 1
0
        public void TraversePositionSet_ConnectedAndSpringEvent(IPositionSet ps)
        {
            if (OnGetConnection != null)
            {
                IPosition_Connected[] ary = (IPosition_Connected[])ps.ToArray();
                if (ary != null)
                {
                    foreach (IPosition_Connected p in ary)
                    {
                        float x = layer.ConvertPositionSetXToScreenX(p.GetX());
                        float y = layer.ConvertPositionSetYToScreenY(p.GetY());
                        IPositionSet_Connected_Adjacency adj_set = p.GetAdjacencyPositionSet();
                        adj_set.InitToTraverseSet();
                        while (adj_set.NextPosition())
                        {
                            IPosition_Connected adj = adj_set.GetPosition_Connected();
                            float adj_x             = layer.ConvertPositionSetXToScreenX(adj.GetX());
                            float adj_y             = layer.ConvertPositionSetYToScreenY(adj.GetY());
                            OnGetConnection(x, y, adj_x, adj_y);
                        }
                    }
                }
            }

            TraversePositionSetAndSpringEvent(ps);
        }
Esempio n. 2
0
        //计算多边形的(有向)面积
        public static double GetArea(IPositionSet ps)
        {
            double sum = 0;

            IPosition[] pa = (IPosition[])ps.ToArray();
            int         n  = pa.Length;
            int         nn;

            //判断是否首尾相接的点序列
            if (pa[0] != pa[n - 1])
            {
                nn = n + 1;
            }
            else
            {
                nn = n;
            }

            //计算叉积和
            for (int i = 0; i < nn - 1; i++)
            {
                sum += pa[i].GetX() * pa[(i + 1) % n].GetY() - pa[i].GetY() * pa[(i + 1) % n].GetX();
            }

            //计算面积
            return(sum / 2);
        }
        /*
         * public SimplePositionSet ConvexHull(SimplePositionSet ps)
         * {
         *  int n = ps.GetCount();
         *  Point[] pts = new Point[n];
         *  for (int i = 0; i < n; i++)
         *  {
         *      SimplePosition pos = ps.GetNextPosition();
         *      pts[i] = new Point(pos.GetX(), pos.GetY());
         *  }
         *  Point[] resPts = _ConvexHull(pts);
         *  SimplePositionSet result = new SimplePositionSet();
         *  for (int i = 0; i < resPts.Length; i++)
         *      result.AddPosition(new SimplePosition(resPts[i].X, resPts[i].Y));
         *  return result;
         * }
         */
        public IPositionSet ConvexHull(IPositionSet ps)
        {
            //转换成数组
            IPosition[] posArr = (IPosition[])ps.ToArray();
            int         N      = posArr.Length;

            //排序
            Polysort.Quicksort(posArr);
            IPosition left  = posArr[0];
            IPosition right = posArr[N - 1];
            // Partition into lower hull and upper hull
            CDLL lower = new CDLL(left), upper = new CDLL(left);

            for (int i = 0; i < N; i++)
            {
                double det = Area2(left, right, posArr[i]);
                if (det > 0)
                {
                    upper = upper.Append(new CDLL(posArr[i]));
                }
                else if (det < 0)
                {
                    lower = lower.Prepend(new CDLL(posArr[i]));
                }
            }
            lower = lower.Prepend(new CDLL(right));
            upper = upper.Append(new CDLL(right)).Next;
            // Eliminate points not on the hull
            eliminate(lower);
            eliminate(upper);
            // Eliminate duplicate endpoints 消除重复点

            /*
             * if (lower.Prev.val.Equals(upper.val))
             *   lower.Prev.Delete();
             * if (upper.Prev.val.Equals(lower.val))
             *   upper.Prev.Delete();
             * */
            // Join the lower and upper hull
            IPosition[] res = new IPosition[lower.Size() + upper.Size()];
            lower.CopyInto(res, 0);
            upper.CopyInto(res, lower.Size());
            PositionSetEdit_ImplementByICollectionTemplate result = new PositionSetEdit_ImplementByICollectionTemplate();

            for (int i = 0; i < res.Length - 1; i++)
            {
                result.AddPosition(res[i]);
            }
            return(result);
        }
        public static void lanch(IConvexHullEngine chEngine, int pointCount, float min, float max)
        {
            //求解凸包并作图
            //IPositionSet ps = testData();
            IPositionSet ps = new RandomPositionSet(pointCount, min, max);

            //System.Console.Out.WriteLine("position set:");
            //printPositionSet(ps);
            IPositionSet cps = chEngine.ConvexHull(ps);

            //System.Console.Out.WriteLine("Jarvis Match:");
            //printPositionSet(cps);
            PainterDialog.Clear();
            PainterDialog.DrawPositionSet(ps);
            PainterDialog.DrawConvexHull(cps);
            PainterDialog.Show();


            AnalyzeReport report = new AnalyzeReport();

            //测试点集引用
            cps.InitToTraverseSet();
            ps.InitToTraverseSet();
            bool correct = true;

            while (correct && cps.NextPosition())
            {
                IPosition cp   = cps.GetPosition();
                bool      find = false;
                ps.InitToTraverseSet();
                while (!find && ps.NextPosition())
                {
                    IPosition p = ps.GetPosition();
                    if (cp == p)
                    {
                        find = true;
                    }
                }
                if (!find)
                {
                    correct = false;
                }
            }
            report.content += "引用测试:" + (correct ? "正确" : "错误") + "\n";

            //测试凸包
            if (correct)
            {
                report.content += "凸包正确性测试:\n";
                IPositionSet cps_ref = (new QuickHull()).ConvexHull(ps);
                //    System.Console.Out.WriteLine("Quick Hull:");
                //    printPositionSet(cps_ref);
                IPosition[] cpa     = (IPosition[])(cps.ToArray());
                IPosition[] cpa_ref = (IPosition[])(cps_ref.ToArray());
                if (cpa.Length != cpa_ref.Length)
                {
                    report.content += "数目不等";
                    correct         = false;
                }
                if (correct)
                {
                    int n = cpa.Length;
                    int m = 0;
                    int p = 0;
                    for (; p < n; p++)
                    {
                        if (cpa[0] == cpa_ref[p])
                        {
                            break;
                        }
                    }
                    if (p == n)
                    {
                        correct         = false;
                        report.content += "发生错误!";
                    }
                    if (correct)
                    {
                        for (int i = 0; i < n; i++)
                        {
                            if (cpa[i] == cpa_ref[(p + i + n) % n])
                            {
                                m++;
                            }
                        }
                        int tm = 0;
                        for (int i = 0; i < n; i++)
                        {
                            if (cpa[i] == cpa_ref[(p - i + n) % n])
                            {
                                tm++;
                            }
                        }
                        if (tm > m)
                        {
                            m = tm;
                        }
                        report.content += "正确率:" + m.ToString() + "/" + n.ToString();
                        if (m == n)
                        {
                            report.content += "正确!";
                        }
                        else
                        {
                            report.content += "不正确!";
                        }
                    }
                }
            }
            report.Show();
        }
        /// <summary>
        /// 遍历positionSet并产生相应的事件(如果有新的时间请在里面添加,并在ResetPainter函数里面设为null)
        /// </summary>
        /// <param name="ps"></param>
        public void TraversePositionSetAndSpringEvent(IPositionSet ps)
        {
            ps.InitToTraverseSet();
            IPosition[] positionSet_ary = (IPosition[])ps.ToArray();

            for (int i = 0; i < positionSet_ary.Length; i++)
            {
                if (OnGetRealCoordinate != null)
                {
                    this.OnGetRealCoordinate(layer.ConvertPositionSetXToRealX(positionSet_ary[i].GetX()),
                                             layer.ConvertPositionSetYToRealY(positionSet_ary[i].GetY()));
                }

                //DrawPointX和DrawPointY是屏幕上显示的坐标
                float DrawPointX = layer.ConvertPositionSetXToScreenX(positionSet_ary[i].GetX());
                float DrawPointY = layer.ConvertPositionSetYToScreenY(positionSet_ary[i].GetY());

                if (i == 0)
                {
                    if (OnGetFirstPoint != null)
                    {
                        this.OnGetFirstPoint(DrawPointX, DrawPointY);
                    }
                }
                else if (i == positionSet_ary.Length - 1)
                {
                    if (OnGetLastPoint != null)
                    {
                        this.OnGetLastPoint(DrawPointX, DrawPointY);
                    }
                }
                else
                {
                    if (OnGetMiddlePoint != null)
                    {
                        this.OnGetMiddlePoint(DrawPointX, DrawPointY);
                    }
                }

                if (OnGetPoint != null)
                {
                    this.OnGetPoint(DrawPointX, DrawPointY);
                }
            }

            #region old implement

            //if (OnGetLastPoint != null)
            //{
            //    this.OnGetLastPoint(x, y);
            //}

            //if (ps.NextPosition())
            //{
            //    if (OnGetRealPoint != null)
            //    {
            //        this.OnGetRealPoint(ps.GetPosition().GetX(), ps.GetPosition().GetY())
            //    }

            //    x = ps.GetPosition().GetX() * scaleX + translationX;
            //    y = -(ps.GetPosition().GetY() * scaleY + translationY);

            //    if (OnGetFirstPoint != null)
            //    {
            //        this.OnGetFirstPoint(x, y);
            //    }

            //    if (OnGetPoint != null)
            //    {
            //        this.OnGetPoint(x, y);
            //    }
            //}
            //while (ps.NextPosition())
            //{
            //    if (OnGetRealPoint != null)
            //    {
            //        this.OnGetRealPoint(ps.GetPosition().GetX(), ps.GetPosition().GetY())
            //    }

            //    x = ps.GetPosition().GetX() * scaleX + translationX;
            //    y = ps.GetPosition().GetY() * scaleY + translationY;

            //    if (OnGetMiddlePoint != null)
            //    {
            //        if(ps.NextPosition())
            //        {
            //            this.OnGetMiddlePoint(x, y);
            //        }
            //    }

            //    if (OnGetPoint != null)
            //    {
            //        this.OnGetPoint(x, y);
            //    }
            //}

            //if (OnGetLastPoint != null)
            //{
            //    this.OnGetLastPoint(x, y);
            //}

            #endregion
        }