Пример #1
0
        private void Run()
        {
            if (pList.Count > 0)
            {
                /* 初始化 */
                v.pList.Clear();
                v.vList.Clear();
                record.Clear();
                stepIndex = 0;
                ClearPaint();

                /* 初始畫布建置 */
                ClearPaint();
                foreach (PointF i in pList)
                {
                    DrawPointF(i, Color.DarkRed);
                }

                /* 排序點 */
                pList = MathEx.SortPointF(pList);

                /* 畫 Convex Hull */
                DrawConvexHull(MathEx.GetConvexHull(pList));

                /* 畫 Voronoi Diagram */
                v = VoronoiMultiPoint(pList);
                DrawVoronoiDiagram(v.vList, Color.DarkGreen);
            }
        }
Пример #2
0
        private void SaveFile()
        {
            //if(v.vList != null && v.vList.Count > 0)
            //{
            /* 依 lexical order 排序 */
            v.pList = MathEx.SortPointF(v.pList);
            v.vList = MathEx.SortEdge(v.vList);

            save_fdg.Title = "Save";
            if (save_fdg.ShowDialog() == DialogResult.OK)
            {
                StreamWriter sw = new StreamWriter(save_fdg.FileName);
                for (int i = 0; i < v.pList.Count; i++)
                {
                    sw.WriteLine("P " + v.pList[i].X + " " + v.pList[i].Y);
                }
                for (int i = 0; i < v.vList.Count; i++)
                {
                    sw.WriteLine("E " + Convert.ToInt32(v.vList[i].A.X) + " " + Convert.ToInt32(v.vList[i].A.Y) + " "
                                 + Convert.ToInt32(v.vList[i].B.X) + " " + Convert.ToInt32(v.vList[i].B.Y));
                }
                sw.Close();
            }
            //}
            //else
            //{
            //    MessageBox.Show("Please draw some diagram!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            //}
        }
Пример #3
0
        public Voronoi VoronoiThreePoint(PointF A, PointF B, PointF C)
        {
            Voronoi v = new Voronoi();
            PointF  triEx;
            PointF  mid;

            v.pList.Add(A);
            v.pList.Add(B);
            v.pList.Add(C);

            /* 三點共線 */
            if (MathEx.isCollinear(v.pList[0], v.pList[1], v.pList[2]))
            {
                /* 將點排序 */
                v.pList = MathEx.SortPointF(v.pList);

                /* 將邊無限延伸的做法 */
                mid = MathEx.GetMidPointF(v.pList[0], v.pList[1]);
                v.vList.Add(new Edge(mid.Add(MathEx.GetNormalVector(v.pList[0], v.pList[1]).Multi(600)), mid.Add(MathEx.GetNormalVector(v.pList[1], v.pList[0]).Multi(600)), v.pList[0], v.pList[1]));
                mid = MathEx.GetMidPointF(v.pList[1], v.pList[2]);
                v.vList.Add(new Edge(mid.Add(MathEx.GetNormalVector(v.pList[1], v.pList[2]).Multi(600)), mid.Add(MathEx.GetNormalVector(v.pList[2], v.pList[1]).Multi(600)), v.pList[1], v.pList[2]));

                /* 將邊畫到邊界的做法
                 * mid = MathEx.GetMidPointF(v.pList[0], v.pList[1]);
                 * v.vList.Add(new Edge(GetSidePointF(mid, mid.Add(MathEx.GetNormalVector(v.pList[1], v.pList[0]))), GetSidePointF(mid, mid.Add(MathEx.GetNormalVector(v.pList[0], v.pList[1])))));
                 * mid = MathEx.GetMidPointF(v.pList[1], v.pList[2]);
                 * v.vList.Add(new Edge(GetSidePointF(mid, mid.Add(MathEx.GetNormalVector(v.pList[2], v.pList[1]))), GetSidePointF(mid, mid.Add(MathEx.GetNormalVector(v.pList[1], v.pList[2])))));
                 */
            }
            else
            {
                /* 計算外心 */
                triEx = MathEx.GetTriangleExcenterPointF(A, B, C);

                /* 將點依逆時針方向排序 */
                v.pList = MathEx.SortVector(v.pList);

                for (int i = 0; i < v.pList.Count; i++)
                {
                    mid = MathEx.GetMidPointF(v.pList[i], v.pList[(i + 1) % 3]);

                    /* 將邊無限延伸的做法 */
                    v.vList.Add(new Edge(triEx, mid.Add(MathEx.GetNormalVector(v.pList[i], v.pList[(i + 1) % 3]).Multi(600)), v.pList[i], v.pList[(i + 1) % 3]));

                    /* 將邊畫到邊界的做法
                     * v.vList.Add(new Edge(triEx, GetSidePointF(mid, mid.Add(MathEx.GetNormalVector(v.pList[i], v.pList[(i + 1) % 3])))));
                     */
                }
            }
            return(v);
        }
