/// 求出每两个节点之间的中间节点 private static void NodesInter_Compute(ref WNode2D N1, ref WNode2D N2, double Res1, double Res2, int CI1, int CI2, int CI_max, ref double[] Res_Each, ref WNode2D[] Ns_O, ref int[] CIs_O, int[] CIs, double[] ERes) { int Q = Ns_O.Length; Q++; Array.Resize <WNode2D>(ref Ns_O, Q); Array.Resize <int>(ref CIs_O, Q); Ns_O[Q - 1] = N1; if (CI1 == CI_max) { CIs_O[Q - 1] = CI1 + 1; } else { CIs_O[Q - 1] = CI1; } if (CI1 == CI2) /////如果两头一样就不要继续了 { return; } double R1, R2, Ratio; if (CI2 > CI1) { for (int i = 1; i <= CI2 - CI1; i++) { R1 = Math.Abs(Res1 - Res_Each[CI1 + i]); R2 = Math.Abs(Res2 - Res_Each[CI1 + i]); Ratio = R1 / (R1 + R2); Q++; Array.Resize <WNode2D>(ref Ns_O, Q); Array.Resize <int>(ref CIs_O, Q); Ns_O[Q - 1] = new WNode2D(N1.X + (N2.X - N1.X) * Ratio, N1.Y + (N2.Y - N1.Y) * Ratio); CIs_O[Q - 1] = CI1 + i; } } if (CI2 < CI1) { for (int i = CI1 - CI2; i >= 1; i--) { R1 = Math.Abs(Res1 - Res_Each[CI2 + i]); R2 = Math.Abs(Res2 - Res_Each[CI2 + i]); Ratio = R1 / (R1 + R2); Q++; Array.Resize <WNode2D>(ref Ns_O, Q); Array.Resize <int>(ref CIs_O, Q); Ns_O[Q - 1] = new WNode2D(N1.X + (N2.X - N1.X) * Ratio, N1.Y + (N2.Y - N1.Y) * Ratio); CIs_O[Q - 1] = CI2 + i; } } }
/// 判断两点是否是同一点 /// <summary> /// 判断两点是否是同一点 /// </summary> /// <param name="P1"></param> /// <param name="P2"></param> /// <returns></returns> public static bool Near_Check(WPoint2D P1, WNode2D P2) { if ((Math.Abs(P1.X - P2.X) < WGeos2D_Paras.E_Merge) && (Math.Abs(P1.Y - P2.Y) < WGeos2D_Paras.E_Merge)) { return(true); } else { return(false); } }
/// 求单元的各种参数 /// <summary> /// 求单元的各种参数 /// </summary> private static void Compute_ElementParas(ref WMesh2D_Mesh Mesh, int EN, ref double[] RES, ref int[] Ns_CIs, ref double[] E_Rs, ref int[] E_CIs, ref WNode2D[] E_Ns) { int K = Mesh.Elements[EN].Kind; E_Rs = new double[K + 1]; E_Ns = new WNode2D[K + 1]; E_CIs = new int[K + 1]; /////为了循环方便,将最后0#节点数值复制到最后 E_Rs[0] = RES[Mesh.Elements[EN].N1]; E_Ns[0] = Mesh.Nodes[Mesh.Elements[EN].N1]; E_CIs[0] = Ns_CIs[Mesh.Elements[EN].N1]; E_Rs[1] = RES[Mesh.Elements[EN].N2]; E_Ns[1] = Mesh.Nodes[Mesh.Elements[EN].N2]; E_CIs[1] = Ns_CIs[Mesh.Elements[EN].N2]; E_Rs[2] = RES[Mesh.Elements[EN].N3]; E_Ns[2] = Mesh.Nodes[Mesh.Elements[EN].N3]; E_CIs[2] = Ns_CIs[Mesh.Elements[EN].N3]; if (K == 4) { E_Rs[3] = RES[Mesh.Elements[EN].N4]; E_Ns[3] = Mesh.Nodes[Mesh.Elements[EN].N4]; E_CIs[3] = Ns_CIs[Mesh.Elements[EN].N4]; } E_Rs[K] = E_Rs[0]; E_Ns[K] = E_Ns[0]; E_CIs[K] = E_CIs[0]; /////为了循环方便,将最后0#节点数值复制到最后 }
private static void PotentNs_App(ref List <WNode2D> Ns, ref List <WPoint2D>[] Ptts, double Potent_Lmax) { for (int i = 0; i < Ns.Count; i++) { /////低电势节点的标记 for (int j = 0; j <= Ptts[0].Count - 1; j++) { if (Math.Abs(Ns[i].X - Ptts[0][j].X) < Potent_Lmax && Math.Abs(Ns[i].Y - Ptts[0][j].Y) < Potent_Lmax) { Ns[i] = new WNode2D(Ns[i].Num, Ns[i].X, Ns[i].Y, -2000); } } //////高电势节点的标记 for (int j = 0; j <= Ptts[1].Count - 1; j++) { if (Math.Abs(Ns[i].X - Ptts[1][j].X) < Potent_Lmax && Math.Abs(Ns[i].Y - Ptts[1][j].Y) < Potent_Lmax) { Ns[i] = new WNode2D(Ns[i].Num, Ns[i].X, Ns[i].Y, 2000); } } } }
public void Add_N(WNode2D Node) { Nodes.Add(Node); Update_Bound(Node.X, Node.Y); }
/// 将单个节点转换为画图用的Point /// <summary> /// 将单个节点转换为画图用的Point /// </summary> /// <param name="Node"></param> /// <param name="Xmin"></param> /// <param name="Ymin"></param> /// <param name="Ratio"></param> /// <param name="Pic_YLim"></param> /// <returns></returns> private static Point Node_To_Point(ref WNode2D Node, double Xmin, double Ymin, ref double[] Ratio, double Pic_YLim) { return(new Point((int)((Node.X - Xmin) / Ratio[0] + Ratio[1]), (int)(Pic_YLim - (Node.Y - Ymin) / Ratio[0] - Ratio[2]))); }
/// 绘制所有单元 /// <summary> /// 绘制所有单元 /// </summary> private static double[] Draw_Elements(ref WFEM_NegPara NP, ref WMesh2D_Mesh Mesh, ref double[] RES, ref double[] Res_Each, ref Graphics graphic, ref double[] DrawRate, int LableHeight) { #region 绘图工具 Pen RimPen = new Pen(NP.ColorEleRim, NP.PicEleRimWidth); Brush[] FBrushs = new Brush[NP.Color_Contours.Length]; for (int i = 0; i < NP.Color_Contours.Length; i++) { FBrushs[i] = new SolidBrush(NP.Color_Contours[i]); } #endregion #region 找出所有节点的CI int[] Ns_CIs = Find_Ns_CIs(ref RES, ref Res_Each); #endregion #region 临时中间变量 ///单元节点参数 int K; /////单元类型 double[] E_Rs = new double[0]; /////每个单元每个节点的结果值 WNode2D[] E_Ns = new WNode2D[0]; /////每个单元的节点 int[] E_CIs = new int[0]; /////每个单元每个节点的颜色编号,从0开始 int CI_max, CI_min; /////每个单元每个节点的CI最值 Point[] PsT = new Point[0]; /////用于画图的临时图像点 WNode2D[] NsT; WNode2D[] All_Ns = new WNode2D[0]; /////将每个单元的所有节点,中间节点混合放置在此 int[] All_CIs = new int[0]; /////计算中间节点时使用的临时变量 int Q; double[] Areas = new double[NP.Color_Contours.Length]; /////用于输出的每个CI的单元面积总和 #endregion #region 绘制单元 for (int i = 0; i < Mesh.Elements.Count; i++) { K = Mesh.Elements[i].Kind; if (K < 3) { continue; } /////初始化四个点的位置,结果,Color_Index Compute_ElementParas(ref Mesh, i, ref RES, ref Ns_CIs, ref E_Rs, ref E_CIs, ref E_Ns); CI_max = E_CIs.Max(); CI_min = E_CIs.Min(); /////如果各个节点;的Color_Index完全相同则直接画图 if (CI_max == CI_min) { PsT = Nodes_To_Points(ref E_Ns, Mesh.Xmin, Mesh.Ymin, ref DrawRate, true, NP.PicHeight - LableHeight); graphic.FillPolygon(FBrushs[CI_max], PsT); if (NP.ShowEleRim == true) { graphic.DrawPolygon(RimPen, PsT); /////绘制单元边界 } Element_Area(ref E_Ns, ref Areas, CI_max, true); continue; } /////四个节点Color_Index不完全相等的情况 ///求取中间节点,并和单元节点放在一起 All_Ns = new WNode2D[0]; All_CIs = new int[0]; for (int j = 0; j < K; j++) { NodesInter_Compute(ref E_Ns[j], ref E_Ns[j + 1], /////节点 E_Rs[j], E_Rs[j + 1], /////节点上的结果数值 E_CIs[j], E_CIs[j + 1], CI_max, ref Res_Each, ref All_Ns, ref All_CIs, E_CIs, E_Rs); } for (int j = CI_min; j <= CI_max; j++) { NsT = new WNode2D[0]; Q = 0; for (int k = 0; k < All_Ns.Length; k++) { if (All_CIs[k] == j) { Q++; Array.Resize <WNode2D>(ref NsT, Q); NsT[Q - 1] = All_Ns[k]; continue; } if (All_CIs[k] == j + 1) { Q++; Array.Resize <WNode2D>(ref NsT, Q); NsT[Q - 1] = All_Ns[k]; continue; } } PsT = Nodes_To_Points(ref NsT, Mesh.Xmin, Mesh.Ymin, ref DrawRate, false, NP.PicHeight - LableHeight); graphic.FillPolygon(FBrushs[j], PsT); if (NP.ShowEleRim == true) { graphic.DrawPolygon(RimPen, PsT); /////绘制单元边界 } Element_Area(ref NsT, ref Areas, CI_max, false); } } #endregion return(Areas); }