Hope is a Dream. Dream is a Hope.

非公開ブログは再開しました。

C# グラフ描画

C#のGraphicsでグラフを書くことは良くある。 そのたびに、座標変換を書いていていよいよ面倒になったので、ここに記す。

        /// <summary>
        /// 正規化座標へ変換
        /// x[0,1], y[0,1]の範囲
        /// </summary>
        /// <param name="Origins">ワールド座標の点</param>
        /// <param name="ClipRect">ワールド座標のクリップ領域. xy:左下. </param>
        static PointF Norm(PointF Origin, RectangleF ClipRect)
        {
            PointF NormPoint = new PointF();

            NormPoint.X = (Origin.X - ClipRect.X) / (ClipRect.Width) + ClipRect.X;
            NormPoint.Y = (Origin.Y - ClipRect.Y) / (ClipRect.Height) + ClipRect.Y;

            return NormPoint;
        }

        /// <summary>
        /// 座標変換するぜ
        /// </summary>
        /// <param name="Origin"></param>
        /// <param name="ClipRect"></param>
        /// <param name="DrawRect"></param>
        static PointF ScreenPosition(PointF Origin, RectangleF ClipRect, RectangleF DrawRect)
        {
            PointF norm = Norm(Origin, ClipRect);

            PointF Screen = new PointF();

            Screen.X = (norm.X * DrawRect.Width) + DrawRect.X;
            Screen.Y = ((1f - norm.Y) * DrawRect.Height) + DrawRect.Y;


            return Screen;

        }

        /// <summary>
        /// 指定した位置にラインを描画
        /// </summary>
        /// <param name="e"></param>
        /// <param name="pen"></param>
        /// <param name="Origins">ワールド座標の点</param>
        /// <param name="ClipRect">ワールド座標のクリップ領域. xy:左下. </param>
        /// <param name="DrawRect">描画先のスクリーン座標. xy:左上</param>
        private void DrawLines(PaintEventArgs e, Pen pen, PointF[] Origins, RectangleF ClipRect, RectangleF DrawRect)
        {
            int N = Origins.Length;

            PointF[] ScrPoints = new PointF[N];

            for (int i = 0; i < Origins.Length; i++)
            {
                PointF _ScrPoint = ScreenPosition(Origins[i], ClipRect, DrawRect);

                ScrPoints[i] = _ScrPoint;
            }

            e.Graphics.DrawLines(pen, ScrPoints);

        }