/// <summary> /// 画多边形的最后一条边 /// </summary> /// <param name="color">当前边的颜色</param> /// <param name="name">名称</param> /// <return>true:成功构成多边形; false:多边形自相交或顶点过少</return> public bool drawLastEdge(Color color, string name) { if (curPolygon.nVertex >= 3) { if (curPolygon.isSelfIntersect() == true) { MessageBox.Show("多边形自相交!"); return(false); } else { Point v1 = curPolygon.getLast(); Point v2 = curPolygon.getFirst(); curPolygon.changeVertexOrder(); drawLine_Bresenham(v1, v2, color); curPolygon.Name = name; listPolygon.AddLast(curPolygon); return(true); } } else { MessageBox.Show("顶点数不足3个,无法构成多边形!"); return(false); } }
/// <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); } }