Пример #4
0
        /// <summary>
        /// 取得上下切線
        /// </summary>
        /// <param name="pListL">左半部的點集合</param>
        /// <param name="pListR">左半部的點集合</param>
        /// <returns>上下切線</returns>
        public List <Edge> GetTangent(List <PointF> pListL, List <PointF> pListR)
        {
            List <Edge>   tangent = new List <Edge>();
            List <PointF> pList   = new List <PointF>();
            List <PointF> chList;

            pList.AddRange(pListL);
            pList.AddRange(pListR);
            pList  = MathEx.SortPointF(pList);
            chList = MathEx.GetConvexHull(pList);

            for (int i = 0; i < chList.Count; i++)
            {
                if ((pListL.Contains(chList[i]) && pListR.Contains(chList[(i + 1) % chList.Count])) || (pListR.Contains(chList[i]) && pListL.Contains(chList[(i + 1) % chList.Count])))
                {
                    tangent.Add(new Edge(chList[i], chList[(i + 1) % chList.Count]));
                }
            }

            record.Add(new Record(chList, tangent, CONVEX_HULL, true));
            return(tangent);
        }
Пример #5
0
        private void Step()
        {
            if (record.Count <= 0 || stepIndex > record.Count - 1)
            {
                /* 初始化 */
                v.pList.Clear();
                v.vList.Clear();
                record.Clear();
                stepIndex = 0;

                /* 排序點 */
                pList = MathEx.SortPointF(pList);

                /* 畫 Voronoi Diagram */
                v = VoronoiMultiPoint(pList);
            }

            /* 初始畫布建置 */
            ClearPaint();
            foreach (PointF i in pList)
            {
                DrawPointF(i, Color.DarkRed);
            }

            /* 隱藏特定紀錄 */
            if (record[stepIndex].type == VORONOI)
            {
                if (record[stepIndex].clear)
                {
                    record[stepIndex - 2].enable = false;
                    int count = 0;
                    for (int i = stepIndex - 1; i >= 0 && count < 2; i--)
                    {
                        if ((record[i].type == MERGE || record[i].type == VORONOI) && record[i].enable == true)
                        {
                            record[i].enable = false;
                            count++;
                        }
                    }
                }
            }
            else if (record[stepIndex].type == CONVEX_HULL)
            {
                if (record[stepIndex].clear)
                {
                    record[stepIndex - 1].enable = false;
                    record[stepIndex - 2].enable = false;
                }
            }
            else if (record[stepIndex].type == MERGE)
            {
                if (record[stepIndex].clear)
                {
                    record[stepIndex - 1].enable = false;
                    record[stepIndex - 2].enable = false;
                }
            }

            /* 畫紀錄 */
            for (int i = 0; i <= stepIndex; i++)
            {
                if (record[i].enable)
                {
                    DrawRecord(record[i]);
                }
                else
                {
                    continue;
                }
            }

            /* 重置步驟數 */
            if (stepIndex < record.Count)
            {
                stepIndex++;
            }
            else
            {
                stepIndex = 0;
            }
        }