【C言語】円・楕円形エリアに対するマウスカーソルの当たり判定をチェックする関数

技術

C言語で、マウスカーソルが円形や楕円形エリア内に入っているかを
判定する処理を実装した際のソースコードを備忘録も兼ねてまとめました。

本記事では、実際に使えるシンプルなサンプルコードを紹介します。
ゲームやツール開発などで、円形・楕円形の判定が必要な場合の参考になれば幸いです。

実装例とコード解説

サンプルプログラム(円・楕円の当たり判定)

まずは、マウスカーソルが指定した円形もしくは、楕円形エリア内に
触れているかを判定する関数のサンプルプログラムです。

#include <math.h>

typedef struct _ST_drawCircle{
	int				x;		// 楕円形エリアの中心(x座標)
	int				y;		// 楕円形エリアの中心(y座標)
	int				a;		// 楕円形の半径(横)
	int				b;		// 楕円形の半径(縦)
}ST_drawCircle;

int isMousePosEllipse( const ST_drawCircle stDrawCircle, const int mousePosX, const int mousePosY ){

	double x, y;
	int ret = -1;

	/* x軸の座標チェック */
	if( 
		( ( mousePosX >= stDrawCircle.x ) && ( mousePosX < ( stDrawCircle.x + stDrawCircle.a ) ) ) ||
		( ( mousePosX <= stDrawCircle.x ) && ( mousePosX > ( stDrawCircle.x - stDrawCircle.a ) ) )
	){
		/* y座標算出で使用するx座標の算出 */
		x = ( mousePosX >= stDrawCircle.x ) ? ( double )mousePosX - stDrawCircle.x : ( double )stDrawCircle.x - mousePosX;

		/* 判定に使用するy座標算出 */
		y = stDrawCircle.b * sqrt( 1.0 - ( ( x * x ) / ( stDrawCircle.a * stDrawCircle.a ) ) );

		/* y軸の座標チェック */
		if(
			( ( mousePosY >= stDrawCircle.y ) && ( mousePosY <= ( stDrawCircle.y + y ) ) ) ||
			( ( mousePosY <= stDrawCircle.y ) && ( mousePosY >= ( stDrawCircle.y - y ) ) )
		){
			ret = 0;
		}
	}

	return ret;
}

ソースコードの解説

ここでは、円形および楕円形エリアの当たり判定を行う関数
isMousePosEllipse() について、処理の流れに沿って解説します。

判定は、マウスカーソルの位置の x 座標・y 座標を順にチェックすることで行います。

マウスカーソル座標について

引数の mousePosX、mousePosY は、
それぞれマウスカーソルの x 座標、y 座標です。

マウスカーソルの座標取得方法については、本記事では割愛しますが、
DXライブラリを使用している場合であれば、GetMousePoint() で取得できます。

x軸方向の判定

はじめに、マウスカーソルの x 座標が楕円形エリアの横方向の範囲内にあるかを判定します。

楕円形エリアの中心座標から左右それぞれ半径 a の範囲内に
マウスカーソルが存在するかを if 文でチェックします。

この条件を満たさない場合、マウスカーソルは楕円形エリアの外側であることが確定するため、
以降の判定は行わずに処理を終了し、楕円の外を示す -1 を返却します。

楕円のx座標に対応するy座標の算出

x 軸方向の判定を通過した場合、次に楕円の方程式を用いて
マウスカーソルの x 座標に対応する y 座標の範囲を求めます。

ここでは、楕円の方程式

y=±b×(1x2/a2)y = ±b × √(1 – x^2 / a^2)

を用いることで、判定に使用する y の最大値を算出しています。

y軸方向の判定

最後に、算出した楕円の y 座標の値を用いて、
マウスカーソルの y 座標が楕円形エリア内にあるかを判定します。

楕円形エリアの中心座標から上下それぞれ y の範囲内に
マウスカーソルが存在するかを if 文でチェックします。
範囲内に収まっている場合は 0 を、範囲外の場合は -1 を返却します。

円にも対応できる理由

本関数では、楕円の半径として横方向に a、縦方向に b を使用しています。
この 2 つの値が同じ場合、楕円の式は円の式と等価になるため、
本処理を円形エリアの当たり判定にもそのまま利用できます。

まとめ

本記事では、マウスカーソルが円形および楕円形エリアに
触れているかを判定する C 言語のサンプルコードを紹介しました。

判定処理は、x 軸方向の判定 →
x 軸に対応する y 座標算出 →
y 軸方向の判定という、シンプルな手順で構成されています。

a と b に同じ値を指定すれば円形の当たり判定としても利用できるため、
ゲームやツール開発など、さまざまな場面で応用可能です。

コメント