/// <summary> /// 生成多边形的同时将其画出来 /// </summary> /// <param name="vertex">最新要插入的顶点</param> /// <param name="color">当前边的颜色</param> public void drawPolygon(Point vertex, Color color) { if (curPolygon == null) { curPolygon = new CG_Polygon(vertex, color); } else { if (curPolygon.nVertex > 0) { Point prep = curPolygon.getLast(); if (curPolygon.addVertex(vertex) == true) { drawLine_Bresenham(prep, vertex, color); } else { MessageBox.Show("加入的顶点不合法!"); } } else { curPolygon.addVertex(vertex); } } }
/// <summary> /// 对于已有的多边形,直接将其按顶点顺序绘制出来 /// </summary> /// <param name="polygon">多边形</param> public void drawPolygon(CG_Polygon polygon) { if (polygon.nVertex < 3) { return; } Point first, prep, cur; first = polygon.getVertex(); prep = first; cur = polygon.getVertex(); while (cur != first) { drawLine_Bresenham(prep, cur, polygon.Color); prep = cur; cur = polygon.getVertex(); } drawLine_Bresenham(prep, cur, polygon.Color); }
/// <summary> /// 根据顶点列表创建多边形,并绘制出来 /// </summary> /// <param name="vertice">顶点集合</param> /// <param name="color">颜色</param> public void createPolygon(Point[] vertice, Color color) { CG_Polygon newPolygon = null; int count = 0; foreach (Point v in vertice) { count++; if (count == 1) { newPolygon = new CG_Polygon(v, color); } else { newPolygon.addVertex(v); } } if (count < 3) { MessageBox.Show("多边形顶点数不能小于3!"); return; } else { Point head = newPolygon.getVertex(); Point tail = newPolygon.getVertex(); Point prep = head; while (tail != head) { drawLine_Bresenham(prep, tail, color); prep = tail; tail = newPolygon.getVertex(); } drawLine_Bresenham(prep, tail, color); } }
/// <summary> /// 根据名称改变当前curXXX所指向的图元,返回值表示所选中的图元类型 /// </summary> /// <param name="name">名称</param> /// <returns>line直线 circle圆 polygon多边形 rectangle矩形</returns> public string changeCurPrimitive(string name) { LinkedListNode <CG_Line> curL = listLine.First; while (curL != null) { if (curL.Value.Name == name) { curLine = curL.Value; return("line"); } curL = curL.Next; } LinkedListNode <CG_Circle> curC = listCircle.First; while (curC != null) { if (curC.Value.Name == name) { curCircle = curC.Value; return("circle"); } curC = curC.Next; } LinkedListNode <CG_Polygon> curPol = listPolygon.First; while (curPol != null) { if (curPol.Value.Name == name) { curPolygon = curPol.Value; return("polygon"); } curPol = curPol.Next; } LinkedListNode <CG_Rectangle> curRec = listRectangle.First; while (curRec != null) { if (curRec.Value.Name == name) { curRectangle = curRec.Value; return("rectangle"); } curRec = curRec.Next; } LinkedListNode <CG_Bezier> curBez = listBezier.First; while (curBez != null) { if (curBez.Value.Name == name) { curBezier = curBez.Value; return("bezier"); } curBez = curBez.Next; } return(null); }
/// <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); } }