ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

C# 画像にラインを引く際にShiftキーで45度に補正する

前回の記事のつづき。

effect.hatenablog.com

45度に補正する処理を加えました。

f:id:moko_03_25:20200308043127g:plain

考え方としては、まず開始位置から終了位置に向かうベクトルの角度をアークタンジェント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);
	}
}