/// <summary> /// 对当前输入的直线,在直线列表中创建图元,并画出来 /// </summary> /// <param name="pStart">直线起点</param> /// <param name="pEnd">直线终点</param> /// <param name="color">直线颜色</param> /// <param name="name">直线的名称</param> public void drawLine_Bresenham(Point pStart, Point pEnd, Color color, string name) { CG_Line newLine = new CG_Line(pStart, pEnd, color); newLine.Name = name; listLine.AddLast(newLine); curLine = newLine; drawLine_Bresenham(pStart, pEnd, color); }
/// <summary> /// 对当前输入的直线,使用Bresenham算法画出图像 /// </summary> /// <param name="pStart">直线起点</param> /// <param name="pEnd">直线终点</param> /// <param name="color">直线颜色</param> public void drawLine_Bresenham(Point pStart, Point pEnd, Color color) { CG_Line newLine = new CG_Line(pStart, pEnd, color); foreach (Point cur in newLine.getPoints()) { drawOnCanvas(cur, 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> /// 使用Liang-Barsky算法裁剪线段,裁剪窗口为矩形 /// </summary> /// <param name="line">待裁剪的线段</param> /// <param name="window">裁剪窗口</param> /// <returns>裁剪完后的线段</returns> public CG_Line clipLines_LiangBarsky(CG_Line line, CG_Rectangle window) { /* * 设直线为(x0,y0)->(x1,y1) * 参数化表示为 * x=x0+u(x1-x0) * y=y0+u(y1-y0) * 裁剪条件为 * xmin<=x0+u(x1-x0)<=xmax * ymin<=y0+u(y1-y0)<=ymax * 可统一表示为u*pk<=qk (k=0,1,2,3 * 根据pk和qk可以求得裁剪线段的端点 * */ //直线的参数 int x0, y0, x1, y1; x0 = line.Param.start.X; y0 = line.Param.start.Y; x1 = line.Param.end.X; y1 = line.Param.end.Y; //裁剪窗口的边界 int xmin, xmax, ymin, ymax; xmin = window.Left; xmax = window.Right; ymin = window.Bottom; ymax = window.Top; int[] p = new int[4]; int[] q = new int[4]; p[0] = -1 * (x1 - x0); q[0] = x0 - xmin; //left p[1] = x1 - x0; q[1] = xmax - x0; //right p[2] = -1 * (y1 - y0); q[2] = y0 - ymin; //bottom p[3] = y1 - y0; q[3] = ymax - y0; //top double u1 = 0, u2 = 1; //初始裁剪端点为原线段的端点 for (int k = 0; k < 4; k++) { if (p[k] == 0 && q[k] < 0) { return(null); //线段完全在边界外部 } double r = Convert.ToDouble(q[k]) / Convert.ToDouble(p[k]); if (p[k] < 0) { if (r > u1) { u1 = r; } } else//pk>0 { if (r < u2) { u2 = r; } } } if (u1 > u2) { return(null); } Point q0 = new Point(x0 + Convert.ToInt32(u1 * (x1 - x0)), y0 + Convert.ToInt32(u1 * (y1 - y0))); Point q1 = new Point(x0 + Convert.ToInt32(u2 * (x1 - x0)), y0 + Convert.ToInt32(u2 * (y1 - y0))); CG_Line clippedLine = new CG_Line(q0, q1, line.Param.color); return(clippedLine); }