/// <summary> /// 周期構造導波路の固有モード分布を描画する /// </summary> /// <param name="g"></param> /// <param name="ofs"></param> /// <param name="delta"></param> /// <param name="regionSize"></param> /// <param name="valueDv"></param> /// <param name="colorMap"></param> public virtual void DrawEigenField(Graphics g, Size ofs, Size delta, Size regionSize, FemElement.ValueDV valueDv, ColorMap colorMap) { }
/// <summary> /// フィールド値を描画する /// </summary> /// <param name="g"></param> /// <param name="ofs"></param> /// <param name="delta"></param> /// <param name="regionSize"></param> /// <param name="fieldDv"></param> /// <param name="valueDv"></param> /// <param name="colorMap"></param> public override void DrawField(Graphics g, Size ofs, Size delta, Size regionSize, FemElement.FieldDV fieldDv, FemElement.ValueDV valueDv, ColorMap colorMap) { //base.DrawField(g, ofs, delta, regionSize, colorMap); if (_Nodes == null || _FValues == null || _RotXFValues == null || _RotYFValues == null || _PoyntingXFValues == null || _PoyntingYFValues == null) { return; } Complex[] tagtValues = null; if (fieldDv == FemElement.FieldDV.Field) { tagtValues = _FValues; } else if (fieldDv == FemElement.FieldDV.RotX) { tagtValues = _RotXFValues; } else if (fieldDv == FemElement.FieldDV.RotY) { tagtValues = _RotYFValues; } else { return; } doDrawField(g, ofs, delta, regionSize, tagtValues, valueDv, colorMap); }
/// <summary> /// 対象のフィールドを描画する /// </summary> /// <param name="g"></param> /// <param name="ofs"></param> /// <param name="delta"></param> /// <param name="regionSize"></param> /// <param name="tagtValues"></param> /// <param name="valueDv"></param> /// <param name="colorMap"></param> public void doDrawField(Graphics g, Size ofs, Size delta, Size regionSize, Complex[] tagtValues, FemElement.ValueDV valueDv, ColorMap colorMap) { const int ndim = Constants.CoordDim2D; //2; // 座標の次元数 const int vertexCnt = Constants.TriVertexCnt; //3; // 三角形の頂点の数(2次要素でも同じ) //const int nodeCnt = Constants.TriNodeCnt_SecondOrder; //6; // 三角形2次要素 int nodeCnt = NodeNumbers.Length; if (nodeCnt != Constants.TriNodeCnt_SecondOrder && nodeCnt != Constants.TriNodeCnt_FirstOrder) { return; } // 三角形の節点座標を取得 double[][] pp = new double[nodeCnt][]; for (int ino = 0; ino < pp.GetLength(0); ino++) { FemNode node = _Nodes[ino]; System.Diagnostics.Debug.Assert(node.Coord.Length == ndim); pp[ino] = new double[ndim]; pp[ino][0] = node.Coord[0] * delta.Width + ofs.Width; //pp[ino][1] = regionSize.Height - node.Coord[1] * delta.Height + ofs.Height; pp[ino][1] = node.Coord[1] * delta.Height + ofs.Height; } // 長方形描画領域のリスト IList<double[][]> rectLiList = _RectLiList; // 描画ロジック上の原点となる頂点 int orginVertexNo = _OrginVertexNo; // 四角形の頂点 const int rectVCnt = 4; foreach (double[][] rectLi in rectLiList) { double[][] rectpp = new double[rectVCnt][]; for (int ino = 0; ino < rectVCnt; ino++) { double[] vLpp = rectLi[ino]; double xx = 0.0; double yy = 0.0; for (int k = 0; k < vertexCnt; k++) { xx += pp[k][0] * vLpp[(k + orginVertexNo) % vertexCnt]; yy += pp[k][1] * vLpp[(k + orginVertexNo) % vertexCnt]; } rectpp[ino] = new double[] { xx, yy }; } // 表示する位置 double[] vLi = new double[] { (rectLi[0][0] + rectLi[1][0]) * 0.5, (rectLi[0][1] + rectLi[3][1]) * 0.5, 0 }; if (vLi[0] < 0.0) { vLi[0] = 0.0; } if (vLi[0] > 1.0) { vLi[0] = 1.0; } if (vLi[1] < 0.0) { vLi[1] = 0.0; } if (vLi[1] > (1.0 - vLi[0])) { vLi[1] = (1.0 - vLi[0]); } vLi[2] = 1.0 - vLi[0] - vLi[1]; if (vLi[2] < 0.0) { System.Diagnostics.Debug.WriteLine("logic error vLi[2] = {0}", vLi[2]); } // 表示する値 Complex cvalue = new Complex(0.0, 0.0); // 表示する位置の形状関数値 double[] vNi = null; double[] shiftedLi = new double[vertexCnt]; for (int i = 0; i < vertexCnt; i++) { shiftedLi[i] = vLi[(i + orginVertexNo) % vertexCnt]; } if (nodeCnt == Constants.TriNodeCnt_FirstOrder) { vNi = new double[] { shiftedLi[0], shiftedLi[1], shiftedLi[2] }; } else { vNi = new double[] { shiftedLi[0] * (2.0 * shiftedLi[0] - 1.0), shiftedLi[1] * (2.0 * shiftedLi[1] - 1.0), shiftedLi[2] * (2.0 * shiftedLi[2] - 1.0), 4.0 * shiftedLi[0] * shiftedLi[1], 4.0 * shiftedLi[1] * shiftedLi[2], 4.0 * shiftedLi[2] * shiftedLi[0], }; } for (int k = 0; k < nodeCnt; k++) { cvalue += tagtValues[k] * vNi[k]; } // 四角形の頂点(描画用) Point[] rectp = new Point[rectVCnt]; for (int ino = 0; ino < rectVCnt; ino++) { rectp[ino] = new Point((int)rectpp[ino][0], (int)rectpp[ino][1]); } try { // 表示する値 double showValue = 0.0; if (valueDv == ValueDV.Real) { showValue = cvalue.Real; } else if (valueDv == ValueDV.Imaginary) { showValue = cvalue.Imaginary; } else { // 既定値は絶対値 showValue = Complex.Abs(cvalue); } // 塗りつぶし色の取得 Color fillColor = colorMap.GetColor(showValue); // 塗りつぶし using (Brush brush = new SolidBrush(fillColor)) { g.FillPolygon(brush, rectp); } } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); } } }
/// <summary> /// 周期構造導波路の固有モード分布を描画する /// </summary> /// <param name="g"></param> /// <param name="ofs"></param> /// <param name="delta"></param> /// <param name="regionSize"></param> /// <param name="valueDv"></param> /// <param name="colorMap"></param> public override void DrawEigenField(Graphics g, Size ofs, Size delta, Size regionSize, FemElement.ValueDV valueDv, ColorMap colorMap) { Complex[] tagtValues = _EigenFValues; if (tagtValues != null) { doDrawField(g, ofs, delta, regionSize, tagtValues, valueDv, colorMap); } }
/// <summary> /// フィールド値を描画する /// </summary> /// <param name="g"></param> /// <param name="ofs"></param> /// <param name="delta"></param> /// <param name="regionSize"></param> /// <param name="fieldDv"></param> /// <param name="valueDv"></param> /// <param name="colorMap"></param> public virtual void DrawField(Graphics g, Size ofs, Size delta, Size regionSize, FemElement.FieldDV fieldDv, FemElement.ValueDV valueDv, ColorMap colorMap) { }
/// <summary> /// 対象のフィールドを描画する /// </summary> /// <param name="g"></param> /// <param name="ofs"></param> /// <param name="delta"></param> /// <param name="regionSize"></param> /// <param name="tagtValues"></param> /// <param name="valueDv"></param> /// <param name="colorMap"></param> public void doDrawField(Graphics g, Size ofs, Size delta, Size regionSize, Complex[] tagtValues, FemElement.ValueDV valueDv, ColorMap colorMap) { const int ndim = Constants.CoordDim2D; //2; // 座標の次元数 const int vertexCnt = Constants.TriVertexCnt; //3; // 三角形の頂点の数(2次要素でも同じ) //const int nodeCnt = Constants.TriNodeCnt_SecondOrder; //6; // 三角形2次要素 int nodeCnt = NodeNumbers.Length; if (nodeCnt != Constants.TriNodeCnt_SecondOrder && nodeCnt != Constants.TriNodeCnt_FirstOrder) { return; } // 三角形の節点座標を取得 double[][] pp = new double[nodeCnt][]; for (int ino = 0; ino < pp.GetLength(0); ino++) { FemNode node = _Nodes[ino]; System.Diagnostics.Debug.Assert(node.Coord.Length == ndim); pp[ino] = new double[ndim]; pp[ino][0] = node.Coord[0] * delta.Width + ofs.Width; //pp[ino][1] = regionSize.Height - node.Coord[1] * delta.Height + ofs.Height; pp[ino][1] = node.Coord[1] * delta.Height + ofs.Height; } // 長方形描画領域のリスト IList <double[][]> rectLiList = _RectLiList; // 描画ロジック上の原点となる頂点 int orginVertexNo = _OrginVertexNo; // 四角形の頂点 const int rectVCnt = 4; foreach (double[][] rectLi in rectLiList) { double[][] rectpp = new double[rectVCnt][]; for (int ino = 0; ino < rectVCnt; ino++) { double[] vLpp = rectLi[ino]; double xx = 0.0; double yy = 0.0; for (int k = 0; k < vertexCnt; k++) { xx += pp[k][0] * vLpp[(k + orginVertexNo) % vertexCnt]; yy += pp[k][1] * vLpp[(k + orginVertexNo) % vertexCnt]; } rectpp[ino] = new double[] { xx, yy }; } // 表示する位置 double[] vLi = new double[] { (rectLi[0][0] + rectLi[1][0]) * 0.5, (rectLi[0][1] + rectLi[3][1]) * 0.5, 0 }; if (vLi[0] < 0.0) { vLi[0] = 0.0; } if (vLi[0] > 1.0) { vLi[0] = 1.0; } if (vLi[1] < 0.0) { vLi[1] = 0.0; } if (vLi[1] > (1.0 - vLi[0])) { vLi[1] = (1.0 - vLi[0]); } vLi[2] = 1.0 - vLi[0] - vLi[1]; if (vLi[2] < 0.0) { System.Diagnostics.Debug.WriteLine("logic error vLi[2] = {0}", vLi[2]); } // 表示する値 Complex cvalue = new Complex(0.0, 0.0); // 表示する位置の形状関数値 double[] vNi = null; double[] shiftedLi = new double[vertexCnt]; for (int i = 0; i < vertexCnt; i++) { shiftedLi[i] = vLi[(i + orginVertexNo) % vertexCnt]; } if (nodeCnt == Constants.TriNodeCnt_FirstOrder) { vNi = new double[] { shiftedLi[0], shiftedLi[1], shiftedLi[2] }; } else { vNi = new double[] { shiftedLi[0] * (2.0 * shiftedLi[0] - 1.0), shiftedLi[1] * (2.0 * shiftedLi[1] - 1.0), shiftedLi[2] * (2.0 * shiftedLi[2] - 1.0), 4.0 * shiftedLi[0] * shiftedLi[1], 4.0 * shiftedLi[1] * shiftedLi[2], 4.0 * shiftedLi[2] * shiftedLi[0], }; } for (int k = 0; k < nodeCnt; k++) { cvalue += tagtValues[k] * vNi[k]; } // 四角形の頂点(描画用) Point[] rectp = new Point[rectVCnt]; for (int ino = 0; ino < rectVCnt; ino++) { rectp[ino] = new Point((int)rectpp[ino][0], (int)rectpp[ino][1]); } try { // 表示する値 double showValue = 0.0; if (valueDv == ValueDV.Real) { showValue = cvalue.Real; } else if (valueDv == ValueDV.Imaginary) { showValue = cvalue.Imaginary; } else { // 既定値は絶対値 showValue = Complex.Abs(cvalue); } // 塗りつぶし色の取得 Color fillColor = colorMap.GetColor(showValue); // 塗りつぶし using (Brush brush = new SolidBrush(fillColor)) { g.FillPolygon(brush, rectp); } } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); } } }