/// <summary> /// 判断新加入的点会不会是边界产生自相交,是则进行修改 /// </summary> /// <param name="ipc"></param> /// <param name="point"></param> /// <returns></returns> public bool Alter(ref VertexCollection ipc, Vertex point) { int count = ipc.Count; if (count >= 3) { bool flag = false; int index = count - 1; for (int i = index - 1; i >= 1; i--) { if (InsectionJudge(ipc.getVer(index), point, ipc.getVer(i), ipc.getVer(i - 1))) { flag = true; index = i; break; } } if (flag) { Vertex insectp = Inter(ipc.getVer(count - 1), point, ipc.getVer(index), ipc.getVer(index - 1)); ipc.removeVers(index, count - index); ipc.addVer(insectp); } } return(true); }
/// <summary> /// 根据给定的一系列有顺序的坐标,逆时针生成轴线左侧的缓冲区边界点 /// </summary> /// <param name="coords">一系列有顺序的坐标</param> /// <param name="radius">缓冲区半径</param> /// <returns>缓冲区的边界坐标</returns> public VertexCollection GetLeftBufferEdgeCoords(VertexCollection coords, double radius) { VertexCollection polyline = new VertexCollection(); Vertex point = new Vertex(); //计算时所需变量 double alpha = 0.0; //向量绕起始点沿顺时针方向旋转到X轴正半轴所扫过的角度 double delta = 0.0; //前后线段所形成的向量之间的夹角 double l = 0.0; //前后线段所形成的向量的叉积 //辅助变量 double startRadian = 0.0; double endRadian = 0.0; double beta = 0.0; double x = 0.0, y = 0.0; //中间节点 for (int i = 1; i < coords.Count - 1; i++) { alpha = GetQuadrantAngle(coords.getVer(i), coords.getVer(i + 1)); delta = GetIncludedAngle(coords.getVer(i - 1), coords.getVer(i), coords.getVer(i + 1)); l = GetVectorProduct(coords.getVer(i - 1), coords.getVer(i), coords.getVer(i + 1)); if (l > 0)//凸 { startRadian = alpha + (3 * Math.PI) / 2 - delta; endRadian = alpha + (3 * Math.PI) / 2; VertexCollection ipc1 = GetBufferCoordsByRadian(coords.getVer(i), startRadian, endRadian, radius); for (int j = 0; j < ipc1.Count; j++) { if (ipc1.getVer(j).X() > 0) { } Alter(ref polyline, ipc1.getVer(j)); polyline.addVer(ipc1.getVer(j)); } } else if (l < 0) { beta = alpha - (Math.PI - delta) / 2; x = Math.Round(coords.getVer(i).X() + radius * Math.Cos(beta), 2); y = Math.Round(coords.getVer(i).Y() + radius * Math.Sin(beta), 2); Vertex ipoint = new Vertex(); ipoint.X(x); ipoint.Y(y); if (ipoint.X() > 0) { } Alter(ref polyline, ipoint); polyline.addVer(ipoint); } } return(polyline); }
/// <summary> /// 建立矩形包围点集 /// </summary> /// <param name="outRing"></param> /// <returns></returns> private static Vertex[] createSuperRectangle(VertexCollection outRing) { Vertex[] rectangle = new Vertex[4];//左上,右上,左下,右下 rectangle[0] = new Vertex(); rectangle[1] = new Vertex(); rectangle[2] = new Vertex(); rectangle[3] = new Vertex(); double minX = 100000000, maxX = 0.0, minY = 100000000, maxY = 0.0; for (int i = 0; i < outRing.Count; ++i) { Vertex ver = outRing.getVer(i); if (ver.X() < minX) { minX = ver.X(); } if (ver.X() > maxX) { maxX = ver.X(); } if (ver.Y() < minY) { minY = ver.Y(); } if (ver.Y() > maxY) { maxY = ver.Y(); } } rectangle[0].X(minX - (maxX - minX) / 10); rectangle[0].Y(maxY + (maxY - minY) / 10); rectangle[0].ID = 10000; rectangle[1].X(maxX + (maxX - minX) / 10); rectangle[1].Y(maxY + (maxY - minY) / 10); rectangle[1].ID = 10001; rectangle[2].X(minX - (maxX - minX) / 10); rectangle[2].Y(minY - (maxY - minY) / 10); rectangle[2].ID = 10002; rectangle[3].X(maxX + (maxX - minX) / 10); rectangle[3].Y(minY - (maxY - minY) / 10); rectangle[3].ID = 10003; return(rectangle); }
public void addVerCollection(VertexCollection vers) { int num = vers.Count; for (int i = 0; i < num; ++i) { this.addVer(vers.getVer(i)); } }
/// <summary> /// 执行线要素的反转 /// </summary> /// <param name="ipc"></param> /// <returns></returns> public VertexCollection Reverse(VertexCollection ipc) { VertexCollection ipc0 = new VertexCollection(); for (int i = ipc.Count - 1; i >= 0; i--) { ipc0.addVer(ipc.getVer(i)); } return(ipc0); }
/// <summary> /// 后处理,删去多余三角形,调整法向 /// </summary> /// <param name="tris"></param> /// <param name="outRing"></param> /// <param name="inRing"></param> private static void postTreatment(ref SortedList <string, Triangle> tris, VertexCollection outRing, VertexCollection inRing) { int minOutRingID = outRing.getVer(0).ID; int maxOutRingID = outRing.getVer(outRing.Count - 1).ID; int minInRingID = 0 != inRing.Count ? inRing.getVer(0).ID : 0; int maxInRingID = 0 != inRing.Count ? inRing.getVer(inRing.Count - 1).ID : 0; Triangle tri; int i; List <String> nameOFTriRemoved = new List <string>(); for (i = 0; i < tris.Count; ++i) { tri = tris.Values[i]; //删去与超级矩形顶点有关的三角形、内环内的三角形、外环外的三角形 if (tri.hasVer(10000) || tri.hasVer(10001) || tri.hasVer(10002) || tri.hasVer(10003) || (0 != inRing.Count && tri.pointsOnRing(minInRingID, maxInRingID) && tri.calVector() < 0.0) || (tri.pointsOnRing(minOutRingID, maxOutRingID) && tri.calVector() > 0.0)) { nameOFTriRemoved.Add(tri.name); } //调整三角形法向 else if (!UpOrDown && tri.calVector() > 0.0) { tri.reverse(); } else if (UpOrDown && tri.calVector() < 0.0) { tri.reverse(); } } //执行删除 for (i = 0; i < nameOFTriRemoved.Count; ++i) { tris.Remove(nameOFTriRemoved[i]); } }
/// <summary> /// 由多边形顶点生成三角网 /// </summary> /// <param name="tris"></param> /// <param name="vc"></param> /// <param name="rectangle"></param> /// <param name="cavity"></param> /// <param name="edges"></param> private static VertexCollection insertVC2Tris(ref SortedList <string, Triangle> tris, VertexCollection vc, Vertex[] rectangle, SortedList <string, Triangle> cavity, List <Edge> edges) { if (null == vc) { return(null); } Triangle tri; int i = 0, j; VertexCollection vcInner = new VertexCollection(); if (0 == tris.Count) { //第一个点连接矩形顶点 Vertex ver0 = vc.getVer(0); Triangle[] triOfRectangle = new Triangle[4]; triOfRectangle[0] = new Triangle(); triOfRectangle[1] = new Triangle(); triOfRectangle[2] = new Triangle(); triOfRectangle[3] = new Triangle(); triOfRectangle[0].addPoint(ver0); triOfRectangle[0].addPoint(rectangle[1]); triOfRectangle[0].addPoint(rectangle[0]); tris.Add(triOfRectangle[0].name, triOfRectangle[0]); triOfRectangle[1].addPoint(ver0); triOfRectangle[1].addPoint(rectangle[3]); triOfRectangle[1].addPoint(rectangle[1]); tris.Add(triOfRectangle[1].name, triOfRectangle[1]); triOfRectangle[2].addPoint(ver0); triOfRectangle[2].addPoint(rectangle[2]); triOfRectangle[2].addPoint(rectangle[3]); tris.Add(triOfRectangle[2].name, triOfRectangle[2]); triOfRectangle[3].addPoint(ver0); triOfRectangle[3].addPoint(rectangle[0]); triOfRectangle[3].addPoint(rectangle[2]); tris.Add(triOfRectangle[3].name, triOfRectangle[3]); ++i; } //将地层顶点插入三角网中 for (; i < vc.Count; ++i) { Vertex verInserted = vc.getVer(i); if (!verInserted.innerPoint) { for (j = 0; j < tris.Count; ++j) { tri = tris.Values[j]; Vertex circumcenter = tri.calCircumCenter(); //点在三角形外接圆中 if (verInserted.calDistance(circumcenter) <= tri.points.getVer(0).calDistance(circumcenter)) { //广度遍历得到空腔 findCavity(verInserted, tri, tris, cavity, edges); //由空腔生成新三角形 createTriByCavity(verInserted, ref tris, cavity, edges); break; } } } else { for (j = 0; j < tris.Count; ++j) { tri = tris.Values[j]; //判断点在三角形中 if (verInserted.inside(tri)) { verInserted.ID = ++idxInnerPoint; vcInner.addVer(verInserted); //广度遍历得到空腔 findCavity(verInserted, tri, tris, cavity, edges); //由空腔生成新三角形 createTriByCavity(verInserted, ref tris, cavity, edges); break; } } } } //插入内部点后调整三角面法向 if (0 != vc.Count && vc.getVer(0).innerPoint) { for (i = 0; i < tris.Count; ++i) { tri = tris.Values[i]; if (tri.calVector() < 0.0) { tri.reverse(); } } } return(vcInner); }