前回の記事のつづき。
45度に補正する処理を加えました。
考え方としては、まず開始位置から終了位置に向かうベクトルの角度をアークタンジェント(atan2)で算出して度数に直しています。
この時、ベクトルを絶対値にすることで360度どの方向でも0~90度でチェックできます。
atanやatan2使用時には0除算対策をしないとエラーが出るので注意。
// マウスドラッグ中 private void PictureBox1_MouseMove(object sender, MouseEventArgs e) { // マウスの左ボタンが押されている場合のみ処理 if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left) { // Shiftキーが押されていれば直線にする if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { // 比較のためにXとYの移動距離を算出 int checkPosX = Math.Abs(cursorPos().X - startPoint.X); int checkPosY = Math.Abs(cursorPos().Y - startPoint.Y); // 角度を算出 double d = 0.0; if (checkPosX != 0 && checkPosY != 0) // 0除算対策 { // 角度を求める d = Math.Atan2(checkPosY, checkPosX); // ラジアンから度数に変換 d = d * 180 / Math.PI; // ラベルに表示 label2.Text = d.ToString(); } // XとYのどちらが長いか比較する if (checkPosX >= checkPosY) // 横長の場合 { if (40.0 < d && d < 50.0) { // 座標を取得 // 開始位置に対して現在位置が正負どちらか判定して処理 endPoint.X = cursorPos().X; endPoint.Y = startPoint.Y + (Math.Sign(cursorPos().Y - startPoint.Y) * checkPosX); } else { // 座標を取得 endPoint.X = cursorPos().X; endPoint.Y = startPoint.Y; } } else // 縦長の場合 { if (40.0 < d && d < 50.0) { // 座標を取得 // 開始位置に対して現在位置が正負どちらか判定して処理 endPoint.X = startPoint.X + (Math.Sign(cursorPos().X - startPoint.X) * checkPosY); endPoint.Y = cursorPos().Y; } else { // 座標を取得 endPoint.X = startPoint.X; endPoint.Y = cursorPos().Y; } } } else { // 座標を取得 endPoint.X = cursorPos().X; endPoint.Y = cursorPos().Y; } // 描画 DrawLine(startPoint, endPoint); } }