角の二等分線について。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Yuyu

角の二等分線について。

#1

投稿記事 by Yuyu » 7年前

初めて質問させていただきます。角の二等分線の表示についてです。
Visual Studio Express 2013 for Windows Desktop C++ DxLibでゲームを制作しています。
まだまだ力のない初心者です。
以下、質問用に組んだプログラムです。

コード:

#include "DxLib.h"
#include "math.h"

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
	SetGraphMode(800,600, 32);
	SetMainWindowText("DxLib");
	ChangeWindowMode(TRUE),
	DxLib_Init(),
	SetDrawScreen(DX_SCREEN_BACK);

	//VECTORですが、2次元で使用しています。
	VECTOR A = { 0 };
	VECTOR B = { 0 };
	VECTOR C = { 0 };
	VECTOR P = { 0 };//点Pは、角の二等分線上の点
	double r = 300;//仮に設定する半径

	//点A,B,Cの設定//点Bは角の中心

	/*角の内側に二等分線を表示させたいのです*/
	int F = 1;//ここを、0か1に変更し、確かめてみてください。
	if (F == 0){
		//▼現在のままのプログラムで内側に表示される座標
		A = VGet(500, 100, 0);
		B = VGet(100, 100, 0);
		C = VGet(300, 400, 0);
	}
	else if (F == 1){
		//▼現在のままのプログラムで外側に表示される座標
		A = VGet(500, 100, 0);
		B = VGet(500, 300, 0);
		C = VGet(300, 400, 0);
	}

	double AngleAB = 0, AngleCB = 0;//AB,CBのatan2での角度
	double BisectorAngle = 0;//角の二等分の角度 ->これを求めたいのです。

	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0){
		AngleAB = atan2(B.y - A.y, B.x - A.x);//取得
		AngleCB = atan2(B.y - C.y, B.x - C.x);//取得
		BisectorAngle = (AngleAB + AngleCB) / 2.0;
		P.x = cos(BisectorAngle)*r + B.x; P.y = sin(BisectorAngle)*r + B.y;
		DrawLine(A.x, A.y, B.x, B.y, GetColor(0, 255, 0), 1);//線分AB
		DrawLine(C.x, C.y, B.x, B.y, GetColor(0, 255, 0), 1);//線分CB
		DrawLine(P.x, P.y, B.x, B.y, GetColor(0, 255, 255), 1);//線分PB
		DrawCircle(P.x, P.y, 3, GetColor(0, 255, 255), TRUE);//点Pをわかりやすく
		DrawFormatString(A.x, A.y, GetColor(0, 255, 0), "点A");
		DrawFormatString(B.x, B.y, GetColor(0, 255, 0), "点B");
		DrawFormatString(C.x, C.y, GetColor(0, 255, 0), "点C");
		DrawFormatString(P.x, P.y, GetColor(0, 255, 255), "点P");
		DrawFormatString(0,0, GetColor(255, 255, 255), "%d番",F);//仮
	}
	DxLib_End();
	return 0;
}
このプログラムは、Fの番号を変えることで角の二等分線がどこに表示されるのかが分かるようになっています。
(点Bに代入される座標が変わります。)
0にした場合はちゃんと角の内側に表示されますが、1にした場合は外側に表示されます。
点がどの座標にあっても、角の内側に角の二等分線が表示されるようにするにはどうすればよいのでしょうか。
(外側の場合はπを足せば内側になりますが、外側なのか内側なのかの判断をつけるにはどうすれば良いのでしょうか?)
教えてください。
(※フォーラムルールを読んだつもりですが、質問の仕方に問題がある場合はご指摘くださると助かります。)

あんどーなつ
記事: 171
登録日時: 7年前
連絡を取る:

Re: 角の二等分線について。

#2

投稿記事 by あんどーなつ » 7年前

数学の問題ですね。

まず、これは引き算が逆だと思います。逆でも多分いいのでしょうけど、∠ABCを出したい場合は→BAベクトルと→BCベクトルを出して、そのベクトルが→(1,0)に対して反時計回りに何度回転しているかを見ると思いますので...
Yuyu さんが書きました:

コード:

		AngleAB = atan2(B.y - A.y, B.x - A.x);//取得
		AngleCB = atan2(B.y - C.y, B.x - C.x);//取得
内側、外側でいうと、三角形の内角の和は180°なので、180°以上の時は360°からその角度を引けばいいと思います。とはいえ、一般的な場合について正しく描画させるためにはatan2関数がとりうる角度の範囲を正しく把握するか、以下のように書く必要があると思います(試験していないので間違っているかもしれないです)。

コード:

// 注意:実際のコードではない
AngleABC = AngleCB - AngleAB;
while (AngleABC < -2.0 * PI) AngleABC += 2.0 * PI;
while (AngleABC > 2.0 * PI) AngleABC -= 2.0 * PI;
if (AngleABC < PI) {
  BisectorAngle = AngleABC / 2.0;
  P = B + A.Rot(BisectorAngle);
} else {
  BisectorAngle = (2 * PI - AngleABC) / 2.0;
  P = B + A.Rot(-BisectorAngle);
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 角の二等分線について。

#3

投稿記事 by ISLe » 7年前

Yuyu さんが書きました:(外側の場合はπを足せば内側になりますが、外側なのか内側なのかの判断をつけるにはどうすれば良いのでしょうか?)
41行目と42行目のあいだに
if (((B.x - A.x)*(B.x - C.x)+(B.y - A.y)*(B.y - C.y)) < 0) BisectorAngle += DX_PI;
を追加してください。

内積を利用して、鋭角か鈍角かを判定し、鈍角の場合は180度回転させます。
ゲームの当たり判定などでよく使われる手法ですので、外積と合わせて使い方を知っておくと良いと思います。

Yuyu

Re: 角の二等分線について。

#4

投稿記事 by Yuyu » 7年前

あんどーなつ様、ISLe様、ご返信ありがとうございます。
無事、うまく実装することができました。
これから使えるように頑張ります。
ご回答ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る