//函数——判断两个三角形是否有公共边 public bool JudgeSame(triangle t1, triangle t2) { bool same = true; for (int i = 0; i < t1.Ts.Count; i++) //t1的三条边 { for (int j = 0; j < t2.Ts.Count; j++) //t2的三条边 { if ((t1.Ts[i].Sp[0].x == t2.Ts[j].Sp[0].x && t1.Ts[i].Sp[0].y == t2.Ts[j].Sp[0].y && t1.Ts[i].Sp[1].x == t2.Ts[j].Sp[1].x && t1.Ts[i].Sp[1].y == t2.Ts[j].Sp[1].y) || (t1.Ts[i].Sp[0].x == t2.Ts[j].Sp[1].x && t1.Ts[i].Sp[0].y == t2.Ts[j].Sp[1].y && t1.Ts[i].Sp[1].x == t2.Ts[j].Sp[0].x && t1.Ts[i].Sp[1].y == t2.Ts[j].Sp[0].y)) { SameSide = t1.Ts[i]; SameSide1 = t2.Ts[j]; same = true; break; } else { same = false; } } if (same) { break; } } return(same); }
//三角形内插,找到高程为h的所有三角形 public void Tri_Intp(double h) { List <triangle> LT = new List <triangle>(); LT.AddRange(T1); //寻找高程为“h”的等高线穿过的所有三角形 for (int i = 0; i < LT.Count; i++) { if (Is_Between(h, LT[i].Ts[0]) && Is_Between(h, LT[i].Ts[1]) || Is_Between(h, LT[i].Ts[2])) { Intpedgs.Add(LT[i]); } } //删除只有一个顶点被穿过的三角形 List <triangle> Dt1 = new List <triangle>(); for (int i = 0; i < Intpedgs.Count; i++) { if (Intpedgs[i].Tp[0].z == h || Intpedgs[i].Tp[1].z == h || Intpedgs[i].Tp[2].z == h) { side Ls = new side(); Ls.Sp = new List <point>(); if (Intpedgs[i].Tp[0].z == h) { Ls.Sp.Add(Intpedgs[i].Tp[1]); Ls.Sp.Add(Intpedgs[i].Tp[2]); } else if (Intpedgs[i].Tp[1].z == h) { Ls.Sp.Add(Intpedgs[i].Tp[0]); Ls.Sp.Add(Intpedgs[i].Tp[2]); } else if (Intpedgs[i].Tp[2].z == h) { Ls.Sp.Add(Intpedgs[i].Tp[0]); Ls.Sp.Add(Intpedgs[i].Tp[1]); } if (!(Is_Between(h, Ls))) { Dt1.Add(Intpedgs[i]); } } } for (int i = 0; i < Dt1.Count; i++) { Intpedgs.Remove(Dt1[i]); } }
//判断三角形的一条边中是否存在等值点 public bool Is_Between(double h, side S) { bool Is = true; if ((h - S.Sp[0].z) * (h - S.Sp[1].z) <= 0) { Is = true; } else { Is = false; } return(Is); }
public point Line_Intp(double h, side S) { point p = new point(); double x = 0, y = 0; double x1, y1, z1, x2, y2, z2; if (S.Sp[0].z == h || S.Sp[1].z == h) { if (S.Sp[0].z == h) { p = S.Sp[0]; } else { p = S.Sp[1]; } dp = 1; } else { x1 = S.Sp[0].x; y1 = S.Sp[0].y; z1 = S.Sp[0].z; x2 = S.Sp[1].x; y2 = S.Sp[1].y; z2 = S.Sp[1].z; x = x1 + (x2 - x1) / (z2 - z1) * (h - z1); y = y1 + (y2 - y1) / (z2 - z1) * (h - z1); p.x = x; p.y = y; p.z = h; dp = 0; } return(p); }
//构建初始三角网 public void BuildInitialTin() { int a = CP.Count; for (int i = 0; i < PO.Count - 1; i++) { side l1 = new side(); side l2 = new side(); side l3 = new side(); l1.Sp = new List <point>(); l2.Sp = new List <point>(); l3.Sp = new List <point>(); triangle t1 = new triangle(); t1.Ts = new List <side>(); t1.Tp = new List <point>(); t1.Tp.Add(PO[i]); t1.Tp.Add(PO[i + 1]); t1.Tp.Add(CP[0]); l1.Sp.Add(PO[i]); l1.Sp.Add(PO[i + 1]); l2.Sp.Add(PO[i + 1]); l2.Sp.Add(CP[0]); l3.Sp.Add(PO[i]); l3.Sp.Add(CP[0]); t1.Ts.Add(l1); t1.Ts.Add(l2); t1.Ts.Add(l3); T1.Add(t1); } }
//等高线的追踪——(一个高程值) public void Puesr(double h) { Intpedgs.Clear(); Tri_Intp(h); //判断开曲线是否转向 bool flag = false; //起始边 side Str_Line = new side(); point Str_Point = new point(); //离去边 side Leave_Line = new side(); side L1 = new side(); side L2 = new side(); //设立标记数组 int[] Tri_Note = new int[Intpedgs.Count]; for (int i = 0; i < Intpedgs.Count; i++) { Tri_Note[i] = 0; } point p1 = new point(); //遍历高程为"h"的等高线所穿过的三角形 for (int i = 0; i < Intpedgs.Count; i++) { if (Tri_Note[i] == 0) { H_p.Clear(); flag = false; //寻找搜索起点 if (Is_Between(h, Intpedgs[i].Ts[0])) { Str_Line = Intpedgs[i].Ts[0]; L1 = Intpedgs[i].Ts[1]; L2 = Intpedgs[i].Ts[2]; } else if (Is_Between(h, Intpedgs[i].Ts[1])) { Str_Line = Intpedgs[i].Ts[1]; L1 = Intpedgs[i].Ts[0]; L2 = Intpedgs[i].Ts[2]; } else { Str_Line = Intpedgs[i].Ts[2]; L1 = Intpedgs[i].Ts[0]; L2 = Intpedgs[i].Ts[1]; } Tri_Note[i] = 1; //对处理过的三角形标记,以后不再处理 p1 = Line_Intp(h, Str_Line); H_p.Add(p1); //寻找离去边 point p12 = new point(); //过三角形顶点 if (dp == 1) { if (L1.Sp.Contains(p1)) { Leave_Line = L2; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } else if (L2.Sp.Contains(p1)) { Leave_Line = L1; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } } else { if (Is_Between(h, L1)) { Leave_Line = L1; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } else { Leave_Line = L2; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } if (dp == 1) { Str_Point = p12; for (int look = 0; look < Intpedgs.Count; look++) { if (Tri_Note[look] == 0) { //找相邻三角形 if (Intpedgs[look].Tp.Contains(Str_Point)) { //找离去边 if (Intpedgs[look].Ts[0].Sp.Contains(Str_Point)) { Leave_Line = Intpedgs[look].Ts[0]; } else if (Intpedgs[look].Ts[1].Sp.Contains(Str_Point)) { Leave_Line = Intpedgs[look].Ts[1]; } else { Leave_Line = Intpedgs[look].Ts[2]; } break; } } } } } //进入相邻三角形 bool Finish = true; //判断一条等高线是否寻找完成 int t = 0; while (Finish) { //寻找相邻三角形 if (Tri_Note[t] == 0) { //三角形定位 if (Intpedgs[t].Tp.Contains(Leave_Line.Sp[0]) && Intpedgs[t].Tp.Contains(Leave_Line.Sp[1])) { Tri_Note[t] = 1; //确定进入边 if (Intpedgs[t].Ts[0].Sp.Contains(Leave_Line.Sp[0]) && Intpedgs[t].Ts[0].Sp.Contains(Leave_Line.Sp[1])) { L1 = Intpedgs[t].Ts[1]; L2 = Intpedgs[t].Ts[2]; } else if (Intpedgs[t].Ts[1].Sp.Contains(Leave_Line.Sp[0]) && Intpedgs[t].Ts[1].Sp.Contains(Leave_Line.Sp[1])) { L1 = Intpedgs[t].Ts[0]; L2 = Intpedgs[t].Ts[2]; } else { L1 = Intpedgs[t].Ts[0]; L2 = Intpedgs[t].Ts[1]; } //寻找离去边 if (dp == 1) { if (L1.Sp.Contains(p12)) { Leave_Line = L2; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } else if (L2.Sp.Contains(p12)) { Leave_Line = L1; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } } else { if (Is_Between(h, L1)) { Leave_Line = L1; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } else { Leave_Line = L2; p12 = Line_Intp(h, Leave_Line); H_p.Add(p12); } if (dp == 1) { Str_Point = p12; for (int look = 0; look < Intpedgs.Count; look++) { if (Tri_Note[look] == 0) { //找相邻三角形 if (Intpedgs[look].Tp.Contains(Str_Point)) { //找离去边 if (Intpedgs[look].Ts[0].Sp.Contains(Str_Point)) { Leave_Line = Intpedgs[look].Ts[0]; } else if (Intpedgs[look].Ts[1].Sp.Contains(Str_Point)) { Leave_Line = Intpedgs[look].Ts[1]; } else { Leave_Line = Intpedgs[look].Ts[2]; } break; } } } } } t = -1; } } //闭曲线 if ((H_p[0].x == H_p[H_p.Count - 1].x) && (H_p[0].y == H_p[H_p.Count - 1].y)) { break; } //开曲线 else { if (t == Intpedgs.Count - 1 && flag == false) { //将开曲线转向 H_p.Reverse(); Leave_Line = Str_Line; flag = true; t = -1; } } if (t == Intpedgs.Count - 1) { break; } t += 1; } contour Contour1 = new contour(); Contour1.C = new List <point>(); Contour1.C.AddRange(H_p); Contour.Add(Contour1); int a = Contour.Count; } } }
//生成平面三角网 public void BuildPlaneTIN() { //循环点 for (int i = 1; i < CP.Count; i++) { int T1count = T1.Count; List <triangle> T3 = new List <triangle>(); //找出所有外接圆包含P的三角形 for (int j = 0; j < T1count; j++) { if (JudgeInTriangle(CP[i], T1[j])) { T3.Add(T1[j]); } } //定位 List <triangle> FT = new List <triangle>(); for (int k = 0; k < T3.Count; k++) { if (PinT(CP[i], T3[k])) { FT.Add(T3[k]); T3.Remove(T3[k]); break; } } if (FT.Count > 0) { if (T3.Count > 0) { int[] Tnote = new int[T3.Count]; //设立标志数组 for (int t = 0; t < T3.Count; t++) { Tnote[t] = 0; } int v = 0; int num = 0; bool F = true; while (F) { if (Tnote[v] == 0) { for (int vv = 0; vv < FT.Count; vv++) { if (JudgeSame(T3[v], FT[vv])) { FT.Add(T3[v]); Tnote[v] = 1; v = -1; break; } else { num = vv; } } if (v == (T3.Count - 1) && num == (FT.Count - 1)) { F = false; } } v += 1; if (v == T3.Count) { F = false; } } } //将三角形加入到T2中 T2.AddRange(FT); //移除T1中三角形; for (int y = 0; y < T2.Count; y++) { T1.Remove(T2[y]); } //寻找公共边 for (int t2 = 0; t2 < T2.Count - 1; t2++) //第一个三角形 { int ii = t2 + 1; //其余三角形 while (ii <= T2.Count - 1) { if (JudgeSame(T2[t2], T2[ii])) { //移除公共边 T2[t2].Ts.Remove(SameSide); T2[ii].Ts.Remove(SameSide1); } ii += 1; } } //将剩下的边添加到S中 S.Clear(); for (int a1 = 0; a1 < T2.Count; a1++) { for (int a2 = 0; a2 < T2[a1].Ts.Count; a2++) { S.Add(T2[a1].Ts[a2]); } } //清空T2 T2.Clear(); //生成新的三角形并添加到T1中 for (int a3 = 0; a3 < S.Count; a3++) { side s0 = new side(); side s1 = new side(); side s2 = new side(); triangle t = new triangle(); //实例化 s0.Sp = new List <point>(); s1.Sp = new List <point>(); s2.Sp = new List <point>(); t.Tp = new List <point>(); t.Ts = new List <side>(); //三个顶点 t.Tp.Add(S[a3].Sp[0]); t.Tp.Add(S[a3].Sp[1]); t.Tp.Add(CP[i]); //三条边 s0 = S[a3]; s1.Sp.Add(S[a3].Sp[1]); s1.Sp.Add(CP[i]); s2.Sp.Add(S[a3].Sp[0]); s2.Sp.Add(CP[i]); t.Ts.Add(s0); t.Ts.Add(s1); t.Ts.Add(s2); T1.Add(t); } } } }