総合 ゲーム 画像動画

WPF 円内に中点から伸びる直線を描く

キャンバス内に描かれた円の中心点から伸びる直線を描く方法を紹介します。もっとスマートな方法があると思いますが学習目的も兼ねて紹介します。

 


 

概要とソースコード

ソースコード

xamlとコードはGithubの方で公開しています。
https://github.com/kame-chan/WPF/tree/master/DrawLineIntoCircle

 

概要

マウスの左クリックを押している間、マウスの位置と円の中心を結ぶ直線を描画します。

円から線がはみ出さないようにすることと、円に近い場合はスナップするようにしています。直線の終点(マウスの座標)も表示しています。

このプログラムから学べること

  • マウスの位置取得
  • 動的な描画
  • 円の中心点からマウスの位置までの距離(長さ)を取得する方法
  • 直角三角形の角度の求め方

 

 

コード解説

https://github.com/kame-chan/WPF/blob/master/DrawLineIntoCircle/MainWindow.xaml.cs

コメントアウトで大体説明しているのでロジックの部分を解説します。

コードフロー

  1. キャンバス読み込み時に背景となる円などを描画
  2. マウスの左クリックにイベントを付け押されている間のみマウスの動きに追従して線を描画させる
  3. 描画される度に背景も含めて全て消して、全て再描画する
  4. マウスの座標を円の中心点0として扱う
  5. マウスの座標と中心点からの距離を直角三角形の斜辺とする
  6. マウスの座標から角度を求める
  7. 斜辺が半径を超える場合は斜辺=半径として角度と合わせて座標を算出する
  8. 線を描画する

 

今回のポイントは7番目の円から線がはみ出ないようにするところです。線を上書きで塗りつぶしたり見た目の実装方法はいろいろあると思います。今回は円に接するときの座標も取得したいのでこのような方法になっています。

 

 

まず斜辺Rはピタゴラスの定理で簡単に求められます。座標はキャンバスの始点(0,0)から円の中心点へと移動させて考える必要があります。今回紹介したコードでは(128,128)が中心となっています。

斜辺 double R = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));

斜辺の長さが円の半径を超えた場合は、長さを円の半径にします。

斜辺=半径の長さのときの座標も知りたいので先に角度を求めます。

 

角度は三角関数を使って求めます。今回は対辺と隣辺が分かっているのでtanθで求めます。

角度 double a = Math.Atan(y / x) * 180.0 / Math.PI;

これで斜辺の長さ(=半径)と角度が分かったので円と接する時の座標が求められます。

 

座標 x = R * Math.Cos(a);

座標 y = R * Math.Sin(a);

Rは半径と同じなので今回は128です。

 

注意したいのがこれは全て中心点から見てX座標もY座標も正の値の場合ということです。最終的には4区分でそれぞれ値を調整する必要があるということです。

 

円ellipseと線lineをの交差をもっとスマートに判定する方法もあるので気になる人は調べてみてください。

コメントを残す。

メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。URLを含むコメントは承認待ちになります。