【C#】寸法線の描画

シェアする

  • このエントリーをはてなブックマークに追加
最近の記事
  • 10/21 【C#】寸法線の描画
  • 10/21 【C#】GraphicsPathの領域取得
  • 10/20 【C#】GraphicsPathの描画
  • 10/18 【C#】GraphicsPath
  • 10/17 【C#】Bitmap画像データの拡大縮小
  • 10/15 【C#】画像の座標系
  • 10/14 【C#】画像の上下左右反転、90,180,270度回転
  • 10/3 【C#】SplitContainerのPanel固定方法
  • 9/7 【Neural Network Console】学習データの出力方法
  • 9/3 Deep Learning向け学習画像撮り込みソフト公開
  • 9/1 【Neural Network Console】新規画像のDataset作成方法
  • 8/28 【Neural Network Console】GUI表示スケールの変更
  • 8/22 【Neural Network Console】CPU/GPU処理の設定切替
  • 8/21 【Neural Network Console】Learning Rate(学習率)の設定
  • 8/20 ソニーの無償AIソフト Neural Network Consoleの入手ダウンロード、インストール
  • 8/20 Deep Learning
  • 8/20
  • 8/19 古いバージョンのVisual Studio Community/Expressの入手ダウンロード
  • 8/19 CUDAの入手、ダウンロード、インストール方法
  • 8/17 【C#.NET】マイクロソフト仕様のアフィン変換
  • 8/5 【C#】ファイルを開くダイアログボックスの表示
  • 8/2 キャノンプリンターのCDトレイはどこ?!
  • 7/6 【参考書籍】画像処理・機械学習プログラミング OpenCV 3対応
  • 6/20 【Python,matplotlib】動くグラフをAnimationGifに保存する方法
  • 6/17 シグモイド関数の微分
  • 6/15 シグモイド関数
  • 6/13 合成関数の微分
  • 6/12 WordPressで数式エディタ風に数式を入力したい
  • 6/11 PythonをVisual Studioでインストールする方法
  • 6/9 【Python】OpenCVをAnacondaでインストール(Windows編)
  • 6/6 【Python】Anacondaで複数バージョンの環境切り替え
  • 6/6 画像センシング展2017に出展します。
  • 6/1 【Office365】Web版Outlookのフォントサイズ変更
  • 6/1 【Anaconda】モジュールのアップデートでエラー発生
  • 6/1 【Anaconda】コマンドリストの表示
  • 5/29 Windows10パソコン購入
  • 5/24 Anacondaのアンインストール
  • 5/24 【Jupyter Notebook】新規プログラムの作成
  • 5/23 【Python】開発環境の構築
  • 5/23 Pythonはじめました
  • 4/6 【Office365】Web版Outlookのスレッド表示を解除する方法
  • 4/5 【Excel】フーリエ解析(FFT)
  • 3/20 Canny edge detection
  • 3/20 【Excel2016】分析ツールの表示
  • 3/5 【Visual Studio】黒い背景色を白に変更する方法
  • 2/8 【Windows10】拡張モニタに表示されたウィンドウを元に戻す
  • 2/7 複素数の計算
  • 1/18 【Excel】棒グラフの横軸の目盛を0始まりにする
  • 1/16 【Excel】フーリエ変換
  • 1/6 【OpenCV】疑似カラー(カラーマップ)

  • GraphicsPathを使うことで、文字を任意角度で表示することが出来るのを知った元メカ屋な私。

    これは寸法線の描画に使えそう!

    と思い、寸法線の描画部分をクラスにまとめたものを作成してみました。

    実行画面

    C# 寸法線の描画

    寸法線描画のクラス↓

    public class Dimension
    {
        ///<summary>
        /// 線の色を取得設定します。
        /// </summary>
        public static Color LineColor { get; set; } = Color.Green;
    
        /// <summary>
        /// 文字の色を取得設定します。
        /// </summary>
        public static Color TextColor { get; set; } = Color.DeepSkyBlue;
    
        /// <summary>
        /// フォントの名前を取得設定します。
        /// </summary>
        public static FontFamily Family { get; set; } = new FontFamily("Century Gothic");
    
        /// <summary>
        /// フォントのスタイルを取得設定します。
        /// </summary>
        public static FontStyle Style { get; set; } = FontStyle.Regular;
    
        /// <summary>
        /// 文字のサイズ(emスクエア)を取得設定します。
        /// </summary>
        public static float EmSize { get; set; } = 18.0f;
    
        /// <summary>
        /// 文字の書式設定を取得設定します。
        /// </summary>
        public static StringFormat Format { get; set; } = new StringFormat();
    
        /// <summary>
        /// 寸法値の表示位置の中心からのズレを取得設定します。
        /// </summary>
        public static float TextOffsetX { get; set; } = 0.0f;
    
        /// <summary>
        /// 寸法値の表示位置の寸法線からの距離を取得設定します。
        /// </summary>
        public static float TextOffsetY { get; set; } = 8.0f;
    
        /// <summary>
        /// 寸法線の線幅を取得設定します。
        /// </summary>
        public static float LineWidth { get; set; } = 1f;
    
        /// <summary>
        /// 矢印の大きさを取得設定します。
        /// </summary>
        public static float ArrowSize { get; set; } = 8f;
    
        /// <summary>
        /// 寸法線の描画
        /// </summary>
        /// <param name="g">描画先のGraphicsオブジェクトを指定します。</param>
        /// <param name="StartPoint">寸法を引き出す位置を指定します。(開始点側)</param>
        /// <param name="EndPoint">寸法を引き出す位置を指定します。(終了点側)</param>
        /// <param name="Offset">指定した点から寸法線を表示するまでの距離を指定します。</param>
        /// <param name="Text">寸法値に表示する文字を指定します。</param>
        public static void DrawDimension(Graphics g, PointF StartPoint, PointF EndPoint, float Offset, string Text)
        {
            // 2点間の中心座標
            PointF center = new PointF((StartPoint.X + EndPoint.X) / 2f, (StartPoint.Y + EndPoint.Y) / 2f);
            // 文字の回転角度
            float thRad = (float)Math.Atan2(EndPoint.Y - StartPoint.Y, EndPoint.X - StartPoint.X);  // ラジアン
            float th = thRad * 180.0f / (float)Math.PI;
    
            // パスの作成
            var pathText = new System.Drawing.Drawing2D.GraphicsPath();
    
            //////////////////////////////////////////////////////////////////
            // 寸法値の描画
            pathText.AddString(
                        Text,
                        Family,
                        (int)Style,
                        EmSize,
                        new PointF(0, 0),
                        Format);
    
            // 文字の領域取得
            RectangleF rect = pathText.GetBounds();
    
            // アフィン変換行列の計算
            var mat = new System.Drawing.Drawing2D.Matrix();
    
            // いったん文字を原点へ移動(文字領域の中心下側が基準)
            mat.Translate(-rect.Width / 2f, -rect.Height, System.Drawing.Drawing2D.MatrixOrder.Append);
            // オフセット分の移動(Y方向は逆に移動する)
            mat.Translate(TextOffsetX, -TextOffsetY - Offset, System.Drawing.Drawing2D.MatrixOrder.Append);
            // 寸法線に合わせた回転
            mat.Rotate(th, System.Drawing.Drawing2D.MatrixOrder.Append);
            // 表示位置まで移動
            mat.Translate(center.X, center.Y, System.Drawing.Drawing2D.MatrixOrder.Append);
    
            // パスをアフィン変換
            pathText.Transform(mat);
    
            // 寸法値用ブラシの作成
            var brushText = new SolidBrush(TextColor);
    
            // 描画
            g.FillPath(brushText, pathText);
    
            //////////////////////////////////////////////////////////////////
            // 寸法補助線の描画
    
            // 寸法線用ペンの作成
            var penLine = new Pen(LineColor, LineWidth);
    
            float lineLength = Offset + 5f; // 少し飛び出させる
    
            // StartPoint側の描画
            var StartPointDst = new PointF(
                StartPoint.X + lineLength * (float)Math.Cos(thRad - Math.PI / 2.0),
                StartPoint.Y + lineLength * (float)Math.Sin(thRad - Math.PI / 2.0)
                );
            g.DrawLine(penLine, StartPoint, StartPointDst);
    
            // EndPoint側の描画
            var EndPointDst = new PointF(
                EndPoint.X + lineLength * (float)Math.Cos(thRad - Math.PI / 2.0),
                EndPoint.Y + lineLength * (float)Math.Sin(thRad - Math.PI / 2.0)
                );
            g.DrawLine(penLine, EndPoint, EndPointDst);
    
            //////////////////////////////////////////////////////////////////
            // 寸法線(矢印)の描画
            System.Drawing.Drawing2D.AdjustableArrowCap  arrow
                        = new System.Drawing.Drawing2D.AdjustableArrowCap(ArrowSize, ArrowSize, false);
    
            penLine.CustomStartCap = arrow;
            penLine.CustomEndCap = arrow;
    
            var StartPointOffset = new PointF(
                StartPoint.X + Offset * (float)Math.Cos(thRad - Math.PI / 2.0),
                StartPoint.Y + Offset * (float)Math.Sin(thRad - Math.PI / 2.0)
                );
    
            var EndPointOffset = new PointF(
                EndPoint.X + Offset * (float)Math.Cos(thRad - Math.PI / 2.0),
                EndPoint.Y + Offset * (float)Math.Sin(thRad - Math.PI / 2.0)
                );
    
            // 矢印の描画
            g.DrawLine(penLine, StartPointOffset, EndPointOffset);
        }
    }
    

    使用する側はこんな感じで↓

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        var StartPoint = new PointF();
        var EndPoint = new PointF();
    
        // 四角形の描画
        var p = new Pen(Brushes.Black, 2);
        e.Graphics.DrawRectangle(p, 100, 100, 200, 200);
        e.Graphics.DrawRectangle(p, 100, 100, 400, 300);
    
        ///////////////////////////////////////////////////////////////
        // 横方向の寸法線の描画
        StartPoint.X = 100; StartPoint.Y = 100;
        EndPoint.X = 300; EndPoint.Y = 100;
        Dimension.DrawDimension(e.Graphics, StartPoint, EndPoint, 20, "200");
    
        StartPoint.X = 100; StartPoint.Y = 100;
        EndPoint.X = 500; EndPoint.Y = 100;
        Dimension.DrawDimension(e.Graphics, StartPoint, EndPoint, 50, "400");
    
        ///////////////////////////////////////////////////////////////
        // 縦方向の寸法線の描画
        StartPoint.X = 100; StartPoint.Y = 300;
        EndPoint.X = 100; EndPoint.Y = 100;
        Dimension.DrawDimension(e.Graphics, StartPoint, EndPoint, 20, "200");
    
        StartPoint.X = 100; StartPoint.Y = 400;
        EndPoint.X = 100; EndPoint.Y = 100;
        Dimension.DrawDimension(e.Graphics, StartPoint, EndPoint, 50, "300");
    
        ///////////////////////////////////////////////////////////////
        // 斜めの寸法線の描画
        StartPoint.X = 100; StartPoint.Y = 100;
        EndPoint.X = 500; EndPoint.Y = 400;
        Dimension.DrawDimension(e.Graphics, StartPoint, EndPoint, 20, "500");
    }
    

    プログラムはこちら↓に置いておきました。

    DrawDimensionLine.zip(Visual Studio 2015)

    機械製図的には寸法線の引き出し方向など、怪しい部分もありそうなので、良い感じになるように修正してみて下さい。

    画像処理のためのC#へ戻る