/// 求出Rese_Each /// <summary> /// 求出Rese_Each /// </summary> private static double[] Compute_ResEach(ref WFEM_NegPara NP, ref double[] RES, ref double[] RESM) { int Q = NP.Color_Contours.Length; /////颜色总数,14,0~13,其中0,13为超过Limit的颜色 double[] REach = new double[Q + 1]; /////Res_Each,其数值数量比颜色数量多1,共15,0~14 double Res_Per, Max, Min; REach[0] = RESM[0]; /////0数值为最小值 REach[Q] = RESM[1]; /////最后的数值为最大值 //==============================// if (NP.ShowFixLimit == false) { Max = RESM[1]; Min = RESM[0]; } else { Max = NP.Neg_Max; if (Max > RESM[1]) { Max = RESM[1]; /////若ULimit大于最大值,忽略ULimit } Min = NP.Neg_Min; if (Min < RESM[0]) { Min = RESM[0]; /////若LLimit小于最小值,忽略LLimit } } //==============================// Res_Per = (Max - Min) / (Q - 2); /////求每档的数值,不设置Limit for (int i = 1; i < Q - 1; i++) /////直接赋值,注意此时1与1相同,最后和倒二相同 { REach[i] = Min + (i - 1) * Res_Per; } REach[Q - 1] = Max; /////防止计算舍入误差,直接赋值 return(REach); }
public static WFEM_NegOut Create(ref WFEM_NegPara NP, WMesh2D_Mesh Mesh, string ResultFile, String ProgramPath, String[] Titles) { double[] RESM = new double[2]; RESM = FindLimit(ResultFile); /////如果不限制最大/最小值则需要找到最大/最小值 StreamReader sr = new StreamReader(ResultFile); sr.ReadLine(); int Quan_Frames = Convert.ToInt16(sr.ReadLine()); sr.ReadLine(); int Quan_Nodes = Convert.ToInt16(sr.ReadLine()); sr.ReadLine(); ///// double[] RES = new double[Quan_Nodes + 1]; String Path = NP.PicPath; String Name = NP.PicName; NP.PicPath = Path + "VT" + DateTime.Now.TimeOfDay.ToString().Replace(":", ""); Directory.CreateDirectory(NP.PicPath); NP.PicPath += "\\"; WFEM_NegOut ParaOut = null; for (int i = 0; i < Quan_Frames; i++) { if (NP.VidTitleOut == true && Titles.Length == Quan_Frames) { NP.PicTitle = Titles[i]; } //Debugger.Break(); for (int j = 1; j <= Quan_Nodes; j++) { RES[j] = Convert.ToDouble(sr.ReadLine()); } sr.ReadLine(); NP.PicName = (i + 1).ToString(); ParaOut = WFEM_NegContour.Draw_to_PNG(ref NP, Mesh, ref RES, ref RESM); } //=============================// Process Proc = new Process(); String Arg = NP.PicPath + ","; Arg += (Path + Name + ".avi" + ","); Arg += (NP.PicWidth.ToString() + ","); Arg += (NP.PicHeight.ToString() + ","); Arg += (NP.VidFrameRate.ToString() + ","); Arg += (Quan_Frames.ToString() + ","); ///// Proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; Proc.StartInfo.FileName = ProgramPath + "\\VideoCreator\\VideoCreator.exe"; //Console.WriteLine(Proc.StartInfo.FileName); Proc.StartInfo.Arguments = Arg; Proc.Start(); /// NP.PicPath = Path; NP.PicName = Name; return(ParaOut); /////返回最后一帧的结果 }
private static Bitmap Draw_to_Bitmap(ref WFEM_NegPara NP, WMesh2D_Mesh Mesh, ref double[] RES, ref WFEM_NegOut ParaOut) { #region 结果的最小值,最大值 double[] RESM_in = new double[0]; int[] NodeM_in = new int[0]; Compute_ResPara(ref RES, ref RESM_in, ref NodeM_in); //Debugger.Break(); if (ParaOut.RESM == null) { ParaOut.RESM = RESM_in; ParaOut.NodeM = NodeM_in; } #endregion #region 求取颜色变量 ParaOut.Res_Each = Compute_ResEach(ref NP, ref RES, ref ParaOut.RESM); #endregion #region "初始化绘图工具" Bitmap bitmap = new Bitmap(NP.PicWidth, NP.PicHeight); Graphics graphic = Graphics.FromImage(bitmap); graphic.Clear(NP.Color_BackGround); #endregion #region 绘制Lable及Title int LableHeight = NP.PicRim; if (NP.ShowLable == true) { LableHeight = Draw_Label(ref NP, ref graphic, ref ParaOut.Res_Each); /////绘制Label } int TitleHeight = NP.PicRim; if (NP.ShowTitle == true) { TitleHeight = Draw_Title(ref NP, ref graphic, NP.PicTitle); /////绘制Title } #endregion #region 求取绘图比例 double[] DrawRate = Compute_DrawRate((Mesh.Xmax - Mesh.Xmin), /////求取绘图比例 (Mesh.Ymax - Mesh.Ymin), NP.PicWidth - NP.PicRim * 2, NP.PicHeight - TitleHeight - LableHeight); #endregion /////绘制所有单元 ParaOut.Areas = Draw_Elements(ref NP, ref Mesh, ref RES, ref ParaOut.Res_Each, ref graphic, ref DrawRate, LableHeight); /////绘制最大值最小值 Draw_MaxMin(ref NP, ref graphic, Mesh, RESM_in, NodeM_in, DrawRate, NP.PicHeight - LableHeight, TitleHeight); graphic.Dispose(); return(bitmap); }
/// 绘制2D结果的云图 /// <summary> /// 绘制2D结果的云图 /// </summary> /// <param name="NP">云图绘制参数</param> /// <param name="Mesh">需要绘制的Mesh</param> /// <param name="RES">每个节点的结果数组,数组编号应与节点编号一致</param> /// <returns></returns> public static WFEM_NegOut Draw_to_PNG(ref WFEM_NegPara NP, WMesh2D_Mesh Mesh, ref double[] RES) { WFEM_NegOut ParaOut = new WFEM_NegOut(); ParaOut.RES = RES; Bitmap bitmap = Draw_to_Bitmap(ref NP, Mesh, ref RES, ref ParaOut); /////保存并结束 bitmap.Save(NP.PicPath + NP.PicName + ".png"); bitmap.Dispose(); return(ParaOut); }
/// 绘制Label条 /// <summary> /// 云图绘制Label条,返回值为Label条占用的高度,注意已经留白,可以直接使用 /// </summary> /// <param name="NP"></param> /// <param name="graphic"></param> /// <param name="RES_Each"></param> /// <returns></returns> private static int Draw_Label(ref WFEM_NegPara NP, ref Graphics graphic, ref double[] RES_Each) { Point[] Psp = new Point[4]; Font font = new Font(NP.LableFont, NP.LableTextHeight); SolidBrush brushR = new SolidBrush(Color.Black); SolidBrush brushF; ///// int Q = NP.Color_Contours.Length; int Start = 0; if (NP.ShowFixLimit == false) { Start = 1; /////开始的编号,对于无FixLimit从1开始 } int End = Q; if (NP.ShowFixLimit == false) { End = Q - 1; /////结束的编号,对于无FixLimit在Q-1处结束 } //---------------------------// int Len_Total = (int)(NP.LableWidthRate * NP.PicWidth); /////Lab的横向长度 int Len_Per = (int)(Len_Total / End); /////每种颜色的Label的长度 int X_Left = (int)(NP.PicWidth - Len_Total) / 2; /////Label最左侧的点的X坐标 int Y_Bott = NP.PicHeight - NP.PicRim; /////Label最低处的Y坐标 int Lab_DisT2L = (int)(NP.LableTextHeight * (0.8)); /////文字到Label条之间的距离 int Y_Text = (int)(Y_Bott - Lab_DisT2L - 2.5 * NP.LableTextHeight); /// -90; for (int i = Start; i < End; i++) { Psp[0] = new Point(X_Left + i * Len_Per, Y_Bott); Psp[1] = new Point(X_Left + (i + 1) * Len_Per, Y_Bott); Psp[2] = new Point(X_Left + (i + 1) * Len_Per, Y_Bott - NP.LableHight); Psp[3] = new Point(X_Left + i * Len_Per, Y_Bott - NP.LableHight); brushF = new SolidBrush(NP.Color_Contours[i]); graphic.FillPolygon(brushF, Psp); graphic.DrawString(Convert.ToString(Math.Round(RES_Each[i], 2)), font, brushR, X_Left - 2 * NP.LableTextHeight + i * Len_Per, Y_Text); } graphic.DrawString(Convert.ToString(Math.Round(RES_Each[End], 2)), font, brushR, X_Left - 2 * NP.LableTextHeight + Len_Total, Y_Text); return(2 * NP.PicRim + NP.LableHight + Lab_DisT2L + NP.LableTextHeight); }
/// 绘制云图的Title /// <summary> /// 绘制云图的Title,返回值为Title高度(包含留白) /// </summary> /// <param name="NP"></param> /// <param name="Gf"></param> /// <param name="Title"></param> /// <returns></returns> private static int Draw_Title(ref WFEM_NegPara NP, ref Graphics Gf, String Title) { StringFormat format = new StringFormat(); Font font = new Font(NP.TitleFont, NP.TitleHeight); SolidBrush brush = new SolidBrush(Color.Black); ///// Rectangle Rec = new Rectangle(NP.PicRim, NP.PicRim, NP.PicWidth, (int)(NP.TitleHeight * 2)); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; Gf.DrawString(NP.PicTitle, font, brush, Rec, format); Rec = new Rectangle(NP.PicRim, (int)(NP.PicRim + NP.TitleHeight * 2.3), NP.PicWidth, (int)(NP.TitleHeight * 1.6)); Gf.DrawString(NP.PicUnit, font, brush, Rec, format); ///// int L = (int)(Gf.MeasureString(Title, font).Width); int Y = NP.PicRim + (int)(NP.TitleHeight * 2); Gf.DrawLine(new Pen(brush, NP.TitleHeight * 0.1f), new Point(NP.PicWidth / 2 - (int)(L * 0.53), Y), new Point(NP.PicWidth / 2 + (int)(L * 0.6), Y)); ///// return(NP.PicRim * 2 + (int)(NP.TitleHeight * 4.3)); }
/// 绘制所有单元 /// <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); }
/// 绘制最大值、最小值的Lable /// <summary> /// 绘制最大值、最小值的Lable /// </summary> /// <param name="NP"></param> /// <param name="Gf"></param> /// <param name="Mesh"></param> /// <param name="RESM"></param> /// <param name="NodeM"></param> /// <param name="DrawRate"></param> /// <param name="Pic_YL">渲染区域下边界Pic坐标</param> /// <param name="Pic_YU">渲染区域上边界Pic坐标</param> private static void Draw_MaxMin(ref WFEM_NegPara NP, ref Graphics Gf, WMesh2D_Mesh Mesh, double[] RESM, int[] NodeM, double[] DrawRate, int Pic_YL, int Pic_YU) { if (NP.ShowMaxMin == false) { return; } Font font = new Font(NP.LableFont, NP.LableTextHeight); Brush brush = new SolidBrush(Color.Black); StringFormat format = new StringFormat(); /// int X, Y, xt, yt; string t1, t2, t3, t4; int[] lts; int lmax; //==========Draw Max========// X = (int)((Mesh.Nodes[NodeM[1]].X - Mesh.Xmin) / DrawRate[0] + DrawRate[1]); Y = (int)(Pic_YL - (Mesh.Nodes[NodeM[1]].Y - Mesh.Ymin) / DrawRate[0] - DrawRate[2]); ///// t1 = "Max.= " + Math.Round(RESM[1], 2).ToString(); t2 = "Node: " + NodeM[1].ToString(); t3 = "x = " + Math.Round(Mesh.Nodes[NodeM[1]].X, 2).ToString(); t4 = "y = " + Math.Round(Mesh.Nodes[NodeM[1]].Y, 2).ToString(); lts = new int[4]; lts[0] = (int)(Gf.MeasureString(t1, font).Width); lts[1] = (int)(Gf.MeasureString(t2, font).Width); lts[2] = (int)(Gf.MeasureString(t3, font).Width); lts[3] = (int)(Gf.MeasureString(t4, font).Width); lmax = lts.Max(); if (Y < (Pic_YL - Pic_YU) / 2) { yt = Y - NP.LableTextHeight / 2; if (X < NP.PicWidth / 2) { xt = X + NP.LableTextHeight / 2; ///第二象限 } else { xt = X - lmax - NP.LableTextHeight / 2; ///第一象限 } } else { yt = Y - (int)(NP.LableTextHeight * 5.5); if (X < NP.PicWidth / 2) { xt = X + NP.LableTextHeight / 2; ///第三象限 } else { xt = X - lmax - NP.LableTextHeight / 2; ///第四象限 } } /// Gf.DrawString(t1, font, brush, new PointF(xt, yt)); if (NP.ShowMaxMinNode == true) { yt = yt + (int)(1.5 * NP.LableTextHeight); Gf.DrawString(t2, font, brush, new PointF(xt, yt)); yt = yt + (int)(1.5 * NP.LableTextHeight); Gf.DrawString(t3, font, brush, new PointF(xt, yt)); yt = yt + (int)(1.5 * NP.LableTextHeight); Gf.DrawString(t4, font, brush, new PointF(xt, yt)); } xt = X - NP.LableTextHeight / 4; yt = Y - NP.LableTextHeight / 4; Gf.FillEllipse(brush, new Rectangle(xt, yt, NP.LableTextHeight / 2, NP.LableTextHeight / 2)); //==========Draw Min========// t1 = "Min.= " + Math.Round(RESM[0], 2).ToString(); t2 = "Node: " + NodeM[0].ToString(); t3 = "x = " + Math.Round(Mesh.Nodes[NodeM[0]].X, 2).ToString(); t4 = "y = " + Math.Round(Mesh.Nodes[NodeM[0]].Y, 2).ToString(); lts[0] = (int)(Gf.MeasureString(t1, font).Width); lts[1] = (int)(Gf.MeasureString(t2, font).Width); lts[2] = (int)(Gf.MeasureString(t3, font).Width); lts[3] = (int)(Gf.MeasureString(t4, font).Width); lmax = lts.Max(); /// X = (int)((Mesh.Nodes[NodeM[0]].X - Mesh.Xmin) / DrawRate[0] + DrawRate[1]); Y = (int)(Pic_YL - (Mesh.Nodes[NodeM[0]].Y - Mesh.Ymin) / DrawRate[0] - DrawRate[2]); if (Y < (Pic_YL - Pic_YU) / 2) { yt = Y - NP.LableTextHeight / 2; ///第二象限 if (X < NP.PicWidth / 2) { xt = X + NP.LableTextHeight / 2; ///第一象限 } else { xt = X - lmax - NP.LableTextHeight / 2; } } else { yt = Y - (int)(NP.LableTextHeight * 5.5); ///第三象限 if (X < NP.PicWidth / 2) { xt = X + NP.LableTextHeight / 2; ///第四象限 } else { xt = X - lmax - NP.LableTextHeight / 2; } } /// Gf.DrawString(t1, font, brush, new PointF(xt, yt)); if (NP.ShowMaxMinNode == true) { yt = yt + (int)(1.5 * NP.LableTextHeight); Gf.DrawString(t2, font, brush, new PointF(xt, yt)); yt = yt + (int)(1.5 * NP.LableTextHeight); Gf.DrawString(t3, font, brush, new PointF(xt, yt)); yt = yt + (int)(1.5 * NP.LableTextHeight); Gf.DrawString(t4, font, brush, new PointF(xt, yt)); } xt = X - NP.LableTextHeight / 4; yt = Y - NP.LableTextHeight / 4; Gf.FillEllipse(brush, new Rectangle(xt, yt, NP.LableTextHeight / 2, NP.LableTextHeight / 2)); }