コード例 #1
0
ファイル: Canvas.cs プロジェクト: againcy/CG_Exp_2d
        /// <summary>
        /// 判断点是否在当前多边形内
        /// </summary>
        /// <param name="p">坐标</param>
        public void checkInPolygon(Point p)
        {
            if (curPolygon == null)
            {
                return;
            }
            string str = "";

            if (curPolygon.isInPolygon(p) == true)
            {
                str = "在内部";
            }
            else
            {
                str = "不在内部";
            }
            MessageBox.Show(str);
        }
コード例 #2
0
ファイル: Canvas.cs プロジェクト: againcy/CG_Exp_2d
        /// <summary>
        /// 双边裁剪
        /// </summary>
        /// <param name="target">目标多边形</param>
        /// <param name="window">裁剪窗口多边形</param>
        /// <returns></returns>
        public CG_Polygon[] clipPolygon_WeilerAtherton(CG_Polygon target, CG_Polygon window)
        {
            Point t_first, t_prev, t_cur; //target
            Point w_first, w_prev, w_cur; //window
            Point tmp;

            //将两多边形裁剪相关的成员链表清空防止之前的裁剪影响本次
            if (target.clipVertex != null)
            {
                target.clipVertex.Clear();
            }
            if (window.clipVertex != null)
            {
                window.clipVertex.Clear();
            }
            if (target.intersections != null)
            {
                target.intersections.Clear();
            }
            if (window.intersections != null)
            {
                window.intersections.Clear();
            }
            target.intersections = new LinkedList <CG_Polygon.tagIntersections>();
            window.intersections = new LinkedList <CG_Polygon.tagIntersections>();

            //求出两多边形的交点列表
            t_first = target.getVertex();
            t_prev  = t_first;
            t_cur   = target.getVertex();
            do
            {
                bool isIn = window.isInPolygon(t_prev);//目标多边形边的始点是否在窗口内部
                w_first = window.getVertex();
                w_prev  = w_first;
                w_cur   = window.getVertex();
                do
                {
                    if (Tool.isCross(t_prev, t_cur, w_prev, w_cur) == true)
                    {
                        tmp = Tool.crossPoint(t_prev, t_cur, w_prev, w_cur);
                        target.addIntersections(tmp, t_prev, t_cur, isIn);
                        window.addIntersections(tmp, w_prev, w_cur, isIn);
                    }
                    w_prev = w_cur;
                    w_cur  = window.getVertex();
                } while (w_prev != w_first);
                t_prev = t_cur;
                t_cur  = target.getVertex();
            } while (t_prev != t_first);

            //将顶点加入到多边形的顶点列表中
            target.setClipVertex();
            window.setClipVertex();
            LinkedListNode <CG_Polygon.tagClipVertex> tclip_cur = target.clipVertex.First;
            LinkedListNode <CG_Polygon.tagClipVertex> wclip_cur;

            while (tclip_cur != null)
            {
                if (tclip_cur.Value.isIntersection == true)
                {
                    wclip_cur = window.clipVertex.First;
                    while (wclip_cur != null)
                    {
                        if (wclip_cur.Value.isIntersection == true && wclip_cur.Value.v == tclip_cur.Value.v)
                        {
                            CG_Polygon.tagClipVertex tmp3 = tclip_cur.Value;
                            LinkedListNode <CG_Polygon.tagClipVertex> prev = wclip_cur.Previous;
                            window.clipVertex.Remove(wclip_cur);
                            if (prev != null)
                            {
                                window.clipVertex.AddAfter(prev, tmp3);
                            }
                            else
                            {
                                window.clipVertex.AddFirst(tmp3);
                            }
                            break;
                        }
                        wclip_cur = wclip_cur.Next;
                    }
                }
                tclip_cur = tclip_cur.Next;
            }

            LinkedList <CG_Polygon> resultPolygon = new LinkedList <CG_Polygon>();//存放结果多边形的多边形列表
            //开始裁剪
            LinkedListNode <CG_Polygon.tagClipVertex> inter = target.findUnTracked();

            //寻找一个没有被跟踪过的交点
            while (inter != null)
            {
                CG_Polygon newPolygon = new CG_Polygon(Color.Red);

                LinkedListNode <CG_Polygon.tagClipVertex> newNode = inter;
                bool polygonFinish  = false; //若已搜索到一个封闭多边形则为true
                bool trackingTarget = true;  //记录当前沿哪一个窗口边界进行跟踪
                while (polygonFinish == false)
                {
                    target.setTracked(newNode.Value.v);
                    window.setTracked(newNode.Value.v);
                    if (newPolygon.addVertex(newNode.Value.v) == false)
                    {
                        polygonFinish = true;
                        break;
                    }
                    if (newNode.Value.isIn == true)
                    {
                        //交点为入点,则沿目标多边形边界跟踪
                        newNode        = target.findByPoint(newNode.Value.v);
                        trackingTarget = true;
                    }
                    else
                    {
                        //交点为出点,沿窗口多边形边界跟踪
                        newNode        = window.findByPoint(newNode.Value.v);
                        trackingTarget = false;
                    }
                    newNode = newNode.Next;
                    if (newNode == null)
                    {
                        if (trackingTarget == true)
                        {
                            newNode = target.clipVertex.First;
                        }
                        else
                        {
                            newNode = window.clipVertex.First;
                        }
                    }

                    while (newNode != null && newNode.Value.isIntersection == false)
                    {
                        if (newPolygon.addVertex(newNode.Value.v) == true)
                        {
                            newNode = newNode.Next;
                            if (newNode == null)
                            {
                                if (trackingTarget == true)
                                {
                                    newNode = target.clipVertex.First;
                                }
                                else
                                {
                                    newNode = window.clipVertex.First;
                                }
                            }
                        }
                        else
                        {
                            polygonFinish = true;
                            break;
                        }
                    }
                }
                resultPolygon.AddLast(newPolygon);
                inter = target.findUnTracked();
            }

            //返回结果多边形列表
            if (resultPolygon.Count == 0)
            {
                CG_Polygon[] ret;
                //无交点,结果多边形列表为空
                if (window.isInPolygon(target.getFirst()) == true)
                {
                    //目标多边形完全在裁剪窗口内部
                    ret    = new CG_Polygon[1];
                    ret[0] = target;
                    return(ret);
                }
                if (target.isInPolygon(window.getFirst()) == true)
                {
                    //裁剪窗口完全在目标多边形内部
                    ret    = new CG_Polygon[1];
                    ret[0] = window;
                    return(ret);
                }
                return(null);
            }
            else
            {
                CG_Polygon[] ret = new CG_Polygon[resultPolygon.Count];
                int          n   = resultPolygon.Count;
                for (int i = 0; i < n; i++)
                {
                    ret[i] = resultPolygon.First();
                    resultPolygon.RemoveFirst();
                }
                return(ret);
            }
        }