/// <summary>
        /// フィールド値を描画する
        /// </summary>
        /// <param name="g"></param>
        /// <param name="ofs"></param>
        /// <param name="delta"></param>
        /// <param name="regionSize"></param>
        /// <param name="colorMap"></param>
        /// <param name="valueDv"></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;
            }

            const int ndim      = Constants.CoordDim2D;    //2;      // 座標の次元数
            const int vertexCnt = Constants.QuadVertexCnt; //3; // 四角形形の頂点の数(2次要素でも同じ)
            //const int nodeCnt = Constants.QuadNodeCnt_SecondOrder_Type2; //8;  // 四角形2次要素
            int nodeCnt = NodeNumbers.Length;

            if (nodeCnt != Constants.QuadNodeCnt_SecondOrder_Type2 && nodeCnt != Constants.QuadNodeCnt_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;
            }
            // 四角形内部を四角形で分割
            // 要素節点座標( 局所r,s成分 )
            //        s
            //        |
            //    3+  6  +2
            //    |   |   |
            // ---7---+---5-->r
            //    |   |   |
            //    0+  4  +1
            //        |
            //
            double[][] n_pts =
            {
                // r, s
                new double[] { -1.0, -1.0 },    //0
                new double[] {  1.0, -1.0 },    //1
                new double[] {  1.0,  1.0 },    //2
                new double[] { -1.0,  1.0 },    //3
                new double[] {    0, -1.0 },    //4
                new double[] {  1.0,    0 },    //5
                new double[] {    0,  1.0 },    //6
                new double[] { -1.0,    0 },    //7
            };

            int    ndiv  = this.IsCoarseFieldMesh ? (Constants.TriDrawFieldMshDivCnt / 2) : Constants.TriDrawFieldMshDivCnt;
            double defdr = 2.0 / (double)ndiv;
            double defds = defdr;

            for (int i1 = 0; i1 < ndiv; i1++)
            {
                double r     = -1.0 + i1 * defdr;
                double rNext = r + defdr;
                for (int i2 = 0; i2 < ndiv; i2++)
                {
                    double s     = -1.0 + i2 * defds;
                    double sNext = s + defds;

                    // 四角形の頂点
                    const int  rectVCnt     = 4;
                    double[][] rect_local_p = new double[rectVCnt][]
                    {
                        new double[] { r, s },
                        new double[] { rNext, s },
                        new double[] { rNext, sNext },
                        new double[] { r, sNext }
                    };
                    double[][] rectpp = new double[rectVCnt][];
                    for (int ino = 0; ino < rectVCnt; ino++)
                    {
                        double work_r = rect_local_p[ino][0];
                        double work_s = rect_local_p[ino][1];
                        double xx     = 0.0;
                        double yy     = 0.0;
                        for (int k = 0; k < vertexCnt; k++)
                        {
                            double ri = n_pts[k][0];
                            double si = n_pts[k][1];
                            xx += pp[k][0] * 0.25 * (1 + ri * work_r) * (1 + si * work_s);
                            yy += pp[k][1] * 0.25 * (1 + ri * work_r) * (1 + si * work_s);
                        }
                        rectpp[ino] = new double[] { xx, yy };
                    }
                    // 表示する位置
                    double[] disp_p = new double[] { (rect_local_p[0][0] + rect_local_p[1][0]) * 0.5, (rect_local_p[0][1] + rect_local_p[3][1]) * 0.5 };

                    // 表示する値
                    Complex cvalue = new Complex(0.0, 0.0);
                    // 表示する位置の形状関数値
                    double[] workN = new double[nodeCnt];
                    if (nodeCnt == Constants.QuadNodeCnt_FirstOrder)
                    {
                        double work_r = disp_p[0];
                        double work_s = disp_p[1];
                        for (int i = 0; i < 4; i++)
                        {
                            // 節点の局所座標
                            double ri = n_pts[i][0];
                            double si = n_pts[i][1];
                            workN[i] = 0.25 * (1.0 + ri * work_r) * (1.0 + si * work_s);
                        }
                    }
                    else
                    {
                        double work_r = disp_p[0];
                        double work_s = disp_p[1];
                        // 節点0~3 : 四角形の頂点
                        for (int i = 0; i < 4; i++)
                        {
                            // 節点の局所座標
                            double ri = n_pts[i][0];
                            double si = n_pts[i][1];
                            // 形状関数N
                            workN[i] = 0.25 * (1.0 + ri * work_r) * (1.0 + si * work_s) * (ri * work_r + si * work_s - 1.0);
                        }
                        // 節点4,6 : r方向辺上中点
                        foreach (int i in new int[] { 4, 6 })
                        {
                            // 節点の局所座標
                            double ri = n_pts[i][0];
                            double si = n_pts[i][1];
                            // 形状関数N
                            workN[i] = 0.5 * (1.0 - work_r * work_r) * (1.0 + si * work_s);
                        }
                        // 節点5,7 : s方向辺上中点
                        foreach (int i in new int[] { 5, 7 })
                        {
                            // 節点の局所座標
                            double ri = n_pts[i][0];
                            double si = n_pts[i][1];
                            // 形状関数N
                            workN[i] = 0.5 * (1.0 + ri * work_r) * (1.0 - work_s * work_s);
                        }
                    }
                    for (int k = 0; k < nodeCnt; k++)
                    {
                        cvalue += tagtValues[k] * workN[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="drawColor"></param>
        /// <param name="fieldDv"></param>
        /// <param name="minRotFValue"></param>
        /// <param name="maxRotFValue"></param>
        public override void DrawRotField(Graphics g, Size ofs, Size delta, Size regionSize, Color drawColor, FemElement.FieldDV fieldDv, double minRotFValue, double maxRotFValue)
        {
            if (_Nodes == null || _FValues == null || _RotXFValues == null || _RotYFValues == null || _PoyntingXFValues == null || _PoyntingYFValues == null)
            {
                return;
            }
            Complex[] tagtXValues = null;
            Complex[] tagtYValues = null;
            if (fieldDv == FemElement.FieldDV.PoyntingXY)
            {
                tagtXValues = _PoyntingXFValues;
                tagtYValues = _PoyntingYFValues;
            }
            else if (fieldDv == FemElement.FieldDV.RotXY)
            {
                tagtXValues = _RotXFValues;
                tagtYValues = _RotYFValues;
            }
            else
            {
                return;
            }

            const int ndim = Constants.CoordDim2D; //2;      // 座標の次元数
            //const int vertexCnt = Constants.QuadVertexCnt; //4; // 四角形形の頂点の数(2次要素でも同じ)
            //const int nodeCnt = Constants.QuadNodeCnt_SecondOrder_Type2; //8;  // 四角形形2次要素
            int nodeCnt = NodeNumbers.Length;

            if (nodeCnt != Constants.QuadNodeCnt_SecondOrder_Type2 && nodeCnt != Constants.QuadNodeCnt_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;
            }
            // 四角形内部を四角形で分割
            // 要素節点座標( 局所r,s成分 )
            //        s
            //        |
            //    3+  6  +2
            //    |   |   |
            // ---7---+---5-->r
            //    |   |   |
            //    0+  4  +1
            //        |
            //
            double[][] n_pts =
            {
                // r, s
                new double[] { -1.0, -1.0 },    //0
                new double[] {  1.0, -1.0 },    //1
                new double[] {  1.0,  1.0 },    //2
                new double[] { -1.0,  1.0 },    //3
                new double[] {    0, -1.0 },    //4
                new double[] {  1.0,    0 },    //5
                new double[] {    0,  1.0 },    //6
                new double[] { -1.0,    0 },    //7
            };

            // 節点上のrot(Ez)を求める
            int nno = nodeCnt;
            {
                double r = 0;
                double s = 0;

                // 形状関数
                double[] N = new double[nno];
                if (nodeCnt == Constants.QuadNodeCnt_SecondOrder_Type2)
                {
                    // 節点0~3 : 四角形の頂点
                    for (int i = 0; i < 4; i++)
                    {
                        // 節点の局所座標
                        double ri = n_pts[i][0];
                        double si = n_pts[i][1];
                        // 形状関数N
                        N[i] = 0.25 * (1.0 + ri * r) * (1.0 + si * s) * (ri * r + si * s - 1.0);
                    }
                    // 節点4,6 : r方向辺上中点
                    foreach (int i in new int[] { 4, 6 })
                    {
                        // 節点の局所座標
                        double ri = n_pts[i][0];
                        double si = n_pts[i][1];
                        // 形状関数N
                        N[i] = 0.5 * (1.0 - r * r) * (1.0 + si * s);
                    }
                    // 節点5,7 : s方向辺上中点
                    foreach (int i in new int[] { 5, 7 })
                    {
                        // 節点の局所座標
                        double ri = n_pts[i][0];
                        double si = n_pts[i][1];
                        // 形状関数N
                        N[i] = 0.5 * (1.0 + ri * r) * (1.0 - s * s);
                    }
                }
                else if (nodeCnt == Constants.QuadNodeCnt_FirstOrder)
                {
                    // 節点0~3 : 四角形の頂点
                    for (int i = 0; i < nno; i++)
                    {
                        // 節点の局所座標
                        double ri = n_pts[i][0];
                        double si = n_pts[i][1];
                        // 形状関数N
                        N[i] = 0.25 * (1.0 + ri * r) * (1.0 + si * s);
                    }
                }
                // 表示する位置
                double showPosX = 0;
                double showPosY = 0;
                for (int k = 0; k < nodeCnt; k++)
                {
                    showPosX += pp[k][0] * N[k];
                    showPosY += pp[k][1] * N[k];
                }
                Complex cvalueX = new Complex(0, 0);
                Complex cvalueY = new Complex(0, 0);
                for (int k = 0; k < nodeCnt; k++)
                {
                    cvalueX += tagtXValues[k] * N[k];
                    cvalueY += tagtYValues[k] * N[k];
                }
                try
                {
                    double showScale = ((double)regionSize.Width / DefPanelWidth) * ArrowLength;
                    // 実数部のベクトル表示
                    int lenX = (int)((double)(cvalueX.Real / maxRotFValue) * showScale);
                    int lenY = (int)((double)(cvalueY.Real / maxRotFValue) * showScale);
                    if (lenX != 0 || lenY != 0)
                    {
                        // Y方向は表示上逆になる
                        lenY = -lenY;
                        using (Pen pen = new Pen(drawColor, 1))
                        {
                            //pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                            //pen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                            pen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
                            //pen.CustomEndCap = new System.Drawing.Drawing2D.AdjustableArrowCap(3, 3, false); // 重い
                            g.DrawLine(pen, (int)showPosX, (int)showPosY, (int)(showPosX + lenX), (int)(showPosY + lenY));
                        }
                    }
                }
                catch (Exception exception)
                {
                    System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace);
                }
            }
        }
Beispiel #3
0
 /// <summary>
 /// フィールド値の回転を描画する
 /// </summary>
 /// <param name="g"></param>
 /// <param name="ofs"></param>
 /// <param name="delta"></param>
 /// <param name="regionSize"></param>
 /// <param name="drawColor"></param>
 /// <param name="fieldDv"></param>
 /// <param name="minRotFValue"></param>
 /// <param name="maxRotFValue"></param>
 public virtual void DrawRotField(Graphics g, Size ofs, Size delta, Size regionSize, Color drawColor, FemElement.FieldDV fieldDv, double minRotFValue, double maxRotFValue)
 {
 }
Beispiel #4
0
 /// <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)
 {
 }
Beispiel #5
0
        /// <summary>
        /// フィールド値の回転を描画する
        /// </summary>
        /// <param name="g"></param>
        /// <param name="ofs"></param>
        /// <param name="delta"></param>
        /// <param name="regionSize"></param>
        /// <param name="drawColor"></param>
        /// <param name="fieldDv"></param>
        /// <param name="minRotFValue"></param>
        /// <param name="maxRotFValue"></param>
        public override void DrawRotField(Graphics g, Size ofs, Size delta, Size regionSize, Color drawColor, FemElement.FieldDV fieldDv, double minRotFValue, double maxRotFValue)
        {
            if (_Nodes == null || _FValues == null || _RotXFValues == null || _RotYFValues == null || _PoyntingXFValues == null || _PoyntingYFValues == null)
            {
                return;
            }
            Complex[] tagtXValues = null;
            Complex[] tagtYValues = null;
            if (fieldDv == FemElement.FieldDV.PoyntingXY)
            {
                tagtXValues = _PoyntingXFValues;
                tagtYValues = _PoyntingYFValues;
            }
            else if (fieldDv == FemElement.FieldDV.RotXY)
            {
                tagtXValues = _RotXFValues;
                tagtYValues = _RotYFValues;
            }
            else
            {
                return;
            }

            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;
            }

            // 表示する位置の面積座標
            double[] Li = new double[vertexCnt]
            {
                1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0
            };
            // 表示する位置の形状関数
            double[] vNi = null;
            if (nodeCnt == Constants.TriNodeCnt_FirstOrder)
            {
                vNi = new double[]
                {
                    Li[0],
                    Li[1],
                    Li[2]
                };
            }
            else
            {
                vNi = new double[]
                {
                    Li[0] * (2.0 * Li[0] - 1.0),
                    Li[1] * (2.0 * Li[1] - 1.0),
                    Li[2] * (2.0 * Li[2] - 1.0),
                    4.0 * Li[0] * Li[1],
                    4.0 * Li[1] * Li[2],
                    4.0 * Li[2] * Li[0],
                };
            }
            // 表示する位置
            double showPosX = 0;
            double showPosY = 0;

            for (int k = 0; k < nodeCnt; k++)
            {
                showPosX += pp[k][0] * vNi[k];
                showPosY += pp[k][1] * vNi[k];
            }
            Complex cvalueX = new Complex(0, 0);
            Complex cvalueY = new Complex(0, 0);

            for (int k = 0; k < nodeCnt; k++)
            {
                cvalueX += tagtXValues[k] * vNi[k];
                cvalueY += tagtYValues[k] * vNi[k];
            }
            try
            {
                double showScale = ((double)regionSize.Width / DefPanelWidth) * ArrowLength;
                // 実数部のベクトル表示
                int lenX = 0;
                int lenY = 0;
                if (Math.Abs(maxRotFValue) >= Constants.PrecisionLowerLimit)
                {
                    lenX = (int)((double)(cvalueX.Real / maxRotFValue) * showScale);
                    lenY = (int)((double)(cvalueY.Real / maxRotFValue) * showScale);
                }
                if (lenX != 0 || lenY != 0)
                {
                    // Y方向は表示上逆になる
                    lenY = -lenY;
                    using (Pen pen = new Pen(drawColor, 1))
                    {
                        //pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                        //pen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                        pen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
                        //pen.CustomEndCap = new System.Drawing.Drawing2D.AdjustableArrowCap(3, 3, false); // 重い
                        g.DrawLine(pen, (int)showPosX, (int)showPosY, (int)(showPosX + lenX), (int)(showPosY + lenY));
                    }
                }
            }
            catch (Exception exception)
            {
                System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace);
            }
        }
Beispiel #6
0
        /// <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;
         *  }
         *
         *  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;
         *  }
         *
         *  // 下記分割ロジックの原点となる頂点
         *  //   頂点0固定で計算していたが、原点の内角が直角のとき長方形メッシュになるので原点を2(頂点を0,1,2としたとき)にする
         *  int orginVertexNo = 2;
         *  // 内角が最大の頂点を取得し、その頂点を原点とする(後のロジックは原点が頂点を0,1,2としたとき、2になっている
         *  {
         *      double minCosth = double.MaxValue;
         *      int minCosthVertexNo = 0;
         *      for (int ino = 0; ino < vertexCnt; ino++)
         *      {
         *          const int vecCnt = 2;
         *          double[][] vec = new double[vecCnt][] { new double[ndim]{0, 0}, new double[ndim]{0, 0} };
         *          double[] len = new double[vecCnt];
         *          double costh;
         *          {
         *              int n1 = ino;
         *              int n2 = (ino + 1) % 3;
         *              int n3 = (ino + 2) % 3;
         *              vec[0][0] = pp[n2][0] - pp[n1][0];
         *              vec[0][1] = pp[n2][1] - pp[n1][1];
         *              vec[1][0] = pp[n3][0] - pp[n1][0];
         *              vec[1][1] = pp[n3][1] - pp[n1][1];
         *              len[0] = FemMeshLogic.GetDistance(pp[n1], pp[n2]);
         *              len[1] = FemMeshLogic.GetDistance(pp[n1], pp[n3]);
         *              costh = (vec[0][0] * vec[1][0] + vec[0][1] * vec[1][1]) / (len[0] * len[1]);
         *              if (costh < minCosth)
         *              {
         *                  minCosth = costh;
         *                  minCosthVertexNo = ino;
         *              }
         *          }
         *      }
         *      orginVertexNo = (minCosthVertexNo + 2) % 3;
         *  }
         *  // 三角形内部を四角形で分割
         *  // 面積座標L1方向分割数
         *  //int ndiv = 4;
         *  int ndiv = Constants.TriDrawFieldMshDivCnt;
         *  double defdL1 = 1.0 / (double)ndiv;
         *  double defdL2 = defdL1;
         *  for (int i1 = 0; i1 < ndiv; i1++)
         *  {
         *      double vL1 = i1 * defdL1;
         *      double vL1Next = (i1 + 1) * defdL1;
         *      if (i1 == ndiv - 1)
         *      {
         *          vL1Next = 1.0;
         *      }
         *      double vL2max = 1.0 - vL1;
         *      if (vL2max < 0.0)
         *      {
         *          // ERROR
         *          System.Diagnostics.Debug.WriteLine("logic error vL2max = {0}", vL2max);
         *          continue;
         *      }
         *      double fdiv2 = (double)ndiv * vL2max;
         *      int ndiv2 = (int)fdiv2;
         *      if (fdiv2 - (double)ndiv2 > Constants.PrecisionLowerLimit)
         *      {
         *          ndiv2++;
         *      }
         *      for (int i2 = 0; i2 < ndiv2; i2++)
         *      {
         *          double vL2 = i2 * defdL2;
         *          double vL2Next = (i2 + 1) * defdL2;
         *          if (i2 == ndiv2 - 1)
         *          {
         *              vL2Next = vL2max;
         *          }
         *          double vL3 = 1.0 - vL1 - vL2;
         *          if (vL3 < 0.0)
         *          {
         *              // ERROR
         *              System.Diagnostics.Debug.WriteLine("logic error vL3 = {0}", vL3);
         *              continue;
         *          }
         *
         *          // 四角形の頂点
         *          const int rectVCnt = 4;
         *          double[][] rectLi = new double[rectVCnt][]
         *          {
         *              new double[]{vL1    , vL2    , 0},
         *              new double[]{vL1Next, vL2    , 0},
         *              new double[]{vL1Next, vL2Next, 0},
         *              new double[]{vL1    , vL2Next, 0}
         *          };
         *          if ((i1 == ndiv - 1) || (i2 == ndiv2 - 1))
         *          {
         *              for (int k = 0; k < 3; k++)
         *              {
         *                  rectLi[2][k] = rectLi[3][k];
         *              }
         *          }
         *          double[][] rectpp = new double[rectVCnt][];
         *          for (int ino = 0; ino < rectVCnt; ino++)
         *          {
         *              if (rectLi[ino][0] < 0.0)
         *              {
         *                  rectLi[ino][0] = 0.0;
         *                  System.Diagnostics.Debug.WriteLine("logical error rectLi[{0}][0] = {1}", ino, rectLi[ino][0]);
         *              }
         *              if (rectLi[ino][0] > 1.0)
         *              {
         *                  rectLi[ino][0] = 1.0;
         *                  System.Diagnostics.Debug.WriteLine("logical error rectLi[{0}][0] = {1}", ino, rectLi[ino][0]);
         *              }
         *              if (rectLi[ino][1] < 0.0)
         *              {
         *                  rectLi[ino][1] = 0.0;
         *                  System.Diagnostics.Debug.WriteLine("logical error rectLi[{0}][1] = {1}", ino, rectLi[ino][1]);
         *              }
         *              if (rectLi[ino][1] > (1.0 - rectLi[ino][0]))  // L2最大値(1 - L1)チェック
         *              {
         *                  rectLi[ino][1] = 1.0 - rectLi[ino][0];
         *              }
         *              rectLi[ino][2] = 1.0 - rectLi[ino][0] - rectLi[ino][1];
         *              if (rectLi[ino][2] < 0.0)
         *              {
         *                  System.Diagnostics.Debug.WriteLine("logical error rectLi[{0}][2] = {1}", ino, rectLi[ino][2]);
         *              }
         *          }
         *          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);
         *          }
         *      }
         *  }
         * }
         */
        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;
            }

            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;
            }

            // 長方形描画領域のリスト
            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);
                }
            }
        }
Beispiel #7
0
 /// <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);
 }